Crypto issue with fractional size
Enhancement description
Due to the high value of single crypto coins, e.g. BTC, it is impossible to do a backtest with absolute quantities instead of fractional quantities. As soon as the size is below 0 it is not an absolute values anymore.
Code sample
# This means 10% of my portfolio, what if I want to buy 0.1 BTC?
self.buy(size=0.1, limit=buy_price, sl=buy_price * (1 - self.sl))
Additional info, images
No response
Have you seen backtesting.lib.FractionalBacktest?
@kernc
I believe that FractionalBacktest is not implemented correctly.
If we execute buy on signal 1 and sell on signal -1
Given this data:
With this code:
from backtesting.test import BTCUSD
import numpy as np
from backtesting import Strategy
from backtesting.lib import FractionalBacktest
data = BTCUSD.tail(10).copy()
signals = np.zeros(len(data), dtype=int)
signals[1] = 1
signals[8] = -1
data["Signal"] = signals
class FirstStrategy(Strategy):
def init(self):
pass
def next(self):
signal = self.data.Signal[-1]
price = self.data.Close[-1]
if signal == 1 and not self.position:
print(f"BUYING at {price}")
self.trade = self.buy(size=1)
elif signal == -1:
if self.position:
print(f"SELLING {self.position.size} BTC at {price}")
self.position.close()
bt = FractionalBacktest(data, FirstStrategy, cash=100_000, commission=0.007)
stats = bt.run()
bt.plot()
print(stats)
This is the output:
BUYING at 0.0005915
SELLING 1 BTC at 0.00072346
Start 2024-03-31 00:00:00
End 2024-12-31 00:00:00
Duration 275 days 00:00:00
Exposure Time [%] 80.0
Equity Final [$] 100000.00037
Equity Peak [$] 100000.00038
Commissions [$] 0.0
Return [%] 0.0
Buy & Hold Return [%] 31.45958
Return (Ann.) [%] 0.0
Volatility (Ann.) [%] 0.0
CAGR [%] 0.0
Sharpe Ratio NaN
Sortino Ratio 4.50958
Calmar Ratio 5.12325
Alpha [%] 0.0
Beta 0.0
Max. Drawdown [%] -0.0
Avg. Drawdown [%] -0.0
Max. Drawdown Duration 153 days 00:00:00
Avg. Drawdown Duration 153 days 00:00:00
# Trades 1
Win Rate [%] 100.0
Best Trade [%] 62.95813
Worst Trade [%] 62.95813
Avg. Trade [%] 62.95813
Max. Trade Duration 214 days 00:00:00
Avg. Trade Duration 214 days 00:00:00
Profit Factor NaN
Expectancy [%] 62.95813
SQN NaN
Kelly Criterion NaN
_strategy FirstStrategy
_equity_curve ...
_trades Size ...
dtype: object
As you can see equity is not correct.
I believe it's because of the how the size is implemented in the class , and that messes up everything.
this is the trade executed stats[_trades]:
| Size | EntryBar | ExitBar | EntryPrice | ExitPrice | SL | TP | PnL | Commission | ReturnPct | EntryTime | ExitTime | Duration | Tag | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 1.000000e-08 | 2 | 9 | 59160.0 | 96515.0 | NaN | NaN | 0.000363 | 0.000011 | 0.613003 | 2024-05-31 | 2024-12-31 | 214 days | None |