链接 综合交易模型----可转债三低策略实盘qmt版,提供源代码 (qq.com)
可转债3低策略是指选择正股市值低、转债余额低、溢价率低的可转债进行投资的策略。
-
市值低:指的是可转债对应的正股市场价值较小,这通常意味着需要较少的资金就可以对股价造成较大的影响,从而可能带来更高的收益。
-
转债余额低:转债余额低意味着市场上流通的可转债数量较少,这样的可转债更容易受到市场资金的关注和操作,也更有可能因为供需关系而价格上涨。
-
溢价率低:溢价率是衡量可转债价格相对于其转换价值的一个指标,低溢价率意味着可转债的市场价格接近其转换为股票后的价值,风险相对较低,且当正股价格上涨时,可转债的价格也可能随之上涨。
以前写了一个双低策略 综合交易模型----可转债双低策略自动轮动实盘,提供源代码
三低策略的交易参数

{"可转债溢价率设置":"可转债溢价率设置","是否测试":"否","集思录账户":"151179","集思录密码":"LXG90","可转债溢价率上限":60,"可转债溢价率下限":-10,"转债余额上限":10,"转债余额下限":0.8,"资金分配设置":"交易数量设置数量和金额","交易模式":"数量","固定交易资金":2500,"持有金额限制":5000,"固定交易数量":100,"持有限制":10,"持股限制":10,"可转债选择配置":"可转债选择配置","价格上限":200,"价格下限":100,"实时涨跌幅上限":8,"实时涨跌幅下限":-1,"三低最小值":100,"三低最大值":200,"三低平仓":200,"是否剔除强制赎回":"是","距离强制赎回天数":10,"策略轮动设置":"策略轮动设置************************,轮动都按排名来","轮动方式说明":"每天/每周/每月/特别时间","轮动方式":"每周","说明":"每天按自定义函数运行","每周轮动是说明":"每周比如0是星期一,4是星期五**********","每周轮动时间":0,"每月轮动是说明":"必须是交易日,需要自己每个月自动输入**********","每月轮动时间":["2024-02-29","2024-02-29","2024-02-29","2024-02-29","2024-02-29","2024-02-29","2024-02-29"],"特定时间说明":"特别的应该交易日","特定时间":["2024-02-23","2024-02-24","2024-02-25","2024-02-26","2024-02-27"],"轮动规则设置":"轮动规则设置88888888**********排名","买入排名前N":10,"持有排名前N":13,"跌出排名卖出N":15,"持股周期设置":"持股轮动设置,可以买入小于持股限制数量不可以卖出","是否开启持股周期":"否","持股持股周期天数":4,"持股周期尾盘是否补仓":"是","持股周期尾盘更新数据时间":"14:48","持股周期是否允许T":"是","持股周期尾盘买入时间":"14:53","持股周期尾盘卖出时间":"14:50","趋势分析设置":"************************************","是否开启趋势轮动":"否","趋势分析参数":"均线分析--日线","使用均线":[5,10,20,30,60],"跌破N日均线卖出":5,"均线最低分数":75,"持有均线最低分":25,"收益率分析模块":"收益率分析模块","最近N天":5,"最近N天最大收益率":10,"最近N天最小收益率":-5,"最近N天最大回撤":-8,"买入前N":5}
默认安周轮动,星期五为4,可以选择轮动方式
策略轮动设置":"策略轮动设置************************,轮动都按排名来","轮动方式说明":"每天/每周/每月/特别时间","轮动方式":"每周","说明":"每天按自定义函数运行","每周轮动是说明":"每周比如0是星期一,4是星期五**********","每周轮动时间":0,"每月轮动是说明":"必须是交易日,需要自己每个月自动输入**********","每月轮动时间":["2024-02-29","2024-02-29","2024-02-29","2024-02-29","2024-02-29","2024-02-29","2024-02-29"],"特定时间说明":"特别的应该交易日","特定时间":["2024-02-23","2024-02-24","2024-02-25","2024-02-26","2024-02-27"],
实盘设置,启动策略,点击分析配置交易系统选择qmt

