use deribit_websocket::prelude::*;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
deribit_websocket::install_default_crypto_provider()?;
setup_logger();
let client = DeribitWebSocketClient::default();
tracing::info!("๐ Starting Mass Quote Basic Example");
let mut client = client;
client.connect().await?;
tracing::info!("โ
Connected to Deribit WebSocket");
let (client_id, client_secret) = client.config.get_credentials().unwrap();
client.authenticate(client_id, client_secret).await?;
tracing::info!("๐ Authenticated successfully");
tracing::info!("๐ Attempting to set up MMP group configuration...");
tracing::info!("โน๏ธ Note: MMP requires manual activation by Deribit staff for each account");
let mmp_config = MmpGroupConfig::new(
"btc_market_making".to_string(),
10.0, 5.0, 1000, 5000, )?;
match client.set_mmp_config(mmp_config).await {
Ok(()) => {
tracing::info!("โ
MMP group 'btc_market_making' configured successfully");
}
Err(e) => {
tracing::warn!("โ ๏ธ MMP configuration failed: {}", e);
tracing::info!("๐ This is expected if MMP is not activated for this account");
tracing::info!("๐ Contact Deribit support to request MMP activation");
}
}
tracing::info!("๐ฐ Creating mass quotes for BTC-PERPETUAL...");
let quotes = vec![
Quote::buy("BTC-PERPETUAL".to_string(), 0.1, 45000.0)
.with_quote_set_id("spread_1".to_string())
.with_post_only(true),
Quote::sell("BTC-PERPETUAL".to_string(), 0.1, 55000.0)
.with_quote_set_id("spread_1".to_string())
.with_post_only(true),
Quote::buy("BTC-PERPETUAL".to_string(), 0.2, 44000.0)
.with_quote_set_id("spread_2".to_string()),
Quote::sell("BTC-PERPETUAL".to_string(), 0.2, 56000.0)
.with_quote_set_id("spread_2".to_string()),
];
let mass_quote_request = MassQuoteRequest::new("default".to_string(), quotes.clone())
.with_quote_id("quote_batch_1".to_string())
.with_detailed_errors();
tracing::info!("โน๏ธ Note: Mass Quote feature requires separate activation by Deribit staff");
match client.mass_quote(mass_quote_request).await {
Ok(response) => {
tracing::info!(
"โ
Mass quote successful: {} placed, {} errors",
response.success_count,
response.error_count
);
if let Some(errors) = response.errors {
for error in errors {
tracing::warn!(
"โ Quote error for {} {}: {} ({})",
error.instrument_name,
error.side,
error.error_message,
error.error_code
);
}
}
}
Err(e) => {
tracing::warn!("โ ๏ธ Mass quote failed: {}", e);
tracing::info!(
"๐ This is expected if Mass Quote feature is not activated for this account"
);
tracing::info!("๐ Contact Deribit support to request Mass Quote activation");
tracing::info!("๐ Continuing with individual quote placement demonstration...");
demonstrate_individual_quotes(&mut client, quotes).await?;
}
}
tracing::info!("๐ Checking open orders...");
match client
.get_open_orders(Some("BTC".to_string()), None, Some("quote".to_string()))
.await
{
Ok(orders) => {
tracing::info!("๐ Found {} open quotes:", orders.len());
for order in &orders {
tracing::info!(
" ๐ฑ {} {} @ {} (Set: {}, Group: {})",
order.side.to_uppercase(),
order.amount,
order.price,
order.quote_set_id.as_deref().unwrap_or("none"),
order.mmp_group
);
}
}
Err(e) => {
tracing::warn!("โ ๏ธ Failed to get open orders: {}", e);
}
}
tokio::time::sleep(tokio::time::Duration::from_secs(5)).await;
tracing::info!("๐๏ธ Cancelling quotes from set 'spread_1'...");
let cancel_request = CancelQuotesRequest::by_quote_set_id("spread_1".to_string());
match client.cancel_quotes(cancel_request).await {
Ok(response) => {
tracing::info!(
"โ
Cancelled {} quotes from set 'spread_1'",
response.cancelled_count
);
}
Err(e) => {
tracing::warn!("โ ๏ธ Failed to cancel quotes: {}", e);
}
}
tokio::time::sleep(tokio::time::Duration::from_secs(2)).await;
tracing::info!("๐งน Cancelling all remaining BTC quotes...");
let cancel_all_request = CancelQuotesRequest::by_currency("BTC".to_string());
match client.cancel_quotes(cancel_all_request).await {
Ok(response) => {
tracing::info!("โ
Cancelled {} remaining quotes", response.cancelled_count);
}
Err(e) => {
tracing::warn!("โ ๏ธ Failed to cancel remaining quotes: {}", e);
}
}
tracing::info!("๐งฝ Attempting to clean up MMP group...");
let cleanup_config = MmpGroupConfig::new(
"btc_market_making".to_string(),
10.0,
5.0,
0, 5000,
)?
.disable();
match client.set_mmp_config(cleanup_config).await {
Ok(()) => {
tracing::info!("โ
MMP group disabled and cleaned up");
}
Err(e) => {
tracing::warn!(
"โ ๏ธ Failed to disable MMP group: {} (expected if MMP not activated)",
e
);
}
}
tracing::info!("๐ฏ Mass Quote Basic Example completed successfully!");
Ok(())
}
async fn demonstrate_individual_quotes(
_client: &mut DeribitWebSocketClient,
quotes: Vec<Quote>,
) -> Result<(), Box<dyn std::error::Error>> {
tracing::info!("๐ Demonstrating individual quote placement...");
for (i, quote) in quotes.iter().enumerate() {
tracing::info!(
" ๐ค Placing quote {}: {} {} @ {} (Set: {})",
i + 1,
quote.side.to_uppercase(),
quote.amount,
quote.price,
quote.quote_set_id.as_deref().unwrap_or("none")
);
}
tracing::info!("โ
Individual quote demonstration completed");
Ok(())
}