Investments API for accessing investment account and holdings data.
This module provides access to investment portfolios including:
- Investment accounts (brokerage, pension, ISA, etc.)
- Holdings (stocks, bonds, funds, ETFs)
- Portfolio valuations
- Asset allocations
Features
- List all investment accounts
- Get detailed holdings for each account
- Track portfolio performance
- Analyze asset allocation
- Monitor investment positions
Prerequisites
- User authentication with authorization code
- Investment account connections via Tink Link
Flow
# Step 1: User connects investment accounts via Tink Link
# Receive authorization code
# Step 2: Exchange code for access token
client = Tink.client(
client_id: "your_client_id",
client_secret: "your_client_secret"
)
{:ok, token_response} = Tink.Auth.exchange_code(client, code)
# Step 3: Create authenticated client
user_client = Tink.client(access_token: token_response["access_token"])
# Step 4: List investment accounts
{:ok, accounts} = Tink.Investments.list_accounts(user_client)
# Step 5: Get holdings for specific account
account_id = hd(accounts["accounts"])["id"]
{:ok, holdings} = Tink.Investments.get_holdings(user_client, account_id)Use Cases
Portfolio Overview
@spec get_portfolio_summary(Client.t()) :: {:ok, map()} | {:error, Error.t()}
def get_portfolio_summary(client) do
{:ok, accounts} = Tink.Investments.list_accounts(client)
total_value =
Enum.reduce(accounts["accounts"], Decimal.new(0), fn account, acc ->
value = get_in(account, ["balance", "amount", "value"])
Decimal.add(acc, Decimal.new(to_string(value)))
end)
%{
total_accounts: length(accounts["accounts"]),
total_value: total_value,
accounts: accounts["accounts"]
}
endAsset Allocation Analysis
@spec analyze_asset_allocation(Client.t(), String.t()) :: {:ok, map()} | {:error, Error.t()}
def analyze_asset_allocation(client, account_id) do
{:ok, holdings} = Tink.Investments.get_holdings(client, account_id)
holdings["holdings"]
|> Enum.group_by(& &1["instrument"]["type"])
|> Enum.map(fn {type, holdings} ->
total = Enum.reduce(holdings, 0, fn h, acc ->
acc + get_in(h, ["marketValue", "amount", "value"])
end)
{type, total}
end)
|> Map.new()
endPerformance Tracking
@spec track_performance(Client.t()) :: {:ok, list(map())} | {:error, Error.t()}
def track_performance(client) do
{:ok, accounts} = Tink.Investments.list_accounts(client)
Enum.map(accounts["accounts"], fn account ->
account_value = get_in(account, ["balance", "amount", "value"])
{:ok, holdings} = Tink.Investments.get_holdings(client, account["id"])
total_cost_basis =
Enum.reduce(holdings["holdings"], 0, fn holding, acc ->
quantity = holding["quantity"]
avg_price = get_in(holding, ["averagePurchasePrice", "amount", "value"])
acc + (quantity * avg_price)
end)
gain_loss = account_value - total_cost_basis
gain_loss_percent = (gain_loss / total_cost_basis) * 100
%{
account_name: account["name"],
current_value: account_value,
cost_basis: total_cost_basis,
gain_loss: gain_loss,
return_percent: gain_loss_percent
}
end)
endRequired Scopes
accounts:read- Read account informationinvestment-accounts:readonly- Read investment account details
Links
Summary
Functions
Gets holdings (positions) for a specific investment account.
Lists all investment accounts for the authenticated user.
Functions
@spec get_holdings(Tink.Client.t(), String.t()) :: {:ok, map()} | {:error, Tink.Error.t()}
Gets holdings (positions) for a specific investment account.
Returns detailed information about all securities held in the account, including stocks, bonds, funds, and other instruments.
Parameters
client- Tink client with user access token and required scopesaccount_id- Investment account ID
Returns
{:ok, holdings}- List of holdings with details{:error, error}- If the request fails
Examples
user_client = Tink.client(access_token: user_access_token)
{:ok, holdings} = Tink.Investments.get_holdings(
user_client,
"investment_account_123"
)
#=> {:ok, %{
# "holdings" => [
# %{
# "id" => "holding_1",
# "instrument" => %{
# "type" => "STOCK",
# "symbol" => "AAPL",
# "name" => "Apple Inc.",
# "isin" => "US0378331005",
# "mic" => "XNAS"
# },
# "quantity" => 100.0,
# "averagePurchasePrice" => %{
# "amount" => %{"value" => 150.00, "currencyCode" => "USD"}
# },
# "currentPrice" => %{
# "amount" => %{"value" => 175.50, "currencyCode" => "USD"}
# },
# "marketValue" => %{
# "amount" => %{"value" => 17550.00, "currencyCode" => "USD"}
# },
# "costBasis" => %{
# "amount" => %{"value" => 15000.00, "currencyCode" => "USD"}
# },
# "unrealizedGainLoss" => %{
# "amount" => %{"value" => 2550.00, "currencyCode" => "USD"}
# },
# "unrealizedGainLossPercent" => 17.0,
# "lastUpdated" => "2024-01-15T16:00:00Z"
# },
# %{
# "id" => "holding_2",
# "instrument" => %{
# "type" => "FUND",
# "symbol" => "VUSA",
# "name" => "Vanguard S&P 500 UCITS ETF",
# "isin" => "IE00B3XXRP09"
# },
# "quantity" => 500.0,
# "marketValue" => %{
# "amount" => %{"value" => 45000.00, "currencyCode" => "GBP"}
# }
# },
# %{
# "id" => "holding_3",
# "instrument" => %{
# "type" => "BOND",
# "name" => "UK Government Bond",
# "isin" => "GB00B128DP46"
# },
# "quantity" => 1000.0,
# "marketValue" => %{
# "amount" => %{"value" => 10500.00, "currencyCode" => "GBP"}
# }
# }
# ],
# "totalValue" => %{
# "amount" => %{"value" => 73050.00, "currencyCode" => "GBP"}
# }
# }}Holding Fields
Instrument Information
- type: STOCK, BOND, FUND, ETF, OPTION, CRYPTO, COMMODITY, etc.
- symbol: Trading symbol (e.g., AAPL, VUSA)
- name: Full instrument name
- isin: International Securities Identification Number
- mic: Market Identifier Code
Position Details
- quantity: Number of units held
- averagePurchasePrice: Average price paid per unit
- currentPrice: Current market price per unit
- marketValue: Total current value (quantity × current price)
- costBasis: Total purchase cost (quantity × average price)
Performance
- unrealizedGainLoss: Current profit/loss (not yet sold)
- unrealizedGainLossPercent: Percentage gain/loss
- lastUpdated: When price was last updated
Use Cases
# Find all stock positions
{:ok, holdings} = Tink.Investments.get_holdings(client, account_id)
stocks =
holdings["holdings"]
|> Enum.filter(&(&1["instrument"]["type"] == "STOCK"))
# Calculate total portfolio value
total =
holdings["holdings"]
|> Enum.reduce(0, fn holding, acc ->
value = get_in(holding, ["marketValue", "amount", "value"])
acc + value
end)
# Find largest position
largest =
holdings["holdings"]
|> Enum.max_by(&get_in(&1, ["marketValue", "amount", "value"]))
# Check diversification
stock_value = calculate_asset_type_value(holdings, "STOCK")
bond_value = calculate_asset_type_value(holdings, "BOND")
total_value = stock_value + bond_value
stock_allocation = (stock_value / total_value) * 100
bond_allocation = (bond_value / total_value) * 100Required Scopes
investment-accounts:readonly
@spec list_accounts(Tink.Client.t()) :: {:ok, map()} | {:error, Tink.Error.t()}
Lists all investment accounts for the authenticated user.
Parameters
client- Tink client with user access token and required scopes
Returns
{:ok, accounts}- List of investment accounts{:error, error}- If the request fails
Examples
# Get access token first
{:ok, token} = Tink.Auth.exchange_code(client, authorization_code)
user_client = Tink.client(access_token: token["access_token"])
{:ok, accounts} = Tink.Investments.list_accounts(user_client)
#=> {:ok, %{
# "accounts" => [
# %{
# "id" => "investment_account_123",
# "name" => "Investment ISA",
# "type" => "ISA",
# "balance" => %{
# "amount" => %{"value" => 125000.50, "currencyCode" => "GBP"}
# },
# "accountNumber" => "12345678",
# "financialInstitution" => %{
# "id" => "bank_abc",
# "name" => "Example Bank"
# }
# },
# %{
# "id" => "investment_account_456",
# "name" => "Pension Account",
# "type" => "PENSION",
# "balance" => %{
# "amount" => %{"value" => 450000.00, "currencyCode" => "GBP"}
# }
# }
# ],
# "nextPageToken" => nil
# }}Account Types
BROKERAGE- Standard brokerage accountPENSION- Pension/retirement accountISA- Individual Savings Account (UK)SIPP- Self-Invested Personal Pension (UK)IRA- Individual Retirement Account (US)401K- 401(k) retirement account (US)OTHER- Other investment account types
Required Scopes
accounts:readinvestment-accounts:readonly