"交易系统设置":"*********************************************","交易系统选择":"ths/qmt","交易系统":"qmt","交易品种":"bond","交易品种说明":["stock","fund","bond","全部"],"同花顺下单路径":"C:/同花顺软件/同花顺/xiadan.exe","识别软件安装位置":"C:/Program Files/Tesseract-OCR/tesseract","qmt路径":"C:/国金QMT交易端模拟/userdata_mini","qmt账户":"55003645","qmt账户类型":"STOCK","证券公司交易设置":"兼容老牌证券公司可转债1手为单位","是否开启特殊证券公司交易设置":"否",
选择交易模型比如三低策略

自定义交易":"************************","是否开启自定义函数模块":"是","自定义运行函数设置":"自定义运行函数说明,运行类型有定时和循环,只需要把自定义模块的函数名称放在下面******","目前设置说明":"早上交易人气,下午做概念,2个策略的间隔长,干扰小,手动更新数据是最后一个策略的","自定义函数运行类型":["定时"],"自定义函数模块运行时间":["09:45"],"自定义函数":["run_convertible_bonds_three_low_strategy"],"黑名单":["600031","159937"],
设置资金分配模式比如每一个买一万
"资金管理模块说明":"程序默认管理方式有数量/资金","资金分配设置":"交易数量设置数量和金额,利用可转债最低单位位设置条件,股票在基础数据*10,etf*100,值调整持有限制,持股限制","交易模式":"金额","固定交易资金":10000,"持有金额限制":10000,"固定交易数量":10,"持有限制":10,"持股限制":10,"滑点设置":"滑点设置滑点价格最后一位,比如滑点0.01,股票换掉0.01,etf,可转债滑点0.01/10=0.001价格最后一位,比如现在12.01,买入12.02,卖出12.00","滑点":0.01,
运行user models更新数据,只需要运行一次,后面全部自动


三低的结果,可以设置参数

Unnamed: 0.3 Unnamed: 0.2 Unnamed: 0.1 序号 证券代码 可转债名称 价格 涨跌幅 正股代码 正股名称 ... 回售 价值 纯债 价值 弹性 信用代码 三低 强制赎回 持股检查 跌破均线 交易状态0 0 0 0 358 123096 思创转债 103.54 3.63 300078 思创医惠 ... 80.39 63.63 0.84 BB 123096 108.91 不是 没有持股 不是 未买1 1 1 1 468 123044 红相转债 109.089 0.34 300427 *ST红相 ... 回售内 98.44 0.55 A- 123044 117.199 不是 没有持股 不是 未买2 2 2 2 544 128039 三力转债 107.97 1.37 2224 三 力 士 ... 回售内 104.49 0.18 A+ 128039 126.08 不是 没有持股 不是 未买3 3 3 3 72 123207 冠中转债 116.63 1.72 300948 冠中生态 ... 76.32 75.97 0.7 A 123207 129 不是 没有持股 不是 未买4 4 4 4 535 128042 凯中转债 116.694 1.58 2823 凯中精密 ... 回售内 110.03 0.38 AA- 128042 131.044 不是 没有持股 不是 未买5 5 5 5 484 128087 孚日转债 116.3 1.53 2083 孚日股份 ... 回售内 100.19 0.57 AA- 128087 131.46 不是 没有持股 不是 未买6 6 6 6 82 123204 金丹转债 122.9 2.93 300829 金丹科技 ... 85.37 89.95 0.65 AA- 123204 134.55 不是 没有持股 不是 未买7 7 7 7 476 127015 希望转债 104.549 0.35 876 新 希 望 ... 回售内 102.92 0.27 AAA 127015 135.419 不是 没有持股 不是 未买8 8 8 8 306 113628 晨丰转债 120.722 2.62 603685 晨丰科技 ... 89.92 89.67 0.62 A 113628 136.612 不是 没有持股 不是 未买9 9 9 9 46 123221 力诺转债 130.008 1.06 301188 力诺特玻 ... 80.48 77.55 0.73 A+ 123221 137.018 不是 没有持股 不是 未买
运行trader st进入实盘交易


程序开始下单

下单的结果

循环监测

24小时运行

