策略内容:
SMA短周期:20
SMA长周期:60
如果短周期上穿长周期则做多,如果短周期下穿长周期则平仓。
具体代码如下:
import backtrader as bt
import pandas as pd
import CeLv
# 从csv获取数据
def csv_data():
df = pd.read_csv('./数据.csv',
names=['time', 'open', 'close', 'high', 'low', 'turn over',
'volume'])
df['datetime'] = pd.to_datetime(df['time'], unit='s')
df = df.drop(columns='time')
# df.columns = ['time', 'open', 'close', 'high', 'low', 'turn over', 'volume']
df.set_index(keys='datetime', drop=True, append=False)
return df
if __name__ == '__main__':
df = csv_data()
cerebro = bt.Cerebro()
data = bt.feeds.PandasData(dataname=df, datetime='datetime',
open='open', high='high', low='low',
close='close', volume='turn over', openinterest=-1)
cerebro = bt.Cerebro() # 创建cerebro
# 在Cerebro中添加价格数据
cerebro.adddata(data)
# 设置启动资金
cerebro.broker.setcash(100000.0)
# 设置交易单位大小
cerebro.addsizer(bt.sizers.FixedSize, stake=5000)
# 设置佣金为千分之一
cerebro.broker.setcommission(commission=0.002)
# 添加策略
cerebro.addstrategy(CeLv.EmaAndDc)
# 添加分析指标
# 收益率
cerebro.addanalyzer(bt.analyzers.Returns, _name='_Returns')
# 收益期间
cerebro.addanalyzer(bt.analyzers.TimeReturn, _name='_TimeReturn')
# 计算最大回撤相关指标
cerebro.addanalyzer(bt.analyzers.DrawDown, _name='_DrawDown')
# 回撤期间
cerebro.addanalyzer(bt.analyzers.TimeDrawDown, _name='_TimeDrawDown')
# 计算年化夏普比率
cerebro.addanalyzer(bt.analyzers.SharpeRatio, _name='_SharpeRatio', timeframe=bt.TimeFrame.Days, annualize=True,
riskfreerate=0) # 计算夏普比率
# 交易统计信息,如获胜、失败次数
cerebro.addanalyzer(bt.analyzers.TradeAnalyzer, _name='_TradeAnalyzer')
result = cerebro.run() # 遍历所有数据
# 提取结果
print('最终资金: %.2f' % cerebro.broker.getvalue())
print("收益率: ",result[0].analyzers._Returns.get_analysis()['rtot'])
print("--------------- 收益期间 -----------------")
print(result[0].analyzers._TimeReturn.get_analysis())
print("--------------- 最大回撤相关指标 -----------------")
print(result[0].analyzers._DrawDown.get_analysis())
print("--------------- 回撤期间 -----------------")
print(result[0].analyzers._TimeDrawDown.get_analysis())
print("夏普比率: ",result[0].analyzers._SharpeRatio.get_analysis()['sharperatio'])
# 绘图
cerebro.plot(style='candlestick')
策略部分:
class SmaCross(bt.Strategy):
# 可配置策略参数
params = dict(
p1=20, # 短期均线周期
p2=60 # 长期均线周期
)
def __init__(self):
sma1 = bt.ind.SMA(period=self.params.p1) # 短期均线
sma2 = bt.ind.SMA(period=self.params.p2) # 长期均线
self.crossover = bt.ind.CrossOver(sma1, sma2) # 交叉信号
self.order = None
def notify_order(self, order):
if order.status in [order.Completed]:
if order.isbuy():
print(
'BUY EXECUTED, Price: %.2f, Cost: %.2f, Comm %.2f' %
(order.executed.price,
order.executed.value,
order.executed.comm))
self.buyprice = order.executed.price
self.buycomm = order.executed.comm
else: # 卖
print('SELL EXECUTED, Price: %.2f, Cost: %.2f, Comm %.2f' %
(order.executed.price,
order.executed.value,
order.executed.comm))
self.bar_executed = len(self)
def next(self):
if not self.position:
if self.crossover > 0:
self.buy(size=1) # 买入
elif self.crossover < 0:
self.close() # 卖出