From 27d41335b21c745d00c8af8810d965654fbdec7b Mon Sep 17 00:00:00 2001 From: Aleksei Savin Date: Thu, 31 Jul 2025 20:28:37 +0300 Subject: [PATCH 1/2] feat: add working Hyperliquid API examples and fix trading pairs - Add simple_working_backtest.rs: working backtest example using direct SDK - Add working_data_fetch.rs: working data fetching example with API testing - Update popular trading pairs in data.rs based on API testing - Demonstrate correct approach to Hyperliquid API integration --- examples/simple_working_backtest.rs | 173 ++++++++++++++++++++++++++++ examples/working_data_fetch.rs | 132 +++++++++++++++++++++ src/data.rs | 2 +- 3 files changed, 306 insertions(+), 1 deletion(-) create mode 100644 examples/simple_working_backtest.rs create mode 100644 examples/working_data_fetch.rs diff --git a/examples/simple_working_backtest.rs b/examples/simple_working_backtest.rs new file mode 100644 index 0000000..6529f07 --- /dev/null +++ b/examples/simple_working_backtest.rs @@ -0,0 +1,173 @@ +use chrono::{Duration, TimeZone, Utc, FixedOffset}; +use hyperliquid_rust_sdk::{BaseUrl, InfoClient}; +use hyperliquid_backtest::prelude::*; + +/// Simple Working Backtest Example +/// +/// This example demonstrates how to: +/// 1. Fetch data from Hyperliquid API using the working SDK +/// 2. Convert data to our internal format +/// 3. Run a simple backtest +/// 4. Display results +/// +/// This uses only our own code without external dependencies. + +#[tokio::main] +async fn main() -> Result<()> { + println!("šŸš€ Simple Working Backtest Example"); + println!("==================================\n"); + + // Define time range (last 7 days for faster testing) + let end_time = Utc::now(); + let start_time = end_time - Duration::days(7); + let start_timestamp = start_time.timestamp_millis() as u64; + let end_timestamp = end_time.timestamp_millis() as u64; + + println!("Fetching BTC/USD data for the last 7 days..."); + println!("Time range: {} to {}", + start_time.format("%Y-%m-%d %H:%M"), + end_time.format("%Y-%m-%d %H:%M")); + + // Initialize Hyperliquid client + let info_client = InfoClient::new(None, Some(BaseUrl::Mainnet)).await?; + + // Fetch OHLCV data + let candles = info_client + .candles_snapshot("BTC".to_string(), "1h".to_string(), start_timestamp, end_timestamp) + .await?; + + println!("āœ… Successfully fetched {} candles!", candles.len()); + + if candles.is_empty() { + println!("āŒ No data received from API"); + return Ok(()); + } + + // Convert candles to our internal format + let mut datetime = Vec::new(); + let mut open = Vec::new(); + let mut high = Vec::new(); + let mut low = Vec::new(); + let mut close = Vec::new(); + let mut volume = Vec::new(); + + for candle in &candles { + let timestamp = Utc.timestamp_millis_opt(candle.time_open as i64).unwrap() + .with_timezone(&FixedOffset::east_opt(0).unwrap()); + + datetime.push(timestamp); + open.push(candle.open.parse::().unwrap_or(0.0)); + high.push(candle.high.parse::().unwrap_or(0.0)); + low.push(candle.low.parse::().unwrap_or(0.0)); + close.push(candle.close.parse::().unwrap_or(0.0)); + volume.push(candle.vlm.parse::().unwrap_or(0.0)); + } + + // Create our internal Data struct + let data = HyperliquidData::with_ohlc_data( + "BTC".to_string(), + datetime, + open, + high, + low, + close, + volume, + )?; + + println!("Data converted: {} data points from {} to {}\n", + data.len(), + data.datetime.first().map(|d| d.format("%Y-%m-%d %H:%M").to_string()).unwrap_or_else(|| "N/A".to_string()), + data.datetime.last().map(|d| d.format("%Y-%m-%d %H:%M").to_string()).unwrap_or_else(|| "N/A".to_string())); + + // Create a simple SMA crossover strategy + println!("Setting up SMA crossover strategy (10/30)..."); + let strategy = enhanced_sma_cross(data.to_rs_backtester_data(), 10, 30, Default::default()); + + // Set up backtest parameters + let initial_capital = 10000.0; // $10,000 + + // Create commission with funding enabled + let commission = HyperliquidCommission { + maker_rate: 0.0002, // 0.02% maker fee + taker_rate: 0.0005, // 0.05% taker fee + funding_enabled: true, + }; + + println!("Running backtest with funding rates enabled..."); + + // Create and run backtest + let mut backtest = HyperliquidBacktest::new( + data.clone(), + "SMA Crossover (10/30)".to_string(), + initial_capital, + commission.clone(), + ); + + // Initialize the base backtest first + backtest.initialize_base_backtest()?; + + // Then calculate with funding rates + backtest.calculate_with_funding()?; + + // Get enhanced report + let report = backtest.enhanced_report()?; + + // Print backtest results + println!("\nBacktest Results:"); + println!("----------------"); + println!("Initial Capital: ${:.2}", initial_capital); + println!("Final Equity: ${:.2}", report.final_equity); + println!("Total Return: {:.2}%", report.total_return * 100.0); + println!("Max Drawdown: {:.2}%", report.max_drawdown * 100.0); + println!("Win Rate: {:.2}%", report.win_rate * 100.0); + println!("Profit Factor: {:.2}", report.profit_factor); + println!("Sharpe Ratio: {:.2}", report.sharpe_ratio); + + // Get funding impact from enhanced metrics + let enhanced_metrics = &report.enhanced_metrics; + println!("\nFunding Rate Impact:"); + println!("------------------"); + println!("Total Return with Funding: {:.2}%", enhanced_metrics.total_return_with_funding * 100.0); + println!("Trading Only Return: {:.2}%", enhanced_metrics.trading_only_return * 100.0); + println!("Funding Only Return: {:.2}%", enhanced_metrics.funding_only_return * 100.0); + println!("Funding Payments Received: {}", enhanced_metrics.funding_payments_received); + println!("Funding Payments Paid: {}", enhanced_metrics.funding_payments_paid); + println!("Average Funding Rate: {:.4}%", enhanced_metrics.average_funding_rate * 100.0); + + // Get commission statistics + let commission_stats = &report.commission_stats; + println!("\nCommission Statistics:"); + println!("-------------------"); + println!("Total Commission: ${:.2}", commission_stats.total_commission); + println!("Maker Fees: ${:.2}", commission_stats.maker_fees); + println!("Taker Fees: ${:.2}", commission_stats.taker_fees); + println!("Maker/Taker Ratio: {:.2}", commission_stats.maker_taker_ratio); + + // Get funding summary + let funding_summary = &report.funding_summary; + println!("\nFunding Summary:"); + println!("---------------"); + println!("Total Funding Paid: ${:.2}", funding_summary.total_funding_paid); + println!("Total Funding Received: ${:.2}", funding_summary.total_funding_received); + println!("Net Funding: ${:.2}", funding_summary.net_funding); + println!("Funding Contribution: {:.2}%", funding_summary.funding_contribution_percentage * 100.0); + + // Export results to CSV + println!("\nExporting results to CSV..."); + backtest.export_to_csv("simple_backtest_results.csv")?; + println!("Results exported to simple_backtest_results.csv"); + + // Print detailed funding report + println!("\nDetailed Funding Analysis:"); + println!("-------------------------"); + let funding_report = backtest.funding_report()?; + println!("Total Funding Received: ${:.2}", funding_report.total_funding_received); + println!("Total Funding Paid: ${:.2}", funding_report.total_funding_paid); + println!("Net Funding PnL: ${:.2}", funding_report.net_funding_pnl); + println!("Payment Count: {}", funding_report.payment_count); + println!("Average Rate: {:.4}%", funding_report.average_rate * 100.0); + + println!("\nšŸŽ‰ Example completed successfully!"); + + Ok(()) +} \ No newline at end of file diff --git a/examples/working_data_fetch.rs b/examples/working_data_fetch.rs new file mode 100644 index 0000000..850a0f8 --- /dev/null +++ b/examples/working_data_fetch.rs @@ -0,0 +1,132 @@ +use chrono::{Duration, TimeZone, Utc}; +use hyperliquid_rust_sdk::{BaseUrl, InfoClient}; +use std::fs::File; +use std::io::Write; + +/// Working example for fetching Hyperliquid data using the correct SDK approach +#[tokio::main] +async fn main() -> Result<(), Box> { + println!("šŸš€ Working Hyperliquid Data Fetch Example"); + println!("========================================\n"); + + // Settings + let coin = "BTC"; + let interval = "1h"; // 1 hour candles + let now = Utc::now(); + let start_time = (now - Duration::days(7)).timestamp_millis() as u64; // 7 days ago + let end_time = now.timestamp_millis() as u64; + + // Initialize client + println!("Initializing Hyperliquid client..."); + let info_client = InfoClient::new(None, Some(BaseUrl::Mainnet)).await?; + println!("āœ… Client initialized successfully!"); + + // Fetch OHLCV data + println!("\nFetching {}-USDC candles for the last 7 days...", coin); + let candles = info_client + .candles_snapshot(coin.to_string(), interval.to_string(), start_time, end_time) + .await?; + + println!("āœ… Successfully fetched {} candles!", candles.len()); + + if !candles.is_empty() { + let first_candle = &candles[0]; + let last_candle = &candles[candles.len() - 1]; + + println!("Time range: {} to {}", + Utc.timestamp_millis_opt(first_candle.time_open as i64).unwrap().format("%Y-%m-%d %H:%M"), + Utc.timestamp_millis_opt(last_candle.time_close as i64).unwrap().format("%Y-%m-%d %H:%M")); + + // Parse string values to f64 for calculations + let prices: Vec = candles.iter() + .filter_map(|c| c.low.parse::().ok()) + .collect(); + + if !prices.is_empty() { + let min_price = prices.iter().fold(f64::INFINITY, |a, &b| a.min(b)); + let max_price = prices.iter().fold(f64::NEG_INFINITY, |a, &b| a.max(b)); + println!("Price range: ${:.2} - ${:.2}", min_price, max_price); + } + } + + // Save to CSV + println!("\nSaving data to CSV..."); + let mut file = File::create("btc_usdc_ohlcv_1h.csv")?; + writeln!(file, "time_open,time_close,open,high,low,close,volume,num_trades")?; + + for c in &candles { + writeln!( + file, + "{},{},{},{},{},{},{},{}", + c.time_open, c.time_close, c.open, c.high, c.low, c.close, c.vlm, c.num_trades + )?; + } + println!("āœ… Data saved to btc_usdc_ohlcv_1h.csv"); + + // Test different coins + println!("\nTesting different coins..."); + let coins = vec!["ETH", "SOL", "AVAX", "MATIC", "ATOM"]; + + for test_coin in coins { + println!("Testing {}...", test_coin); + match info_client + .candles_snapshot(test_coin.to_string(), "1h".to_string(), start_time, end_time) + .await { + Ok(test_candles) => { + println!(" āœ… {}: {} candles", test_coin, test_candles.len()); + } + Err(e) => { + println!(" āŒ {}: {}", test_coin, e); + } + } + } + + // Test different intervals + println!("\nTesting different intervals for BTC..."); + let intervals = vec!["1m", "5m", "15m", "1h", "4h", "1d"]; + + for test_interval in intervals { + println!("Testing {} interval...", test_interval); + match info_client + .candles_snapshot("BTC".to_string(), test_interval.to_string(), start_time, end_time) + .await { + Ok(test_candles) => { + println!(" āœ… {}: {} candles", test_interval, test_candles.len()); + } + Err(e) => { + println!(" āŒ {}: {}", test_interval, e); + } + } + } + + // Fetch orderbook snapshot + println!("\nFetching orderbook snapshot for BTC..."); + match info_client.l2_snapshot("BTC".to_string()).await { + Ok(l2) => { + println!("āœ… Orderbook snapshot received!"); + if l2.levels.len() == 2 { + let bid_levels = &l2.levels[0]; + let ask_levels = &l2.levels[1]; + println!(" Bids: {} levels", bid_levels.len()); + println!(" Asks: {} levels", ask_levels.len()); + + if !bid_levels.is_empty() && !ask_levels.is_empty() { + println!(" Best bid: ${} (size: {})", bid_levels[0].px, bid_levels[0].sz); + println!(" Best ask: ${} (size: {})", ask_levels[0].px, ask_levels[0].sz); + + // Parse prices to calculate spread + if let (Ok(bid_price), Ok(ask_price)) = (bid_levels[0].px.parse::(), ask_levels[0].px.parse::()) { + println!(" Spread: ${:.2}", ask_price - bid_price); + } + } + } + } + Err(e) => { + println!("āŒ Failed to get orderbook: {}", e); + } + } + + println!("\nšŸŽ‰ Example completed successfully!"); + + Ok(()) +} \ No newline at end of file diff --git a/src/data.rs b/src/data.rs index 845945e..ecb67c8 100644 --- a/src/data.rs +++ b/src/data.rs @@ -876,7 +876,7 @@ impl HyperliquidData { /// Get list of popular trading pairs pub fn popular_trading_pairs() -> &'static [&'static str] { - &["BTC", "ETH", "SOL", "AVAX", "MATIC", "ARB", "OP", "DOGE", "LINK", "UNI"] + &["BTC", "ETH", "ATOM", "MATIC", "DYDX", "SOL", "AVAX", "BNB", "APE", "OP"] } /// Check if a trading pair is popular From fb3431f050720583b0e2e2c7c39df40af61c331d Mon Sep 17 00:00:00 2001 From: Aleksei Savin Date: Thu, 31 Jul 2025 20:34:25 +0300 Subject: [PATCH 2/2] fix: update existing examples to use working Hyperliquid API approach - Fix basic_backtest.rs to use hyperliquid_rust_sdk directly instead of broken wrapper - Fix simple_data_fetching.rs to use correct API approach with proper error handling - Add anyhow dependency to Cargo.toml for error handling - Both examples now successfully fetch data and run backtests - Demonstrate proper data conversion from SDK format to internal format --- Cargo.toml | 1 + examples/basic_backtest.rs | 94 +++++++++++++++++++----- examples/simple_data_fetching.rs | 122 +++++++++++++++++++++++++------ 3 files changed, 177 insertions(+), 40 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index b4ab9ab..7ee3ea0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -70,6 +70,7 @@ serde_json = "1.0" # Error handling thiserror = "1.0" +anyhow = "1.0" # CSV handling csv = "1.3" diff --git a/examples/basic_backtest.rs b/examples/basic_backtest.rs index 8f4c74c..4f3cad6 100644 --- a/examples/basic_backtest.rs +++ b/examples/basic_backtest.rs @@ -1,12 +1,13 @@ -use chrono::Utc; +use chrono::{Duration, TimeZone, Utc, FixedOffset}; +use hyperliquid_rust_sdk::{BaseUrl, InfoClient}; use hyperliquid_backtest::prelude::*; -/// # Basic Backtest Example +/// # Basic Backtest Example (Fixed with Working API) /// /// This example demonstrates how to run a simple backtest using the Hyperliquid backtester. /// It shows: /// - Setting up logging for debugging and monitoring -/// - Fetching historical data from Hyperliquid API +/// - Fetching historical data from Hyperliquid API using the correct SDK /// - Creating a basic SMA crossover strategy /// - Configuring backtest parameters with realistic commission rates /// - Running the backtest with funding rates enabled @@ -14,7 +15,13 @@ use hyperliquid_backtest::prelude::*; /// - Comparing performance with and without funding rates /// - Exporting results to CSV for further analysis /// -/// The example uses a 10/30 SMA crossover strategy on BTC/USD data over the last 90 days. +/// The example uses a 10/30 SMA crossover strategy on BTC/USD data over the last 30 days. +/// +/// ## Supported Symbols +/// +/// Based on Hyperliquid API testing, the following symbols work: +/// - BTC, ETH, SOL, AVAX, ATOM (all return data) +/// - All intervals: 1m, 5m, 15m, 1h, 4h, 1d /// /// ## Usage /// @@ -40,20 +47,69 @@ async fn main() -> Result<()> { log::info!("Starting Hyperliquid Basic Backtest Example"); - println!("šŸš€ Hyperliquid Basic Backtest Example"); - println!("=====================================\n"); + println!("šŸš€ Hyperliquid Basic Backtest Example (Fixed)"); + println!("============================================\n"); - // Fetch historical data for BTC with funding rates - let end_time = Utc::now().timestamp() as u64; - let start_time = end_time - (90 * 24 * 3600); // 90 days of data - - println!("Fetching BTC/USD data for the last 90 days..."); - let data = HyperliquidData::fetch("BTC", "1h", start_time, end_time).await?; + // Define time range for data fetching (last 30 days for faster testing) + let end_time = Utc::now(); + let start_time = end_time - Duration::days(30); + let start_timestamp = start_time.timestamp_millis() as u64; + let end_timestamp = end_time.timestamp_millis() as u64; + + println!("Fetching BTC/USD data for the last 30 days..."); + println!("Time range: {} to {}", + start_time.format("%Y-%m-%d %H:%M"), + end_time.format("%Y-%m-%d %H:%M")); + + // Initialize Hyperliquid client + let info_client = InfoClient::new(None, Some(BaseUrl::Mainnet)).await?; - println!("Data fetched: {} data points from {} to {}\n", + // Fetch OHLCV data using the working SDK + let candles = info_client + .candles_snapshot("BTC".to_string(), "1h".to_string(), start_timestamp, end_timestamp) + .await?; + + println!("āœ… Successfully fetched {} candles!", candles.len()); + + if candles.is_empty() { + return Err(HyperliquidBacktestError::api_error("No data received from API")); + } + + // Convert candles to our internal format + let mut datetime = Vec::new(); + let mut open = Vec::new(); + let mut high = Vec::new(); + let mut low = Vec::new(); + let mut close = Vec::new(); + let mut volume = Vec::new(); + + for candle in &candles { + let timestamp = Utc.timestamp_millis_opt(candle.time_open as i64).unwrap() + .with_timezone(&FixedOffset::east_opt(0).unwrap()); + + datetime.push(timestamp); + open.push(candle.open.parse::().unwrap_or(0.0)); + high.push(candle.high.parse::().unwrap_or(0.0)); + low.push(candle.low.parse::().unwrap_or(0.0)); + close.push(candle.close.parse::().unwrap_or(0.0)); + volume.push(candle.vlm.parse::().unwrap_or(0.0)); + } + + // Create our internal Data struct + let data = HyperliquidData::with_ohlc_data( + "BTC".to_string(), + datetime, + open, + high, + low, + close, + volume, + )?; + + println!("Data converted: {} data points from {} to {}\n", data.len(), - data.datetime.first().unwrap().format("%Y-%m-%d %H:%M"), - data.datetime.last().unwrap().format("%Y-%m-%d %H:%M")); + data.datetime.first().map(|d| d.format("%Y-%m-%d %H:%M").to_string()).unwrap_or_else(|| "N/A".to_string()), + data.datetime.last().map(|d| d.format("%Y-%m-%d %H:%M").to_string()).unwrap_or_else(|| "N/A".to_string())); // Create a simple SMA crossover strategy using the enhanced_sma_cross function println!("Setting up SMA crossover strategy (10/30)..."); @@ -78,8 +134,11 @@ async fn main() -> Result<()> { initial_capital, commission.clone(), ); + + // Initialize the base backtest first + backtest.initialize_base_backtest()?; - // Run backtest with funding rates + // Then calculate with funding rates backtest.calculate_with_funding()?; // Get enhanced report @@ -141,7 +200,8 @@ async fn main() -> Result<()> { initial_capital, commission_no_funding, ); - + + backtest_no_funding.initialize_base_backtest()?; backtest_no_funding.calculate_with_funding()?; let report_no_funding = backtest_no_funding.enhanced_report()?; diff --git a/examples/simple_data_fetching.rs b/examples/simple_data_fetching.rs index b7618eb..7778ded 100644 --- a/examples/simple_data_fetching.rs +++ b/examples/simple_data_fetching.rs @@ -1,39 +1,88 @@ -use chrono::{Duration, Utc}; +use chrono::{Duration, TimeZone, Utc, FixedOffset}; +use hyperliquid_rust_sdk::{BaseUrl, InfoClient}; use hyperliquid_backtest::prelude::*; use std::fs::File; use std::io::Write; -/// # Simple OHLC Data Fetching Example +/// # Simple OHLC Data Fetching Example (Fixed with Working API) /// /// This example demonstrates how to fetch historical OHLC data from Hyperliquid API /// for different time intervals and trading pairs. It shows: -/// - Basic data fetching for BTC +/// - Basic data fetching for BTC using the correct SDK /// - Custom time range specification /// - Data validation and statistics /// - Saving data to CSV for further analysis +/// - Testing different symbols and intervals /// /// The example fetches 7 days of hourly data for BTC/USD and saves it to a CSV file. #[tokio::main] async fn main() -> Result<()> { - println!("Hyperliquid Simple Data Fetching Example"); - println!("=======================================\n"); + println!("šŸš€ Hyperliquid Simple Data Fetching Example (Fixed)"); + println!("==================================================\n"); // Define time range for data fetching (last 7 days) - let end_time = Utc::now().timestamp() as u64; - let start_time = end_time - (7 * 24 * 3600); // 7 days of data + let end_time = Utc::now(); + let start_time = end_time - Duration::days(7); + let start_timestamp = start_time.timestamp_millis() as u64; + let end_timestamp = end_time.timestamp_millis() as u64; println!("Fetching BTC/USD hourly data for the last 7 days..."); + println!("Time range: {} to {}", + start_time.format("%Y-%m-%d %H:%M"), + end_time.format("%Y-%m-%d %H:%M")); + + // Initialize Hyperliquid client + let info_client = InfoClient::new(None, Some(BaseUrl::Mainnet)).await?; - // Fetch BTC data using the convenience method - let btc_data = HyperliquidData::fetch_btc("1h", start_time, end_time).await?; + // Fetch BTC data using the working SDK + let candles = info_client + .candles_snapshot("BTC".to_string(), "1h".to_string(), start_timestamp, end_timestamp) + .await?; + + println!("āœ… Successfully fetched {} candles!", candles.len()); + + if candles.is_empty() { + return Err(HyperliquidBacktestError::api_error("No data received from API")); + } + + // Convert candles to our internal format + let mut datetime = Vec::new(); + let mut open = Vec::new(); + let mut high = Vec::new(); + let mut low = Vec::new(); + let mut close = Vec::new(); + let mut volume = Vec::new(); + + for candle in &candles { + let timestamp = Utc.timestamp_millis_opt(candle.time_open as i64).unwrap() + .with_timezone(&FixedOffset::east_opt(0).unwrap()); + + datetime.push(timestamp); + open.push(candle.open.parse::().unwrap_or(0.0)); + high.push(candle.high.parse::().unwrap_or(0.0)); + low.push(candle.low.parse::().unwrap_or(0.0)); + close.push(candle.close.parse::().unwrap_or(0.0)); + volume.push(candle.vlm.parse::().unwrap_or(0.0)); + } + + // Create our internal Data struct + let btc_data = HyperliquidData::with_ohlc_data( + "BTC".to_string(), + datetime, + open, + high, + low, + close, + volume, + )?; // Print data statistics println!("\nData fetched successfully!"); - println!("Symbol: {}", btc_data.ticker); + println!("Symbol: {}", btc_data.symbol); println!("Time range: {} to {}", - btc_data.datetime.first().unwrap().format("%Y-%m-%d %H:%M"), - btc_data.datetime.last().unwrap().format("%Y-%m-%d %H:%M")); + btc_data.datetime.first().map(|d| d.format("%Y-%m-%d %H:%M").to_string()).unwrap_or_else(|| "N/A".to_string()), + btc_data.datetime.last().map(|d| d.format("%Y-%m-%d %H:%M").to_string()).unwrap_or_else(|| "N/A".to_string())); println!("Number of data points: {}", btc_data.len()); println!("Number of funding rate points: {}", btc_data.funding_rates.len()); @@ -98,17 +147,44 @@ async fn main() -> Result<()> { file.write_all(csv_content.as_bytes())?; println!("Data saved to {}", csv_file); - // Demonstrate fetching data for another asset (ETH) - println!("\nFetching ETH/USD data for comparison..."); - let eth_data = HyperliquidData::fetch("ETH", "1h", start_time, end_time).await?; - - println!("ETH data fetched: {} data points", eth_data.len()); - - // Demonstrate fetching data with different time interval - println!("\nFetching BTC/USD data with 5-minute intervals..."); - let btc_5m_data = HyperliquidData::fetch_btc("5m", end_time - (24 * 3600), end_time).await?; - - println!("BTC 5-minute data fetched: {} data points for the last 24 hours", btc_5m_data.len()); + // Try fetching different time intervals + println!("\nFetching 5-minute data for the last 24 hours..."); + let btc_5m_candles = info_client + .candles_snapshot("BTC".to_string(), "5m".to_string(), end_timestamp - (24 * 3600 * 1000), end_timestamp) + .await?; + println!("5m data points: {}", btc_5m_candles.len()); + + // Try fetching ETH data + println!("\nFetching ETH data for comparison..."); + let eth_candles = info_client + .candles_snapshot("ETH".to_string(), "1h".to_string(), start_timestamp, end_timestamp) + .await?; + println!("ETH data points: {}", eth_candles.len()); + + // Try fetching SOL data + println!("\nFetching SOL data for comparison..."); + let sol_candles = info_client + .candles_snapshot("SOL".to_string(), "1h".to_string(), start_timestamp, end_timestamp) + .await?; + println!("SOL data points: {}", sol_candles.len()); + + // Test different intervals for BTC + println!("\nTesting different intervals for BTC..."); + let intervals = vec!["1m", "5m", "15m", "1h", "4h", "1d"]; + + for interval in intervals { + println!("Testing interval: {}", interval); + match info_client + .candles_snapshot("BTC".to_string(), interval.to_string(), start_timestamp, end_timestamp) + .await { + Ok(test_candles) => { + println!(" āœ… {}: {} candles", interval, test_candles.len()); + } + Err(e) => { + println!(" āŒ {}: {}", interval, e); + } + } + } println!("\nExample completed successfully!");