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")
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.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