use deribit_websocket::config::WebSocketConfig;
use deribit_websocket::model::trading::{OrderRequest, TimeInForce};
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!("🚀 Trading Operations Example");
tracing::info!("Demonstrating: buy, sell, edit, cancel orders");
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);
tracing::info!(" Scope: {}", auth_response.scope);
}
Err(e) => {
tracing::error!("❌ Authentication failed: {}", e);
client.disconnect().await?;
return Err(e.into());
}
}
tracing::info!("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
tracing::info!("📈 Placing a BUY limit order...");
let buy_request = OrderRequest::limit("BTC-PERPETUAL".to_string(), 10.0, 50000.0)
.with_time_in_force(TimeInForce::GoodTilCancelled)
.with_label("example_buy_order".to_string());
tracing::info!(" Instrument: BTC-PERPETUAL");
tracing::info!(" Amount: 10 USD");
tracing::info!(" Price: $50,000 (limit)");
tracing::info!(" Type: Limit, GTC");
match client.buy(buy_request).await {
Ok(order_response) => {
tracing::info!("✅ Buy order placed successfully!");
tracing::info!(" Order ID: {}", order_response.order.order_id);
tracing::info!(" State: {}", order_response.order.order_state);
tracing::info!(" Direction: {:?}", order_response.order.direction);
let order_id = order_response.order.order_id.clone();
tracing::info!("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
tracing::info!("✏️ Editing the order (changing price)...");
let edit_request =
deribit_websocket::model::trading::EditOrderRequest::new(order_id.clone(), 10.0)
.with_price(49000.0);
match client.edit(edit_request).await {
Ok(edit_response) => {
tracing::info!("✅ Order edited successfully!");
tracing::info!(" New Order ID: {}", edit_response.order.order_id);
tracing::info!(" New Price: {:?}", edit_response.order.price);
}
Err(e) => {
tracing::error!("❌ Edit failed: {}", e);
}
}
tracing::info!("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
tracing::info!("❌ Cancelling the order...");
match client.cancel(&order_id).await {
Ok(cancel_response) => {
tracing::info!("✅ Order cancelled successfully!");
tracing::info!(" Order ID: {}", cancel_response.order_id);
tracing::info!(" State: {}", cancel_response.order_state);
}
Err(e) => {
tracing::error!("❌ Cancel failed: {}", e);
}
}
}
Err(e) => {
tracing::error!("❌ Buy order failed: {}", e);
}
}
tracing::info!("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
tracing::info!("📉 Placing a SELL limit order...");
let sell_request = OrderRequest::limit("BTC-PERPETUAL".to_string(), 10.0, 100000.0)
.with_time_in_force(TimeInForce::GoodTilCancelled)
.with_label("example_sell_order".to_string());
match client.sell(sell_request).await {
Ok(order_response) => {
tracing::info!("✅ Sell order placed successfully!");
tracing::info!(" Order ID: {}", order_response.order.order_id);
tracing::info!(" State: {}", order_response.order.order_state);
}
Err(e) => {
tracing::error!("❌ Sell order failed: {}", e);
}
}
tracing::info!("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
tracing::info!("🗑️ Cancelling all orders for BTC-PERPETUAL...");
match client.cancel_all_by_instrument("BTC-PERPETUAL").await {
Ok(count) => {
tracing::info!("✅ Cancelled {} orders for BTC-PERPETUAL", count);
}
Err(e) => {
tracing::error!("❌ Cancel all by instrument failed: {}", e);
}
}
tracing::info!("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
tracing::info!("🗑️ Cancelling all BTC orders...");
match client.cancel_all_by_currency("BTC").await {
Ok(count) => {
tracing::info!("✅ Cancelled {} BTC orders", count);
}
Err(e) => {
tracing::error!("❌ Cancel all by currency failed: {}", e);
}
}
tracing::info!("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
tracing::info!("🗑️ Cancelling ALL orders...");
match client.cancel_all().await {
Ok(count) => {
tracing::info!("✅ Cancelled {} orders in total", count);
}
Err(e) => {
tracing::error!("❌ Cancel all failed: {}", e);
}
}
tracing::info!("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
tracing::info!("🔌 Disconnecting...");
client.disconnect().await?;
tracing::info!("✅ Disconnected successfully");
tracing::info!("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
tracing::info!("✅ Trading operations example completed!");
Ok(())
}