backtrader demo
-
from __future__ import (absolute_import, division, print_function, unicode_literals) import datetime # For datetime objects import os.path # To manage paths import sys # To find out the script name (in argv[0]) # Import the backtrader platform import backtrader as bt # Create a Stratey class TestStrategy(bt.Strategy): def log(self, txt, dt=None): ''' Logging function fot 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 # 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]: # current close less than previous close if self.dataclose[-1] < self.dataclose[-2]: # previous close less than the previous close # BUY, BUY, BUY!!! (with default parameters) self.log('BUY CREATE, %.2f' % self.dataclose[0]) # Keep track of the created order to avoid a 2nd order self.order = self.buy() else: # Already in the market ... we might sell if len(self) >= (self.bar_executed + 5): # SELL, SELL, SELL!!! (with all possible default parameters) self.log('SELL CREATE, %.2f' % self.dataclose[0]) # Keep track of the created order to avoid a 2nd order self.order = self.sell() if __name__ == '__main__': # Create a cerebro entity cerebro = bt.Cerebro() # Add a strategy cerebro.addstrategy(TestStrategy) # 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') # Create a Data Feed data = bt.feeds.YahooFinanceCSVData( dataname=datapath, # Do not pass values before this date fromdate=datetime.datetime(2000, 1, 1), # Do not pass values before this date todate=datetime.datetime(2000, 12, 31), # Do not pass values after this date reverse=False) # Add the Data Feed to Cerebro cerebro.adddata(data) # Set our desired cash start cerebro.broker.setcash(100000[ NaN:0 ].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())
-
from __future__ import (absolute_import, division, print_function, unicode_literals) from Klang import Kl,Klang import backtrader as bt import pandas as pd import math class LongOnly(bt.Sizer): params = (('stake', 1),) def _getsizing(self, comminfo, cash, data, isbuy): # buy 1/2 cash = math.floor(cash * 95 / 100 ) if isbuy: divide = math.floor(cash/data.close[0]) self.p.stake = divide return self.p.stake # Sell situation position = self.broker.getposition(data) if not position.size: return 0 # do not sell if nothing is open return self.p.stake class PandasData(bt.feeds.PandasData): params = ( ('datetime', None), ('open','open'), ('high','high'), ('low','low'), ('close','close'), ('volume','vol'), ('openinterest',None), ) # Create a Stratey class KStrategy(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 self.order = None self.macdhist = bt.ind.MACDHisto(self.data) def notify_order(self, order): if order.status == order.Completed: pass if not order.alive(): self.order = None # indicate no order is pending if order.status in [order.Submitted, order.Accepted]: # Buy/Sell order submitted/accepted to/by broker - Nothing to do return if order.status in [order.Completed, order.Canceled, order.Margin]: if order.isbuy(): self.log( 'BUY EXECUTED, Price: %.2f, Cost: %.2f, Comm %.2f,value %.2f' % (order.executed.price, order.executed.value, order.executed.comm,self.broker.getvalue())) self.buyprice = order.executed.price self.buycomm = order.executed.comm else: # Sell self.log('SELL EXECUTED, Price: %.2f, Cost: %.2f, Comm %.2f,value %.2f' % (order.executed.price, order.executed.value, order.executed.comm,self.broker.getvalue())) self.order = None def next(self): # Simply log the closing price of the series from the reference if not self.position: if self.macdhist > 0: self.order=self.buy() else: if self.macdhist < 0: self.order = self.sell() def init_btr(): cerebro = bt.Cerebro(stdstats=False) # Add a strategy cerebro.addstrategy(KStrategy) Kl.code("sh.600062[ 22.08:-0.72 ]") df = Kl.currentdf['df'] df.index=pd.to_datetime(df.datetime) df['openinterest'] = 0 df= df[['open','high','low','close','vol','openinterest']] data = PandasData(dataname=df) cerebro.adddata(data) cerebro.addsizer(LongOnly) cerebro.broker.setcash(100000[ NaN:0 ].0) print('成本: %.2f' % cerebro.broker.getvalue()) # Run over everything cerebro.run() print('总剩余: %.2f' % cerebro.broker.getvalue()) # Plot the result cerebro.plot(style='bar') if __name__ == '__main__': Klang.Klang_init(); #加载所有股票列表 init_btr();
结果:
正在从文件 /Users/jiashenghe/.klang_stock_list.csv 加载股票列表
正在从网上下载股票数据,时间将会有点长
成本: 100000.00
2021-09-02, BUY EXECUTED, Price: 11.55, Cost: 94998.75, Comm 0.00,value 100082.25
2021-10-27, SELL EXECUTED, Price: 11.60, Cost: 94998.75, Comm 0.00,value 100411.25
2021-11-19, BUY EXECUTED, Price: 11.75, Cost: 95386.50, Comm 0.00,value 100979.51
2022-01-27, SELL EXECUTED, Price: 12.15, Cost: 95386.50, Comm 0.00,value 103658.45
2022-03-08, BUY EXECUTED, Price: 12.54, Cost: 98627.10, Comm 0.00,value 99883.25
2022-03-09, SELL EXECUTED, Price: 12.10, Cost: 98627.10, Comm 0.00,value 100197.85
2022-03-23, BUY EXECUTED, Price: 12.84, Cost: 95182.92, Comm 0.00,value 100271.98
总剩余: 228220.36