Skip to main content

Overview

The PortfolioFetcher retrieves your profile, open positions, and trading history from the Limitless Exchange API. It requires an authenticated HttpClient.

Setup

import limitless "github.com/limitless-labs-group/limitless-exchange-go-sdk/limitless"

client := limitless.NewHttpClient() // loads LIMITLESS_API_KEY from env
portfolio := limitless.NewPortfolioFetcher(client)
PortfolioFetcher requires an authenticated client. Configure LIMITLESS_API_KEY, use WithAPIKey, or use WithHMACCredentials for partner/backend flows.

Current Profile

Use GetCurrentProfile() to fetch the authenticated caller’s private profile via GET /profiles/me. This is the preferred helper when the client is already authenticated and you do not want to pass a wallet address.
ctx := context.Background()
profile, err := portfolio.GetCurrentProfile(ctx)
if err != nil {
    log.Fatal(err)
}

fmt.Printf("Profile ID: %d\n", profile.ID)
fmt.Printf("Account: %s\n", profile.Account)
if profile.Rank != nil {
    fmt.Printf("Fee rate: %d bps\n", profile.Rank.FeeRateBps)
}

Fetching a Profile by Address

Use GetProfile() to retrieve a user profile by wallet address:
profile, err := portfolio.GetProfile(ctx, "0xYOUR_WALLET_ADDRESS")
if err != nil {
    log.Fatal(err)
}

fmt.Printf("Username: %s\n", profile.Username)
fmt.Printf("Display name: %s\n", profile.DisplayName)
if profile.Rank != nil {
    fmt.Printf("Rank: %s (fee rate: %d bps)\n", profile.Rank.Name, profile.Rank.FeeRateBps)
}

UserProfile Fields

FieldTypeDescription
IDintUser ID
AccountstringWallet address
Username*stringUsername (nil if unset)
DisplayName*stringDisplay name (nil if unset)
Rank*UserRankUser rank with fee rate
Points*float64Accumulated points (nil if unset)

Fetching All Positions

Use GetPositions() to retrieve all your open positions:
positions, err := portfolio.GetPositions(ctx)
if err != nil {
    log.Fatal(err)
}

fmt.Printf("CLOB positions: %d\n", len(positions.CLOB))
fmt.Printf("AMM positions: %d\n", len(positions.AMM))
The response is a PortfolioPositionsResponse with the following fields:
FieldTypeDescription
CLOB[]CLOBPositionPositions on CLOB (order book) markets
AMM[]AMMPositionPositions on AMM (automated market maker) markets
Points*stringAccumulated points (nil if unset)
Rewards*PortfolioRewardsAccumulated rewards (nil if unset)

CLOB Positions

Use GetCLOBPositions() for CLOB-only positions, or iterate over positions.CLOB:
clobPositions, err := portfolio.GetCLOBPositions(ctx)
if err != nil {
    log.Fatal(err)
}

for _, pos := range clobPositions {
    fmt.Printf("%s — yes: %s, no: %s\n", pos.Market.Title, pos.TokensBalance.Yes, pos.TokensBalance.No)
}

CLOBPosition Fields

FieldTypeDescription
MarketPositionMarketMarket title, slug, and metadata
MakerAddressstringYour wallet address
PositionsCLOBPositionSidesPosition details per side
TokensBalanceTokenBalanceCurrent token balance (per-outcome)
LatestTradeLatestTradeMost recent trade on this position
Orders*CLOBPositionOrdersOpen orders (nil if none)

AMM Positions

Use GetAMMPositions() for AMM-only positions:
ammPositions, err := portfolio.GetAMMPositions(ctx)
if err != nil {
    log.Fatal(err)
}

for _, pos := range ammPositions {
    fmt.Printf("%s — outcome: %d, unrealized PnL: %s\n",
        pos.Market.Title, pos.OutcomeIndex, pos.UnrealizedPnl)
}

AMMPosition Fields

FieldTypeDescription
MarketPositionMarketMarket title, slug, and metadata
AccountstringYour wallet address
OutcomeIndexintOutcome index
CollateralAmountstringCollateral deposited
OutcomeTokenAmountstringOutcome tokens held
AverageFillPricestringAverage entry price
RealizedPnlstringRealized profit and loss
UnrealizedPnlstringUnrealized profit and loss

Trading History

Use GetUserHistory() to retrieve cursor-paginated trading history. The signature is GetUserHistory(ctx, cursor string, limit int) — pass an empty cursor for the first page, then *history.NextCursor for subsequent pages:
history, err := portfolio.GetUserHistory(ctx, "", 20) // first page, 20 items
if err != nil {
    log.Fatal(err)
}

fmt.Printf("Fetched %d trades\n", len(history.Data))
for _, entry := range history.Data {
    fmt.Printf("%+v\n", entry)
}

// Next page, if any
if history.NextCursor != nil {
    next, err := portfolio.GetUserHistory(ctx, *history.NextCursor, 20)
    if err != nil {
        log.Fatal(err)
    }
    _ = next
}

Complete Example

package main

import (
    "context"
    "fmt"
    "log"

    limitless "github.com/limitless-labs-group/limitless-exchange-go-sdk/limitless"
)

func main() {
    client := limitless.NewHttpClient()
    portfolio := limitless.NewPortfolioFetcher(client)
    ctx := context.Background()

    // Fetch all positions
    positions, err := portfolio.GetPositions(ctx)
    if err != nil {
        log.Fatal(err)
    }

    fmt.Printf("CLOB positions: %d\n", len(positions.CLOB))
    for _, pos := range positions.CLOB {
        fmt.Printf("  %s — yes: %s, no: %s\n", pos.Market.Title, pos.TokensBalance.Yes, pos.TokensBalance.No)
    }

    fmt.Printf("\nAMM positions: %d\n", len(positions.AMM))
    for _, pos := range positions.AMM {
        fmt.Printf("  %s — unrealized PnL: %s\n", pos.Market.Title, pos.UnrealizedPnl)
    }

    // Fetch trading history (cursor-based; empty cursor = first page)
    history, err := portfolio.GetUserHistory(ctx, "", 10)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("\nRecent trades: %d\n", len(history.Data))
}