可转债双低策略量化回测python源码(已更新)

鉴于复制黏贴到集思录的代码给一些朋友造成困扰,我已重新上传了新的回测代码,改动点:
1、预先取数,大幅优化回测速度;
2、可用不同调仓频率;
3、原先是卖出的资金全部买入,会造成仓位越来越不平衡,这点极不合理。现在是按理论仓位和实际资金做平衡,终于解决了困扰我很久的交易问题。比如目标转债数量4只,手持3只,总市值28万,理论上每只应配置7万。如果现金有5万则5万买入1只,如果现金有9万,则8万买入一只,剩余1万留待后续交易时平衡过去。

下载链接: https://pan.baidu.com/s/1XHqk4dFuqwslTfDp73OTSw 提取码: p658

————以下是原帖:————
自15年接触量化交易,一直都是在折腾股票策略,果仁、聚宽都在实盘自动交易中。今年受双低转债策略启发,投入了可转债,习惯上是想要量化回测策略历史效果的。几个量化平台看了看,也就优矿勉强会搞:有可转债收盘价等数据,代码格式什么的不算复杂,不过优矿是无法回测可转债的,只能自己计算持仓和现金。于是,我就写了这么个策略,敝帚自珍了许久,想想还不知道有多少疏漏给自己埋了多大的坑呢,还是放出来供有兴趣者批评指正吧。

start = '2020-01-02' # 回测起始时间
end = '2020-11-13' # 回测结束时间
universe = DynamicUniverse('HS300') # 证券池,支持股票、基金、期货、指数四种资产
benchmark = 'HS300' # 策略参考标准
freq = 'd' # 策略类型,'d'表示日间策略使用日线回测,'m'表示日内策略使用分钟线回测
refresh_rate = (1, ['14:52']) # 调仓频率,表示执行handle_data的时间间隔,若freq = 'd' 时间间隔的单位为交易日,取盘前数据,若freq = 'm' 时间间隔为分钟

def initialize(context):
global MyPosition, HighValue, MyCash, Withdraw, HoldRank, HoldNum
MyPosition = {} #持仓
MyCash = 100000 #现金
HighValue = MyCash #最高市值
Withdraw = 0 #最大回撤
HoldRank = 10 #排名多少之后卖出
HoldNum = 4 #持债支数

def handle_data(context):

global MyCash, HighValue, Withdraw
previous_date = context.previous_date.strftime('%Y%m%d')
today_date = context.now.strftime('%Y%m%d')

#每天重新计算双低排名
ConBonds = DataAPI.SecIDGet(partyID=u"",ticker=u"",cnSpell=u"",assetClass=u"B",exchangeCD="XSHE,XSHG",listStatusCD="",field=u"secID",pandas="1")
data = DataAPI.MktConsBondPerfGet(beginDate=today_date,endDate=today_date,secID=ConBonds['secID'],tickerBond=u"",tickerEqu=u"",field=u"secID,closePriceBond,bondPremRatio",pandas="1")
data.set_index('secID',inplace=True)
data['DoubleLow'] = data.closePriceBond + data.bondPremRatio
data = data.sort_values(by="DoubleLow" , ascending=True)
PosValue = MyCash

#抛出不在持有排名HoldRank的
for stock in MyPosition.keys():
try:
CurPrice = data.loc[stock]['closePriceBond']
except:
NoPrice = DataAPI.MktConsBondPerfGet(beginDate=previous_date,endDate=previous_date,secID=stock,tickerBond=u"",tickerEqu=u"",field=u"closePriceBond",pandas="1")
CurPrice = NoPrice.closePriceBond[0]
PosValue += MyPosition[stock] * CurPrice * 10 #计算当前市值
if stock not in data.index[:HoldRank]:
MyCash += MyPosition[stock] * CurPrice * 9.9 # 卖出后回收现金,交易摩擦成本按百分之一,10*0.99=9.9
del MyPosition[stock]
if PosValue > HighValue:HighValue = PosValue
if (HighValue - PosValue) / HighValue > Withdraw:Withdraw = (HighValue - PosValue) / HighValue

#买入排在HoldRank内的,总持有数量HoldNum
for i in range(HoldRank):
if len(MyPosition) == HoldNum or len(data.index) < HoldNum:break
if data.index[i] not in MyPosition.keys():
MyPosition[data.index[i]] = int(MyCash / (HoldNum - len(MyPosition)) / data['closePriceBond'][i] / 10) # 简单粗暴地资金均分买入
MyCash -= MyPosition[data.index[i]] * data['closePriceBond'][i] * 10 # 买入时不再计算交易摩擦成本,直接扣减
print(today_date + ': 最高市值 ' + str(HighValue) + ' , 当前市值 ' + str(PosValue) + ' , 最大回撤 ' + str(round(Withdraw*100,2)))
print(MyPosition)
0

无双0

赞同来自:

我怎么下载下来用python运行,可是显示就是定义了函数。。是多加了空行吗? 也没有任何输出。。
2021-09-26 10:35 引用

要回复问题请先登录注册

发起人

问题状态

  • 最新活动: 2022-10-14 15:09
  • 浏览: 19855
  • 关注: 207