#![allow(deprecated)]
use ccxt_core::{
prelude::*,
time::{TimestampConversion, TimestampUtils},
};
use ccxt_exchanges::binance::Binance;
use rust_decimal_macros::dec;
use std::env;
#[tokio::main]
async fn main() -> std::result::Result<(), Box<dyn std::error::Error>> {
println!("=== Timestamp Migration Example ===\n");
let config = ExchangeConfig {
api_key: env::var("BINANCE_API_KEY")
.ok()
.map(ccxt_core::SecretString::new),
secret: env::var("BINANCE_API_SECRET")
.ok()
.map(ccxt_core::SecretString::new),
sandbox: false,
..Default::default()
};
let exchange = Binance::new(config)?;
example_timestamp_creation().await?;
example_data_structures().await?;
example_ohlcv_migration(&exchange).await?;
example_trades_migration(&exchange).await?;
example_conversion_utilities().await?;
example_error_handling().await?;
println!("\n=== Migration Example Complete ===");
Ok(())
}
async fn example_timestamp_creation() -> std::result::Result<(), Box<dyn std::error::Error>> {
println!("📅 Example 1: Timestamp Creation");
println!("--------------------------------");
#[allow(clippy::cast_possible_truncation)]
let _old_timestamp = chrono::Utc::now().timestamp_millis() as u64;
println!("❌ Old way: casting to u64 (deprecated)");
let new_timestamp: i64 = chrono::Utc::now().timestamp_millis();
println!("✅ New way: using i64 directly");
println!(" Current timestamp: {} ms", new_timestamp);
let util_timestamp = TimestampUtils::now_ms();
println!("✅ Using utilities: {} ms", util_timestamp);
let formatted = TimestampUtils::format_iso8601(new_timestamp);
println!(" Formatted: {:?}", formatted);
println!();
Ok(())
}
async fn example_data_structures() -> std::result::Result<(), Box<dyn std::error::Error>> {
println!("🏗️ Example 2: Data Structures");
println!("------------------------------");
let timestamp: i64 = chrono::Utc::now().timestamp_millis();
let ticker = Ticker::new("BTC/USDT".to_string(), timestamp);
println!("✅ Ticker created with i64 timestamp: {}", ticker.timestamp);
let orderbook = OrderBook::new("BTC/USDT".to_string(), timestamp);
println!(
"✅ OrderBook created with i64 timestamp: {}",
orderbook.timestamp
);
let trade = Trade::new(
"BTC/USDT".to_string(),
OrderSide::Buy,
dec!(50000.0).into(),
dec!(0.1).into(),
timestamp,
);
println!("✅ Trade created with i64 timestamp: {}", trade.timestamp);
let ohlcv = Ohlcv::new(
timestamp,
dec!(49000.0).into(), dec!(51000.0).into(), dec!(48500.0).into(), dec!(50000.0).into(), dec!(1234.5).into(), );
println!("✅ OHLCV created with i64 timestamp: {}", ohlcv.timestamp);
println!();
Ok(())
}
async fn example_ohlcv_migration(
exchange: &Binance,
) -> std::result::Result<(), Box<dyn std::error::Error>> {
println!("📊 Example 3: OHLCV Fetching Migration");
println!("--------------------------------------");
println!("❌ Old way (deprecated):");
println!(" // This would show deprecation warnings:");
println!(
" // exchange.fetch_ohlcv_u64(\"BTC/USDT\", Timeframe::H1, Some(timestamp_u64), Some(100), None)"
);
println!("✅ New way 1: Basic method");
match exchange
.fetch_ohlcv("BTC/USDT", "1h", None, Some(5), None)
.await
{
Ok(candles) => {
println!(" Fetched {} candles using basic method", candles.len());
if let Some(first) = candles.first() {
println!(" First candle timestamp: {}", first.timestamp);
}
}
Err(e) => println!(" Error: {}", e),
}
println!("✅ New way 2: Parameter-based method");
let since: i64 = chrono::Utc::now().timestamp_millis() - (24 * 60 * 60 * 1000);
match exchange
.fetch_ohlcv("BTC/USDT", "1h", Some(since), Some(10), None)
.await
{
Ok(candles) => {
println!(
" Fetched {} candles using parameter method",
candles.len()
);
if let Some(first) = candles.first() {
println!(" First candle timestamp: {}", first.timestamp);
println!(" Since parameter (i64): {}", since);
}
}
Err(e) => println!(" Error: {}", e),
}
println!();
Ok(())
}
async fn example_trades_migration(
exchange: &Binance,
) -> std::result::Result<(), Box<dyn std::error::Error>> {
println!("💱 Example 4: Trade Fetching Migration");
println!("--------------------------------------");
println!("❌ Old way (no longer available):");
println!(" // exchange.fetch_trades(\"BTC/USDT\", Some(5)) // This signature is gone");
println!("✅ New way 1: Basic trades");
match exchange.fetch_trades("BTC/USDT", None).await {
Ok(trades) => {
println!(" Fetched {} trades using basic method", trades.len());
}
Err(e) => println!(" Error: {}", e),
}
println!("✅ New way 2: With limit");
match exchange.fetch_trades("BTC/USDT", Some(5)).await {
Ok(trades) => {
println!(" Fetched {} trades with limit", trades.len());
}
Err(e) => println!(" Error: {}", e),
}
println!("✅ New way 3: With timestamp filtering");
let since: i64 = chrono::Utc::now().timestamp_millis() - (60 * 60 * 1000); println!(" Note: Using fetch_trades with limit parameter");
match exchange.fetch_trades("BTC/USDT", Some(10)).await {
Ok(trades) => {
println!(" Fetched {} trades with timestamp filter", trades.len());
println!(" Since parameter (i64): {}", since);
}
Err(e) => println!(" Error: {}", e),
}
println!();
Ok(())
}
#[allow(deprecated)] async fn example_conversion_utilities() -> std::result::Result<(), Box<dyn std::error::Error>> {
println!("🔄 Example 5: Conversion Utilities");
println!("----------------------------------");
let u64_timestamp = 1609459200000u64; match TimestampUtils::u64_to_i64(u64_timestamp) {
Ok(i64_timestamp) => {
println!(
"✅ u64 to i64 conversion: {} -> {}",
u64_timestamp, i64_timestamp
);
}
Err(e) => println!("❌ Conversion error: {}", e),
}
let u64_option = Some(1609459200000u64);
match u64_option.to_i64() {
Ok(i64_option) => {
println!(
"✅ Option<u64> to Option<i64>: {:?} -> {:?}",
u64_option, i64_option
);
}
Err(e) => println!("❌ Conversion error: {}", e),
}
let timestamp = 1609459200000i64;
match TimestampUtils::validate_timestamp(timestamp) {
Ok(validated) => {
println!("✅ Timestamp validation: {} is valid", validated);
}
Err(e) => println!("❌ Validation error: {}", e),
}
match TimestampUtils::parse_timestamp("1609459200000") {
Ok(parsed) => {
println!("✅ String parsing: '1609459200000' -> {}", parsed);
}
Err(e) => println!("❌ Parse error: {}", e),
}
let seconds = 1609459200i64;
let milliseconds = TimestampUtils::seconds_to_ms(seconds);
let back_to_seconds = TimestampUtils::ms_to_seconds(milliseconds);
println!(
"✅ Time conversions: {}s -> {}ms -> {}s",
seconds, milliseconds, back_to_seconds
);
println!();
Ok(())
}
#[allow(deprecated)] async fn example_error_handling() -> std::result::Result<(), Box<dyn std::error::Error>> {
println!("⚠️ Example 6: Error Handling");
println!("-----------------------------");
let large_u64 = u64::MAX;
match TimestampUtils::u64_to_i64(large_u64) {
Ok(converted) => {
println!("Unexpected success: {}", converted);
}
Err(e) => {
println!("✅ Correctly caught overflow: {}", e);
}
}
let negative_i64 = -1000i64;
match TimestampUtils::i64_to_u64(negative_i64) {
Ok(converted) => {
println!("Unexpected success: {}", converted);
}
Err(e) => {
println!("✅ Correctly caught underflow: {}", e);
}
}
let invalid_timestamp = -1i64;
match TimestampUtils::validate_timestamp(invalid_timestamp) {
Ok(validated) => {
println!("Unexpected success: {}", validated);
}
Err(e) => {
println!("✅ Correctly caught invalid range: {}", e);
}
}
match TimestampUtils::parse_timestamp("not_a_number") {
Ok(parsed) => {
println!("Unexpected success: {}", parsed);
}
Err(e) => {
println!("✅ Correctly caught parse error: {}", e);
}
}
println!();
Ok(())
}