Feature: Pacifica Multi-Account Hedging System
Date: 2024-12-29
Status: Complete
Version: 1.0.0
The Hedging API provides comprehensive endpoints for managing multi-account hedging sessions, including session creation, monitoring, risk management, and real-time updates. This API enables coordinated trading across multiple accounts to generate volume while maintaining position neutrality.
Base URL: /api/v1/hedging
Authentication: Bearer token in Authorization header
Content-Type: application/json
Rate Limit: 100 requests/minute per client
curl -X POST https://api.pacifica.exchange/api/v1/hedging/sessions \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"strategy": {
"symbol": "ETH/USD",
"volumeDistribution": "equal",
"priceRange": { "min": 0.001, "max": 0.01 },
"timing": { "minInterval": 30, "maxInterval": 120, "orderSize": { "min": 100, "max": 500 } },
"riskLimits": { "maxPositionSize": 0.1, "stopLossThreshold": 0.05, "maxSlippage": 0.02 },
"orderTypes": { "primary": "limit", "fallback": "market" }
},
"accounts": ["account1", "account2"],
"duration": 300000
}'
curl -X POST https://api.pacifica.exchange/api/v1/hedging/sessions/{sessionId}/start \
-H "Authorization: Bearer YOUR_API_KEY"
const ws = new WebSocket('wss://api.pacifica.exchange/ws/sessions/{sessionId}?api_key=YOUR_API_KEY');
ws.onmessage = (event) => {
const update = JSON.parse(event.data);
console.log('Session update:', update);
};
Endpoint: POST /sessions
Purpose: Create a new hedging session with multiple accounts
Request Schema:
interface CreateHedgingSessionRequest {
name: string; // Session name (3-50 chars)
accountIds: string[]; // Array of account IDs (min 2)
volumeTarget: number; // Target trading volume
strategy: {
symbol: string; // Trading pair (e.g., "ETH/USD")
volumeDistribution: 'equal' | 'weighted'; // Volume distribution method
priceRange: {
min: number; // Minimum price deviation
max: number; // Maximum price deviation
};
timing: {
minInterval: number; // Minimum seconds between orders
maxInterval: number; // Maximum seconds between orders
orderSize: {
min: number; // Minimum order size
max: number; // Maximum order size
};
};
riskLimits: {
maxPositionSize: number; // Max position size per account
stopLossThreshold: number; // Portfolio loss % to trigger halt
maxSlippage: number; // Maximum acceptable slippage
};
orderTypes: {
primary: 'limit' | 'market'; // Primary order type
fallback: 'limit' | 'market'; // Fallback order type
};
};
}
Response Schema:
interface CreateHedgingSessionResponse {
success: boolean;
session: {
id: string;
name: string;
status: 'pending';
accounts: string[];
strategy: HedgingStrategy;
volumeTarget: number;
volumeGenerated: number;
startTime: string; // ISO timestamp
riskBreaches: [];
orders: [];
};
message?: string;
}
Validation Rules:
Endpoint: GET /sessions
Purpose: Retrieve all hedging sessions
Query Parameters:
status
: Filter by session statusaccountId
: Filter by participating accountlimit
: Maximum number of sessions to return (default: 50)offset
: Number of sessions to skip (default: 0)Response Schema:
interface ListHedgingSessionsResponse {
success: boolean;
sessions: Array<{
id: string;
name: string;
status: SessionStatus;
accounts: string[];
volumeTarget: number;
volumeGenerated: number;
startTime: string;
endTime?: string;
}>;
total: number;
limit: number;
offset: number;
}
Endpoint: GET /sessions/{id}
Purpose: Retrieve detailed information for a specific session
Response Schema:
interface GetHedgingSessionResponse {
success: boolean;
session: {
id: string;
name: string;
status: SessionStatus;
accounts: string[];
strategy: HedgingStrategy;
volumeTarget: number;
volumeGenerated: number;
startTime: string;
endTime?: string;
riskBreaches: Array<{
id: string;
breachType: string;
severity: 'warning' | 'critical';
timestamp: string;
resolved: boolean;
}>;
orders: Array<{
id: string;
orderPair: {
buyOrder: OrderDetails;
sellOrder: OrderDetails;
};
status: OrderPairStatus;
volume: number;
price: number;
createdAt: string;
}>;
metrics: HedgingMetrics;
};
}
Endpoint: POST /sessions/{id}/start
Purpose: Start a pending hedging session
Response Schema:
interface StartHedgingSessionResponse {
success: boolean;
session: {
id: string;
status: 'active';
startTime: string;
};
message?: string;
}
Validation Rules:
Endpoint: POST /sessions/{id}/pause
Purpose: Pause an active hedging session
Response Schema:
interface PauseHedgingSessionResponse {
success: boolean;
session: {
id: string;
status: 'paused';
pausedAt: string;
};
message?: string;
}
Validation Rules:
Endpoint: POST /sessions/{id}/resume
Purpose: Resume a paused hedging session
Response Schema:
interface ResumeHedgingSessionResponse {
success: boolean;
session: {
id: string;
status: 'active';
resumedAt: string;
};
message?: string;
}
Validation Rules:
Endpoint: POST /sessions/{id}/stop
Purpose: Stop a hedging session (active or paused)
Response Schema:
interface StopHedgingSessionResponse {
success: boolean;
session: {
id: string;
status: 'completed';
endTime: string;
finalVolume: number;
};
message?: string;
}
Validation Rules:
Endpoint: GET /sessions/{id}/orders
Purpose: Retrieve all orders for a hedging session
Query Parameters:
status
: Filter by order statusaccountId
: Filter by accountside
: Filter by order sidelimit
: Maximum number of orders to return (default: 100)offset
: Number of orders to skip (default: 0)Response Schema:
interface GetSessionOrdersResponse {
success: boolean;
orders: Array<{
id: string;
orderPair: {
buyOrder: {
accountId: string;
side: 'buy';
type: 'market' | 'limit';
size: number;
price?: number;
status: OrderStatus;
fillPrice?: number;
fillSize?: number;
fees: number;
createdAt: string;
};
sellOrder: {
accountId: string;
side: 'sell';
type: 'market' | 'limit';
size: number;
price?: number;
status: OrderStatus;
fillPrice?: number;
fillSize?: number;
fees: number;
createdAt: string;
};
};
status: OrderPairStatus;
volume: number;
price: number;
slippage?: number;
fees: number;
createdAt: string;
executedAt?: string;
completedAt?: string;
}>;
total: number;
limit: number;
offset: number;
}
Endpoint: GET /sessions/{id}/risk-status
Purpose: Get current risk status for a session
Response Schema:
interface RiskStatusResponse {
success: boolean;
riskStatus: {
sessionId: string;
overallRisk: 'low' | 'medium' | 'high';
accountRisks: Array<{
accountId: string;
riskLevel: 'low' | 'medium' | 'high';
positionSize: number;
marginRatio: number;
pnl: number;
}>;
portfolioRisk: {
totalPnl: number;
maxDrawdown: number;
var95: number;
};
activeBreaches: Array<{
id: string;
breachType: string;
severity: 'warning' | 'critical';
timestamp: string;
}>;
};
}
Endpoint: POST /sessions/{id}/risk-breaches/{breachId}/acknowledge
Purpose: Acknowledge and resolve a risk breach
Request Schema:
interface AcknowledgeRiskBreachRequest {
action: 'resolve' | 'ignore';
comment?: string;
}
Response Schema:
interface AcknowledgeRiskBreachResponse {
success: boolean;
breach: {
id: string;
resolved: boolean;
acknowledgedAt: string;
action: string;
};
message?: string;
}
Endpoint: WebSocket /ws/sessions/{id}
Purpose: Real-time session status updates
Connection Schema:
interface SessionSubscription {
type: 'subscribe';
sessionId: string;
channels: ('status' | 'orders' | 'risk' | 'metrics')[];
}
Message Schema:
interface SessionUpdateMessage {
type: 'session_update';
sessionId: string;
channel: 'status' | 'orders' | 'risk' | 'metrics';
data: {
status?: SessionStatus;
volumeGenerated?: number;
volumeTarget?: number;
activeOrders?: number;
riskBreaches?: number;
orders?: HedgingOrder[];
riskBreaches?: RiskBreach[];
metrics?: HedgingMetrics;
};
timestamp: number;
}
interface ErrorResponse {
success: false;
error: {
code: string;
message: string;
details?: any;
};
timestamp: string;
}
SESSION_NOT_FOUND
: Hedging session does not existINVALID_SESSION_STATUS
: Session not in required statusINSUFFICIENT_ACCOUNTS
: Not enough accounts for hedgingINSUFFICIENT_BALANCE
: Not enough balance in accountsRISK_LIMIT_EXCEEDED
: Risk limits would be exceededMARKET_DATA_UNAVAILABLE
: Real-time data not availableORDER_EXECUTION_FAILED
: Order could not be executedACCOUNT_NOT_ACTIVE
: Account is not activeINVALID_STRATEGY
: Strategy parameters are invalidAuthorization
headerBearer <api-key>
?api_key=<api-key>
success: true
for successful operationssuccess: false
for failed operationscurl -X POST https://api.pacifica.exchange/api/v1/hedging/sessions \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"strategy": {
"symbol": "ETH/USD",
"volumeDistribution": "equal",
"priceRange": { "min": 0.001, "max": 0.01 },
"timing": { "minInterval": 30, "maxInterval": 120, "orderSize": { "min": 100, "max": 500 } },
"riskLimits": { "maxPositionSize": 0.1, "stopLossThreshold": 0.05, "maxSlippage": 0.02 },
"orderTypes": { "primary": "limit", "fallback": "market" }
},
"accounts": ["account1", "account2", "account3"],
"duration": 300000
}'
Response:
{
"success": true,
"session": {
"id": "session_1234567890",
"status": "created",
"accounts": ["account1", "account2", "account3"],
"strategy": { ... },
"metrics": {
"totalVolume": 0,
"netPosition": 0,
"pnl": 0,
"slippage": 0
},
"riskBreaches": [],
"orders": []
}
}
curl -X POST https://api.pacifica.exchange/api/v1/hedging/sessions/session_1234567890/start \
-H "Authorization: Bearer YOUR_API_KEY"
Response:
{
"success": true,
"session": {
"id": "session_1234567890",
"status": "running",
"startTime": "2024-12-29T10:00:00Z"
}
}
curl -X GET https://api.pacifica.exchange/api/v1/hedging/sessions/session_1234567890 \
-H "Authorization: Bearer YOUR_API_KEY"
Response:
{
"success": true,
"session": {
"id": "session_1234567890",
"status": "running",
"accounts": ["account1", "account2", "account3"],
"strategy": { ... },
"metrics": {
"totalVolume": 1500,
"netPosition": 0,
"pnl": 25.50,
"slippage": 0.001
},
"riskBreaches": [],
"orders": [
{
"id": "order_001",
"orderPair": {
"buyOrder": {
"accountId": "account1",
"side": "buy",
"type": "limit",
"size": 100,
"price": 2500,
"status": "filled",
"fillPrice": 2499.5,
"fillSize": 100,
"fees": 2.5
},
"sellOrder": {
"accountId": "account2",
"side": "sell",
"type": "limit",
"size": 100,
"price": 2500,
"status": "filled",
"fillPrice": 2500.5,
"fillSize": 100,
"fees": 2.5
}
},
"status": "filled",
"volume": 100,
"price": 2500,
"slippage": 0.0004,
"fees": 5.0,
"createdAt": "2024-12-29T10:00:30Z",
"executedAt": "2024-12-29T10:00:31Z"
}
]
}
}
curl -X GET https://api.pacifica.exchange/api/v1/hedging/sessions/session_1234567890/risk-status \
-H "Authorization: Bearer YOUR_API_KEY"
Response:
{
"success": true,
"riskStatus": {
"sessionId": "session_1234567890",
"overallRisk": "low",
"accountRisks": [
{
"accountId": "account1",
"riskLevel": "low",
"positionSize": 0.05,
"marginRatio": 0.8,
"pnl": 12.75
},
{
"accountId": "account2",
"riskLevel": "low",
"positionSize": 0.05,
"marginRatio": 0.8,
"pnl": 12.75
}
],
"portfolioRisk": {
"totalPnl": 25.50,
"maxDrawdown": 0,
"var95": 0
},
"activeBreaches": []
}
}
curl -X POST https://api.pacifica.exchange/api/v1/hedging/sessions/session_1234567890/stop \
-H "Authorization: Bearer YOUR_API_KEY"
Response:
{
"success": true,
"session": {
"id": "session_1234567890",
"status": "stopped",
"endTime": "2024-12-29T10:05:00Z",
"finalVolume": 1500
}
}
const ws = new WebSocket('wss://api.pacifica.exchange/ws/sessions/session_1234567890?api_key=YOUR_API_KEY');
ws.onopen = () => {
console.log('Connected to hedging session updates');
// Subscribe to all channels
ws.send(JSON.stringify({
type: 'subscribe',
sessionId: 'session_1234567890',
channels: ['status', 'orders', 'risk', 'metrics']
}));
};
ws.onmessage = (event) => {
const update = JSON.parse(event.data);
switch (update.type) {
case 'session_update':
handleSessionUpdate(update);
break;
case 'order_update':
handleOrderUpdate(update);
break;
case 'risk_update':
handleRiskUpdate(update);
break;
case 'metrics_update':
handleMetricsUpdate(update);
break;
}
};
function handleSessionUpdate(update) {
console.log('Session status:', update.data.status);
console.log('Volume generated:', update.data.volumeGenerated);
console.log('Active orders:', update.data.activeOrders);
}
function handleOrderUpdate(update) {
console.log('New order:', update.data.order);
console.log('Order status:', update.data.order.status);
}
function handleRiskUpdate(update) {
console.log('Risk level:', update.data.riskLevel);
if (update.data.breach) {
console.log('Risk breach detected:', update.data.breach);
}
}
function handleMetricsUpdate(update) {
console.log('Metrics updated:', update.data.metrics);
console.log('PnL:', update.data.metrics.pnl);
console.log('Slippage:', update.data.metrics.slippage);
}
Session Status Update:
{
"type": "session_update",
"sessionId": "session_1234567890",
"channel": "status",
"data": {
"status": "running",
"volumeGenerated": 1500,
"volumeTarget": 10000,
"activeOrders": 2,
"riskBreaches": 0
},
"timestamp": 1703847600000
}
Order Update:
{
"type": "order_update",
"sessionId": "session_1234567890",
"channel": "orders",
"data": {
"order": {
"id": "order_002",
"orderPair": {
"buyOrder": {
"accountId": "account1",
"side": "buy",
"type": "limit",
"size": 150,
"price": 2501,
"status": "filled",
"fillPrice": 2500.8,
"fillSize": 150,
"fees": 3.75
},
"sellOrder": {
"accountId": "account3",
"side": "sell",
"type": "limit",
"size": 150,
"price": 2501,
"status": "filled",
"fillPrice": 2501.2,
"fillSize": 150,
"fees": 3.75
}
},
"status": "filled",
"volume": 150,
"price": 2501,
"slippage": 0.0008,
"fees": 7.5,
"createdAt": "2024-12-29T10:01:00Z",
"executedAt": "2024-12-29T10:01:01Z"
}
},
"timestamp": 1703847661000
}
Risk Update:
{
"type": "risk_update",
"sessionId": "session_1234567890",
"channel": "risk",
"data": {
"riskLevel": "medium",
"breach": {
"id": "breach_001",
"category": "position_size",
"severity": "warning",
"details": "Position size approaching limit",
"timestamp": "2024-12-29T10:02:00Z"
}
},
"timestamp": 1703847720000
}
Metrics Update:
{
"type": "metrics_update",
"sessionId": "session_1234567890",
"channel": "metrics",
"data": {
"metrics": {
"totalVolume": 1650,
"netPosition": 0,
"pnl": 28.25,
"slippage": 0.0012,
"lastUpdated": "2024-12-29T10:02:00Z"
}
},
"timestamp": 1703847720000
}
{
"success": false,
"error": {
"code": "SESSION_NOT_FOUND",
"message": "Hedging session with ID 'invalid_session_id' not found",
"details": {
"sessionId": "invalid_session_id"
}
},
"timestamp": "2024-12-29T10:00:00Z"
}
{
"success": false,
"error": {
"code": "INVALID_SESSION_STATUS",
"message": "Cannot start session in 'running' status",
"details": {
"sessionId": "session_1234567890",
"currentStatus": "running",
"requiredStatus": "created"
}
},
"timestamp": "2024-12-29T10:00:00Z"
}
{
"success": false,
"error": {
"code": "RISK_LIMIT_EXCEEDED",
"message": "Position size would exceed maximum allowed limit",
"details": {
"limit": 0.1,
"requested": 0.15,
"accountId": "account1"
}
},
"timestamp": "2024-12-29T10:00:00Z"
}
import { HedgingClient } from '@pacifica/hedging-sdk';
const client = new HedgingClient({
apiKey: 'YOUR_API_KEY',
baseUrl: 'https://api.pacifica.exchange'
});
// Create and start a session
const session = await client.createSession({
strategy: {
symbol: 'ETH/USD',
volumeDistribution: 'equal',
priceRange: { min: 0.001, max: 0.01 },
timing: { minInterval: 30, maxInterval: 120, orderSize: { min: 100, max: 500 } },
riskLimits: { maxPositionSize: 0.1, stopLossThreshold: 0.05, maxSlippage: 0.02 },
orderTypes: { primary: 'limit', fallback: 'market' }
},
accounts: ['account1', 'account2'],
duration: 300000
});
await client.startSession(session.id);
// Monitor session
client.subscribeToSession(session.id, (update) => {
console.log('Session update:', update);
});
from pacifica_hedging import HedgingClient
client = HedgingClient(
api_key='YOUR_API_KEY',
base_url='https://api.pacifica.exchange'
)
# Create and start a session
session = client.create_session({
'strategy': {
'symbol': 'ETH/USD',
'volumeDistribution': 'equal',
'priceRange': {'min': 0.001, 'max': 0.01},
'timing': {'minInterval': 30, 'maxInterval': 120, 'orderSize': {'min': 100, 'max': 500}},
'riskLimits': {'maxPositionSize': 0.1, 'stopLossThreshold': 0.05, 'maxSlippage': 0.02},
'orderTypes': {'primary': 'limit', 'fallback': 'market'}
},
'accounts': ['account1', 'account2'],
'duration': 300000
})
client.start_session(session['id'])
# Monitor session
def handle_update(update):
print(f'Session update: {update}')
client.subscribe_to_session(session['id'], handle_update)
For additional support and documentation: