大佬厉害,就是这个代码好复杂我这个小白看不懂,我突然想起来我几年前在优矿写过一个可转债策略,后来又用聚宽数据改写了一个,比较粗糙,连变量名都是aaabbb,采用自己计算净值画自定义曲线显示收益的方式,有需要的自取:
import pandas as pd
from sqlalchemy.sql.expression import or_
# 导入函数库
from jqdata import *
# 初始化函数,设定基准等等
def initialize(context):
# 设定沪深300作为基准
set_benchmark('000300.XSHG')
# 开启动态复权模式(真实价格)
set_option('use_real_price', True)
# 输出内容到日志 log.info()
### 股票相关设定 ###
# 股票类每笔交易时的手续费是:买入时佣金万分之三,卖出时佣金万分之三加千分之一印花税, 每笔交易佣金最低扣5块钱
set_order_cost(OrderCost(close_tax=0.001, open_commission=0.0003, close_commission=0.0003, min_commission=5), type='stock')
g.MyPosition = {}
g.MyCash = 1000000
g.HighValue = g.MyCash
g.Withdraw = 0
g.HoldRank = 25
g.HoldNum = 10
def handle_data(context,data):
#每天重新计算双低排名
today = context.current_dt.strftime('%Y-%m-%d')
newday = (context.current_dt + datetime.timedelta(days=30)).strftime('%Y-%m-%d')
aaa=bond.run_query(query(bond.CONBOND_BASIC_INFO.code,bond.CONBOND_BASIC_INFO.company_code).filter(bond.CONBOND_BASIC_INFO.list_date < = today,or_(bond.CONBOND_BASIC_INFO.delist_Date > newday,bond.CONBOND_BASIC_INFO.delist_Date==None)))
bbb=bond.run_query(query(bond.CONBOND_DAILY_PRICE.code,bond.CONBOND_DAILY_PRICE.close).filter(bond.CONBOND_DAILY_PRICE.money>0,bond.CONBOND_DAILY_PRICE.date==today,bond.CONBOND_DAILY_PRICE.code.in_(list(aaa['code']))))
#print(bbb)
ccc=get_price(list(aaa['company_code']), start_date=today, end_date=today, fq=None, panel=False)
kkk=bond.run_query(query(bond.CONBOND_CONVERT_PRICE_ADJUST.code,bond.CONBOND_CONVERT_PRICE_ADJUST.new_convert_price).filter(bond.CONBOND_CONVERT_PRICE_ADJUST.code.in_(list(aaa['code'])),bond.CONBOND_CONVERT_PRICE_ADJUST.adjust_date< =today))
ddd=pd.merge(bbb,aaa,on='code')
eee=pd.merge(ddd,kkk.groupby('code').last(),on='code')
ttt=pd.merge(eee,ccc,left_on='company_code',right_on='code')
ttt['yijia']=ttt['close_x'] * ttt['new_convert_price'] / ttt['close_y'] - 100
ttt.set_index('code_x',inplace=True)
ttt['DoubleLow'] = ttt.close_x * 1 + ttt.yijia * 0
ttt = ttt.sort_values(by="DoubleLow" , ascending=True)
#ttt = ttt.sort_values(by="yijia" , ascending=True)
PosValue = g.MyCash
#print(len(ttt))
#抛出不在持有排名HoldRank的
for stock in list(g.MyPosition.keys()):
abc = bond.run_query(query(bond.CONBOND_DAILY_PRICE.close,bond.CONBOND_DAILY_PRICE.pre_close).filter(bond.CONBOND_DAILY_PRICE.code == stock,bond.CONBOND_DAILY_PRICE.date == today))
#print(stock)
CurPrice = abc.close[0] if abc.close[0] > 0 else abc.pre_close[0]
PosValue += g.MyPosition[stock] * CurPrice * 10
if stock not in ttt.index[:g.HoldRank] and abc.close[0] > 0:
g.MyCash += g.MyPosition[stock] * CurPrice * 9.95 # * 10 * 交易摩擦成本
del g.MyPosition[stock]
if PosValue > g.HighValue:g.HighValue = PosValue
if (g.HighValue - PosValue) / g.HighValue > g.Withdraw:g.Withdraw = (g.HighValue - PosValue) / g.HighValue
#买入排在HoldRank内的,总持有数量HoldNum
#print(len(g.Myposition))
if len(g.MyPosition) < g.HoldNum:# and len(ttt.index) >= g.HoldNum:
BuyMoney = min(g.MyCash / (g.HoldNum - len(g.MyPosition)), (g.MyCash / (g.HoldNum - len(g.MyPosition)) + PosValue / g.HoldNum) / 2)
for i in range(g.HoldRank):
if len(g.MyPosition) == g.HoldNum or len(ttt.index) < g.HoldNum:break
if ttt.index[i] not in g.MyPosition.keys():
g.MyPosition[ttt.index[i]] = int(BuyMoney / ttt['close_x'][i] / 10)
g.MyCash -= g.MyPosition[ttt.index[i]] * ttt['close_x'][i] * 10
record(净值 = int(PosValue / 10000) / 100)
if context.current_dt.day > 25:
print(today + ' , ' + str(g.HighValue) + ' , ' + str(PosValue) + ' , ' + str(g.Withdraw))
print(g.MyPosition)
2025-12-10