昨天花了12个小时完成了可转债趋势策略的回测,当然这个全市场的和实盘还是有一点不同,实盘有溢价率限制,可以参考我给的回测模块加入溢价率,价格限制就可以
回测模板
from xgtrader_backtrader.backtrader import backtrader
from xgtrader_backtrader.user_def_data.user_def_data import user_def_data
from xgtrader_backtrader.trader_tool import tdx_indicator
import pandas as pd
from xgtrader_backtrader.trader_tool import jsl_data
df=jsl_data.get_all_cov_bond_data()
print(df)
df.to_excel(r'数据.xlsx')
stock_list=df['证券代码'].tolist()
class my_backtrader:
'''
多标的均线策略
外面可用采用提前计算买卖点的方式
也可用实时计算
'''
def __init__(self,start_date='20160101',end_date='20500101',data_type='D',
starting_cash=100000,cash=100000,commission=0.001):
self.start_date=start_date
self.end_date=end_date
self.data_type=data_type
self.starting_cash=starting_cash
self.commission=commission
'''
证券代码 名称
513100 纳斯达克ETF
513500 标普500ETF
513290 纳斯达克生物科技ETF
159509 纳斯达克科技ETf
159655 标普ETF
513850 美国50ETF
159518 标普油气ETF
164824 印度ETF
513880 日本225ETF
513030 德国ETF
513730 东南亚科技ETF
159985 豆粕ETF
'''
self.stock_list=stock_list
'''
['513100','513500','513290','159509',
'159655','513850','159518','164824','513880',
'513030','513730','159985']
'''
self.amount=1000
self.hold_limit=2000
#采用目标数量交易
self.buy_target_volume=10000
self.sell_target_volume=0
self.buy_target_value=5000
self.sell_target_value=0
#上涨突破5日线买
self.buy_mean_line=5
#下跌10日线卖
self.sell_mean_line=10
#买的最低分
self.buy_min_score=50
#持有最低分
self.hold_min_score=50
self.trader=backtrader(start_date=self.start_date,end_date=self.end_date,
data_type=self.data_type,starting_cash=self.starting_cash,commission=self.commission,cash=cash)
self.data=user_def_data(start_date=self.start_date,end_date=self.end_date,data_type=self.data_type)
def add_all_data(self):
'''
多线程加载数据
'''
self.data.get_thread_add_data(stock_list=self.stock_list)
self.hist=self.data.hist
return self.hist
def get_cacal_all_indicators(self):
'''
计算全部的指标
'''
hist=self.add_all_data()
trader_info=pd.DataFrame()
#拆分数据
for stock in self.stock_list:
df=hist[hist['stock']==stock]
df['mean_5']=df['close'].rolling(5).mean()
df['mean_10']=df['close'].rolling(10).mean()
df['mean_20']=df['close'].rolling(20).mean()
df['mean_30']=df['close'].rolling(30).mean()
df['mean_60']=df['close'].rolling(60).mean()
df['mean_5_mean_10']=df['mean_5']>=df['mean_10']
df['mean_10_mean_20']=df['mean_10']>=df['mean_20']
df['mean_20_mean_30']=df['mean_20']>=df['mean_30']
df['mean_30_mean_60']=df['mean_30']>=df['mean_60']
for i in ['mean_5_mean_10','mean_10_mean_20','mean_20_mean_30','mean_30_mean_60']:
df[i]=df[i].apply(lambda x: 25 if x==True else 0)
df1=df[['mean_5_mean_10','mean_10_mean_20','mean_20_mean_30','mean_30_mean_60']]
df['score']=df1.sum(axis=1).tolist()
df['buy']=df['close']>df['mean_5']
df['sell']=df['close']<df['mean_5']
trader_info=pd.concat([trader_info,df],ignore_index=True)
return trader_info
def run_backtrader(self):
'''
运行回测
'''
trader_list=self.trader.get_trader_date_list()
trader_info=self.get_cacal_all_indicators()
for date in trader_list:
df=trader_info[trader_info['date']==date]
stock_list=df['stock'].tolist()
for stock in stock_list:
df1=df[df['stock']==stock]
price=df1['close'].tolist()[-1]
price=float(price)
buy=df1['buy'].tolist()[-1]
sell=df1['sell'].tolist()[-1]
score=df1['score'].tolist()[-1]
'''
if buy==True:
if self.trader.check_stock_is_av_buy(date=date,stock=stock,price=price,amount=self.amount,hold_limit=self.hold_limit):
self.trader.buy(date=date,stock=stock,price=price,amount=self.amount)
else:
self.trader.settle(date=date,stock=stock,price=price)
elif sell==True:
if self.trader.check_stock_is_av_sell(date=date,stock=stock,price=price,amount=self.amount):
self.trader.sell(date=date,stock=stock,price=price,amount=self.amount)
else:
self.trader.settle(date=date,stock=stock,price=price)
else:
self.trader.settle(date=date,stock=stock,price=price)
'''
#目标数量回测例子
if buy==True and score>=self.buy_min_score:
result=self.trader.order_target_volume(date=date,stock=stock,amount=self.buy_target_volume,price=price)
if result==True:
pass
else:
self.trader.settle(date=date,stock=stock,price=price)
elif sell==True or score<=self.hold_min_score:
result=self.trader.order_target_volume(date=date,stock=stock,amount=self.sell_target_volume,price=price)
if result==True:
pass
else:
self.trader.settle(date=date,stock=stock,price=price)
else:
self.trader.settle(date=date,stock=stock,price=price)
'''
#目标价值交易
if buy==True:
result=self.trader.order_target_value(date=date,stock=stock,value=self.buy_target_value,price=price)
if result==True:
pass
else:
self.trader.settle(date=date,stock=stock,price=price)
elif sell==True:
result=self.trader.order_target_value(date=date,stock=stock,value=self.sell_target_value,price=price)
if result==True:
pass
else:
self.trader.settle(date=date,stock=stock,price=price)
else:
self.trader.settle(date=date,stock=stock,price=price)
'''
if __name__=='__main__':
trader=my_backtrader(data_type='D')
trader.run_backtrader()
#获取全部的交易报告
trader.trader.get_poition_all_trader_report_html()
#获取策略报告
trader.trader.get_portfolio_trader_report_html()
#显示个股的交易图
trader.trader.get_plot_all_trader_data_figure(limit=1000)
#显示策略数据
df=trader.trader.get_portfolio_trader_data_figure(limit=100000)
点击运行
多线程加载数据回测
设置回测参数
class my_backtrader:
'''
多标的均线策略
外面可用采用提前计算买卖点的方式
也可用实时计算
'''
def __init__(self,start_date='20160101',end_date='20500101',data_type='D',
starting_cash=100000,cash=100000,commission=0.001):
self.start_date=start_date
self.end_date=end_date
self.data_type=data_type
self.starting_cash=starting_cash
self.commission=commission
'''
证券代码 名称
513100 纳斯达克ETF
513500 标普500ETF
513290 纳斯达克生物科技ETF
159509 纳斯达克科技ETf
159655 标普ETF
513850 美国50ETF
159518 标普油气ETF
164824 印度ETF
513880 日本225ETF
513030 德国ETF
513730 东南亚科技ETF
159985 豆粕ETF
'''
self.stock_list=stock_list
'''
['513100','513500','513290','159509',
'159655','513850','159518','164824','513880',
'513030','513730','159985']
'''
self.amount=1000
self.hold_limit=2000
#采用目标数量交易
self.buy_target_volume=10000
self.sell_target_volume=0
self.buy_target_value=5000
self.sell_target_value=0
#上涨突破5日线买
self.buy_mean_line=5
#下跌10日线卖
self.sell_mean_line=10
#买的最低分
self.buy_min_score=50
#持有最低分
self.hold_min_score=50
self.trader=backtrader(start_date=self.start_date,end_date=self.end_date,
data_type=self.data_type,starting_cash=self.starting_cash,commission=self.commission,cash=cash)
self.data=user_def_data(start_date=self.start_date,end_date=self.end_date,data_type=self.data_type)
交易算法
def get_cacal_all_indicators(self):
'''
计算全部的指标
'''
hist=self.add_all_data()
trader_info=pd.DataFrame()
#拆分数据
for stock in self.stock_list:
df=hist[hist['stock']==stock]
df['mean_5']=df['close'].rolling(5).mean()
df['mean_10']=df['close'].rolling(10).mean()
df['mean_20']=df['close'].rolling(20).mean()
df['mean_30']=df['close'].rolling(30).mean()
df['mean_60']=df['close'].rolling(60).mean()
df['mean_5_mean_10']=df['mean_5']>=df['mean_10']
df['mean_10_mean_20']=df['mean_10']>=df['mean_20']
df['mean_20_mean_30']=df['mean_20']>=df['mean_30']
df['mean_30_mean_60']=df['mean_30']>=df['mean_60']
for i in ['mean_5_mean_10','mean_10_mean_20','mean_20_mean_30','mean_30_mean_60']:
df[i]=df[i].apply(lambda x: 25 if x==True else 0)
df1=df[['mean_5_mean_10','mean_10_mean_20','mean_20_mean_30','mean_30_mean_60']]
df['score']=df1.sum(axis=1).tolist()
df['buy']=df['close']>df['mean_5']
df['sell']=df['close']<df['mean_5']
trader_info=pd.concat([trader_info,df],ignore_index=True)
return trader_info
def run_backtrader(self):
'''
运行回测
'''
trader_list=self.trader.get_trader_date_list()
trader_info=self.get_cacal_all_indicators()
for date in trader_list:
df=trader_info[trader_info['date']==date]
stock_list=df['stock'].tolist()
for stock in stock_list:
df1=df[df['stock']==stock]
price=df1['close'].tolist()[-1]
price=float(price)
buy=df1['buy'].tolist()[-1]
sell=df1['sell'].tolist()[-1]
score=df1['score'].tolist()[-1]
'''
if buy==True:
if self.trader.check_stock_is_av_buy(date=date,stock=stock,price=price,amount=self.amount,hold_limit=self.hold_limit):
self.trader.buy(date=date,stock=stock,price=price,amount=self.amount)
else:
self.trader.settle(date=date,stock=stock,price=price)
elif sell==True:
if self.trader.check_stock_is_av_sell(date=date,stock=stock,price=price,amount=self.amount):
self.trader.sell(date=date,stock=stock,price=price,amount=self.amount)
else:
self.trader.settle(date=date,stock=stock,price=price)
else:
self.trader.settle(date=date,stock=stock,price=price)
'''
#目标数量回测例子
if buy==True and score>=self.buy_min_score:
result=self.trader.order_target_volume(date=date,stock=stock,amount=self.buy_target_volume,price=price)
if result==True:
pass
else:
self.trader.settle(date=date,stock=stock,price=price)
elif sell==True or score<=self.hold_min_score:
result=self.trader.order_target_volume(date=date,stock=stock,amount=self.sell_target_volume,price=price)
if result==True:
pass
else:
self.trader.settle(date=date,stock=stock,price=price)
else:
self.trader.settle(date=date,stock=stock,price=price)
'''
#目标价值交易
if buy==True:
result=self.trader.order_target_value(date=date,stock=stock,value=self.buy_target_value,price=price)
if result==True:
pass
else:
self.trader.settle(date=date,stock=stock,price=price)
elif sell==True:
result=self.trader.order_target_value(date=date,stock=stock,value=self.sell_target_value,price=price)
if result==True:
pass
else:
self.trader.settle(date=date,stock=stock,price=price)
else:
self.trader.settle(date=date,stock=stock,price=price)
'''
数据加载开始回测
我们直接看回测结果非常多,每一个标的
交易报告
全市场回测的可以继续优化
实盘的有比较多的条件限制
我们看个股的买卖点分析
我们看策略的报告,17不知道发生了什么,我还在读高中,高一,得加入溢价率指标,价格来优化策略,实盘有这个参数限制
我们随便选择一个个股看看个股的交易报告
111000
看看程序的交易效果
需要全部的交易报告直接回复20240213就可以
数据分析与运用
很高兴和志同道合的你们一起学习,本公众号分享金融知识,大家一起相互学习,信息分享如有侵权,或者没有作者的同意,我们将撤回,同时也感谢大家积极的分享,大家的支持。让我们一起加油
271篇原创内容
公众号
回测框架,实盘策略全部上传了知识星球可以直接下载,最后2张优惠券