Tutoriel technique "Sweeper Backtrader Powerful Tutorial Series 1: Stock Quantitative Backtest Core"
Le document backtrader lui-même ne propose pas le concept de «table d'itération de stratégie», qui est le concept que nous proposons dans notre tutoriel auto-édité. En fonctionnement multi-brins, vous devez comprendre l'alignement des données dans la table d'itération de stratégie impliquant plusieurs brins, sinon vous ne serez pas en mesure de comprendre certains phénomènes de fonctionnement. Par exemple, la question suivante est causée par la non-compréhension de ce concept.
Quelqu'un a posé une question sur le forum backtrader , voir ici , il a écrit un simple code de test, comme suit. Deux données de marché sont ajoutées à la stratégie, data0 est l'indice (Shanghai et Shenzhen 300) et data1 est l'action 000001.SZ. Dans l'itération suivante dans une barre, indiquez la date de data0, le cours de clôture de data1, etc.
class TestStrategy(bt.Strategy):
def log(self, txt, dt=None):
''' Logging function for this strategy'''
dt = dt or self.datas[0].datetime.date(0)
print('%s, %s' % (dt.isoformat(), txt))
def __init__(self):
# Keep a reference to the "close" line in the data[0] dataseries
self.dataclose = self.datas[0].close
def next(self):
# Simply log the closing price of the series from the reference
self.log('Close, %.2f, open, %.2f, cash, %.2f' % (self.datas[1].close[0],self.datas[1].open[0],cerebro.broker.getcash()))
self.buy(self.datas[1])
# if __name__ == '__main__':
# Create a cerebro entity
cerebro = bt.Cerebro()
# Add a strategy
# Datas are in a subfolder of the samples. Need to find where the script is
# because it could have been called from anywhere
# modpath = os.path.dirname(os.path.abspath(sys.argv[0]))
# datapath = os.path.join(modpath, '../../datas/orcl-1995-2014.txt')
idxpath = ('data2/idx300.csv')
fromdate=datetime(2013, 1, 4)
todate=datetime(2013, 12, 31)
top_buyers=10
keep_buyers=50
universe_size=100
idx = bt.feeds.GenericCSVData(
dataname=idxpath,
name="idx300",
dtformat ="%Y-%m-%d",
# Do not pass values before this date
fromdate=fromdate,
todate=todate,
openinterest=-1)
# spy = bt.feeds.YahooFinanceData(dataname='SPY',
# fromdate=datetime(2012,2,28),
# todate=datetime(2018,2,28),
# plot=False)
cerebro.adddata(idx,timeframe=bt.TimeFrame.Days) # add 沪深300 Index
ticker="000001.SZ"
df = pd.read_csv(f"data2/{ticker}.csv",
parse_dates=True,
usecols=[1,2,3,4,5],
index_col=0).dropna(axis=0)
df[~df.index.duplicated()]
df=df.iloc[::-1]
df=df.loc[fromdate:todate]
cerebro.adddata(bt.feeds.PandasData(dataname=df,name=ticker, plot=False),timeframe=bt.TimeFrame.Days)
cerebro.addstrategy(TestStrategy)
# Set our desired cash start
cerebro.broker.setcash(100000.0)
# Print out the starting conditions
print('Starting Portfolio Value: %.2f' % cerebro.broker.getvalue())
# Run over everything
cerebro.run()
# Print out the final result
print('Final Portfolio Value: %.2f' % cerebro.broker.getvalue())
Résultat de sortie
Starting Portfolio Value: 100000.00
2013-01-04, Close, 5.21, open, 5.32, cash, 100000.00
2013-01-04, Close, 5.31, open, 5.21, cash, 99994.79
2013-01-07, Close, 5.31, open, 5.21, cash, 99994.79
2013-01-07, Close, 5.21, open, 5.31, cash, 99984.18
2013-01-08, Close, 5.21, open, 5.31, cash, 99984.18
2013-01-08, Close, 5.17, open, 5.20, cash, 99973.78
2013-01-09, Close, 5.17, open, 5.20, cash, 99973.78
2013-01-09, Close, 5.17, open, 5.17, cash, 99963.45
2013-01-10, Close, 5.17, open, 5.17, cash, 99963.45
2013-01-10, Close, 5.06, open, 5.17, cash, 99953.11
Sa question est de savoir pourquoi la date du résultat de sortie est répétée deux fois le même jour. Il s'attendait à un record par jour.
Pour cette question, veuillez vous référer aux deux sections suivantes de notre didacticiel: 1.2 est une table d'itération de stratégie simple impliquant un seul stock, et 11.2 est une table d'itération de stratégie complexe impliquant plusieurs actions.