每天坚持做逆回购,一年下来,年化收益能达到多少?(附代码)

空口无凭,用数据说话,你可以自己检验各种逆回购策略的历史收益率。

比如说下面这段代码,可以自动进行沪深两市一天期国债逆回购的交易,在收盘之前,或下午 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”, 零门槛获取的量化交易策略终端!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值