use deribit_websocket::config::WebSocketConfig;
use deribit_websocket::prelude::*;
use std::env;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
deribit_websocket::install_default_crypto_provider()?;
unsafe {
std::env::set_var("DERIBIT_LOG_LEVEL", "DEBUG");
}
setup_logger();
tracing::info!("🚀 Position Management Example");
tracing::info!("Demonstrating: close_position, move_positions");
tracing::info!("⚠️ WARNING: This example may execute real trades!");
dotenv::dotenv().ok();
let client_id = env::var("DERIBIT_CLIENT_ID").expect("DERIBIT_CLIENT_ID must be set");
let client_secret =
env::var("DERIBIT_CLIENT_SECRET").expect("DERIBIT_CLIENT_SECRET must be set");
let config = WebSocketConfig::default()
.with_heartbeat_interval(std::time::Duration::from_secs(30))
.with_max_reconnect_attempts(3);
let client = DeribitWebSocketClient::new(&config)?;
tracing::info!("✅ Client created successfully");
tracing::info!("🔌 Connecting to Deribit WebSocket...");
client.connect().await?;
tracing::info!("✅ Connected to Deribit WebSocket");
tracing::info!("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
tracing::info!("🔐 Authenticating...");
match client.authenticate(&client_id, &client_secret).await {
Ok(auth_response) => {
tracing::info!("✅ Authentication successful!");
tracing::info!(" Token type: {}", auth_response.token_type);
tracing::info!(" Expires in: {} seconds", auth_response.expires_in);
}
Err(e) => {
tracing::error!("❌ Authentication failed: {}", e);
client.disconnect().await?;
return Err(e.into());
}
}
tracing::info!("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
tracing::info!("📊 Checking current BTC positions...");
match client.get_positions(Some("BTC"), None).await {
Ok(positions) => {
tracing::info!(" Found {} position(s)", positions.len());
for position in &positions {
if position.size != 0.0 {
tracing::info!(" ────────────────────────────────────────────────────");
tracing::info!(" Instrument: {}", position.instrument_name);
tracing::info!(" Direction: {:?}", position.direction);
tracing::info!(" Size: {}", position.size);
tracing::info!(" Avg Price: {}", position.average_price);
}
}
let open_positions: Vec<_> = positions.iter().filter(|p| p.size != 0.0).collect();
if !open_positions.is_empty() {
let position_to_close = &open_positions[0];
tracing::info!("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
tracing::info!(
"📉 Closing position for {}...",
position_to_close.instrument_name
);
tracing::info!(" Current size: {}", position_to_close.size);
tracing::info!(" ⚠️ Skipping actual close to avoid unwanted trades");
tracing::info!(" To close a position, use:");
tracing::info!(" client.close_position(\"BTC-PERPETUAL\", \"market\").await");
} else {
tracing::info!(" No open positions to close");
tracing::info!("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
tracing::info!("📉 close_position() usage example:");
tracing::info!(" // Close with market order");
tracing::info!(" client.close_position(\"BTC-PERPETUAL\", \"market\").await");
tracing::info!(" ");
tracing::info!(" // Close with limit order");
tracing::info!(" client.close_position(\"BTC-PERPETUAL\", \"limit\").await");
}
}
Err(e) => {
tracing::error!("❌ Failed to get positions: {}", e);
}
}
tracing::info!("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
tracing::info!("🔄 move_positions() usage example:");
tracing::info!(" // Move positions between subaccounts");
tracing::info!(" let trades = vec![");
tracing::info!(" MovePositionTrade {{");
tracing::info!(" instrument_name: \"BTC-PERPETUAL\".to_string(),");
tracing::info!(" amount: 100.0,");
tracing::info!(" price: 50000.0,");
tracing::info!(" }}");
tracing::info!(" ];");
tracing::info!(" client.move_positions(");
tracing::info!(" \"BTC\", // currency");
tracing::info!(" 123, // source_uid");
tracing::info!(" 456, // target_uid");
tracing::info!(" trades // positions to move");
tracing::info!(" ).await");
tracing::info!(" ⚠️ Skipping actual move_positions to avoid unwanted transfers");
tracing::info!("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
tracing::info!("🔌 Disconnecting...");
client.disconnect().await?;
tracing::info!("✅ Disconnected successfully");
tracing::info!("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
tracing::info!("✅ Position management example completed!");
Ok(())
}