Creating trading bots these days on intraday data become more and more popular days. For simple backtesting trades usually go to Pine Script. But with libraries like vectorbt backtesting in Python become quite simple. Also, not many people know that you can get intraday data for stocks from Yahoo Finance for free. So in summary intraday backtest can be written just in a few lines of code and in this article I’ll show you an example.
First, let’s export vectorbt library:
import vectorbt as vbt
Next, let’s get some data. We’re getting data from yahoo finance and currently, the following timeframes are supported:
- 1m – 1 minute
- 2m – 2 minutes
- 5m – 5 minutes
- 15m – 15 minutes
- 30m – 30 minutes
- 60m – 60 minutes
- 90m – 90 minutes
- 1h – 1 hour
- 1d – 1 day
- 5d – 5 days
- 1wk – 1 week
- 1mo – 1 month
- 3mo – 3 month
Also, be careful with the start parameter of your function. For every timeframe, there is a corresponding limit so it won’t allow you to download too much data. For example for a 5-minute timeframe the limit is 60 days, so only about 3k records will be downloaded for you. Of course that’s not a lot for a backtest. You can try to get this data from Yahoo Finance and save it yourself, this way you will be able to collect more history over time.
The syntax for getting data from Yahoo Finance is the following:
aapl_data = vbt.YFData.download(
'AAPL',
interval='5m',
missing_index='drop',
start='2022-07-01'
)
aapl_close = aapl_data.get('Close')
If you get an error about data quantity – increase your start date. Also in the code, I’m getting only close of my data because I’ll use only it in my calculations.
Next, let’s compute moving averages variables:
fast_ma = vbt.MA.run(aapl_close, 10, short_name='fast MA')
slow_ma = vbt.MA.run(aapl_close, 50, short_name='fast MA')
After that I’m computing entry/exit signals for the backtest:
long_entries = fast_ma.ma_crossed_above(slow_ma)
short_entries = fast_ma.ma_crossed_below(slow_ma)
Now we already can run our strategy:
pf = vbt.Portfolio.from_signals(
aapl_close,
entries=long_entries,
short_entries=short_entries,
freq = '5m'
)
When you run the strategy also provide a parameter with frequency so it will know how to compute certain metrics. So backtest is computed so now you can check its performance:
pf.stats()
Start 2022-07-01 13:30:00+00:00 End 2022-08-15 20:00:00+00:00 Period 8 days 09:35:00 Start Value 100.0 End Value 97.434231 Total Return [%] -2.565769 Benchmark Return [%] 26.600876 Max Gross Exposure [%] 100.0 Total Fees Paid 0.0 Max Drawdown [%] 8.293664 Max Drawdown Duration 7 days 09:40:00 Total Trades 50 Total Closed Trades 49 Total Open Trades 1 Open Trade PnL 1.907165 Win Rate [%] 34.693878 Best Trade [%] 3.890129 Worst Trade [%] -1.932058 Avg Winning Trade [%] 1.159227 Avg Losing Trade [%] -0.749084 Avg Winning Trade Duration 0 days 06:43:14.117647058 Avg Losing Trade Duration 0 days 01:51:15 Profit Factor 0.809225 Expectancy -0.091284 Sharpe Ratio -1.715084 Calmar Ratio -8.16064 Omega Ratio 0.982959 Sortino Ratio -2.37456 dtype: object
Or plot results on a chart:
fig = pf.plot(subplots=['orders','trade_pnl','cum_returns'])
fast_ma.ma.vbt.plot(fig=fig)
slow_ma.ma.vbt.plot(fig=fig)
fig.show()
Here is the full code of the backtest of this article:
import vectorbt as vbt
aapl_data = vbt.YFData.download(
'AAPL',
interval='5m',
missing_index='drop',
start='2022-06-18'
)
aapl_close = aapl_data.get('Close')
fast_ma = vbt.MA.run(aapl_close, 10, short_name='fast MA')
slow_ma = vbt.MA.run(aapl_close, 50, short_name='fast MA')
long_entries = fast_ma.ma_crossed_above(slow_ma)
short_entries = fast_ma.ma_crossed_below(slow_ma)
pf = vbt.Portfolio.from_signals(
aapl_close,
entries=long_entries,
short_entries=short_entries,
freq = '5m'
)
pf.stats()
fig = pf.plot(subplots=['orders','trade_pnl','cum_returns'])
fast_ma.ma.vbt.plot(fig=fig)
slow_ma.ma.vbt.plot(fig=fig)
fig.show()
Off course, Yahoo Finance is not perfect to run intraday strategies for stocks, but it can be a good place to start. In future articles, I’ll share with you better-suited APIs.
Follow me on TradingView and YouTube.