全部的源代码上传了知识星球直接下载就可以运行
策略源代码
from trader_tool.stock_data import stock_datafrom trader_tool.bond_cov_data import bond_cov_datafrom trader_tool.shape_analysis import shape_analysisfrom trader_tool.analysis_models import analysis_modelsimport pandas as pdfrom trader_tool.ths_rq import ths_rqfrom tqdm import tqdmimport numpy as npimport jsonfrom trader_tool import jsl_datafrom qmt_trader.qmt_trader_ths import qmt_trader_thsfrom xgtrader.xgtrader import xgtraderimport numpy as npimport osfrom datetime import datetimeimport timeclass convertible_bonds_three_low_strategy: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',name='run_bond_cov_rend_strategy'):'''可转债三低策略'''self.exe=exeself.tesseract_cmd=tesseract_cmdself.qq=qqself.trader_tool=trader_toolself.open_set=open_setself.qmt_path=qmt_pathself.qmt_account=qmt_accountself.qmt_account_type=qmt_account_typeif trader_tool=='ths':self.trader=xgtrader(exe=self.exe,tesseract_cmd=self.tesseract_cmd,open_set=open_set)else:self.trader=qmt_trader_ths(path=qmt_path,account=qmt_account,account_type=qmt_account_type)self.stock_data=stock_data()self.bond_cov_data=bond_cov_data()self.ths_rq=ths_rq()self.path=os.path.dirname(os.path.abspath(__file__))self.name=namedef save_position(self):'''保存持股数据'''with open(r'分析配置.json',encoding='utf-8') as f:com=f.read()text=json.loads(com)del_stock_list=text['黑名单']def select_del_stock_list(x):if str(x)[:6] in del_stock_list:return '是'else:return '否'self.trader.connect()df=self.trader.position()def select_bond_cov(x):'''选择可转债'''if x[:3] in ['110','113','123','127','128','111','118'] or x[:2] in ['11','12']: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['持股天数']=1df1=df[df['选择']=='是']df1=df1[df1['可用余额']>=10]df1['黑名单']=df1['证券代码'].apply(select_del_stock_list)df1=df1[df1['黑名单']=='否']print('剔除黑名单**********')df1.to_excel(r'持股数据\持股数据.xlsx')return df1else:df=pd.DataFrame()df['账号类型']=Nonedf['资金账号']=Nonedf['证券代码']=Nonedf['股票余额']=Nonedf['可用余额']=Nonedf['成本价']=Nonedf['市值']=Nonedf['选择']=Nonedf['持股天数']=Nonedf['交易状态']=Nonedf['明细']=Nonedf['证券名称']=Nonedf['冻结数量']=Nonedf['市价']=Nonedf['盈亏']=Nonedf['盈亏比(%)']=Nonedf['当日买入']=Nonedf['当日卖出']=Nonedf.to_excel(r'持股数据\持股数据.xlsx')return dfdef save_position(self):'''保存持股数据'''with open(r'分析配置.json',encoding='utf-8') as f:com=f.read()text=json.loads(com)del_stock_list=text['黑名单']def select_del_stock_list(x):if str(x)[:6] in del_stock_list:return '是'else:return '否'self.trader.connect()df=self.trader.position()def select_bond_cov(x):'''选择可转债'''if x[:3] in ['110','113','123','127','128','111','118'] or x[:2] in ['11','12']: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['持股天数']=1df1=df[df['选择']=='是']df1=df1[df1['可用余额']>=10]df1['黑名单']=df1['证券代码'].apply(select_del_stock_list)df1=df1[df1['黑名单']=='否']print('剔除黑名单**********')df1.to_excel(r'持股数据\持股数据.xlsx')return df1else:df=pd.DataFrame()df['账号类型']=Nonedf['资金账号']=Nonedf['证券代码']=Nonedf['股票余额']=Nonedf['可用余额']=Nonedf['成本价']=Nonedf['市值']=Nonedf['选择']=Nonedf['持股天数']=Nonedf['交易状态']=Nonedf['明细']=Nonedf['证券名称']=Nonedf['冻结数量']=Nonedf['市价']=Nonedf['盈亏']=Nonedf['盈亏比(%)']=Nonedf['当日买入']=Nonedf['当日卖出']=Nonedf.to_excel(r'持股数据\持股数据.xlsx')return dfdef select_bond_cov(self,x):'''选择证券代码'''if x[:3] in ['110','113','123','127','128','111'] or x[:2] in ['11','12']: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)self.trader.connect()df=self.trader.balance()df.to_excel(r'账户数据\账户数据.xlsx')return dfdef get_all_jsl_data(self):'''获取可转债全部数据'''print('获取可转债全部数据')with open(r'{}/可转债三低策略设置.json'.format(self.path),encoding='utf-8') as f:com=f.read()text=json.loads(com)max_yjl=text['可转债溢价率上限']min_yjl=text['可转债溢价率下限']max_gm=text['转债余额上限']min_gm=text['转债余额下限']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))df['代码']=df['证券代码'].tolist()df1=df[df['转股溢价率']<=max_yjl]df2=df1[df1['转股溢价率']>=min_yjl]try:df3=df2[df2['转债 余额']>=min_gm]except:df3=df2[df2['转债余额']>=min_gm]try:df4=df3[df3['转债 余额']<=max_gm]except:df4=df3[df3['转债余额']<=max_gm]df4.to_excel(r'{}\目前溢价率可转债\目前溢价率可转债.xlsx'.format(self.path))return df4def calculated_double_low(self):'''计算三低三低=价格+100*转股溢价率+转债余额'''with open(r'{}/可转债三低策略设置.json'.format(self.path),encoding='utf-8') as f:com=f.read()text=json.loads(com)min_value=text['三低最小值']max_value=text['三低最大值']df=pd.read_excel(r'{}\目前溢价率可转债\目前溢价率可转债.xlsx'.format(self.path),dtype='object')try:del df['Unnamed: 0']except:passtry:df['三低']=df['价格']+df['转股溢价率']+df['转债 余额']except:df['三低']=df['价格']+df['转股溢价率']+df['转债余额']df.to_excel(r'{}\原始三低\原始三低.xlsx'.format(self.path ))#排序df=df.sort_values(by='三低',ascending=True)df['三低']=pd.to_numeric(df['三低'])df1=df[df['三低']>=min_value]df2=df1[df1['三低']<=max_value]df2.to_excel(r'{}\三低\三低.xlsx'.format(self.path))def mean_line_models(self,df):'''均线模型趋势模型5,10,20,30,60'''df=df#df=self.bond_cov_data.get_cov_bond_hist_data(stock=stock,start=start_date,end=end_date,limit=1000000000)df1=pd.DataFrame()df1['date']=df['date']df1['5']=df['close'].rolling(window=5).mean()df1['10']=df['close'].rolling(window=10).mean()df1['20']=df['close'].rolling(window=20).mean()df1['30']=df['close'].rolling(window=30).mean()df1['60']=df['close'].rolling(window=60).mean()score=0#加分的情况mean_5=df1['5'].tolist()[-1]mean_10=df1['10'].tolist()[-1]mean_20=df1['20'].tolist()[-1]mean_30=df1['30'].tolist()[-1]mean_60=df1['60'].tolist()[-1]#相邻2个均线进行比较if mean_5>mean_10:score+=25if mean_10>mean_20:score+=25if mean_20>mean_30:score+=25if mean_30>mean_60:score+=25return scoredef get_return_ananlysis(self,df='',n=5):'''收益率分析'''#涨跌幅df1=dfprices=df1[-n:]['close']zdf= ((prices.iloc[-1] / prices.iloc[0]) - 1)*100#最大回撤max_down_result=((prices / prices.expanding(min_periods=1).max()).min() - 1)*100#累计收益】return zdf,max_down_resultdef get_cov_bond_shape_analysis(self):'''可转债形态分析'''print('可转债形态分析')df=pd.read_excel(r'{}\三低\三低.xlsx'.format(self.path),dtype='object')with open(r'{}/可转债三低策略设置.json'.format(self.path),encoding='utf-8') as f:com=f.read()text=json.loads(com)n=text['跌破N日均线卖出']try:del df['Unnamed: 0']except:passstock_list=df['证券代码'].tolist()over_lining=[]mean_line=[]for i in tqdm(range(len(stock_list))):stock=stock_list[i]try:hist_df=self.bond_cov_data.get_cov_bond_hist_data(stock=stock)models=shape_analysis(df=hist_df)over=models.get_over_lining_sell()over_lining.append(over)#均线分析line=models.get_down_mean_line_sell(n=n)mean_line.append(line)except:over_lining.append(None)mean_line.append(None)df['上影线']=over_liningdf['跌破均线']=mean_linedf1=df[df['跌破均线']=='不是']df1.to_excel(r'{}\选择可转债\选择可转债.xlsx'.format(self.path))return df1def get_stock_mean_line_retuen_analysis(self):'''可转债均线收益分析'''print('可转债均线收益分析')with open(r'{}/可转债三低策略设置.json'.format(self.path),encoding='utf-8') as f:com=f.read()text=json.loads(com)n=text['最近N天']max_retuen=text['最近N天最大收益率']min_return=text['最近N天最小收益率']max_down=text['最近N天最大回撤']min_secore=text['均线最低分数']mean_sorce_list=[]zdf_list=[]max_down_list=[]df=pd.read_excel(r'{}\选择可转债\选择可转债.xlsx'.format(self.path),dtype='object')try:df['Unnamed: 0']except:passstock_list=df['证券代码'].tolist()for i in tqdm(range(len(stock_list))):stock=stock_list[i]try:df1=self.bond_cov_data.get_cov_bond_hist_data(stock=stock,start='19990101',end='20500101',limit=10000000)sorce=self.mean_line_models(df=df1)zdf,down=self.get_return_ananlysis(df=df1,n=n)mean_sorce_list.append(sorce)zdf_list.append(zdf)max_down_list.append(down)except:mean_sorce_list.append(None)zdf_list.append(None)max_down_list.append(None)df['均线得分']=mean_sorce_listdf['最近{}天收益'.format(n)]=zdf_listdf['最近天{}最大回撤'.format(n)]=max_down_listdf.to_excel(r'{}\分析原始数据\分析原始数据.xlsx'.format(self.path))df1=df[df['均线得分']>=min_secore]df2=df1[df1['最近{}天收益'.format(n)]>=min_return]df3=df2[df2['最近{}天收益'.format(n)]<=max_retuen]df4=df3[df3['最近天{}最大回撤'.format(n)]>=max_down]df4.to_excel(r'{}\交易股票池\交易股票池.xlsx'.format(self.path))return df4def get_select_trader_type(self):'''选择交易方式'''with open(r'{}/可转债三低策略设置.json'.format(self.path),encoding='utf-8') as f:com=f.read()text=json.loads(com)rend=text['是否开启趋势轮动']if rend=='是':self.get_cov_bond_shape_analysis()self.get_stock_mean_line_retuen_analysis()else:df=pd.read_excel(r'{}\三低\三低.xlsx'.format(self.path),dtype='object')try:df['Unnamed: 0']except:passdf.to_excel(r'{}\交易股票池\交易股票池.xlsx'.format(self.path))def get_del_qzsh_data(self):'''剔除强制赎回'''print('剔除强制赎回')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()del_list=[]for i in range(1,n+1):n_text='至少还需{}天'.format(i)del_list.append(n_text)del_list.append('临近到期')del_list.append('已满足强赎条件')del_list.append('是否剔除强制赎回')text_n=''for select_text in del_list:text_n+='"{}" in x or '.format(select_text)text_n=text_n[:-3]if del_select=='是':df1=dfdef select_bond_cov(x):'''选择可转债'''if eval(text_n):return '是'else:return '不是'df1['选择']=df1['cell.redeem_count'].apply(select_bond_cov)df2=df1[df1['选择']=='是']df2.to_excel(r'{}\强制赎回\强制赎回.xlsx'.format(self.path))trader_stock=pd.read_excel(r'{}\交易股票池\交易股票池.xlsx'.format(self.path),dtype='object')try:trader_stock['Unnamed: 0']except:passdef select_trader_stock(x):'''选择交易股票池'''if x not in df2['cell.bond_id'].tolist():return '不是'else:return '是'trader_stock['强制赎回']=trader_stock['证券代码'].apply(select_trader_stock)trader_stock=trader_stock[trader_stock['强制赎回']=='不是']trader_stock.to_excel(r'{}\交易股票池\交易股票池.xlsx'.format(self.path))return trader_stockelse:df.to_excel(r'非强制赎回\非强制赎回.xlsx')return dfdef get_del_buy_sell_data(self):'''处理交易股票池买入股票'''with open(r'{}/可转债三低策略设置.json'.format(self.path),encoding='utf-8') as f:com=f.read()text=json.loads(com)limit=text['持股限制']df=self.save_position()df['证券代码']=df['证券代码'].astype(str)df1=df[df['可用余额']>=10]hold_stock_list=df1['证券代码'].tolist()n=text['跌破N日均线卖出']trader_df=self.get_del_qzsh_data()trader_df['证券代码']=trader_df['证券代码'].astype(str)def select_data(stock):if stock in hold_stock_list:return '持股超过限制'else:return '没有持股'trader_df['持股检查']=trader_df['证券代码'].apply(select_data)trader_df=trader_df[trader_df['持股检查'] !='持股超过限制']hold_stock_list=trader_df['证券代码'].tolist()sell_list=[]for stock in hold_stock_list:try:hist_df=self.bond_cov_data.get_cov_bond_hist_data(stock=stock)models=shape_analysis(df=hist_df)mean_line=models.get_down_mean_line_sell(n=n)if mean_line=='是':sell_list.append('是')else:sell_list.append('不是')except:print('{}有问题'.format(stock))sell_list.append('是')trader_df['跌破均线']=sell_listtrader_df=trader_df[trader_df['跌破均线']=='不是']for i in range(0,10):try:trader_df['Unnamed: {}'.format(i/10)]except:passtrader_df.to_excel(r'{}\交易股票池\交易股票池.xlsx'.format(self.path))return trader_dfdef get_time_rotation(self):'''轮动方式'''with open('{}/可转债三低策略设置.json'.format(self.path),encoding='utf-8') as f:com=f.read()text=json.loads(com)now_date=''.join(str(datetime.now())[:10].split('-'))now_time=time.localtime()trader_type=text['轮动方式']trader_wday=text['每周轮动时间']moth_trader_time=text['每月轮动时间']specific_time=text['特定时间']year=now_time.tm_yearmoth=now_time.tm_monwday=now_time.tm_wdaydaily=now_time.tm_mdayif trader_type=='每天':print('轮动方式每天')return Trueelif trader_type=='每周':if trader_wday==wday:return Trueelif trader_wday<wday:print('安周轮动 目前星期{} 轮动时间星期{} 目前时间大于轮动时间不轮动'.format(wday+1,trader_wday+1))return Falseelse:print('安周轮动 目前星期{} 轮动时间星期{} 目前时间小于轮动时间不轮动'.format(wday+1,trader_wday+1))return Falseelif trader_type=='每月轮动时间':stats=''for date in moth_trader_time:data=''.join(data.split('-'))if int(moth_trader_time)==int(date):print('安月轮动 目前{} 轮动时间{} 目前时间等于轮动时间轮动'.format(now_date,date))stats=Truebreakelif int(moth_trader_time)<int(date):print('安月轮动 目前{} 轮动时间{} 目前时间小于轮动时间轮动'.format(now_date,date))stats=Falseelse:print('安月轮动 目前{} 轮动时间{} 目前时间大于轮动时间轮动'.format(now_date,date))stats=Falsereturn statselse:#特别时间stats=''for date in specific_time:data=''.join(data.split('-'))if int(specific_time)==int(date):print('安月轮动 目前{} 轮动时间{} 目前时间等于轮动时间轮动'.format(now_date,date))stats=Truebreakelif int(specific_time)<int(date):print('安月轮动 目前{} 轮动时间{} 目前时间小于轮动时间轮动'.format(now_date,date))stats=Falseelse:print('安月轮动 目前{} 轮动时间{} 目前时间大于轮动时间轮动'.format(now_date,date))stats=Falsereturn statsdef 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_rank_num=text['持有排名前N']sell_rank_num=text['跌出排名卖出N']sell_value=text['三低平仓']hold_limit=text['持有限制']df=pd.read_excel(r'持股数据\持股数据.xlsx',dtype='object')df['证券代码']=df['证券代码'].astype(str)df_yjl=pd.read_excel(r'{}\原始三低\原始三低.xlsx'.format(self.path))sd_dict=dict(zip(df_yjl['证券代码'],df_yjl['三低']))trend=text['是否开启趋势轮动']df1=df[df['可用余额']>=10]hold_stock_list=df['证券代码'].tolist()def select_stock(x):'''选择etf'''if x in hold_stock_list:return '持股'else:return "持股不足"try:del df['Unnamed: 0']except:passtrader_df=pd.read_excel(r'{}\交易股票池\交易股票池.xlsx'.format(self.path),dtype='object')trader_df['证券代码']=trader_df['证券代码'].astype(str)try:del trader_df['Unnamed: 0']except:passprint('交易股票池*******************')print(trader_df)trader_df['选择']=trader_df['证券代码'].apply(select_stock)trader_df=trader_df[trader_df['选择']=='持股不足']select=text['是否开启持股周期']hold_daily_limit=text['持股持股周期天数']try:del trader_df['Unnamed: 0']except:passif df1.shape[0]>0:#卖出列表sell_list=[]#持股列表hold_stock_list=df['证券代码'].tolist()#排名列表if select=='是':hold_daily=df[df['证券代码']==stock]['持股天数'].tolist()[-1]if hold_daily>=hold_daily_limit:sell_list.append(stock)else:print('目前持股 {} 没有大于{}'.format(hold_daily,hold_daily_limit))else:print('不启动持股限制')#跌破均线分析n=text['跌破N日均线卖出']if trend=='是':for stock in hold_stock_list:try:hist_df=self.etf_fund_data.get_ETF_fund_hist_data(stock=stock)models=shape_analysis(df=hist_df)mean_line=models.get_down_mean_line_sell(n=n)if mean_line=='是':sell_list.append(stock)print('{}跌破均线'.format(stock))else:passexcept:passelse:print('**************************88不开启持股趋势分析')#三低平仓for stock in hold_stock_list:value=sd_dict.get(stock,0)if value>=sell_value:print('三低平仓 {} 三低{} 大于 平仓值{}'.format(stock,value,sell_value))sell_list.append(stock)else:print('三低平仓 {} 三低{} 小于 平仓值{}'.format(stock,value,sell_value))#跌出排名卖出Nrank_df=pd.read_excel(r'{}\三低\三低.xlsx'.format(self.path),dtype='object')sell_rank_stock=rank_df['证券代码'].tolist()[:sell_rank_num]if len(sell_rank_stock)>0:for stock in hold_stock_list:if stock in sell_rank_stock:print('{} 在持有排名里面'.format(stock))else:print('{} 不在持有排名里面'.format(stock))sell_list.append(stock)sell_list=list(set(sell_list))sell_df=pd.DataFrame()sell_df['证券代码']=sell_listsell_df['交易状态']='未卖'if sell_df.shape[0]>0:print('卖出etf*****************')print(sell_df)sell_df['策略名称']=self.namesell_df.to_excel(r'卖出股票\卖出股票.xlsx')else:print('没有卖出etf')sell_df['证券代码']=Nonesell_df['交易状态']=Nonesell_df['策略名称']=self.namesell_df.to_excel(r'卖出股票\卖出股票.xlsx')hold_num=df1.shape[0]if hold_num>0:av_buy_num=hold_limit-hold_numav_buy_num=av_buy_num+sell_df.shape[0]if av_buy_num>=hold_limit:av_buy_num=hold_limitelse:av_buy_num=av_buy_numbuy_df=trader_df[:av_buy_num]else:buy_df=trader_df[:buy_num]buy_df['交易状态']='未买'print('买入可转债*****************')df['证券代码']=df['证券代码']print(buy_df)buy_df['策略名称']=self.namebuy_df.to_excel(r'买入股票\买入股票.xlsx')return buy_dfelse:buy_df=trader_df[:buy_num]print(trader_df)buy_df['证券代码']=buy_df['证券代码']buy_df['交易状态']='未买'print('买入etf*****************')print(buy_df)buy_df['策略名称']=self.namebuy_df.to_excel(r'买入股票\买入股票.xlsx')return buy_dfdef updata_all_data(self):'''更新全部数据'''with open(r'{}/可转债三低策略设置.json'.format(self.path),encoding='utf-8') as f:com=f.read()text=json.loads(com)select=text['是否测试']if select=='是':self.save_position()self.save_balance()self.get_all_jsl_data()self.calculated_double_low()self.get_select_trader_type()self.get_del_qzsh_data()self.get_del_buy_sell_data()self.get_buy_sell_stock()else:if self.get_time_rotation()==True:self.save_position()self.save_balance()self.get_all_jsl_data()print("今天{} 是轮动时间".format(datetime.now()))self.calculated_double_low()self.get_select_trader_type()self.get_del_qzsh_data()self.get_del_buy_sell_data()self.get_buy_sell_stock()else:print("今天{} 不是是轮动时间".format(datetime.now()))