import sys
from rqalpha.apis import *
from rqalpha import run_func
from decimal import *
import ast
import MySQLdb
aginCash=8000000000
startDate='2019-01-02'
endDate='2019-02-01'
codeType=''
CYCLE="M"
CYCLE_NUM= 6
codeStr= ""
memberStr="{'ZJQH161033162103000':0.5,'YDQH161032278909000':0.5}"
ret=""
for i in range(1, len(sys.argv)):
if i == 1:
aginCash = int(sys.argv[i])
if i == 2:
startDate = sys.argv[i]
if i == 3:
endDate = sys.argv[i]
if i == 4:
codeType = sys.argv[i]
if i == 5:
CYCLE = sys.argv[i]
if i == 6:
CYCLE_NUM = int(sys.argv[i])
if i == 7:
codeStr = sys.argv[i]
if i == 8:
memberStr = sys.argv[i]
print(aginCash,startDate,endDate,codeType,CYCLE,CYCLE_NUM,codeStr)
memberinfo= ast.literal_eval(memberStr)
config = {
"base": {
"start_date": startDate,
"end_date": endDate,
"benchmark": "000300.XSHG",
"accounts": {
"future": aginCash
}
},
"extra": {
"log_level": "info",
},
"mod": {
"sys_analyser": {
"enabled": True,
"plot": False,
},
}
}
db = MySQLdb.connect("127.0.0.1", "root", "root", "quant_test", port=33006, charset='utf8' )
# 使用cursor()方法获取操作游标
cursor = db.cursor()
# 在这个方法中编写任何的初始化逻辑。context对象将会在你的算法策略的任何方法之间做传递
def init(context):
context.codeType = codeType
context.code = codeStr
context.codeDic = {}
context.memberDic = {}
context.memberInfoDic = memberinfo
context.Vol = {}
context.MBuy = {}
context.MSell = {}
context.EBuy = {}
context.ESell = {}
# 你选择的期货数据更新将会触发此段逻辑,例如日线或分钟线更新
def open_auction (context, bar_dict):
members = context.memberInfoDic.keys()
#sql = "SELECT * FROM crawler_gain_loss_analysis WHERE TRADE_DATE = " +"'"+bar_dict.dt.year+"-"+bar_dict.dt.month+"-"+bar_dict.dt.day+"'"
sql1 = ""
sql = ''
date = str(bar_dict.dt.year)+"-"+str(bar_dict.dt.month)+"-"+str(bar_dict.dt.day)
if codeType != '':
sql1 = "SELECT * FROM crawler_gain_loss_analysis WHERE TRADE_DATE ='{}' and CODE_TYPE ='{}' and MEMBER in (%s)"
sql = sql1.format(date, context.codeType) # 转化后的sql语句
elif codeStr != '':
sql1 = "SELECT * FROM crawler_gain_loss_analysis WHERE TRADE_DATE ='{}' and CODE ='{}' and MEMBER in (%s)"
sql = sql1.format(date, context.code) # 转化后的sql语句
elif codeStr == '' and codeType == '':
sql1 = "SELECT * FROM crawler_gain_loss_analysis WHERE TRADE_DATE ='{}' and MEMBER in (%s)"
sql = sql1.format(date) # 转化后的sql语句
cursor.execute(sql % ", ".join(map(lambda x:"'%s'"% x,members)) )
results = cursor.fetchall()
# 迭代当日交易
for data in results:
# 合约
code = data[1]
# 会员
member = data[4]
# 会员倍数
member_bs = 0
# 当前会员比例
member_bl = context.memberInfoDic[member]*2
m_num = 0
e_num = 0
# 获得会员倍数
if member in context.memberDic.keys():
member_bs = context.memberDic[member].get("member_bs")
else:
# 查询倍数
membersql1 = "select * from crawler_member where MEMBER_CODE = '{}'"
membersql = membersql1.format(member) # 转化后的sql语句
cursor.execute(membersql)
memberBean = cursor.fetchall()
if len(memberBean) == 1:
context.memberDic[member] = {'member_bs': memberBean[0][12]}
member_bs = memberBean[0][12]
# 合约存在
if code in context.codeDic.keys():
# 查出今日原有的
# 多单
m_num = context.codeDic[code].get("m_num")
# 空单
e_num = context.codeDic[code].get("e_num")
m_BS_num = Decimal(str(data[9]))*Decimal(str(member_bs))*Decimal(str(member_bl)).quantize(Decimal('0.00'))
e_BS_num = Decimal(str(data[15]))*Decimal(str(member_bs))*Decimal(str(member_bl)).quantize(Decimal('0.00'))
context.codeDic[code]['m_num'] = Decimal(str(m_num)) + Decimal(str(m_BS_num))
context.codeDic[code]['e_num'] = Decimal(str(e_num)) + Decimal(str(e_BS_num))
# 合约不存在
else:
context.codeDic[code]={}
m_BS_num = Decimal(str(data[9]))*Decimal(str(member_bs))*Decimal(str(member_bl)).quantize(Decimal('0.00'))
context.codeDic[code].update({'m_num': m_BS_num})
e_BS_num = Decimal(str(data[15])) * Decimal(str(member_bs))*Decimal(str(member_bl)).quantize(Decimal('0.00'))
context.codeDic[code].update({'e_num': e_BS_num})
# 开始交易
for k, v in context.codeDic.items():
code = k
obj = v
m_num = int(obj.get('m_num')/100)
e_num = int(obj.get('e_num')/100)
have_m_num = get_position(code, 'LONG').quantity
have_e_num = get_position(code, 'SHORT').quantity
buy_sell_m(have_m_num, m_num, code, context)
buy_sell_e(have_e_num, e_num, code, context)
def handle_tick(context, tick):
# 继续交易上次未交易完成的订单
#多单买入
for k in list(context.MBuy.keys()):
v=context.MBuy[k]
otherCode=v['order_book_id']
amount=v['quantity']
# 删除已经处理的订单
context.MBuy.pop(k)
logger.info("再次多单买入"+str(otherCode)+"数量"+str(amount))
buy_sell_m(0,amount,otherCode,context)
# 平买仓
for k in list(context.MSell.keys()):
v = context.MSell[k]
otherCode=v['order_book_id']
amount=v['quantity']
# 删除已经处理的订单
context.MSell.pop(k)
# logger.info("再次多单卖出" + str(otherCode) + "数量" + str(amount))
buy_sell_m(amount,0,otherCode,context)
# 空单买入
for k in list(context.EBuy.keys()):
v = context.EBuy[k]
otherCode=v['order_book_id']
amount=v['quantity']
# 删除已经处理的订单
context.EBuy.pop(k)
# logger.info("再次空单买入" + str(otherCode) + "数量" + str(amount))
buy_sell_e(0,amount,otherCode,context)
# 平空仓
for k in list(context.ESell.keys()):
v = context.ESell[k]
otherCode=v['order_book_id']
amount=v['quantity']
# 删除已经处理的订单
context.ESell.pop(k)
#logger.info("再次空单卖出" + str(otherCode) + "数量" + str(amount))
buy_sell_e(amount,0,otherCode,context)
def buy_sell_m(MVol,nowMVol,code,context):
# 多单持仓量<当前多单持仓量
if MVol < nowMVol:
# 开单买入
amount = nowMVol - MVol
#logger.info("多单买入" + str(code) + "数量" + str(amount))
ret = buy_open(code, amount)
#logger.info(ret)
if type(ret) is list:
return
if ret.message.strip()!='':
context.MBuy[ret.order_id]={'order_book_id':ret.order_book_id , 'quantity':ret.quantity}
# 多单持仓量>当前多单持仓量
if MVol > nowMVol:
# 平买仓
amount=MVol - nowMVol
#logger.info("多单卖出" + str(code) + "数量" + str(amount))
haveamount = get_position(code, 'LONG').quantity
ret = None
if haveamount >= amount :
ret = sell_close(code, amount)
elif haveamount != 0:
ret = sell_close(code, haveamount)
else:
return
#logger.info(ret)
if type(ret) is list:
return
if ret.message.strip()!='':
context.MSell[ret.order_id]={'order_book_id':ret.order_book_id , 'quantity':ret.quantity}
def buy_sell_e(EVol,nowEVol,code,context):
# 空单持仓量<当前空单持仓量
if EVol < nowEVol:
# 空单买入
amount=nowEVol - EVol
# logger.info("空单买入" + str(code) + "数量" + str(amount))
ret=sell_open(code, amount)
#logger.info(ret)
if type(ret) is list:
return
if ret.message.strip()!='':
context.EBuy[ret.order_id] = {'order_book_id': ret.order_book_id, 'quantity': ret.quantity}
# 空单持仓量>当前空单持仓量
if EVol > nowEVol:
# 平空仓
amount=EVol - nowEVol
# logger.info("空单卖出" + str(code) + "数量" + str(amount))
haveamount=get_position(code, 'SHORT').quantity
ret=None
if haveamount>=amount:
ret=buy_close(code, amount)
elif haveamount!=0:
ret = buy_close(code, haveamount)
else:
return
#logger.info(ret)
if type(ret) is list:
return
if ret.message.strip()!='':
context.ESell[ret.order_id]={'order_book_id':ret.order_book_id , 'quantity':ret.quantity}
results = run_func(init=init, open_auction=open_auction,handle_tick=handle_tick, config=config)
# report = results["sys_analyser"]
# ret=report["summary"]
# #print("member",member)
#
# CASH=ret["FUTURE"]
# #print("CASH",ret["FUTURE"])
#
# START_DATE=ret["start_date"]
# #print("START_DATE",ret["start_date"])
#
# END_DATE=ret["end_date"]
# #print("END_DATE",ret["end_date"])
#
# MAX_DRAWDOWN=ret["max_drawdown"]
# #print("MAX_DRAWDOWN",ret["max_drawdown"])
#
# INCOME=ret["total_returns"]
# #print("INCOME",ret["total_returns"])
#
# INCOME_YEAR=ret["annualized_returns"]
# #print("INCOME_YEAR",ret["annualized_returns"])
#
# SHARPE=ret["sharpe"]
# #print("SHARPE",ret["sharpe"])
# #评分=0.3*年化率+0.4*夏普率+0.3*最大回撤率
# getcontext().prec = 6
# v1=Decimal('0.3')*Decimal(str(INCOME_YEAR))
# v2=Decimal('0.4')*Decimal(str(SHARPE))
# v3=Decimal('0.3')*Decimal(str(MAX_DRAWDOWN))
# SCORING=v1+v2+v3
# #print("SCORING",SCORING)
#
# def insert_data(dbName,data_dict):
#
# try:
#
# data_values = "(" + "%s," * (len(data_dict)) + ")"
# data_values = data_values.replace(',)', ')')
#
# dbField = data_dict.keys()
# dataTuple = tuple(data_dict.values())
# dbField = str(tuple(dbField)).replace("'",'')
#
# sql = """ insert into %s %s values %s """ % (dbName,dbField,data_values)
# params = dataTuple
# cursor.execute(sql, params)
# db.commit()
# cursor.close()
# ret="success"
# print("success")
# return 1
#
# except Exception as e:
# ret = "error"
# print("error")
# return 0
# dbName="crawler_gain_loss_analysis_ret"
# id = str(CYCLE) + '_' + str(CYCLE_NUM) + '_' + str(START_DATE) + '_' + str(END_DATE)
#
# data_dict = {
# "ID":id,
# "CODE": codeStr,
# "CASH": CASH,
# "START_DATE": START_DATE,
# "END_DATE": END_DATE,
# "MAX_DRAWDOWN": MAX_DRAWDOWN,
# "INCOME": INCOME,
# "INCOME_YEAR": INCOME_YEAR,
# "SHARPE": SHARPE,
# "CODE_TYPE": codeType,
# "CYCLE": CYCLE,
# "CYCLE_NUM": CYCLE_NUM,
# "CREATE_BY": "ww",
# "CREATE_DATE": datetime.datetime.now().strftime('%Y-%m-%d'),
# "DATA_STATU": "valid",
# "SCORING": SCORING,
# "VAL1":"ret"
# }
# result = insert_data(dbName, data_dict)
# print(ret)
#
#
5. 错误堆栈日志信息
C:\Users\being\anaconda3\python.exe "D:\soft\PyCharm Community Edition 2020.2.3\plugins\python-ce\helpers\pydev\pydevd.py" --multiproc --qt-support=auto --client 127.0.0.1 --port 60340 --file D:/pythonProject/test/backTrader.py
pydev debugger: process 42556 is connecting
Connected to pydev debugger (build 202.7660.27)
8000000000 2019-01-02 2019-02-01 M 6
[2020-12-30 15:02:57.120546] WARN: system_log: rqdatac 初始化失败,部分扩展 API 可能无法使用,错误信息:user auth failed! code: 202 message: 该 License 已过期。您可以访问 https://www.ricequant.com/welcome/rqdata 获取 rqdatac
[2020-12-30 15:02:57.176409] WARN: user_system_log: 配置'base.benchmark'已被弃用,使用'mod.sys_analyser.benchmark'代替
[2019-01-18 15:30:00.000000] WARN: user_system_log: IC1901 已退市/交割,系统自动平仓
[2019-01-18 15:30:00.000000] WARN: user_system_log: IC1901 已退市/交割,系统自动平仓
[2019-01-18 15:30:00.000000] WARN: user_system_log: IH1901 已退市/交割,系统自动平仓
[2019-01-18 15:30:00.000000] WARN: user_system_log: IH1901 已退市/交割,系统自动平仓
[2019-01-18 15:30:00.000000] WARN: user_system_log: IF1901 已退市/交割,系统自动平仓
[2019-01-21 00:00:00.000000] ERROR: user_system_log: 策略运行产生异常
Traceback (most recent call last):
File "C:\Users\being\anaconda3\lib\site-packages\rqalpha\core\strategy.py", line 99, in open_auction
self._open_auction(self._user_context, bar_dict)
File "D:/pythonProject/test/backTrader.py", line 166, in open_auction
buy_sell_m(have_m_num, m_num, code, context)
File "D:/pythonProject/test/backTrader.py", line 222, in buy_sell_m
ret = buy_open(code, amount)
File "C:\Users\being\anaconda3\lib\site-packages\rqalpha\core\execution_context.py", line 104, in wrapper
return func(*args, kwargs)
File "C:\Users\being\anaconda3\lib\site-packages\rqalpha\utils\arg_checker.py", line 440, in api_rule_check_wrapper
return func(*args, *kwargs)
File "C:\Users\being\anaconda3\lib\site-packages\rqalpha\utils\functools.py", line 104, in wrapper
return impl(args, kwargs)
File "C:\Users\being\anaconda3\lib\site-packages\rqalpha\mod\rqalpha_mod_sys_accounts\api\api_future.py", line 188, in future_buy_open
return _submit_order(id_or_ins, amount, SIDE.BUY, POSITION_EFFECT.OPEN, cal_style(price, style))
File "C:\Users\being\anaconda3\lib\site-packages\rqalpha\mod\rqalpha_mod_sys_accounts\api\api_future.py", line 59, in _submit_order
price = env.get_last_price(order_book_id)
File "C:\Users\being\anaconda3\lib\site-packages\rqalpha\environment.py", line 149, in get_last_price
return self.data_proxy.get_last_price(order_book_id)
File "C:\Users\being\anaconda3\lib\site-packages\rqalpha\data\data_proxy.py", line 261, in get_last_price
return float(self._price_board.get_last_price(order_book_id))
File "C:\Users\being\anaconda3\lib\site-packages\rqalpha\data\bar_dict_price_board.py", line 33, in get_last_price
return self._get_bar(order_book_id).last
File "C:\Users\being\anaconda3\lib\site-packages\rqalpha\model\bar.py", line 51, in
last = property(lambda self: self.open)
File "C:\Users\being\anaconda3\lib\site-packages\rqalpha\model\bar.py", line 48, in
open = property(fget=lambda self: self._tick.open)
AttributeError: 'NoneType' object has no attribute 'open'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\being\anaconda3\lib\site-packages\rqalpha\main.py", line 214, in run
executor.run(bar_dict)
File "C:\Users\being\anaconda3\lib\site-packages\rqalpha\core\executor.py", line 52, in run
self._split_and_publish(event)
File "C:\Users\being\anaconda3\lib\site-packages\rqalpha\core\executor.py", line 98, in _split_and_publish
self._env.event_bus.publish_event(e)
File "C:\Users\being\anaconda3\lib\site-packages\rqalpha\core\events.py", line 42, in publish_event
if listener(event):
File "C:\Users\being\anaconda3\lib\site-packages\rqalpha\core\strategy.py", line 34, in wrapper
return func(*args, **kwargs)
File "C:\Users\being\anaconda3\lib\site-packages\rqalpha\core\strategy.py", line 99, in open_auction
self._open_auction(self._user_context, bar_dict)
File "C:\Users\being\anaconda3\lib\site-packages\rqalpha\core\execution_context.py", line 93, in exit
raise user_exc
rqalpha.utils.exception.CustomException: 'NoneType' object has no attribute 'open'
[2019-01-21 00:00:00.000000] ERROR: user_system_log: 'NoneType' object has no attribute 'open'
1. RQAlpha的版本4.2.4
2. Python的版本 3.8
3. 是Windows
4. 源码如下
5. 错误堆栈日志信息
C:\Users\being\anaconda3\python.exe "D:\soft\PyCharm Community Edition 2020.2.3\plugins\python-ce\helpers\pydev\pydevd.py" --multiproc --qt-support=auto --client 127.0.0.1 --port 60340 --file D:/pythonProject/test/backTrader.py pydev debugger: process 42556 is connecting
Connected to pydev debugger (build 202.7660.27) 8000000000 2019-01-02 2019-02-01 M 6 [2020-12-30 15:02:57.120546] WARN: system_log: rqdatac 初始化失败,部分扩展 API 可能无法使用,错误信息:user auth failed! code: 202 message: 该 License 已过期。您可以访问 https://www.ricequant.com/welcome/rqdata 获取 rqdatac [2020-12-30 15:02:57.176409] WARN: user_system_log: 配置'base.benchmark'已被弃用,使用'mod.sys_analyser.benchmark'代替 [2019-01-18 15:30:00.000000] WARN: user_system_log: IC1901 已退市/交割,系统自动平仓 [2019-01-18 15:30:00.000000] WARN: user_system_log: IC1901 已退市/交割,系统自动平仓 [2019-01-18 15:30:00.000000] WARN: user_system_log: IH1901 已退市/交割,系统自动平仓 [2019-01-18 15:30:00.000000] WARN: user_system_log: IH1901 已退市/交割,系统自动平仓 [2019-01-18 15:30:00.000000] WARN: user_system_log: IF1901 已退市/交割,系统自动平仓 [2019-01-21 00:00:00.000000] ERROR: user_system_log: 策略运行产生异常 Traceback (most recent call last): File "C:\Users\being\anaconda3\lib\site-packages\rqalpha\core\strategy.py", line 99, in open_auction self._open_auction(self._user_context, bar_dict) File "D:/pythonProject/test/backTrader.py", line 166, in open_auction buy_sell_m(have_m_num, m_num, code, context) File "D:/pythonProject/test/backTrader.py", line 222, in buy_sell_m ret = buy_open(code, amount) File "C:\Users\being\anaconda3\lib\site-packages\rqalpha\core\execution_context.py", line 104, in wrapper return func(*args, kwargs) File "C:\Users\being\anaconda3\lib\site-packages\rqalpha\utils\arg_checker.py", line 440, in api_rule_check_wrapper return func(*args, *kwargs) File "C:\Users\being\anaconda3\lib\site-packages\rqalpha\utils\functools.py", line 104, in wrapper return impl(args, kwargs) File "C:\Users\being\anaconda3\lib\site-packages\rqalpha\mod\rqalpha_mod_sys_accounts\api\api_future.py", line 188, in future_buy_open return _submit_order(id_or_ins, amount, SIDE.BUY, POSITION_EFFECT.OPEN, cal_style(price, style)) File "C:\Users\being\anaconda3\lib\site-packages\rqalpha\mod\rqalpha_mod_sys_accounts\api\api_future.py", line 59, in _submit_order price = env.get_last_price(order_book_id) File "C:\Users\being\anaconda3\lib\site-packages\rqalpha\environment.py", line 149, in get_last_price return self.data_proxy.get_last_price(order_book_id) File "C:\Users\being\anaconda3\lib\site-packages\rqalpha\data\data_proxy.py", line 261, in get_last_price return float(self._price_board.get_last_price(order_book_id)) File "C:\Users\being\anaconda3\lib\site-packages\rqalpha\data\bar_dict_price_board.py", line 33, in get_last_price return self._get_bar(order_book_id).last File "C:\Users\being\anaconda3\lib\site-packages\rqalpha\model\bar.py", line 51, in
last = property(lambda self: self.open)
File "C:\Users\being\anaconda3\lib\site-packages\rqalpha\model\bar.py", line 48, in
open = property(fget=lambda self: self._tick.open)
AttributeError: 'NoneType' object has no attribute 'open'
During handling of the above exception, another exception occurred:
Traceback (most recent call last): File "C:\Users\being\anaconda3\lib\site-packages\rqalpha\main.py", line 214, in run executor.run(bar_dict) File "C:\Users\being\anaconda3\lib\site-packages\rqalpha\core\executor.py", line 52, in run self._split_and_publish(event) File "C:\Users\being\anaconda3\lib\site-packages\rqalpha\core\executor.py", line 98, in _split_and_publish self._env.event_bus.publish_event(e) File "C:\Users\being\anaconda3\lib\site-packages\rqalpha\core\events.py", line 42, in publish_event if listener(event): File "C:\Users\being\anaconda3\lib\site-packages\rqalpha\core\strategy.py", line 34, in wrapper return func(*args, **kwargs) File "C:\Users\being\anaconda3\lib\site-packages\rqalpha\core\strategy.py", line 99, in open_auction self._open_auction(self._user_context, bar_dict) File "C:\Users\being\anaconda3\lib\site-packages\rqalpha\core\execution_context.py", line 93, in exit raise user_exc rqalpha.utils.exception.CustomException: 'NoneType' object has no attribute 'open' [2019-01-21 00:00:00.000000] ERROR: user_system_log: 'NoneType' object has no attribute 'open'
Process finished with exit code 0