Skip to main content

Overview

The PortfolioFetcher retrieves your profile, open positions, and trading history. It requires an authenticated client.

Setup

use limitless_exchange_rust_sdk::Client;

let client = Client::new()?;

// Access through the root client
let portfolio = client.portfolio.clone();
PortfolioFetcher requires authentication. Configure LIMITLESS_API_KEY or HMAC credentials before calling these endpoints.

Fetching Your Profile

Use get_profile() to retrieve a profile by wallet address:
let profile = client
    .portfolio
    .get_profile("0xYOUR_WALLET_ADDRESS")
    .await?;

println!("id {}", profile.id);
println!("account {}", profile.account);

if let Some(display_name) = profile.display_name.as_deref() {
    println!("display name {}", display_name);
}

if let Some(rank) = profile.rank.as_ref() {
    println!("rank {} fee {}", rank.name, rank.fee_rate_bps);
}

Fetching All Positions

Use get_positions() to retrieve your portfolio:
let positions = client.portfolio.get_positions().await?;

println!("CLOB positions: {}", positions.clob.len());
println!("AMM positions: {}", positions.amm.len());

CLOB Positions

Use get_clob_positions() for CLOB-only positions:
let positions = client.portfolio.get_clob_positions().await?;

for pos in positions {
    println!("{} {}", pos.market.title, pos.tokens_balance.yes);
}

AMM Positions

Use get_amm_positions() for AMM-only positions:
let positions = client.portfolio.get_amm_positions().await?;

for pos in positions {
    println!(
        "{} outcome={} unrealized={}",
        pos.market.title,
        pos.outcome_index,
        pos.unrealized_pnl
    );
}

User History

The Rust SDK uses the current cursor-based history API:
  • pass None for the first request
  • the SDK sends cursor= with an empty value on that first call
  • subsequent requests use the returned next_cursor
  • limit defaults to 20 when omitted
let history = client.portfolio.get_user_history(None, Some(20)).await?;

for entry in &history.data {
    println!(
        "block={} tx={:?} strategy={:?}",
        entry.block_timestamp,
        entry.transaction_hash,
        entry.strategy
    );
}

if let Some(next_cursor) = history.next_cursor.as_deref() {
    let next_page = client
        .portfolio
        .get_user_history(Some(next_cursor), Some(20))
        .await?;

    println!("next page entries {}", next_page.data.len());
}

HistoryResponse

FieldTypeDescription
dataVec<HistoryEntry>History records
next_cursorOption<String>Cursor token for the next page

HistoryEntry

FieldTypeDescription
block_timestampi64Block timestamp
collateral_amountOption<String>Collateral amount when present
marketOption<HistoryMarket>Market metadata
outcome_indexOption<i32>Outcome index
outcome_token_amountOption<String>Single token amount
outcome_token_amountsOption<Vec<String>>Multi-outcome token amounts
outcome_token_priceOption<Value>Price payload from the API
strategyOption<String>Strategy label
transaction_hashOption<String>Related transaction hash
The first cursor request is not page=1. The Rust SDK intentionally opts into the new backend flow by sending cursor= empty on the first request.

Authentication Errors

If the client is missing credentials, portfolio methods return LimitlessError::AuthenticationRequired before making the HTTP request:
match client.portfolio.get_positions().await {
    Err(limitless_exchange_rust_sdk::LimitlessError::AuthenticationRequired { operation }) => {
        eprintln!("auth required for {}", operation);
    }
    other => println!("{:?}", other),
}