use ostium_rust_sdk::{Network, OpenPositionParams, OstiumClient, PositionSide};
use rust_decimal::Decimal;
use rust_decimal_macros::dec;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
tracing_subscriber::fmt::init();
println!("📏 Minimum Size Constraint Validation Example");
println!("==============================================");
println!("Testing minimum collateral requirements based on Ostium documentation\n");
let client = OstiumClient::new(Network::Mainnet).await?;
let test_cases = vec![
("BTC/USD", dec!(0.00001), 10), ("ETH/USD", dec!(0.001), 10), ("EUR/USD", dec!(0.01), 20), ("SPX/USD", dec!(0.1), 50), ("GOLD/USD", dec!(0.001), 10), ];
for (symbol, size, leverage) in test_cases {
println!("🔍 Testing minimum size validation for {}", symbol);
println!(
" Position size: {} {}",
size,
symbol.split('/').next().unwrap()
);
println!(" Leverage: {}x", leverage);
match test_minimum_size_validation(&client, symbol, size, Decimal::from(leverage)).await {
Ok(_) => {
println!(" ✅ Position size meets minimum requirements");
}
Err(e) => {
println!(" ❌ Position size validation failed:");
for line in e.to_string().lines() {
println!(" {}", line);
}
}
}
println!();
}
println!("🎯 Testing Valid Positions (Should Pass)");
println!("==========================================");
let valid_test_cases = vec![
("BTC/USD", dec!(0.1), 5), ("ETH/USD", dec!(1.0), 5), ("EUR/USD", dec!(1000), 2), ];
for (symbol, size, leverage) in valid_test_cases {
println!(
"🔍 Testing {} with size {} at {}x leverage",
symbol, size, leverage
);
match test_minimum_size_validation(&client, symbol, size, Decimal::from(leverage)).await {
Ok(_) => {
println!(" ✅ Position passed validation");
}
Err(e) => {
println!(" ❌ Unexpected validation failure: {}", e);
}
}
println!();
}
println!("📊 Minimum Size Information by Asset");
println!("====================================");
let info_symbols = vec!["BTC/USD", "ETH/USD", "EUR/USD", "SPX/USD", "GOLD/USD"];
for symbol in info_symbols {
match client.get_minimum_position_size(symbol).await {
Ok(min_size) => {
println!(
" {}: minimum {} {}",
symbol,
min_size,
symbol.split('/').next().unwrap()
);
if let Ok(price) = client.get_price(symbol).await {
let min_collateral_1x = min_size * price.mark_price;
println!(" Current price: ${:.2}", price.mark_price);
println!(" Min collateral (1x): ${:.2} USDC", min_collateral_1x);
println!(
" Min collateral (10x): ${:.2} USDC",
min_collateral_1x / Decimal::from(10)
);
}
}
Err(e) => {
println!(" {}: Error getting minimum size: {}", symbol, e);
}
}
println!();
}
println!("📖 Documentation Reference:");
println!(" https://ostium-labs.gitbook.io/ostium-docs/ostium-trading-engine/opening-trades");
println!(" \"Collateral: the minimum amount is as low as 7 USDC on some assets.\"");
Ok(())
}
async fn test_minimum_size_validation(
client: &OstiumClient,
symbol: &str,
size: Decimal,
leverage: Decimal,
) -> Result<(), Box<dyn std::error::Error>> {
let params = OpenPositionParams {
symbol: symbol.to_string(),
side: PositionSide::Long,
size,
leverage,
take_profit: None,
stop_loss: None,
slippage_tolerance: dec!(0.02), };
match client
.validate_trading_constraints(¶ms.symbol, params.side, params.size, params.leverage)
.await
{
Ok(_) => Ok(()),
Err(e) => Err(Box::new(e)),
}
}