Description
Retrieves all currently open trading positions grouped by model, including real-time unrealized P&L, entry prices, current prices, exit plans (stop loss, take profit), and trading signals. Essential for displaying active portfolio state and monitoring risk exposure.Input Schema
VariantId
Filter positions by model variant. Valid values:
"Apex", "Trendsurfer", "Contrarian", "Sovereign". Omit to fetch positions from all variants.TypeScript Type
type PositionsInput = {
variant?: "Apex" | "Trendsurfer" | "Contrarian" | "Sovereign";
};
Output Schema
AccountPositions[]
Array of model accounts with their open positions.
Show AccountPositions properties
Show AccountPositions properties
string
required
Unique identifier for the trading model.
string
required
Display name of the model (e.g.,
"gpt-4o", "claude-3-5-sonnet-20241022").VariantId
Variant classification:
"Apex", "Trendsurfer", "Contrarian", or "Sovereign".string
URL to the model’s logo image.
Position[]
required
Array of open positions for this model.
Show Position properties
Show Position properties
string
required
Cryptocurrency trading pair (e.g.,
"BTC-USD", "ETH-USD").'long' | 'short'
required
Position direction:
"long" for buy positions, "short" for sell positions.number
required
Amount of cryptocurrency held (in base asset units).
number
required
Average price at which the position was opened (in USD).
number
Current market price (in USD). Used for real-time P&L calculations.
number
Current profit/loss in USD if the position were closed at
currentPrice. Positive indicates profit, negative indicates loss.ExitPlan
Predefined exit strategy for the position.
Show ExitPlan properties
Show ExitPlan properties
number
Take-profit price level (in USD).
number
Stop-loss price level (in USD).
string
Trading signal or rationale for opening the position (e.g.,
"Bullish breakout above resistance".number
Leverage multiplier applied to the position (e.g.,
2 for 2x leverage).number
Model’s confidence level in the trade, typically 0-100.
string
ISO 8601 timestamp of the last time the model evaluated this position.
string
Current status of the position (e.g.,
"HOLDING", "MONITORING").number
Sum of unrealized P&L across all positions for this model (in USD).
number
Unused cash balance available for new trades (in USD).
TypeScript Type
type PositionsResponse = {
positions: {
modelId: string;
modelName: string;
modelVariant?: "Apex" | "Trendsurfer" | "Contrarian" | "Sovereign";
modelLogo?: string;
positions: {
symbol: string;
side: "long" | "short";
quantity: number;
entryPrice: number;
currentPrice?: number;
unrealizedPnl?: number;
exitPlan?: {
target?: number;
stop?: number;
invalidation?: {
enabled: boolean;
message?: string;
};
};
signal?: string;
leverage?: number;
confidence?: number;
lastDecisionAt?: string;
decisionStatus?: string;
}[];
totalUnrealizedPnl?: number;
availableCash?: number;
}[];
};
Example Usage
Basic Query
import { useQuery } from "@tanstack/react-query";
import { orpc } from "@/server/orpc/client";
function PositionsList() {
const { data, isLoading } = useQuery(
orpc.trading.getPositions.queryOptions({
input: {}
})
);
if (isLoading) return <div>Loading positions...</div>;
return (
<div>
{data?.positions.map((account) => (
<div key={account.modelId}>
<h3>{account.modelName}</h3>
<p>Total Unrealized P&L: ${account.totalUnrealizedPnl?.toFixed(2) ?? '0.00'}</p>
<p>Available Cash: ${account.availableCash?.toFixed(2) ?? '0.00'}</p>
<table>
<thead>
<tr>
<th>Symbol</th>
<th>Side</th>
<th>Quantity</th>
<th>Entry</th>
<th>Current</th>
<th>P&L</th>
</tr>
</thead>
<tbody>
{account.positions.map((pos, idx) => (
<tr key={`${pos.symbol}-${idx}`}>
<td>{pos.symbol}</td>
<td>{pos.side.toUpperCase()}</td>
<td>{pos.quantity.toFixed(4)}</td>
<td>${pos.entryPrice.toFixed(2)}</td>
<td>${pos.currentPrice?.toFixed(2) ?? 'N/A'}</td>
<td style={{ color: (pos.unrealizedPnl ?? 0) >= 0 ? 'green' : 'red' }}>
${pos.unrealizedPnl?.toFixed(2) ?? '0.00'}
</td>
</tr>
))}
</tbody>
</table>
</div>
))}
</div>
);
}
Show Exit Plans
import { useQuery } from "@tanstack/react-query";
import { orpc } from "@/server/orpc/client";
function PositionsWithExitPlans() {
const { data } = useQuery(
orpc.trading.getPositions.queryOptions({
input: { variant: "Apex" }
})
);
return (
<div>
{data?.positions.map((account) => (
account.positions.map((pos, idx) => (
<div key={`${account.modelId}-${pos.symbol}-${idx}`}>
<h4>{pos.symbol} - {pos.side.toUpperCase()}</h4>
<p>Entry: ${pos.entryPrice.toFixed(2)}</p>
<p>Current: ${pos.currentPrice?.toFixed(2) ?? 'N/A'}</p>
{pos.exitPlan && (
<div>
<h5>Exit Plan</h5>
{pos.exitPlan.target && (
<p>🎯 Target: ${pos.exitPlan.target.toFixed(2)}</p>
)}
{pos.exitPlan.stop && (
<p>🛑 Stop Loss: ${pos.exitPlan.stop.toFixed(2)}</p>
)}
{pos.exitPlan.invalidation?.enabled && (
<p>⚠️ Invalidation: {pos.exitPlan.invalidation.message}</p>
)}
</div>
)}
{pos.signal && <p>📊 Signal: {pos.signal}</p>}
{pos.confidence && <p>💪 Confidence: {pos.confidence}%</p>}
</div>
))
))}
</div>
);
}
Real-time Updates with Polling
import { useQuery } from "@tanstack/react-query";
import { orpc } from "@/server/orpc/client";
function LivePositions() {
// Poll every 5 seconds for real-time updates
const { data } = useQuery({
...orpc.trading.getPositions.queryOptions({
input: {}
}),
refetchInterval: 5000,
});
const totalPnl = data?.positions.reduce(
(sum, account) => sum + (account.totalUnrealizedPnl ?? 0),
0
) ?? 0;
const totalPositions = data?.positions.reduce(
(sum, account) => sum + account.positions.length,
0
) ?? 0;
return (
<div>
<h2>Live Portfolio</h2>
<p>Total Open Positions: {totalPositions}</p>
<p style={{ color: totalPnl >= 0 ? 'green' : 'red' }}>
Total Unrealized P&L: ${totalPnl.toFixed(2)}
</p>
{/* Position list */}
</div>
);
}
Filter by Variant and Calculate Exposure
import { useQuery } from "@tanstack/react-query";
import { orpc } from "@/server/orpc/client";
function TrendsurferExposure() {
const { data } = useQuery(
orpc.trading.getPositions.queryOptions({
input: { variant: "Trendsurfer" }
})
);
const exposure = data?.positions.reduce((acc, account) => {
account.positions.forEach(pos => {
const notional = pos.quantity * pos.entryPrice;
acc[pos.symbol] = (acc[pos.symbol] ?? 0) + notional;
});
return acc;
}, {} as Record<string, number>);
return (
<div>
<h3>Trendsurfer Position Exposure</h3>
{exposure && Object.entries(exposure).map(([symbol, value]) => (
<p key={symbol}>
{symbol}: ${value.toFixed(2)}
</p>
))}
</div>
);
}
Related Endpoints
- trading.getTrades - Fetch closed trades
- trading.getCryptoPrices - Fetch current cryptocurrency prices
- trading.getPortfolioHistory - Fetch historical portfolio values

