Skip to content

Commit 92fec65

Browse files
authored
Merge pull request #1 from xsa-dev/examples-startup
Examples startup
2 parents dce3974 + 9986592 commit 92fec65

35 files changed

Lines changed: 175 additions & 238 deletions

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
6464
- N/A (initial release)
6565

6666
### Migration Guide
67-
- See [Migration Guide](https://docs.rs/hyperliquid-backtest/latest/hyperliquid_backtester/migration/index.html) for upgrading from rs-backtester
67+
- See [Migration Guide](https://docs.rs/hyperliquid-backtest/latest/hyperliquid_backtest/migration/index.html) for upgrading from rs-backtester
6868

6969
---
7070

CONTRIBUTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ mod tests {
192192
/// # Examples
193193
///
194194
/// ```rust
195-
/// use hyperliquid_backtester::prelude::*;
195+
/// use hyperliquid_backtest::prelude::*;
196196
///
197197
/// let result = function_name(param1, param2)?;
198198
/// assert_eq!(result.value, expected_value);

README.md

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ chrono = { version = "0.4", features = ["serde"] }
4343
### Basic Backtesting Example
4444

4545
```rust
46-
use hyperliquid_backtester::prelude::*;
46+
use hyperliquid_backtest::prelude::*;
4747
use chrono::{DateTime, FixedOffset, Utc};
4848

4949
#[tokio::main]
@@ -88,7 +88,7 @@ async fn main() -> Result<(), HyperliquidBacktestError> {
8888
### Funding Arbitrage Strategy
8989

9090
```rust
91-
use hyperliquid_backtester::prelude::*;
91+
use hyperliquid_backtest::prelude::*;
9292

9393
#[tokio::main]
9494
async fn main() -> Result<(), HyperliquidBacktestError> {
@@ -131,7 +131,7 @@ async fn main() -> Result<(), HyperliquidBacktestError> {
131131
The library supports fetching historical data for various cryptocurrencies and time intervals:
132132

133133
```rust
134-
use hyperliquid_backtester::prelude::*;
134+
use hyperliquid_backtest::prelude::*;
135135

136136
// Supported intervals: "1m", "5m", "15m", "1h", "4h", "1d"
137137
let data = HyperliquidData::fetch("BTC", "1h", start_time, end_time).await?;
@@ -160,7 +160,7 @@ The library supports all major cryptocurrencies available on Hyperliquid:
160160
Configure realistic trading fees based on Hyperliquid's fee structure:
161161

162162
```rust
163-
use hyperliquid_backtester::prelude::*;
163+
use hyperliquid_backtest::prelude::*;
164164

165165
// Default Hyperliquid fees
166166
let commission = HyperliquidCommission::default(); // 0.02% maker, 0.05% taker
@@ -178,7 +178,7 @@ let custom_commission = HyperliquidCommission {
178178
Create custom strategies using the built-in framework:
179179

180180
```rust
181-
use hyperliquid_backtester::prelude::*;
181+
use hyperliquid_backtest::prelude::*;
182182

183183
// Enhanced SMA crossover with funding awareness
184184
let strategy = enhanced_sma_cross(
@@ -218,7 +218,7 @@ backtest.export_enhanced_csv("backtest_results.csv")?;
218218
Configure logging for development and production:
219219

220220
```rust
221-
use hyperliquid_backtester::prelude::*;
221+
use hyperliquid_backtest::prelude::*;
222222

223223
// Basic logging setup
224224
init_logger(); // INFO level by default
@@ -274,7 +274,7 @@ cargo run --example funding_arbitrage_advanced
274274
Track performance of operations with built-in spans:
275275

276276
```rust
277-
use hyperliquid_backtester::prelude::*;
277+
use hyperliquid_backtest::prelude::*;
278278
use tracing::Instrument;
279279

280280
async fn fetch_and_backtest() -> Result<(), HyperliquidBacktestError> {
@@ -299,7 +299,7 @@ async fn fetch_and_backtest() -> Result<(), HyperliquidBacktestError> {
299299
Comprehensive error handling with detailed context:
300300

301301
```rust
302-
use hyperliquid_backtester::prelude::*;
302+
use hyperliquid_backtest::prelude::*;
303303

304304
match HyperliquidData::fetch("INVALID", "1h", start, end).await {
305305
Ok(data) => println!("Success!"),
@@ -325,7 +325,7 @@ use rs_backtester::prelude::*;
325325
let data = Data::from_csv("data.csv")?;
326326

327327
// After (hyperliquid-backtest)
328-
use hyperliquid_backtester::prelude::*;
328+
use hyperliquid_backtest::prelude::*;
329329
let data = HyperliquidData::fetch("BTC", "1h", start, end).await?;
330330
let rs_data = data.to_rs_backtester_data(); // Convert if needed
331331
```

benches/performance_benchmarks.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
//! data conversion, funding calculations, and backtesting workflows.
55
66
use criterion::{black_box, criterion_group, criterion_main, Criterion, BenchmarkId};
7-
use hyperliquid_backtester::prelude::*;
7+
use hyperliquid_backtest::prelude::*;
88
use chrono::{DateTime, FixedOffset};
99
use std::time::Duration;
1010

examples/basic_backtest.rs

Lines changed: 66 additions & 129 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,5 @@
1-
use chrono::{Duration, Utc};
2-
use hyperliquid_backtester::prelude::*;
3-
use rs_backtester::prelude::*;
4-
use std::fs::File;
5-
use std::io::Write;
6-
use tracing::Instrument;
1+
use chrono::Utc;
2+
use hyperliquid_backtest::prelude::*;
73

84
/// # Basic Backtest Example
95
///
@@ -38,7 +34,7 @@ use tracing::Instrument;
3834
/// ```
3935
4036
#[tokio::main]
41-
async fn main() -> Result<(), HyperliquidBacktestError> {
37+
async fn main() -> Result<()> {
4238
// Initialize logging for better debugging and monitoring
4339
init_logger_with_level("info");
4440

@@ -52,60 +48,16 @@ async fn main() -> Result<(), HyperliquidBacktestError> {
5248
let start_time = end_time - (90 * 24 * 3600); // 90 days of data
5349

5450
println!("Fetching BTC/USD data for the last 90 days...");
55-
let data = HyperliquidData::fetch_btc("1h", start_time, end_time).await?;
51+
let data = HyperliquidData::fetch("BTC", "1h", start_time, end_time).await?;
5652

5753
println!("Data fetched: {} data points from {} to {}\n",
5854
data.len(),
5955
data.datetime.first().unwrap().format("%Y-%m-%d %H:%M"),
6056
data.datetime.last().unwrap().format("%Y-%m-%d %H:%M"));
6157

62-
// Create a simple SMA crossover strategy
58+
// Create a simple SMA crossover strategy using the enhanced_sma_cross function
6359
println!("Setting up SMA crossover strategy (10/30)...");
64-
let mut strategy = Strategy::new();
65-
66-
// Strategy parameters
67-
let short_period = 10;
68-
let long_period = 30;
69-
70-
// Initialize strategy
71-
strategy.init(Box::new(move |_ctx, _data| {
72-
// No initialization needed for this simple strategy
73-
}));
74-
75-
// Define strategy logic
76-
strategy.next(Box::new(move |ctx, data| {
77-
// Wait until we have enough data for the long SMA
78-
if data.index < long_period {
79-
return;
80-
}
81-
82-
// Calculate short and long SMAs
83-
let mut short_sum = 0.0;
84-
let mut long_sum = 0.0;
85-
86-
for i in 0..short_period {
87-
short_sum += data.close[data.index - i];
88-
}
89-
90-
for i in 0..long_period {
91-
long_sum += data.close[data.index - i];
92-
}
93-
94-
let short_sma = short_sum / short_period as f64;
95-
let long_sma = long_sum / long_period as f64;
96-
97-
// Get current position
98-
let position = ctx.position();
99-
100-
// Trading logic
101-
if short_sma > long_sma && position <= 0.0 {
102-
// Bullish crossover - go long
103-
ctx.entry_qty(1.0);
104-
} else if short_sma < long_sma && position >= 0.0 {
105-
// Bearish crossover - go short
106-
ctx.entry_qty(-1.0);
107-
}
108-
}));
60+
let strategy = enhanced_sma_cross(data.to_rs_backtester_data(), 10, 30, Default::default());
10961

11062
// Set up backtest parameters
11163
let initial_capital = 10000.0; // $10,000
@@ -122,60 +74,61 @@ async fn main() -> Result<(), HyperliquidBacktestError> {
12274
// Create and run backtest
12375
let mut backtest = HyperliquidBacktest::new(
12476
data.clone(),
125-
strategy,
77+
"SMA Crossover (10/30)".to_string(),
12678
initial_capital,
127-
commission,
79+
commission.clone(),
12880
);
12981

13082
// Run backtest with funding rates
131-
backtest.calculate_with_funding();
83+
backtest.calculate_with_funding()?;
13284

133-
// Get backtest results
134-
let stats = backtest.stats();
85+
// Get enhanced report
86+
let report = backtest.enhanced_report()?;
13587

13688
// Print backtest results
13789
println!("\nBacktest Results:");
13890
println!("----------------");
13991
println!("Initial Capital: ${:.2}", initial_capital);
140-
println!("Final Capital: ${:.2}", stats.final_capital);
141-
println!("Net Profit: ${:.2} ({:.2}%)",
142-
stats.net_profit,
143-
stats.net_profit_pct * 100.0);
144-
println!("Max Drawdown: {:.2}%", stats.max_drawdown * 100.0);
145-
println!("Win Rate: {:.2}%", stats.win_rate * 100.0);
146-
println!("Profit Factor: {:.2}", stats.profit_factor);
147-
println!("Sharpe Ratio: {:.2}", stats.sharpe_ratio);
148-
149-
// Get funding impact
150-
let funding_impact = backtest.funding_impact();
92+
println!("Final Equity: ${:.2}", report.final_equity);
93+
println!("Total Return: {:.2}%", report.total_return * 100.0);
94+
println!("Max Drawdown: {:.2}%", report.max_drawdown * 100.0);
95+
println!("Win Rate: {:.2}%", report.win_rate * 100.0);
96+
println!("Profit Factor: {:.2}", report.profit_factor);
97+
println!("Sharpe Ratio: {:.2}", report.sharpe_ratio);
98+
99+
// Get funding impact from enhanced metrics
100+
let enhanced_metrics = &report.enhanced_metrics;
151101
println!("\nFunding Rate Impact:");
152102
println!("------------------");
153-
println!("Total Funding Payments: ${:.2}", funding_impact.total_funding);
154-
println!("Funding as % of PnL: {:.2}%",
155-
if stats.net_profit != 0.0 {
156-
(funding_impact.total_funding / stats.net_profit).abs() * 100.0
157-
} else {
158-
0.0
159-
});
160-
161-
// Get trade statistics
162-
let trade_stats = backtest.trade_stats();
163-
println!("\nTrade Statistics:");
164-
println!("----------------");
165-
println!("Total Trades: {}", trade_stats.total_trades);
166-
println!("Winning Trades: {}", trade_stats.winning_trades);
167-
println!("Losing Trades: {}", trade_stats.losing_trades);
168-
println!("Average Profit per Trade: ${:.2}", trade_stats.avg_profit_per_trade);
169-
println!("Average Profit per Winning Trade: ${:.2}", trade_stats.avg_profit_per_winning_trade);
170-
println!("Average Loss per Losing Trade: ${:.2}", trade_stats.avg_loss_per_losing_trade);
103+
println!("Total Return with Funding: {:.2}%", enhanced_metrics.total_return_with_funding * 100.0);
104+
println!("Trading Only Return: {:.2}%", enhanced_metrics.trading_only_return * 100.0);
105+
println!("Funding Only Return: {:.2}%", enhanced_metrics.funding_only_return * 100.0);
106+
println!("Funding Payments Received: {}", enhanced_metrics.funding_payments_received);
107+
println!("Funding Payments Paid: {}", enhanced_metrics.funding_payments_paid);
108+
println!("Average Funding Rate: {:.4}%", enhanced_metrics.average_funding_rate * 100.0);
109+
110+
// Get commission statistics
111+
let commission_stats = &report.commission_stats;
112+
println!("\nCommission Statistics:");
113+
println!("-------------------");
114+
println!("Total Commission: ${:.2}", commission_stats.total_commission);
115+
println!("Maker Fees: ${:.2}", commission_stats.maker_fees);
116+
println!("Taker Fees: ${:.2}", commission_stats.taker_fees);
117+
println!("Maker/Taker Ratio: {:.2}", commission_stats.maker_taker_ratio);
118+
119+
// Get funding summary
120+
let funding_summary = &report.funding_summary;
121+
println!("\nFunding Summary:");
122+
println!("---------------");
123+
println!("Total Funding Paid: ${:.2}", funding_summary.total_funding_paid);
124+
println!("Total Funding Received: ${:.2}", funding_summary.total_funding_received);
125+
println!("Net Funding: ${:.2}", funding_summary.net_funding);
126+
println!("Funding Contribution: {:.2}%", funding_summary.funding_contribution_percentage * 100.0);
171127

172128
// Export results to CSV
173129
println!("\nExporting results to CSV...");
174-
let csv_data = backtest.to_csv()?;
175-
let csv_file = "basic_backtest_results.csv";
176-
let mut file = File::create(csv_file)?;
177-
file.write_all(csv_data.as_bytes())?;
178-
println!("Results exported to {}", csv_file);
130+
backtest.export_to_csv("basic_backtest_results.csv")?;
131+
println!("Results exported to basic_backtest_results.csv");
179132

180133
// Run the same backtest without funding to compare
181134
println!("\nRunning comparison backtest without funding rates...");
@@ -184,54 +137,38 @@ async fn main() -> Result<(), HyperliquidBacktestError> {
184137

185138
let mut backtest_no_funding = HyperliquidBacktest::new(
186139
data.clone(),
187-
Strategy::new_from_fn(move |ctx, data| {
188-
// Same strategy logic as above
189-
if data.index < long_period {
190-
return;
191-
}
192-
193-
let mut short_sum = 0.0;
194-
let mut long_sum = 0.0;
195-
196-
for i in 0..short_period {
197-
short_sum += data.close[data.index - i];
198-
}
199-
200-
for i in 0..long_period {
201-
long_sum += data.close[data.index - i];
202-
}
203-
204-
let short_sma = short_sum / short_period as f64;
205-
let long_sma = long_sum / long_period as f64;
206-
207-
let position = ctx.position();
208-
209-
if short_sma > long_sma && position <= 0.0 {
210-
ctx.entry_qty(1.0);
211-
} else if short_sma < long_sma && position >= 0.0 {
212-
ctx.entry_qty(-1.0);
213-
}
214-
}),
140+
"SMA Crossover (10/30) - No Funding".to_string(),
215141
initial_capital,
216142
commission_no_funding,
217143
);
218144

219-
backtest_no_funding.calculate();
145+
backtest_no_funding.calculate_with_funding()?;
220146

221-
let stats_no_funding = backtest_no_funding.stats();
147+
let report_no_funding = backtest_no_funding.enhanced_report()?;
222148

223149
println!("\nComparison Results (Without Funding):");
224150
println!("-----------------------------------");
225-
println!("Net Profit: ${:.2} ({:.2}%)",
226-
stats_no_funding.net_profit,
227-
stats_no_funding.net_profit_pct * 100.0);
151+
println!("Total Return: {:.2}%", report_no_funding.total_return * 100.0);
152+
println!("Final Equity: ${:.2}", report_no_funding.final_equity);
228153

229154
println!("\nFunding Impact on Performance:");
230155
println!("----------------------------");
231-
println!("Net Profit Difference: ${:.2}",
232-
stats.net_profit - stats_no_funding.net_profit);
156+
println!("Return Difference: {:.2}%",
157+
(report.total_return - report_no_funding.total_return) * 100.0);
158+
println!("Equity Difference: ${:.2}",
159+
report.final_equity - report_no_funding.final_equity);
233160
println!("Performance Impact: {:.2}%",
234-
((stats.net_profit / stats_no_funding.net_profit) - 1.0) * 100.0);
161+
((report.total_return / report_no_funding.total_return) - 1.0) * 100.0);
162+
163+
// Print detailed funding report
164+
println!("\nDetailed Funding Analysis:");
165+
println!("-------------------------");
166+
let funding_report = backtest.funding_report()?;
167+
println!("Total Funding Received: ${:.2}", funding_report.total_funding_received);
168+
println!("Total Funding Paid: ${:.2}", funding_report.total_funding_paid);
169+
println!("Net Funding PnL: ${:.2}", funding_report.net_funding_pnl);
170+
println!("Payment Count: {}", funding_report.payment_count);
171+
println!("Average Rate: {:.4}%", funding_report.average_rate * 100.0);
235172

236173
println!("\nExample completed successfully!");
237174

examples/comprehensive_example.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use chrono::{Duration, Utc};
2-
use hyperliquid_backtester::prelude::*;
2+
use hyperliquid_backtest::prelude::*;
33
use rs_backtester::prelude::*;
44
use std::fs::File;
55
use std::io::Write;

examples/csv_export_example.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use chrono::{DateTime, Duration, FixedOffset, Utc};
2-
use hyperliquid_backtester::prelude::*;
2+
use hyperliquid_backtest::prelude::*;
33
use std::path::Path;
44

55
#[tokio::main]

examples/enhanced_csv_export_example.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use chrono::{DateTime, Duration, FixedOffset, Utc};
2-
use hyperliquid_backtester::prelude::*;
2+
use hyperliquid_backtest::prelude::*;
33
use std::path::Path;
44

55
#[tokio::main]

examples/funding_arbitrage_advanced.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use chrono::{Duration, Utc};
2-
use hyperliquid_backtester::prelude::*;
3-
use hyperliquid_backtester::indicators::*;
2+
use hyperliquid_backtest::prelude::*;
3+
use hyperliquid_backtest::indicators::*;
44
use rs_backtester::prelude::*;
55
use std::fs::File;
66
use std::io::Write;

0 commit comments

Comments
 (0)