curl -X GET "https://api.strike.markets/positions/0x742d35cc6C6C7532B1140Da4C8A2f6C8ECfC9B46"
{
"open": [
{
"id": 12345,
"symbol": "BTC-USD",
"wallet_address": "0x742d35cc6c6c7532b1140da4c8a2f6c8ecfc9b46",
"szi": "0.006667",
"margin": "300.0",
"entry_price": "45000.00",
"liquidation_price": "41234.15",
"exit_price": null,
"realized_pnl": "0.00",
"total_fee": "0.00",
"status": "open",
"created_at": "2024-01-15T14:30:00Z",
"closed_at": null,
"settled_at": null
}
],
"closed": [
{
"id": 12340,
"symbol": "BTC-USD",
"wallet_address": "0x742d35cc6c6c7532b1140da4c8a2f6c8ecfc9b46",
"szi": "0.018182",
"margin": "100.0",
"entry_price": "44000.00",
"liquidation_price": "40150.00",
"exit_price": "45500.00",
"realized_pnl": "127.85",
"total_fee": "8.75",
"status": "closed",
"created_at": "2024-01-10T09:00:00Z",
"closed_at": "2024-01-12T15:30:00Z",
"settled_at": null
}
],
"settled": [
{
"id": 12330,
"symbol": "SOL-USD",
"wallet_address": "0x742d35cc6c6c7532b1140da4c8a2f6c8ecfc9b46",
"szi": "0.078947",
"margin": "75.0",
"entry_price": "95.00",
"liquidation_price": "90.25",
"exit_price": "90.25",
"realized_pnl": "-75.00",
"total_fee": "0.00",
"status": "settled",
"created_at": "2024-01-05T08:30:00Z",
"closed_at": "2024-01-06T14:15:00Z",
"settled_at": "2024-01-06T14:15:00Z"
}
]
}
Overview
Retrieve all positions for a specific wallet address, organized by their current status. This endpoint provides comprehensive position data including real-time PnL calculations for open positions.
This endpoint does NOT require authentication and can be called for any wallet address. Position data is publicly accessible on the blockchain.
Path Parameters
Ethereum wallet address to retrieve positions for.Format: 42-character hex string starting with “0x”
Example: “0x742d35cc6C6C7532B1140Da4C8A2f6C8ECfC9B46”
Response Structure
Position Collections
Currently active positions with reserved margin
Positions manually closed by user, may be pending payout
Positions fully processed (liquidated or payout completed)
Position Object Properties
Unique identifier for the position (contract position ID)
Trading pair symbol (e.g., “BTC-USD”, “ETH-USD”, “SOL-USD”, “BNB-USD”, “XRP-USD”, “HYPE-USD”)
Owner’s wallet address (lowercase hex format)
Position size in base asset units (positive=long, negative=short)
Initial margin amount used to open the position (USD)
Price at which the position was opened
Price at which the position will be liquidated
Price at which position was closed (null for open positions)
Final realized profit/loss when closed (0.00 for open positions)
Total fees paid on the position (0.00 for open positions)
Position status: “open”, “closed”, or “settled”
ISO timestamp when the position was created
ISO timestamp when the position was closed (null for open positions)
ISO timestamp when position was fully settled (null for open/closed positions)
Position Status Definitions
Open Positions
- Status: “open”
- Characteristics: Active positions with ongoing market exposure
- PnL: Real-time unrealized profit/loss calculations
- Actions: Can be closed manually or liquidated automatically
- Margin: Reserved from account balance
Closed Positions
- Status: “closed”
- Characteristics: Manually closed by user through Close Position
- PnL: Final realized profit/loss (unrealizedPnl shows 0)
- Closure: User-initiated at market price
- Settlement: Immediate or queued based on available funds
Settled Positions
- Status: “liquidated” or “settled”
- Characteristics: Automatically closed by the system
- Liquidation: Closed when reaching liquidation price
- Settlement: System-initiated closure
- Timing: Occurs automatically based on market conditions
Real-time Data
Open Position Updates
Open positions include real-time data:
- Mark Price: Current market price from HyperLiquid
- Unrealized PnL: Calculated based on current vs. entry price
- Liquidation Distance: How close the position is to liquidation
PnL Calculations
Long Position PnL
Unrealized PnL = Position Size × ((Mark Price - Entry Price) / Entry Price)
Example:
- Entry: 45,000 USD, Mark: 46,500 USD, Size: 3,000 USD
- PnL = 3,000 USD × ((46,500 - 45,000 USD) / 45,000 USD) = 100.00 USD
Short Position PnL
Unrealized PnL = Position Size × ((Entry Price - Mark Price) / Entry Price)
Example:
- Entry: 2,500 USD, Mark: 2,450 USD, Size: 1,000 USD
- PnL = 1,000 USD × ((2,500 - 2,450 USD) / 2,500 USD) = 20.00 USD
Funding Adjustments
For positions held longer than 8 hours:
- Funding payments: Applied hourly based on market imbalance
- PnL impact: Funding costs/earnings included in unrealized PnL
- Rate updates: Funding rates update continuously
Use Cases
Portfolio Monitoring
- Active positions: Monitor real-time performance of open positions
- Risk assessment: Evaluate liquidation distance and exposure
- Performance tracking: Analyze historical position outcomes
- Balance planning: Understand margin allocation across positions
Trading Strategy
- Position sizing: Review current position sizes and leverage usage
- Market exposure: Assess long/short exposure by market
- Historical analysis: Learn from past position performance
- Risk management: Monitor positions approaching liquidation
Account Management
- Margin utilization: See how much margin is currently in use
- Position diversity: Review market and direction diversification
- Closure timing: Plan position closures based on performance
- Liquidation monitoring: Track positions at risk of liquidation
Error Responses
Invalid wallet address format{
"error": 400,
"message": "Invalid wallet address format"
}
Wallet address not found in system (no positions){
"error": 404,
"message": "No positions found for this wallet address"
}
Usage Examples
Get Open Position Summary
async function getOpenPositionSummary(walletAddress) {
const response = await fetch(`https://api.strike.markets/positions/${walletAddress}`);
const data = await response.json();
const openPositions = data.openPositions;
const totalUnrealizedPnl = openPositions.reduce((sum, pos) =>
sum + parseFloat(pos.unrealizedPnl), 0
);
const totalMarginUsed = openPositions.reduce((sum, pos) =>
sum + parseFloat(pos.margin), 0
);
return {
count: openPositions.length,
totalUnrealizedPnl,
totalMarginUsed,
avgLeverage: openPositions.length > 0 ?
openPositions.reduce((sum, pos) => sum + pos.leverage, 0) / openPositions.length : 0
};
}
Monitor Liquidation Risk
async function checkLiquidationRisk(walletAddress) {
const response = await fetch(`https://api.strike.markets/positions/${walletAddress}`);
const data = await response.json();
const riskyPositions = data.openPositions.filter(pos => {
const currentPrice = parseFloat(pos.markPrice);
const liquidationPrice = parseFloat(pos.liquidationPrice);
if (pos.side === 'long') {
return (currentPrice - liquidationPrice) / currentPrice < 0.1; // Less than 10% buffer
} else {
return (liquidationPrice - currentPrice) / currentPrice < 0.1; // Less than 10% buffer
}
});
return riskyPositions.map(pos => ({
positionId: pos.positionId,
symbol: pos.symbol,
side: pos.side,
liquidationDistance: calculateLiquidationDistance(pos),
urgency: assessUrgency(pos)
}));
}
async function calculatePositionPerformance(walletAddress) {
const response = await fetch(`https://api.strike.markets/positions/${walletAddress}`);
const data = await response.json();
const allClosedPositions = [...data.closedPositions, ...data.settledPositions];
if (allClosedPositions.length === 0) {
return { message: "No closed positions to analyze" };
}
const winners = allClosedPositions.filter(pos => calculateRealizedPnl(pos) > 0);
const losers = allClosedPositions.filter(pos => calculateRealizedPnl(pos) < 0);
const totalPnl = allClosedPositions.reduce((sum, pos) =>
sum + calculateRealizedPnl(pos), 0
);
return {
totalTrades: allClosedPositions.length,
winners: winners.length,
losers: losers.length,
winRate: (winners.length / allClosedPositions.length * 100).toFixed(2) + '%',
totalPnl: totalPnl.toFixed(2),
avgWin: winners.length > 0 ?
(winners.reduce((sum, pos) => sum + calculateRealizedPnl(pos), 0) / winners.length).toFixed(2) : '0',
avgLoss: losers.length > 0 ?
(losers.reduce((sum, pos) => sum + calculateRealizedPnl(pos), 0) / losers.length).toFixed(2) : '0'
};
}
Filter Positions by Market
async function getPositionsByMarket(walletAddress, symbol = null) {
const response = await fetch(`https://api.strike.markets/positions/${walletAddress}`);
const data = await response.json();
const filterBySymbol = (positions) =>
symbol ? positions.filter(pos => pos.symbol === symbol) : positions;
return {
open: filterBySymbol(data.openPositions),
closed: filterBySymbol(data.closedPositions),
settled: filterBySymbol(data.settledPositions)
};
}
// Usage examples:
// getAllPositions = await getPositionsByMarket(wallet);
// btcPositions = await getPositionsByMarket(wallet, 'BTC-USD');
// ethPositions = await getPositionsByMarket(wallet, 'ETH-USD');
Integration Patterns
Real-time Position Monitoring
class PositionMonitor {
constructor(walletAddress, updateInterval = 10000) {
this.walletAddress = walletAddress;
this.updateInterval = updateInterval;
this.positions = null;
this.callbacks = [];
}
async start() {
await this.updatePositions();
this.timer = setInterval(() => this.updatePositions(), this.updateInterval);
}
stop() {
if (this.timer) clearInterval(this.timer);
}
async updatePositions() {
try {
const response = await fetch(`https://api.strike.markets/positions/${this.walletAddress}`);
const newPositions = await response.json();
if (this.positions) {
this.detectChanges(this.positions, newPositions);
}
this.positions = newPositions;
this.notifyCallbacks(newPositions);
} catch (error) {
console.error('Failed to update positions:', error);
}
}
onUpdate(callback) {
this.callbacks.push(callback);
}
notifyCallbacks(positions) {
this.callbacks.forEach(cb => cb(positions));
}
detectChanges(oldPositions, newPositions) {
// Compare position counts and PnL changes
const oldOpenCount = oldPositions.openPositions.length;
const newOpenCount = newPositions.openPositions.length;
if (oldOpenCount !== newOpenCount) {
console.log('Position count changed:', oldOpenCount, '->', newOpenCount);
}
// Check for significant PnL changes
newPositions.openPositions.forEach(newPos => {
const oldPos = oldPositions.openPositions.find(p => p.positionId === newPos.positionId);
if (oldPos) {
const pnlChange = Math.abs(parseFloat(newPos.unrealizedPnl) - parseFloat(oldPos.unrealizedPnl));
if (pnlChange > 10) { // Alert on 10+ USD PnL changes
console.log(`Significant PnL change for position ${newPos.positionId}: ${pnlChange}`);
}
}
});
}
}
Position Dashboard Component
function PositionsDashboard({ walletAddress }) {
const [positions, setPositions] = useState(null);
const [loading, setLoading] = useState(true);
const [selectedTab, setSelectedTab] = useState('open');
useEffect(() => {
async function loadPositions() {
try {
const response = await fetch(`https://api.strike.markets/positions/${walletAddress}`);
const data = await response.json();
setPositions(data);
} catch (error) {
console.error('Failed to load positions:', error);
} finally {
setLoading(false);
}
}
loadPositions();
// Set up periodic updates for open positions
const interval = setInterval(loadPositions, 15000);
return () => clearInterval(interval);
}, [walletAddress]);
if (loading) return <div>Loading positions...</div>;
if (!positions) return <div>Failed to load positions</div>;
const tabData = {
open: positions.openPositions,
closed: positions.closedPositions,
settled: positions.settledPositions
};
return (
<div>
<div className="tab-navigation">
{Object.keys(tabData).map(tab => (
<button
key={tab}
className={selectedTab === tab ? 'active' : ''}
onClick={() => setSelectedTab(tab)}
>
{tab.charAt(0).toUpperCase() + tab.slice(1)} ({tabData[tab].length})
</button>
))}
</div>
<div className="position-list">
{tabData[selectedTab].map(position => (
<PositionCard key={position.positionId} position={position} />
))}
</div>
</div>
);
}
Caching Strategy
For applications that frequently access position data:
class PositionCache {
constructor(ttl = 10000) { // 10 second TTL for open positions
this.cache = new Map();
this.ttl = ttl;
}
getCacheKey(walletAddress) {
return `positions_${walletAddress}`;
}
async getPositions(walletAddress) {
const key = this.getCacheKey(walletAddress);
const cached = this.cache.get(key);
if (cached && Date.now() - cached.timestamp < this.ttl) {
return cached.data;
}
const response = await fetch(`https://api.strike.markets/positions/${walletAddress}`);
const data = await response.json();
this.cache.set(key, {
data,
timestamp: Date.now()
});
return data;
}
invalidate(walletAddress) {
const key = this.getCacheKey(walletAddress);
this.cache.delete(key);
}
}
Best Practices
Data Usage
- Cache open positions: Use shorter cache times due to real-time PnL changes
- Cache historical data: Closed/settled positions change infrequently
- Error handling: Handle wallet addresses with no positions gracefully
- Performance: Consider pagination for users with many positions
Monitoring and Alerts
- Liquidation alerts: Monitor positions approaching liquidation
- PnL notifications: Alert on significant profit/loss changes
- Position limits: Track position count and total exposure
- Performance metrics: Calculate and track trading performance
Monitor open positions frequently as unrealized PnL changes with market prices. Consider setting up alerts for positions approaching liquidation.
Position data includes sensitive trading information. While publicly accessible, use appropriate security measures when displaying this data in applications.
Positions retrieved successfully