參考資料 : https://www.backtrader.com/docu/quickstart/quickstart.html
有一些地方我也還不懂, 不過不影響操作(....吧?)
先輸入以下代碼
import backtrader as bt
import pandas as pd
import datetime
if __name__ == '__main__':
cerebro = bt.Cerebro()
cerebro.broker.setcash(100000.0)
print('Starting Portfolio Value: %.2f' % cerebro.broker.getvalue())
cerebro.run()
print('Final Portfolio Value: %.2f' % cerebro.broker.getvalue())
當然也是先import必要的套件
然後引入"經紀人broker", 大概是理專之類的意思吧
然後資金設為十萬~
cerebro.run()策略執行前後, 分別print出資金的變化
然後載入我們的數據
import backtrader as bt
import pandas as pd
import datetime
if __name__ == '__main__':
cerebro = bt.Cerebro()
cerebro.broker.setcash(100000.0)
dataframe = pd.read_csv('d://0050.tw.csv', index_col=0, parse_dates=True)
dataframe['openinterest'] = 0
data0 = bt.feeds.PandasData(dataname=dataframe,
fromdate = datetime.datetime(2008, 1, 1),
todate = datetime.datetime(2010, 1, 1)
)
cerebro.adddata(data0)
print('Starting Portfolio Value: %.2f' % cerebro.broker.getvalue())
cerebro.run()
print('Final Portfolio Value: %.2f' % cerebro.broker.getvalue())
執行結果沒有啥米變化, 因為我們還沒有導入策略
dataframe['openinterest'] = 0是做啥的我還不清楚, 為什麼要在數據最後多加一行這個呢?
然後開始導入策略
import backtrader as bt
import pandas as pd
import datetime
class TestStrategy(bt.Strategy):
def log(self, txt, dt=None):
''' Logging function fot this strategy'''
dt = 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
# To keep track of pending orders
self.order = None
def notify_order(self, order):
if order.status in [order.Submitted, order.Accepted]:
# Buy/Sell order submitted/accepted to/by broker - Nothing to do
return
# Check if an order has been completed
# Attention: broker could reject order if not enough cash
if order.status in [order.Completed]:
if order.isbuy():
self.log('BUY EXECUTED, %.2f' % order.executed.price)
elif order.issell():
self.log('SELL EXECUTED, %.2f' % order.executed.price)
self.bar_executed = len(self)
elif order.status in [order.Canceled, order.Margin, order.Rejected]:
self.log('Order Canceled/Margin/Rejected')
# Write down: no pending order
self.order = None
def next(self):
# Simply log the closing price of the series from the reference
self.log('Close, %.2f' % self.dataclose[0])
# Check if an order is pending ... if yes, we cannot send a 2nd one
if self.order:
return
# Check if we are in the market
if not self.position:
# Not yet ... we MIGHT BUY if ...
if self.dataclose[0] < self.dataclose[-1]:
if self.dataclose[-1] < self.dataclose[-2]:
self.log('BUY CREATE, %.2f' % self.dataclose[0])
self.order = self.buy()
else:
if self.dataclose[-1] > self.dataclose[-2]:
if self.dataclose[0] > self.dataclose[-1]:
self.log('SELL CREATE, %.2f' % self.dataclose[0])
self.order = self.sell()
if __name__ == '__main__':
cerebro = bt.Cerebro()
cerebro.addstrategy(TestStrategy)
cerebro.broker.setcash(100000.0)
dataframe = pd.read_csv('d://0050.tw.csv', index_col=0, parse_dates=True)
dataframe['openinterest'] = 0
data0 = bt.feeds.PandasData(dataname=dataframe,
fromdate = datetime.datetime(2008, 1, 1),
todate = datetime.datetime(2010, 1, 1)
)
cerebro.adddata(data0)
print('Starting Portfolio Value: %.2f' % cerebro.broker.getvalue())
cerebro.run()
print('Final Portfolio Value: %.2f' % cerebro.broker.getvalue())
程式碼雖然看起來一大串, 但是我們先注意在紅色的部分就好
self.dataclose[0] < self.dataclose[-1] 意思是今天收盤價 < 昨天收盤價
self.dataclose[-1] < self.dataclose[-2] 昨天收盤價 < 前天收盤價
也就是連三跌的意思, 咱們就給他買下去
那賣出的我們設為相反, 連三漲就給他放棄..喔不是
執行看看
哇! 賺錢耶! 聖杯~~
那我們檢查一下
2009-11-25 54元
2009-11-26 53.85元
2009-11-27 52.20元
符合連三跌, 所以買進
我們最愛看圖表了, 在程式碼最後加這一行 cerebro.plot()
完整程式碼在貼一次
import backtrader as bt
import pandas as pd
import datetime
class TestStrategy(bt.Strategy):
def log(self, txt, dt=None):
''' Logging function fot this strategy'''
dt = 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
# To keep track of pending orders
self.order = None
def notify_order(self, order):
if order.status in [order.Submitted, order.Accepted]:
# Buy/Sell order submitted/accepted to/by broker - Nothing to do
return
# Check if an order has been completed
# Attention: broker could reject order if not enough cash
if order.status in [order.Completed]:
if order.isbuy():
self.log('BUY EXECUTED, %.2f' % order.executed.price)
elif order.issell():
self.log('SELL EXECUTED, %.2f' % order.executed.price)
self.bar_executed = len(self)
elif order.status in [order.Canceled, order.Margin, order.Rejected]:
self.log('Order Canceled/Margin/Rejected')
# Write down: no pending order
self.order = None
def next(self):
# Simply log the closing price of the series from the reference
self.log('Close, %.2f' % self.dataclose[0])
# Check if an order is pending ... if yes, we cannot send a 2nd one
if self.order:
return
# Check if we are in the market
if not self.position:
# Not yet ... we MIGHT BUY if ...
if self.dataclose[0] < self.dataclose[-1]:
if self.dataclose[-1] < self.dataclose[-2]:
self.log('BUY CREATE, %.2f' % self.dataclose[0])
self.order = self.buy()
else:
if self.dataclose[-1] > self.dataclose[-2]:
if self.dataclose[0] > self.dataclose[-1]:
self.log('SELL CREATE, %.2f' % self.dataclose[0])
self.order = self.sell()
if __name__ == '__main__':
cerebro = bt.Cerebro()
cerebro.addstrategy(TestStrategy)
cerebro.broker.setcash(100000.0)
dataframe = pd.read_csv('d://0050.tw.csv', index_col=0, parse_dates=True)
dataframe['openinterest'] = 0
data0 = bt.feeds.PandasData(dataname=dataframe,
fromdate = datetime.datetime(2008, 1, 1),
todate = datetime.datetime(2010, 1, 1)
)
cerebro.adddata(data0)
print('Starting Portfolio Value: %.2f' % cerebro.broker.getvalue())
cerebro.run()
print('Final Portfolio Value: %.2f' % cerebro.broker.getvalue())
cerebro.plot()