Team Ai
Apppublic

diegobeyl/backtesting

sourceHugging Faceupdated 9mo agoView on Hugging Face
2likes
inspect_trades.py86 linesDownload Raw Back to analysis
1
2from backtesting import Backtest, Strategy
3import pandas as pd
4import numpy as np
5
6class DonchianStructuralStrategy(Strategy):
7    donchian_period = 1
8    risk_percent = 1.0
9    leverage = 30
10    trailing_mode = "FAST"
11    
12    def init(self):
13        # Donchian High and Low
14        self.donchian_high = self.I(lambda h: pd.Series(h).shift(1).rolling(self.donchian_period).max().values, self.data.High)
15        self.donchian_low = self.I(lambda l: pd.Series(l).shift(1).rolling(self.donchian_period).min().values, self.data.Low)
16        self.tracking_highs = []
17        self.structure_level = None
18
19    def _calculate_position_size(self, entry_price: float, stop_loss: float) -> float:
20        equity = self.equity
21        risk_amount = equity * (self.risk_percent / 100.0)
22        sl_distance = abs(entry_price - stop_loss)
23        if sl_distance <= 0: return 0.0
24        quantity = risk_amount / sl_distance
25        buying_power = equity * self.leverage
26        return max(0.0, min((quantity * entry_price) / buying_power, 0.999))
27
28    def next(self):
29        if not self.position:
30            # Simple entry for testing
31            if self.data.Close[-1] > self.donchian_high[-1]:
32                sl = self.donchian_low[-1]
33                size = self._calculate_position_size(self.data.Close[-1], sl)
34                self.buy(size=size, sl=sl)
35            elif self.data.Close[-1] < self.donchian_low[-1]:
36                sl = self.donchian_high[-1]
37                size = self._calculate_position_size(self.data.Close[-1], sl)
38                self.sell(size=size, sl=sl)
39        elif self.position.is_short and self.data.Close[-1] > self.donchian_high[-1]:
40            self.position.close()
41        elif self.position.is_long and self.data.Close[-1] < self.donchian_low[-1]:
42            self.position.close()
43
44# 1. Create real BTC data
45price_scaling_factor = 100000.0
46data = pd.DataFrame({
47    'Open': [70000, 71000, 69000, 68000, 67000, 66000, 65000, 64000]*2,
48    'High': [72000]*16,
49    'Low': [64000]*16,
50    'Close': [71000, 69000, 68000, 67000, 66000, 65000, 64000, 63000]*2
51})
52data.index = pd.date_range('2024-01-01', periods=16, freq='W')
53
54scaled_data = data / price_scaling_factor
55
56# 2. Run backtest
57bt = Backtest(scaled_data, DonchianStructuralStrategy, cash=10000, commission=0.001, margin=1/30)
58stats = bt.run()
59
60print(f"--- Full Trade Inspection ---")
61print(f"Final Equity: {stats['Equity Final [$]']:.2f}")
62
63if '_trades' in stats is not None:
64    trades = stats['_trades']
65    for i, t in trades.iterrows():
66        real_entry = t['EntryPrice'] * price_scaling_factor
67        real_exit = t['ExitPrice'] * price_scaling_factor
68        real_size = t['Size'] / price_scaling_factor
69        pnl = t['PnL']
70        ret = t['ReturnPct'] * 100
71        
72        print(f"\nTrade {i} ({'LONG' if t['Size'] > 0 else 'SHORT'}):")
73        print(f"  Entry: {real_entry:.2f}, Exit: {real_exit:.2f}")
74        print(f"  Size: {real_size:.5f} BTC (Units: {t['Size']})")
75        print(f"  PnL Result: {pnl:.2f}")
76        print(f"  ReturnPct: {ret:.2f}%")
77        
78        expected_raw_pnl = (real_exit - real_entry) * real_size
79        print(f"  Expected Raw PnL (No Comm): {expected_raw_pnl:.2f}")
80        
81        # Estimate Commission
82        comm_entry = 0.001 * t['EntryPrice'] * abs(t['Size'])
83        comm_exit = 0.001 * t['ExitPrice'] * abs(t['Size'])
84        print(f"  Est. Commission: {comm_entry + comm_exit:.2f}")
85        print(f"  Expected Net PnL: {expected_raw_pnl - (comm_entry + comm_exit):.2f}")
86