Expand description
§Migration Guide from rs-backtester
This module provides comprehensive guidance for migrating existing rs-backtester code to use hyperliquid-backtester with enhanced Hyperliquid-specific features.
§Overview
hyperliquid-backtester is designed as a drop-in enhancement to rs-backtester, meaning most existing code will work with minimal changes while gaining access to:
- Real Hyperliquid market data
- Funding rate calculations
- Enhanced commission structures
- Perpetual futures mechanics
- Advanced reporting features
§Basic Migration Steps
§1. Update Dependencies
Before (rs-backtester only):
[dependencies]
rs-backtester = "0.1"
After (with hyperliquid-backtester):
[dependencies]
hyperliquid-backtester = "0.1"
tokio = { version = "1.0", features = ["full"] }
§2. Update Imports
Before:
use rs_backtester::prelude::*;
After:
use hyperliquid_backtest::prelude::*;
§3. Replace Data Sources
Before (CSV or manual data):
let data = Data::from_csv("data.csv")?;
After (Live Hyperliquid data):
let data = HyperliquidData::fetch("BTC", "1h", start_time, end_time).await?;
§Detailed Migration Examples
§Example 1: Simple Moving Average Strategy
Before (rs-backtester):
use rs_backtester::prelude::*;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let data = Data::from_csv("btc_data.csv")?;
let strategy = sma_cross(data.clone(), 10, 20);
let mut backtest = Backtest::new(
data,
strategy,
10000.0,
Commission { rate: 0.001 },
);
backtest.run();
let report = backtest.report();
println!("Total Return: {:.2}%", report.total_return * 100.0);
Ok(())
}
After (hyperliquid-backtester):
use hyperliquid_backtest::prelude::*;
#[tokio::main]
async fn main() -> Result<(), HyperliquidBacktestError> {
// Fetch real Hyperliquid data
let data = HyperliquidData::fetch("BTC", "1h", start_time, end_time).await?;
// Use enhanced SMA strategy with funding awareness
let strategy = enhanced_sma_cross(10, 20, Default::default())?;
let mut backtest = HyperliquidBacktest::new(
data,
strategy,
10000.0,
HyperliquidCommission::default(), // Realistic Hyperliquid fees
)?;
// Include funding calculations
backtest.calculate_with_funding()?;
let report = backtest.enhanced_report()?;
println!("Total Return: {:.2}%", report.total_return * 100.0);
println!("Funding PnL: ${:.2}", report.funding_pnl); // New!
Ok(())
}
§Example 2: Custom Strategy Migration
Before (rs-backtester custom strategy):
use rs_backtester::prelude::*;
fn rsi_strategy(data: Data, period: usize, oversold: f64, overbought: f64) -> Strategy {
let mut strategy = Strategy::new();
strategy.next(Box::new(move |ctx, _| {
let rsi = calculate_rsi(&ctx.data().close, period, ctx.index());
if rsi < oversold {
ctx.entry_qty(1.0); // Go long
} else if rsi > overbought {
ctx.entry_qty(-1.0); // Go short
}
}));
strategy
}
After (hyperliquid-backtester with funding awareness):
use hyperliquid_backtest::prelude::*;
fn enhanced_rsi_strategy(
data: &HyperliquidData,
period: usize,
oversold: f64,
overbought: f64,
funding_config: FundingAwareConfig,
) -> Result<Strategy, HyperliquidBacktestError> {
let mut strategy = Strategy::new();
let data_clone = data.clone();
strategy.next(Box::new(move |ctx, _| {
let rsi = calculate_rsi(&ctx.data().close, period, ctx.index());
// Get funding rate for current timestamp
let current_time = data_clone.datetime[ctx.index()];
let funding_rate = data_clone.get_funding_rate_at(current_time).unwrap_or(0.0);
// Combine RSI and funding signals
let mut signal = 0.0;
if rsi < oversold {
signal = 1.0; // RSI suggests long
} else if rsi > overbought {
signal = -1.0; // RSI suggests short
}
// Adjust signal based on funding rate
if funding_rate.abs() > funding_config.funding_threshold {
if funding_rate > 0.0 {
// Positive funding - longs pay shorts, favor long
signal += funding_config.funding_weight;
} else {
// Negative funding - shorts pay longs, favor short
signal -= funding_config.funding_weight;
}
}
// Apply final signal
if signal > 0.5 {
ctx.entry_qty(1.0);
} else if signal < -0.5 {
ctx.entry_qty(-1.0);
} else {
ctx.exit();
}
}));
Ok(strategy)
}
§Key Differences and Enhancements
§1. Async Operations
hyperliquid-backtester uses async operations for data fetching:
// Always use #[tokio::main] for async main function
#[tokio::main]
async fn main() -> Result<(), HyperliquidBacktestError> {
let data = HyperliquidData::fetch("BTC", "1h", start, end).await?;
// ... rest of code
}
§2. Enhanced Commission Structure
rs-backtester:
Commission { rate: 0.001 } // Single rate for all trades
hyperliquid-backtester:
HyperliquidCommission {
maker_rate: 0.0002, // 0.02% for maker orders
taker_rate: 0.0005, // 0.05% for taker orders
funding_enabled: true, // Include funding calculations
}
§3. Enhanced Reporting
rs-backtester:
let report = backtest.report();
println!("Return: {:.2}%", report.total_return * 100.0);
hyperliquid-backtester:
let report = backtest.enhanced_report()?;
println!("Trading Return: {:.2}%", report.trading_return * 100.0);
println!("Funding Return: {:.2}%", report.funding_return * 100.0);
println!("Total Return: {:.2}%", report.total_return * 100.0);
// Additional funding-specific metrics
let funding_report = backtest.funding_report()?;
println!("Avg Funding Rate: {:.4}%", funding_report.avg_funding_rate * 100.0);
§Common Migration Patterns
§Pattern 1: Data Loading
From CSV files:
// Old
let data = Data::from_csv("data.csv")?;
// New - convert existing CSV to HyperliquidData format
let data = HyperliquidData::from_csv("data.csv").await?;
// Or fetch fresh data
let data = HyperliquidData::fetch("BTC", "1h", start, end).await?;
§Pattern 2: Strategy Enhancement
Add funding awareness to existing strategies:
// Wrap existing rs-backtester strategy
let base_strategy = your_existing_strategy();
let enhanced_strategy = base_strategy.with_funding_awareness(0.0001)?;
§Pattern 3: Error Handling
Update error handling:
// Old
fn run_backtest() -> Result<(), Box<dyn std::error::Error>> {
// ...
}
// New
async fn run_backtest() -> Result<(), HyperliquidBacktestError> {
// ...
}
§Compatibility Notes
§What Stays the Same
- Core strategy logic and indicators
- Basic backtest workflow
- Report structure (with additions)
- CSV export functionality (enhanced)
§What Changes
- Data fetching becomes async
- Commission structure is more detailed
- Error types are more specific
- Additional funding-related methods
§Breaking Changes
- Async requirement: Data fetching requires async context
- Error types:
HyperliquidBacktestError
instead of generic errors - Commission structure: More detailed fee structure
- Import paths: Use
hyperliquid_backtest::prelude::*
§Migration Checklist
-
Update
Cargo.toml
dependencies -
Change imports to
hyperliquid_backtest::prelude::*
-
Add
#[tokio::main]
to main function -
Replace data loading with
HyperliquidData::fetch()
-
Update commission structure to
HyperliquidCommission
-
Update error handling to use
HyperliquidBacktestError
- Test enhanced features (funding calculations, etc.)
- Update documentation and examples
§Getting Help
If you encounter issues during migration:
- Check the API documentation
- Review the examples directory
- Open an issue on GitHub
§Performance Considerations
- Data fetching: Cache data locally for repeated backtests
- Funding calculations: Can be disabled if not needed via
funding_enabled: false
- Memory usage: HyperliquidData includes additional funding rate arrays
- Network calls: Batch data requests when possible