I have an intraday data for SPY for 11/2020. I'm using a simple test code with a GoldenCross strategy to buy when crossing up and sell when the faster crosses down. I tested the strategy with a daily data pulled using bt.feeds.YahooFinanceData
. The only thing I did for is to replace the data to use my CSV using bt.feeds.GenericCSVData
with parameters set as
data = bt.feeds.GenericCSVData(
dataname = 'SPY_1_M_01_11_2020-29_11_2020.csv',
fromdate = params['fromdate'],
todate = params['todate'],
dtformat = ('%m/%d/%Y %H:%M:%S'),
period = bt.TimeFrame.Minutes,
compression = 1,
datetime = 0,
open = 1,
high = 2,
low = 3,
close = 4,
volume = 5,
openinterest = -1,
)
the CSV looks like :
timedate open high low close volume
11/2/20 9:30 330.187 330.188 329.947 330.038 4.79
11/2/20 9:31 330.038 330.438 329.538 329.677 5.49
The strategy is :
import math
import backtrader as bt
from params import params
class GoldenCross(bt.Strategy):
def __init__(self):
self.fast_sma = bt.indicators.MovingAverageSimple(self.data.close, period = params['fast'])
self.slow_sma = bt.indicators.MovingAverageSimple(self.data.close, period = params['slow'])
self.crossover = bt.indicators.CrossOver(self.fast_sma, self.slow_sma)
self.order = None
def next(self):
amount_to_invest = params['order_percentage'] * self.broker.cash
self.size = math.floor(amount_to_invest/self.data.close[0])
if self.order:
return
if self.position.size == 0:
if self.crossover > 0:
print('Buy\t{}\tshares of {} at\t{}'.format(self.size, params['ticker'], self.data.close[0]))
self.buy(size = self.size)
if self.position.size > 0:
if self.crossover < 0:
print('Sell\t{}\tshares of {} at\t{}'.format(self.position.size, params['ticker'], self.data.close[0]))
self.close()
And I run it from the main module as:
import backtrader as bt
from params import params
from strategies.GoldenCross import GoldenCross
cerebro = bt.Cerebro()
cerebro.broker.set_cash(params['portfolio_size'])
print('Start Portfolio Value: %.2f' % cerebro.broker.get_value())
# data = bt.feeds.YahooFinanceData(
# dataname = params['ticker'],
# fromdate = params['fromdate'],
# todate = params['todate'],
# )
data = bt.feeds.GenericCSVData(
dataname = 'SPY_1_M_01_11_2020-29_11_2020.csv',
fromdate = params['fromdate'],
todate = params['todate'],
dtformat = ('%m/%d/%Y %H:%M:%S'),
period = bt.TimeFrame.Minutes,
compression = 1,
datetime = 0,
open = 1,
high = 2,
low = 3,
close = 4,
volume = 5,
openinterest = -1,
)
cerebro.adddata(data)
cerebro.addsizer(bt.sizers.FixedSize, stake=500)
cerebro.addstrategy(GoldenCross)
cerebro.run()
cerebro.plot()
print('Final Portfolio Value: %.2f' % cerebro.broker.get_value())
when I run it, i get the output which shows the printout of the logs from the strategy but i just doesn't actually buy or close the position.
Output:
user-> python3 run.py
Start Portfolio Value: 100000.00
Buy 54 shares of SPY at 363.858
Buy 54 shares of SPY at 363.758
Buy 54 shares of SPY at 363.978
Buy 54 shares of SPY at 363.907
Buy 54 shares of SPY at 363.867
Buy 55 shares of SPY at 363.027
Final Portfolio Value: 100000.00
The code works just fine when using the
data = bt.feeds.YahooFinanceData(
dataname = params['ticker'],
fromdate = params['fromdate'],
todate = params['todate'],
)
and actually executes the buy and sell, just not with the minute data.