链接 综合交易模型----可转债三低策略实盘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_data
from trader_tool.bond_cov_data import bond_cov_data
from trader_tool.shape_analysis import shape_analysis
from trader_tool.analysis_models import analysis_models
import pandas as pd
from trader_tool.ths_rq import ths_rq
from tqdm import tqdm
import numpy as np
import json
from trader_tool import jsl_data
from qmt_trader.qmt_trader_ths import qmt_trader_ths
from xgtrader.xgtrader import xgtrader
import numpy as np
import os
from datetime import datetime
import time
class 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=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
if 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=name
def 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['持股天数']=1
df1=df[df['选择']=='是']
df1=df1[df1['可用余额']>=10]
df1['黑名单']=df1['证券代码'].apply(select_del_stock_list)
df1=df1[df1['黑名单']=='否']
print('剔除黑名单**********')
df1.to_excel(r'持股数据\持股数据.xlsx')
return df1
else:
df=pd.DataFrame()
df['账号类型']=None
df['资金账号']=None
df['证券代码']=None
df['股票余额']=None
df['可用余额']=None
df['成本价']=None
df['市值']=None
df['选择']=None
df['持股天数']=None
df['交易状态']=None
df['明细']=None
df['证券名称']=None
df['冻结数量']=None
df['市价']=None
df['盈亏']=None
df['盈亏比(%)']=None
df['当日买入']=None
df['当日卖出']=None
df.to_excel(r'持股数据\持股数据.xlsx')
return df
def 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['持股天数']=1
df1=df[df['选择']=='是']
df1=df1[df1['可用余额']>=10]
df1['黑名单']=df1['证券代码'].apply(select_del_stock_list)
df1=df1[df1['黑名单']=='否']
print('剔除黑名单**********')
df1.to_excel(r'持股数据\持股数据.xlsx')
return df1
else:
df=pd.DataFrame()
df['账号类型']=None
df['资金账号']=None
df['证券代码']=None
df['股票余额']=None
df['可用余额']=None
df['成本价']=None
df['市值']=None
df['选择']=None
df['持股天数']=None
df['交易状态']=None
df['明细']=None
df['证券名称']=None
df['冻结数量']=None
df['市价']=None
df['盈亏']=None
df['盈亏比(%)']=None
df['当日买入']=None
df['当日卖出']=None
df.to_excel(r'持股数据\持股数据.xlsx')
return df
def 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 df
def 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 df4
def 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:
pass
try:
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+=25
if mean_10>mean_20:
score+=25
if mean_20>mean_30:
score+=25
if mean_30>mean_60:
score+=25
return score
def get_return_ananlysis(self,df='',n=5):
'''
收益率分析
'''
#涨跌幅
df1=df
prices=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_result
def 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:
pass
stock_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_lining
df['跌破均线']=mean_line
df1=df[df['跌破均线']=='不是']
df1.to_excel(r'{}\选择可转债\选择可转债.xlsx'.format(self.path))
return df1
def 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:
pass
stock_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_list
df['最近{}天收益'.format(n)]=zdf_list
df['最近天{}最大回撤'.format(n)]=max_down_list
df.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 df4
def 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:
pass
df.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=df
def 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:
pass
def 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_stock
else:
df.to_excel(r'非强制赎回\非强制赎回.xlsx')
return df
def 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_list
trader_df=trader_df[trader_df['跌破均线']=='不是']
for i in range(0,10):
try:
trader_df['Unnamed: {}'.format(i/10)]
except:
pass
trader_df.to_excel(r'{}\交易股票池\交易股票池.xlsx'.format(self.path))
return trader_df
def 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_year
moth=now_time.tm_mon
wday=now_time.tm_wday
daily=now_time.tm_mday
if trader_type=='每天':
print('轮动方式每天')
return True
elif trader_type=='每周':
if trader_wday==wday:
return True
elif trader_wday<wday:
print('安周轮动 目前星期{} 轮动时间星期{} 目前时间大于轮动时间不轮动'.format(wday+1,trader_wday+1))
return False
else:
print('安周轮动 目前星期{} 轮动时间星期{} 目前时间小于轮动时间不轮动'.format(wday+1,trader_wday+1))
return False
elif 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=True
break
elif int(moth_trader_time)<int(date):
print('安月轮动 目前{} 轮动时间{} 目前时间小于轮动时间轮动'.format(now_date,date))
stats=False
else:
print('安月轮动 目前{} 轮动时间{} 目前时间大于轮动时间轮动'.format(now_date,date))
stats=False
return stats
else:
#特别时间
stats=''
for date in specific_time:
data=''.join(data.split('-'))
if int(specific_time)==int(date):
print('安月轮动 目前{} 轮动时间{} 目前时间等于轮动时间轮动'.format(now_date,date))
stats=True
break
elif int(specific_time)<int(date):
print('安月轮动 目前{} 轮动时间{} 目前时间小于轮动时间轮动'.format(now_date,date))
stats=False
else:
print('安月轮动 目前{} 轮动时间{} 目前时间大于轮动时间轮动'.format(now_date,date))
stats=False
return stats
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_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:
pass
trader_df=pd.read_excel(r'{}\交易股票池\交易股票池.xlsx'.format(self.path),dtype='object')
trader_df['证券代码']=trader_df['证券代码'].astype(str)
try:
del trader_df['Unnamed: 0']
except:
pass
print('交易股票池*******************')
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:
pass
if 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:
pass
except:
pass
else:
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))
#跌出排名卖出N
rank_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_list
sell_df['交易状态']='未卖'
if sell_df.shape[0]>0:
print('卖出etf*****************')
print(sell_df)
sell_df['策略名称']=self.name
sell_df.to_excel(r'卖出股票\卖出股票.xlsx')
else:
print('没有卖出etf')
sell_df['证券代码']=None
sell_df['交易状态']=None
sell_df['策略名称']=self.name
sell_df.to_excel(r'卖出股票\卖出股票.xlsx')
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
else:
av_buy_num=av_buy_num
buy_df=trader_df[:av_buy_num]
else:
buy_df=trader_df[:buy_num]
buy_df['交易状态']='未买'
print('买入可转债*****************')
df['证券代码']=df['证券代码']
print(buy_df)
buy_df['策略名称']=self.name
buy_df.to_excel(r'买入股票\买入股票.xlsx')
return buy_df
else:
buy_df=trader_df[:buy_num]
print(trader_df)
buy_df['证券代码']=buy_df['证券代码']
buy_df['交易状态']='未买'
print('买入etf*****************')
print(buy_df)
buy_df['策略名称']=self.name
buy_df.to_excel(r'买入股票\买入股票.xlsx')
return buy_df
def 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()))