空口无凭,用数据说话,你可以自己检验各种逆回购策略的历史收益率。
比如说下面这段代码,可以自动进行沪深两市一天期国债逆回购的交易,在收盘之前,或下午 4 点钟之前,自动进行国债逆回购,用闲余资金理财获取收益。
如果你想知道这样交易能不能赚钱,或者每年能赚几个点,别人说的都没用,自己去回测。
如果你认为回测1年、2年,得到的结果难以令人信服,可能包含了偶然因素,
那么通过简单的修改参数,就可以完成回测5年、10年。
如果你也想尝试一下国债逆回购策略回测,
可以直接回复“QMT”, 零门槛获取的量化交易策略终端!!!
# 比较沪深两市的一天期的买一国债逆回购,选择值大的进行卖出
def place_order_based_on_asset(xt_trader, acc, xtdata):
# 检查连接结果
connect_result = xt_trader.connect()
if connect_result == 0:
print('连接成功')
try:
# 查询证券资产
asset = xt_trader.query_stock_asset(acc)
print("证券资产查询保存成功, 可用资金:", asset.cash)
# 判断可用资金是否足够
if asset.cash >= 1000:
# 根据资产计算订单量
order_volume = int(asset.cash / 1000) * 10
# 获取市场数据以确定股票代码和价格
xtdata.subscribe_quote('131810.SZ', period='tick', start_time='', end_time='', count=1, callback=None)
xtdata.subscribe_quote('204001.SH', period='tick', start_time='', end_time='', count=1, callback=None)
generate_func = xtdata.get_market_data(field_list=['bidPrice'], stock_list=['131810.SZ','204001.SH'], period='tick', start_time='', end_time='', count=-1, dividend_type='none', fill_data=True)
# 提取 '131810.SZ' 和 '204001.SH' 的最后一个 bidPrice
price_131810 = generate_func['131810.SZ']['bidPrice'][-1][0]
price_204001 = generate_func['204001.SH']['bidPrice'][-1][0]
# 根据价格选择股票代码和价格
if price_131810 >= price_204001:
stock_code, price = '131810.SZ', price_131810
else:
stock_code, price = '204001.SH', price_204001
# 下达股票订单
xt_trader.order_stock(
acc,
stock_code,
xtconstant.STOCK_SELL,
order_volume,
xtconstant.FIX_PRICE,
price,
'国债逆回购策略',
''
)
print(f"成功下达订单,股票代码:{stock_code},价格:{price},订单量:{order_volume}。")
else:
print("可用资金不足,不进行交易")
except Exception as e:
print("下达订单时出现错误:", e)
else:
print('连接失败')
当你对简单策略有所了解之后,就可以尝试逻辑复杂一些的策略,并且在基础上进行参数调整,尝试能否带来更高的收益
# encoding:gbk
import logging
from datetime import datetime, timedelta
from decimal import Decimal as D
from decimal import InvalidOperation
logging.basicConfig(level=logging.INFO)
# 挂单失败后的等待时长,以秒计
TIMEOUT_ON_FAIL_SEC = 30
# 等待account_callback的时长
# RUN_TIME_DELAY = 30
# how is this not defined in package??
MORNING_START = datetime.strptime(datetime.now().strftime('%Y%m%d') + '093000', '%Y%m%d%H%M%S')
MORNING_END = datetime.strptime(datetime.now().strftime('%Y%m%d') + '113000', '%Y%m%d%H%M%S')
NOON_START = datetime.strptime(datetime.now().strftime('%Y%m%d') + '130000', '%Y%m%d%H%M%S')
NOON_END = datetime.strptime(datetime.now().strftime('%Y%m%d') + '153000', '%Y%m%d%H%M%S')
# for SH only
TRANS_COST_1D = D('5e-6')
TRANS_COST_LONG = D('1.5e-7')
TRANS_COST_MAX = 100
# ORDER LIMITS
SH_UPPER = 1e7
SH_LOWER = 1e5
SZ_UPPER = 1e8
SZ_LOWER = 1e3
# ASSET NAME DICT
SH_REV_REPO = {'上交所1天': '204001.SH', '上交所2天': '204002.SH', '上交所3天': '204003.SH',
'上交所4天': '204004.SH', '上交所7天': '204007.SH', '上交所14天': '204014.SH',
'上交所28天': '204028.SH', '上交所91天': '204091.SH', '上交所182天': '204182.SH',
}
SZ_REV_REPO = {'深交所3天': '131800.SZ', '深交所7天': '131801.SZ', '深交所14天': '131802.SZ',
'深交所28天': '131803.SZ', '深交所91天': '131805.SZ', '深交所182天': '131806.SZ',
'深交所4天': '131809.SZ', '深交所1天': '131810.SZ', '深交所2天': '131811.SZ',
}
def init(ContextInfo):
ContextInfo.accID = account
ContextInfo.set_account(ContextInfo.accID)
ContextInfo.use_all_cap = False if ALL_CAP == '否' else True
# global trading control, set to False if detected error on user's side
# stop() does not halt strat
ContextInfo.order_control = False
if not ContextInfo.use_all_cap:
try:
ContextInfo.dollar_vol = float(D(DOLLAR_VOL))
except InvalidOperation:
ContextInfo.order_control = True
raise ValueError('读取资金量失败')
else:
if DOLLAR_VOL != '':
logging.warning('已设定使用全部账户资金,忽略所设置资金量')
try:
ContextInfo.start_time = datetime.strptime(datetime.now().strftime('%Y%m%d') + str(START_TIME), '%Y%m%d%H%M%S')
ContextInfo.asset_name = SH_REV_REPO[ASSET_NAME]
except KeyError:
ContextInfo.asset_name = SZ_REV_REPO[ASSET_NAME]
except ValueError as error:
if 'unconverted data remains' in str(error):
ContextInfo.order_control = True
raise ValueError('读取挂单时间失败')
if not (MORNING_END > ContextInfo.start_time >= MORNING_START) \
and not (NOON_END > ContextInfo.start_time >= NOON_START):
ContextInfo.order_control = True
raise ValueError('挂单时间不在可交易时间内')
ContextInfo.can_order = False
ContextInfo.order_done = False
if not ContextInfo.order_control:
ContextInfo.run_time("place_order", "{0}nSecond".format(TIMEOUT_ON_FAIL_SEC),
ContextInfo.start_time.strftime('%Y-%m-%d %H:%M:%S'), 'SH')
def account_callback(ContextInfo, accountInfo):
if not ContextInfo.can_order:
ContextInfo.can_order = True
if ContextInfo.use_all_cap:
ContextInfo.dollar_vol = accountInfo.m_dAvailable
else:
if ContextInfo.dollar_vol > accountInfo.m_dAvailable:
ContextInfo.order_control = True
raise ValueError('下单额度大于账户可用资金')
# check if order satisfies lower limit for each exchange
if ('SH' in ContextInfo.asset_name and ContextInfo.dollar_vol < SH_LOWER) \
or ('SZ' in ContextInfo.asset_name and ContextInfo.dollar_vol < SZ_LOWER):
ContextInfo.order_control = True
raise ValueError('下单额度低于交易所最低限额')
# checks dollar_vol and rounds the total amount
if 'SH' in ContextInfo.asset_name and ContextInfo.dollar_vol % SH_LOWER != 0:
ContextInfo.dollar_vol = (ContextInfo.dollar_vol // SH_LOWER) * SH_LOWER
logging.warning('下单额度已规整为:{0}'.format(ContextInfo.dollar_vol))
elif 'SZ' in ContextInfo.asset_name and ContextInfo.dollar_vol % SZ_LOWER != 0:
ContextInfo.dollar_vol = (ContextInfo.dollar_vol // SZ_LOWER) * SZ_LOWER
logging.warning('下单额度已规整为:{0}'.format(ContextInfo.dollar_vol))
'''
if 'SH' in ContextInfo.asset_name:
num_batch_order = int(ContextInfo.dollar_vol // SH_UPPER)
remain_order = ContextInfo.dollar_vol - num_batch_order * SH_UPPER
if ContextInfo.asset_name == '204001.SH':
transaction_cost = TRANS_COST_MAX * num_batch_order + remain_order * TRANS_COST_1D
else:
transaction_cost = TRANS_COST_MAX * num_batch_order + remain_order * TRANS_COST_LONG
if transaction_cost + ContextInfo.dollar_vol > accountInfo.m_dAvailable:
ContextInfo.order_control = True
raise ValueError('可用资金不足以垫付交易金额与手续费')
'''
ContextInfo.remain_vol = ContextInfo.dollar_vol
def handlebar(ContextInfo):
return
def place_order(ContextInfo):
if not ContextInfo.can_order or ContextInfo.order_control:
return
if not ContextInfo.order_done:
if 'SH' in ContextInfo.asset_name:
num_batch_order = int(ContextInfo.remain_vol // SH_UPPER)
remain_order = ContextInfo.remain_vol - num_batch_order * SH_UPPER
for _ in range(num_batch_order):
order_remark = '国债逆回购:尝试报单{0}元 {1}'.format(SH_UPPER, ContextInfo.asset_name)
passorder(24, 1102, ContextInfo.accID, ContextInfo.asset_name, 5, -1, SH_UPPER, order_remark, 1,
order_remark, ContextInfo)
else:
num_batch_order = int(ContextInfo.remain_vol // SZ_UPPER)
remain_order = ContextInfo.remain_vol - num_batch_order * SZ_UPPER
for _ in range(num_batch_order):
order_remark = '国债逆回购:尝试报单{0}元 {1}'.format(SZ_UPPER, ContextInfo.asset_name)
passorder(24, 1102, ContextInfo.accID, ContextInfo.asset_name, 5, -1, SZ_UPPER, order_remark, 1,
order_remark, ContextInfo)
order_remark = '国债逆回购:尝试报单{0}元 {1}'.format(remain_order, ContextInfo.asset_name)
passorder(24, 1102, ContextInfo.accID, ContextInfo.asset_name, 5, -1, remain_order, order_remark, 1,
order_remark, ContextInfo)
ContextInfo.remain_vol = 0
ContextInfo.order_done = True
def order_callback(ContextInfo, orderInfo):
curr_remark = orderInfo.m_strRemark
curr_status = orderInfo.m_nOrderStatus
if '国债逆回购' in curr_remark and ContextInfo.asset_name in curr_remark and curr_status == 57:
ContextInfo.order_done = False
# up the leftover dollar vol by failed amount
# logging.info('reported trade amount:{0}, reported_trade_volume:{1}'.format(orderInfo.m_dTradeAmount, orderInfo.m_nVolumeTotal))
# 单张100元
ContextInfo.remain_vol += orderInfo.m_nVolumeTotal * 100
if '交易时间不合法' in orderInfo.m_strCancelInfo:
ContextInfo.order_control = True
raise ValueError('国债逆回购:未能在交易时间内完成下单,停止报单。余量{0}元未报'.format(ContextInfo.remain_vol))
logging.warning('国债逆回购:报单废单,原因:\"{0}\",尝试重报'.format(orderInfo.m_strCancelInfo))
elif '国债逆回购' in curr_remark and ContextInfo.asset_name in curr_remark and curr_status == 50:
logging.info('国债逆回购:报单{0}元成功'.format(orderInfo.m_nVolumeTotal * 100))
return
类似于这个自动逆回购策略:在QMT软件中,相当多成熟策略的代码可以直接用pycharm就可以打开,没有加密的,
说一下开通量化交易的条件,仅需要在券商开户,资金量达到合规门槛既可申请免费使用。佣金费用为万0.854 ETF免5,非常厚道,有更多交易的客制化需求或者想深入了解系统可v❤️联系我:XD1996CD
如果你也想尝试一下国债逆回购策略回测,
可以直接回复“QMT”, 零门槛获取的量化交易策略终端!!!