Getting Started¶
This guide will help you get started with backtesting trading strategies using QTrade.
Strategy¶
Let’s create a simple SMA strategy to backtest. Our custome strategy need inherit from qtrade.Strategy and implement init() and next() method
from qtrade.backtest import Strategy
class SMAStrategy(Strategy):
def init(self):
return super().init()
def on_bar_close(self):
if self.data.SMA3[-2] < self.data.SMA10[-2] and \
self.data.SMA3[-1] > self.data.SMA10[-1]:
self.buy()
if self.data.SMA10[-2] > self.data.SMA10[-2] and \
self.data.SMA10[-1] < self.data.SMA10[-1]:
self.close()
Data¶
For simplicity, the QTrade library does not provide a data processing component. Users need to prepare OHLC data as a pandas.DataFrame
with the required columns: Open
, High
, Low
, Close
, and optionally Volume
. The dataframe should also include any indicators that will be used.
In this guide, we’ll use yfinance
to obtain the data:
$ pip install yfinance
import yfinance as yf
# Download gold data with daily intervals
data = yf.download(
"GC=F",
start="2023-01-01",
end="2024-01-01",
interval="1d",
multi_level_index=False
)
data['SMA3'] = data['Close'].rolling(3).mean()
data['SMA10'] = data['Close'].rolling(10).mean()
Backtest¶
Now let’s backtest our stratgy on prepared data.
from qtrade.backtest import Backtest
bt = Backtest(
data=data,
strategy_class=SMAStrategy,
cash=10000,
)
bt.run()
# Show backtest results
bt.show_stats()
Start : 2023-01-03 00:00:00
End : 2023-12-29 00:00:00
Duration : 360 days 00:00:00
Start Value : 5000.0
End Value : 5504.3994140625
Total Return [%] : 10.08798828125
Total Commission Cost[%] : 0
Buy & Hold Return [%] : 12.10523221626531
Return (Ann.) [%] : 18.074280342264217
Volatility (Ann.) [%] : 7.44
Max Drawdown [%] : -3.8180767955781354
Max Drawdown Duration : 186 days 00:00:00
Total Trades : 14
Win Rate [%] : 42.857142857142854
Best Trade [%] : 239.0
Worst Trade [%] : -58.0
Avg Winning Trade [%] : 126.69986979166667
Avg Losing Trade [%] : -31.9749755859375
Avg Winning Trade Duration : 21 days 00:00:00
Avg Losing Trade Duration : 4 days 15:00:00
Profit Factor : 2.9718522251363866
Expectancy : 36.028529575892854
Sharpe Ratio : 2.271145457445316
Sortino Ratio : 2.6654676881799224
Calmar Ratio : 4.733870299098423
Omega Ratio : 1.7873724100138564
Plot¶
Qtrade uses Bokeh to plot result charts. You can generate a plot of your backtest results with the following command:
bt.plot()
Trades¶
You can also check all trades by using the following commands:
trade_details = bt.get_trade_history()
print(trade_details)
Type Size Entry Price Exit Price Entry Time Exit Date Profit Tag Exit Reason Duration
0 Long 2.0 1833.500000 1812.699951 2023-03-02 2023-03-08 -41.600098 None signal 6 days
1 Long 2.0 1862.000000 2007.400024 2023-03-10 2023-04-18 290.800049 None signal 39 days
2 Long 2.0 2014.300049 2014.500000 2023-05-02 2023-05-12 0.399902 None signal 10 days
3 Long 2.0 1978.000000 1965.500000 2023-06-01 2023-06-06 -25.000000 None signal 5 days
4 Long 2.0 1963.599976 1962.199951 2023-06-08 2023-06-09 -2.800049 None signal 1 days
5 Long 2.0 1955.300049 1944.599976 2023-06-12 2023-06-13 -21.400146 None signal 1 days
6 Long 2.0 1958.400024 1935.500000 2023-06-16 2023-06-20 -45.800049 None signal 4 days
7 Long 2.0 1919.599976 1962.099976 2023-07-05 2023-07-25 85.000000 None signal 20 days
8 Long 2.0 1918.500000 1917.500000 2023-08-23 2023-09-07 -2.000000 None signal 15 days
9 Long 2.0 1931.500000 1916.599976 2023-09-18 2023-09-25 -29.800049 None signal 7 days
10 Long 2.0 1861.000000 1985.599976 2023-10-10 2023-11-02 249.199951 None signal 23 days
11 Long 2.0 1991.500000 1966.800049 2023-11-03 2023-11-07 -49.399902 None signal 4 days
12 Long 2.0 1983.900024 2030.500000 2023-11-16 2023-12-06 93.199951 None signal 20 days
13 Long 2.0 2021.099976 2062.399902 2023-12-15 2023-12-29 82.599854 None end 14 days