目前完成了自定义策略,支持60多个默认因子,直接启动程序选择默认因子就可以交易
自定义双低策略
自定义因子设置":"自定义因子设置",
"是否开启因子上下限轮动":"是",
"因子排序列表":["转股溢价率"],
"排序方式":"倒序",
"可转债存在交易股票池是否追加":"否",
"自定义默认因子字典":{"价格":[110,130],"转股溢价率":[-10,50]},
"自定义因子函数说明":"自定义因子函数必须有返回值,输入的参数包容stock默认的股票可转债一样",
"是否启动自定义因子":"否",
"自定义因子函数表达形式":{"可转债5日波动率":["get_cov_bond_var(stock,n=5)",[-1,20]]},
"自定义因子函数":{}
全部的默认因子
"可转债支持的默认因子":["价格", "涨跌幅","正股涨跌", "正股PB", "转股价",
"转股价值", "转股溢价率", "双低", "申万", "市场", "上市时间", "持有",
"债券评级", "期权价值", "回售触发价", "强赎触发价", "转债占比", "基金持仓",
"到期时间", "剩余年限", "剩余规模", "成交额", "svolume",
"换手率", "到期税前收益", "融资融券"],
"正股默认因子":["股票现价", "股票最高价", "股票最低价", "股票今开",
"股票成交量", "股票成交额", "股票量比", "股票涨停", "股票跌停",
"股票昨收", "股票总市值", "股票流通市值", "股票动态市盈率", "股票市净率",
"股票换手率", "股票涨跌", "股票涨跌幅", "股票振幅"],
选择交易策略比如自定义因子轮动函数名称
run_bond_cov_custom_factor_rotation

设置自定义函数
"自定义运行函数设置":"自定义运行函数说明,运行类型有定时和循环,只需要把自定义模块的函数名称放在下面******",
"自定义函数运行类型":["定时"],
"自定义函数模块运行时间":["14:30"],
"自定义函数":["run_bond_cov_custom_factor_rotation"],
"黑名单":["600031"],
"买入时间":"09:30",
"卖出时间":"09:31",
"资金管理模块说明":"程序默认管理方式有数量/资金",
"资金分配设置":"交易数量设置数量和金额,利用可转债最低单位位设置条件,股票在基础数据*10,etf*100,值调整持有限制,持股限制",
"交易模式":"数量",
"固定交易资金":2500,
"持有金额限制":5000,
"固定交易数量":10,
"持有限制":10,
"持股限制":20,
更新交易数据运行user_def_models,24小时运行自定义更新数据


运行实盘交易直接运行trader_st开头的程序交易系统选择qmt,ths都可以
交易系统设置":"*********************************************",
"交易系统选择":"ths/qmt",
"交易系统":"qmt",
"交易品种":"全部",
"交易品种说明":["stock","fund","bond","全部"],
"同花顺下单路径":"C:/同花顺软件/同花顺/xiadan.exe",
"识别软件安装位置":"C:/Program Files/Tesseract-OCR/tesseract",
"qmt路径":"D:/国金QMT交易端模拟/userdata_mini",
"qmt账户":"55009640",
"qmt账户类型":"STOCK",
"证券公司交易设置":"兼容老牌证券公司可转债1手为单位",
实盘结果


下单的结果当前时间不能交易

自动分析


