QMT vs PTrade资金更新速度|高频中如何处理

平时在手动交易中,下单委托后,再切换回去持仓页面,可以看到你的可用资金变少了。而在QMT和PTrade里面,却可能会表现得不一样。本文用代码和实盘来作对比。希望本文对量化新手有所帮助,记得收藏哦!公众号首页链接了视频号,里面也有不少的券商的Ptrade|QMT新手入门教程和进阶教程,欢迎观看。

可转债量化分析

http://www.30daydo.com/article/44619

了解量化交易程序里面的资金更新速度,无论对量化T+0日内交易(可转债,T+0 ETF),还是轮动策略调仓,都是必须的。

Ptrade

以交易逆回购为例,这也便于量化新手也可以实践,可以放心跑,不会亏钱。

代码很简单,每个tick_data行情更新时间(3秒)里打印当前的可用资金。中途买入(借出)逆回购后,看看当面打印的可用资金什么时候发生变化。

import datetime# 作者:可转债量化分析def initialize(context):
    # 初始化策略
    g.already_run = False

def handle_data(context, data):
    pass

def get_available_cash(context):
    # 读取变量protfolio里的可用资金的值
    return context.portfolio.cash

def current_time():
    return datetime.datetime.now().strftime('%H:%M:%S.%f')

def tick_data(context, data):
    log.info('可用资金{}'.format(get_available_cash(context)))
    if not g.already_run:
        g.already_run = True
        # 卖出100手 R-001
        ret = order_tick('131810.SZ', -10, priceGear='1', limit_price=None)

def on_order_response(context, trade_list):
    # 委托回调函数,有委托出现就调用此函数
    log.info('已委托下单 {}'.format(current_time()))

注意,逆回购是卖出操作,所以 order_tick('131810.SZ', -10, priceGear='1', limit_price=None) 里面操作张数是-10

放到Ptrade的实盘里执行,得到下面日志

ptrade日志

下单前可用资金为17902,程序启动后下单时间在10:41:08,卖出10张R-001,市值1000元;间隔3s后打印可用资金,在10:41:13的时候,可用资金依然是17902,此时时间已经过去了5秒;

在10:41:18打印的时候资产才发生了变化,此时可用资金为16902,此时距离下单时的10:41:08,已经过去了10秒。所以如果在高频下单时,使用读取内置的context.portfolio.cash 来获取可用资金,那就寄了。那是不是意味着Ptrade无法进行高频率的交易了呢?当然不是的,此时可以使用内置的成交主推函数来更新可用资金,后面下面再介绍。

QMT

而qmt的代码如下,把打印的可用资金的操作放到handlebar里面,它和上面的Ptrade作用一样,每隔3s执行一次。

# encoding:gbk
import datetime
# 作者:可转债量化分析

ACCOUNT = '你的账户ID'
start = True

def init(ContextInfo):
    ContextInfo.set_account(ACCOUNT)

def current_time():
    return datetime.datetime.now().strftime('%H:%M:%S.%f')


def get_available_cash(ContextInfo):
    acct_info = get_trade_detail_data(ACCOUNT, 'stock', 'account')
    return acct_info[0].m_dAvailable


def deal_callback(ContextInfo, dealInfo):
    print('before')
    print(dealInfo.m_strProductID)
    print(dealInfo.m_nDirection)
    print(dealInfo.m_dTradeAmount)
    print(dealInfo.m_nVolume)
    print(dealInfo.m_dPrice)
    print('call back --- ')
    print(current_time())

def buy_action(ContextInfo):
    opType = 24
    orderType = 1101
    accountID = ACCOUNT
    orderCode = '131810.SZ'
    prType = 11
    price = 1.8
    volume = 10
    quickTrade = 2
    passorder(opType, orderType, accountID, orderCode, prType, price, volume, quickTrade, ContextInfo)

def handlebar(ContextInfo):
    global start
    if ContextInfo.is_last_bar():

        cash = get_available_cash(ContextInfo)
        print('{} 可用资金{}'.format(current_time(),cash))
        if start:
            print('下单逆回购 131810 ')
            buy_action(ContextInfo)
            start = False

部署到QMT实盘后,执行。

得到下面的运行日志:

QMT实盘

从上面的日志看出,程序在14:35:11启动,马上使用passorder下单,卖出1000元的R-001,此时时间14:35:12,马上成交了。而可用资金在下单后的0.47秒后,14:35:12,显示少了1000元。此时的资金状态已经被更新了。

所以QMT的资金持仓更新速度要比Ptrade快出不少的,如果不是追求毫秒级别的话,这个速度足够满足大部分的轮动和T+0操作了。

虽然QMT的资金持仓更新很快,但如果你的策略是高频或偏高频运行,比如你这一个时刻刚刚买入,下一个tick来到时就要卖出,或者采用驱动成交型的网格交易,你无法知道挂单是在哪一个时刻成交的,此时也亦不能一直循环读取你的可以资金或者持仓来判断是否成交,因为这样会阻塞QMT无法进行下一步的操作(除非你本身就是一直在等待成交,成交后才进行下程序一步)。

委托、成交回调函数

Ptrade和QMT都有对应的委托成交回调函数,用于应对需要即时获取成交状态的情景下。

接口文档介绍如下 Ptrade  http://ptradeapi.com/#on_trade_response

QMT:http://qmt.ptradeapi.com/QMT_Python_API_Doc.html#deal-callback

API文档

里面就说明了,“该函数会在成交主推回调时响应,比引擎和get_trades()函数更新Order状态的速度更快,适合对速度要求比较高的策略。”

Ptrade的部分代码片段如下:

# 交易回调
def on_trade_response(context, trade_list):
    # 成交主推
    now = context.blotter.current_dt.strftime("%H:%M:%S")

    for trade_info in trade_list:
        if trade_info['order_id'] == '':
            # 不是本策略跳过
            log.info('非本策略订单')
            continue

        code = trade_info['stock_code']
        code = post_fix_convert(code)
        business_time = trade_info['business_time']
        business_amount = trade_info['business_amount']  # 这个是负数,如果卖出
        business_price = trade_info['business_price']
        g.total_cash -= business_amount # 马上更新资金状态

g.total_cash是一个全局的可用资金, 可以提前设定好,亦可以是开盘前读取一次你的账户可用资金。

每次成交的那一刻,on_trade_response这个函数就会被动触发,在这里就可以简单的更新你的资金状态了。上面的例子是最基础的更新资金。

实际可以使用其他的诸如dict或类对象来更新仓位。

代码片

上面代码是把仓位更新放到一个全局dict里面,key是股票代码,value也是一个dict,里面包含交易时间,持仓数目,价格等等。

好了,时间有限,今天的教程就到这里了,码字不易,欢迎点赞+收藏哦~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值