程序源代码
from .user_def_factor_data import user_def_factor_data
from trader_tool.stock_data import stock_data
from trader_tool.bond_cov_data import bond_cov_data
from trader_tool.etf_fund_data import etf_fund_data
from trader_tool.trader_frame import trader_frame
from trader_tool.shape_analysis import shape_analysis
from trader_tool.ths_rq import ths_rq
import pandas as pd
from tqdm import tqdm
import numpy as np
import json
from trader_tool import jsl_data
import os
class bond_cov_custom_factor_rotation:
def __init__(self,trader_tool='ths',exe='C:/同花顺软件/同花顺/xiadan.exe',tesseract_cmd='C:/Program Files/Tesseract-OCR/tesseract',
qq='1029762153@qq.com',open_set='否',qmt_path='D:/国金QMT交易端模拟/userdata_mini',
qmt_account='55009640',qmt_account_type='STOCK'):
'''
分析模型
'''
self.exe=exe
self.tesseract_cmd=tesseract_cmd
self.qq=qq
self.trader_tool=trader_tool
self.open_set=open_set
self.qmt_path=qmt_path
self.qmt_account=qmt_account
self.qmt_account_type=qmt_account_type
order_frame=trader_frame(trader_tool=self.trader_tool,exe=self.exe,tesseract_cmd=self.tesseract_cmd,
open_set=self.open_set,qmt_path=self.qmt_path,qmt_account=self.qmt_account,
qmt_account_type=self.qmt_account_type)
self.trader=order_frame.get_trader_frame()
self.trader.connect()
self.etf_fund_data=etf_fund_data()
self.path=os.path.dirname(os.path.abspath(__file__))
self.ths_rq=ths_rq()
self.bond_cov_data=bond_cov_data()
self.stock_data=stock_data()
self.etf_fund_data=etf_fund_data()
self.user_factor=user_def_factor_data()
def save_position(self):
'''
保存持股数据
'''
with open(r'{}/可转债自定义因子轮动交易配置.json'.format(self.path),encoding='utf-8') as f:
com=f.read()
text=json.loads(com)
df=self.trader.position()
def select_bond_cov(x):
'''
选择可转债
'''
if x[:3] in ['110','113','123','127','128','111','118']:
return '是'
else:
return '不是'
try:
if df==False:
print('获取持股失败')
except:
if df.shape[0]>0:
df['选择']=df['证券代码'].apply(select_bond_cov)
try:
df['持股天数']=df['持股天数'].replace('--',1)
except:
df['持股天数']=1
df1=df[df['选择']=='是']
df1['交易状态']='未卖'
df1=df1[df1['可用余额']>=10]
df1.to_excel(r'持股数据\持股数据.xlsx')
return df1
else:
print('没有持股')
def save_position_1(self):
'''
保存持股数据
'''
with open(r'{}/可转债自定义因子轮动交易配置.json'.format(self.path),encoding='utf-8') as f:
com=f.read()
text=json.loads(com)
df=self.trader.position()
print(df)
def select_bond_cov(x):
'''
选择可转债
'''
if x[:3] in ['110','113','123','127','128','111']:
return '是'
else:
return '不是'
try:
if df==False:
print('获取持股失败')
except:
if df.shape[0]>0:
df['选择']=df['证券代码'].apply(select_bond_cov)
try:
df['持股天数']=df['持股天数'].replace('--',1)
except:
df['持股天数']=1
df1=df[df['选择']=='是']
df1=df1[df1['可用余额']>=10]
df1['交易状态']='未卖'
#df1.to_excel(r'持有可转债\持有可转债.xlsx')
df1.to_excel(r'持股数据\持股数据.xlsx')
return df1
else:
print('没有持股')
def select_bond_cov(self,x):
'''
选择证券代码
'''
if x[:3] in ['110','113','123','127','128','111']:
return '是'
else:
return '不是'
def save_balance(self):
'''
保持账户数据
'''
with open(r'{}/可转债自定义因子轮动交易配置.json'.format(self.path),encoding='utf-8') as f:
com=f.read()
text=json.loads(com)
df=self.trader.balance()
df.to_excel(r'账户数据\账户数据.xlsx')
return df
def get_ths_rq_data(self):
'''
获取同花顺人气数据
'''
df=self.ths_rq.get_cov_bond_rot_rank()
df.to_excel(r'{}\同花顺人气原始数据\同花顺人气原始数据.xlsx'.format(self.path))
print(df)
def get_all_jsl_data(self):
'''
获取可转债全部数据
'''
with open('{}/可转债自定义因子轮动交易配置.json'.format(self.path),encoding='utf-8') as f:
com=f.read()
text=json.loads(com)
user=text['集思录账户']
password=text['集思录密码']
df=jsl_data.get_all_cov_bond_data(jsl_user=user,jsl_password=password)
df.to_excel(r'{}\默认因子数据\默认因子数据.xlsx'.format(self.path))
return df
def get_concact_data(self):
'''
获取合并数据,默认因子合并
把股票默认因子
'''
df=pd.read_excel(r'{}\默认因子数据\默认因子数据.xlsx'.format(self.path),dtype='object')
try:
del df['Unnamed: 0']
except:
pass
stock_list=df['正股代码'].tolist()
all_df=pd.DataFrame()
for i in tqdm(range(len(stock_list))):
stock=stock_list[i]
try:
df1=self.stock_data.get_stock_spot_data_1(stock=stock)
all_df=pd.concat([all_df,df1])
except:
df1=pd.DataFrame()
all_df=pd.concat([all_df,df1])
all_df.to_excel(r'{}\股票默认因子\股票默认因子.xlsx'.format(self.path))
df.reset_index(inplace=True)
all_df.reset_index(inplace=True)
df=pd.concat([df,all_df],axis=1)
df.to_excel(r'{}\默认因子数据\默认因子数据.xlsx'.format(self.path))
return df
def get_concact_user_factor_data(self):
'''
合并自定义因子数据
'''
with open('{}/可转债自定义因子轮动交易配置.json'.format(self.path),encoding='utf-8') as f:
com=f.read()
text=json.loads(com)
text1=text['自定义因子函数']
#自定义因子名称
user_factor_name=list(text1.keys())
if len(user_factor_name)<1:
print('没有自定义因子')
else:
#自定义因子函数
user_factor_func=list(text1.values())
user_factor_func_list=[]
for func in user_factor_func:
user_factor_func_list.append(func[0])
df=pd.read_excel(r'{}\默认因子数据\默认因子数据.xlsx'.format(self.path),dtype='object')
try:
del df['Unnamed: 0']
except:
pass
stock_list=df['正股代码'].tolist()
bond_list=df['证券代码'].tolist()
all_df=pd.DataFrame()
for j in tqdm(range(len(stock_list))):
factor_df=pd.DataFrame()
stock_1,stock_2=stock_list[j],bond_list[j]
for i in range(len(user_factor_name)):
name=user_factor_name[i]
func=user_factor_func_list[i]
if name[:2]=='股票':
stock=stock_1
factor_type,factor_value=eval('self.user_factor.'+func)
factor_df['因子代码']=[stock]
factor_df[name]=[factor_value]
else:
stock=stock_2
factor_type,factor_value=eval('self.user_factor.'+func)
factor_df['因子代码']=[stock]
factor_df[name]=[factor_value]
all_df=pd.concat([all_df,factor_df],ignore_index=True)
all_df.to_excel(r'{}\自定义因子数据\自定义因子数据.xlsx'.format(self.path))
return all_df
def get_concat_all_factor_data(self):
'''
连接全部因子数据
'''
#默认因子
df1=pd.read_excel(r'{}\默认因子数据\默认因子数据.xlsx'.format(self.path),dtype='object')
try:
del df1['Unnamed: 0']
del df1['level_0']
except:
pass
#自定义因子
df2=pd.read_excel(r'{}\自定义因子数据\自定义因子数据.xlsx'.format(self.path),dtype='object')
try:
del df2['Unnamed: 0']
except:
pass
df1.reset_index(inplace=True)
df2.reset_index(inplace=True)
df=pd.concat([df1,df2],axis=1)
df.to_excel(r'{}\全部因子数据\全部因子数据.xlsx'.format(self.path))
return df
def get_select_trader_bond_cov_data(self):
'''
选择交易的可转债数据
'''
with open('{}/可转债自定义因子轮动交易配置.json'.format(self.path),encoding='utf-8') as f:
com=f.read()
text=json.loads(com)
rank_list=text['因子排序列表']
rank_type=text['排序方式']
if rank_type=='倒序':
rank_type=True
else:
rank_type=False
df=pd.read_excel(r'{}\全部因子数据\全部因子数据.xlsx'.format(self.path),dtype='object')
#选择默认因子
try:
del df['Unnamed: 0']
except:
pass
mr_factor=text['自定义默认因子字典']
text1=text['自定义因子函数']
mr_factor_keys=list(mr_factor.keys())
if len(mr_factor_keys)<0:
print('没有默认因子')
else:
for keys in mr_factor_keys:
try:
min_value=mr_factor[keys][0]
max_value=mr_factor[keys][1]
df=df[df[keys]>=min_value]
df=df[df[keys]<=max_value]
except:
value=mr_factor[keys][-1]
df=df[df[keys]==value]
#选择自定义因子
#自定义因子名称
user_factor_name=list(text1.keys())
if len(user_factor_name)<1:
print('没有自定义因子')
else:
#自定义因子函数
for name in user_factor_name:
try:
min_value=text1[name][1][0]
max_value=text1[name][1][1]
df=df[df[name]>=min_value]
df=df[df[name]<=max_value]
except:
values=text1[name][1][-1]
df=df[df[name]==values]
df=df.sort_values(by=rank_list,ascending=True)
#选择因子数据
for i in mr_factor_keys:
user_factor_name.append(i)
user_factor_name.insert(0,'证券代码')
user_factor_name.insert(0,'可转债名称')
df=df[user_factor_name]
df.rename(columns={'证券代码':"代码"},inplace=True)
df.to_excel(r'{}\交易股票池\交易股票池.xlsx'.format(self.path))
return df
def get_del_qzsh_data(self):
'''
剔除强制赎回
'''
with open('{}/可转债自定义因子轮动交易配置.json'.format(self.path),encoding='utf-8') as f:
com=f.read()
text=json.loads(com)
del_select=text['是否剔除强制赎回']
n=text['距离强制赎回天数']
df=self.bond_cov_data.bank_cov_qz()
df.to_excel(r'{}\强制赎回\强制赎回.xlsx'.format(self.path))
if del_select=='是':
df1=df[df['cell.redeem_real_days']<=n]
def select_bond_cov(x):
'''
选择可转债
'''
if '临近到期' in x or '已满足强赎条件' in x:
return '是'
else:
return '不是'
df1['选择']=df1['cell.redeem_count'].apply(select_bond_cov)
df2=df1[df1['选择']=='不是']
df2.to_excel(r'{}\非强制赎回\非强制赎回.xlsx'.format(self.path))
return df2
else:
df.to_excel(r'{}\非强制赎回\非强制赎回.xlsx'.format(self.path))
return df
def get_buy_sell_stock(self):
'''
获取买卖数据
'''
with open('{}/可转债自定义因子轮动交易配置.json'.format(self.path),encoding='utf-8') as f:
com=f.read()
text=json.loads(com)
buy_num=text['买入前N']
hold_limit=text['持有限制']
df=pd.read_excel(r'持股数据\持股数据.xlsx',dtype='object')
df1=df[df['可用余额']>=10]
hold_stock_list=df['证券代码'].tolist()
def select_stock(x):
'''
选择股票
'''
if x in hold_stock_list:
return '持股'
else:
return "持股不足"
try:
del df['Unnamed: 0']
except:
pass
trader_df=pd.read_excel(r'{}\交易股票池\交易股票池.xlsx'.format(self.path),dtype='object')
trader_df['选择']=trader_df['代码'].apply(select_stock)
trader_df=trader_df[trader_df['选择']=='持股不足']
try:
del trader_df['Unnamed: 0']
except:
pass
trader_df.to_excel(r'{}\交易股票池\交易股票池.xlsx'.format(self.path))
rank_data=pd.read_excel(r'{}\交易股票池\交易股票池.xlsx'.format(self.path),dtype='object')
print('交易股票池*************')
print(trader_df)
try:
del rank_data['Unnamed: 0']
except:
pass
if df1.shape[0]>0:
hold_rank_data=rank_data
#卖出列表
sell_list=[]
#持股列表
hold_stock_list=df['证券代码'].tolist()
#排名列表
rank_stock_list=hold_rank_data['代码'].tolist()
for stock in hold_stock_list:
if stock in rank_stock_list:
pass
else:
sell_list.append(stock)
sell_df=pd.DataFrame()
sell_df['证券代码']=sell_list
sell_df['交易状态']='未卖'
#剔除新股申购
sell_df['选择']=sell_df['证券代码'].apply(self.select_bond_cov)
sell_df=sell_df[sell_df['选择']=='是']
if sell_df.shape[0]>0:
sell_df.to_excel(r'卖出股票\卖出股票.xlsx')
print('卖出可转债**********')
print(sell_df)
else:
print('没有卖出的可转债')
sell_df['证券代码']=[None]
sell_df['交易状态']=[None]
sell_df.to_excel(r'卖出股票\卖出股票.xlsx')
print('卖出可转债**********')
print(sell_df)
hold_num=df1.shape[0]
if hold_num>0:
av_buy_num=hold_limit-hold_num
av_buy_num=av_buy_num+sell_df.shape[0]
if av_buy_num>=hold_limit:
av_buy_num=hold_limit
buy_df=trader_df[:av_buy_num]
else:
buy_df=trader_df[:buy_num]
buy_df['交易状态']='未买'
buy_df['证券代码']=buy_df['代码']
buy_df.to_excel(r'买入股票\买入股票.xlsx')
print('买入可转债**********************')
print(buy_df)
return buy_df
else:
buy_df=trader_df[:buy_num]
buy_df['交易状态']='未买'
buy_df['证券代码']=buy_df['代码']
buy_df.to_excel(r'买入股票\买入股票.xlsx')
print('买入可转债**********************')
print(buy_df)
return buy_df
def updata_all_data(self):
'''
更新全部数据
'''
self.save_position()
self.save_balance()
self.get_all_jsl_data()
self.get_ths_rq_data()
self.get_concact_data()
self.get_concact_user_factor_data()
self.get_concat_all_factor_data()
self.get_select_trader_bond_cov_data()
self.get_del_qzsh_data()
self.get_buy_sell_stock()
发布者:股市刺客,转载请注明出处:https://www.95sca.cn/archives/68812
站内所有文章皆来自网络转载或读者投稿,请勿用于商业用途。如有侵权、不妥之处,请联系站长并出示版权证明以便删除。敬请谅解!