关闭

您正在使用的浏览器版本较低,无法支持GTJAQuant的某些特性。

为了获得更好的体验,推荐使用: Google Chrome 或者 Mozilla Firefox 或者 IE9以上

1.数据问题

1.1.数据频率:天,分种

  • 当选择天频率时, 算法在每根日线 Bar 都会运行一次,即每天运行一次。
  • 当选择分钟频率时, 算法在每根分钟 Bar 都会运行一次,即每分钟运行一次。
  • 在算法中,可以获取任何粒度的数据。

1.2单个bar时间处理事情过多,导致行情堵塞问题

  • 通过选项设置可以开启异步报单模式,调用order相关函数报单后,不会等到交易网关确认报单成功即调用成功,返回包含委托单ID的order对象,定单的后续处理都通过后续同步记录来完成。
  • 如果不确定自己函数的处理时间,可参考:https://quant.gtja.com/api#%E6%80%A7%E8%83%BD%E5%88%86%E6%9E%90

1.3 获取行情接口的情况说明

(此类函数的注意事项在API文档中有说明:https://quant.gtja.com/api#获取数据函数
- get_price - 获取历史数据:获取一支或者多只股票的行情数据,按天或者按分钟,这里请在使用时注意防止未来函数。
- 关于停牌: 因为此API可以获取多只股票的数据,可能有的股票停牌有的没有,为了保持时间轴的一致,我们默认没有跳过停牌的日期, 停牌时使用停牌前的数据填充(请看 SecurityUnitData 的 paused 属性). 如想跳过, 请使用 skip_paused=True 参数,同时只取一只股票的信息

  • get_orders/get_trades API支持部分查询
get_orders 支持按照 order_id/security/status 查询,默认不传参数时行为与原来一致,会获取当日所有订单;
def get_orders(order_id=None, security=None, status=None)  

示例用法如下:

get_orders(order_id=context.order_id)
# 根据订单id查询订单

get_orders(security='000002.XSHE')
# 查询所有标的为 000002.XSHE 的订单

get_orders(status=OrderStatus.held)
# 查询订单状态为 OrderStatus.held 的所有订单

get_orders(security='000002.XSHE', status=OrderStatus.held)
# 查询标的为 000002.XSHE 且状态为 OrderStatus.held 的所有订单;
get_trades支持按照 order_id 查询某一订单的所有成交,默认行为与原来一致,返回当日所有成交:
def get_trades(order_id=None)  

示例用法如下:
get_trades(order_id=context.order_id)
#根据订单id查询该订单的所有成交

2.持仓问题处理

2.1 清算功能(包括除权除息配股分红)

  • 每天17:00执行清算。
  • T+1交易品种,清算后所有持仓变为可用持仓(处于红股上市日前被锁定的部分除外)。
  • 未成交订单执行内部废单,冻结资金恢复。
  • 当日委托和成交归档到历史表中。
  • 处理当日除权除息配股分红的股票,分红资金划入可用资金,分红股票划入冻结持仓直到红股上市日解冻。
  • 处理当日的换股股票,换股前的持仓数量按比例折合为换股后的数量,划入换股后的持仓。

2.2 context中关于持仓的获取说明

    示例:
    def handle_data(context, data):
        # 获取账户的持仓价值
        positions_value = context.portfolio.positions_value

        # 获取仓位subportfolios[0]的可用资金
        available_cash = context.subportfolios[0].available_cash

        # 获取subportfolios[0]中多头仓位的security的持仓成本
        hold_cost = context.subportfolios[0].long_positions[security].hold_cost

3.下单接口说明

3.1 下单方式

  • 市价单
    • 5档成交剩余转撤销:买入时从“卖一”到“卖五”价格依次成交,卖出时从“买一”到“买五”价格依次成交。若无法全部成交,则剩余未匹配量自动撤销
class MarketOrderStyle(OrderStyle):
    pass
  • 限价单
    • 将用户指定的价格报入交易所,等待系统成交
class LimitOrderStyle(OrderStyle):
    def __init__(self, limit_price):
        self.limit_price = limit_price
  • 上述过程中, 如果实际价格已经涨停或者跌停, 则相对应的买单或卖单不成交, 市价单直接取消(log中有警告信息), 限价单会挂单直到可以成交.
  • 一天结束后, 所有未完成的订单会被取消

3.2 下单函数

提示:所有下单函数可以在 handle_data中 与 定时运行函数 的 time 参数为 “every_bar”, “open”, “morning”, “night” 时使用。

order - 按股数下单
order(security, amount, style=None, side='long', pindex=0)

买卖标的。调用成功后, 您将可以调用[get_open_orders]取得所有未完成的交易, 也可以调用[cancel_order]取消交易

参数
- security: 标的代码
- amount: 交易数量, 正数表示买入, 负数表示卖出
- style: 参见[order styles], None代表MarketOrder
- side: ‘long’/’short’,开空单还是多单。默认为多单,股票、基金暂不支持开空单
- pindex: 在使用set_subportfolios创建了多个仓位时,指定subportfolio 的序号, 从 0 开始, 比如 0 指定第一个 subportfolio, 1 指定第二个 subportfolio,默认为0

返回
Order对象或者None, 如果创建订单成功, 则返回Order对象, 失败则返回None

示例

#买入平安银行股票100股
order('000001.XSHE', 100) # 下一个市价单
order('000001.XSHE', 100, MarketOrderStyle()) # 下一个市价单, 功能同上
order('000001.XSHE', 100, LimitOrderStyle(10.0)) # 以10块价格下一个限价单

可能的失败原因:
1. 股票数量经调整后变成0 (请看下面的说明)
2. 股票停牌
3. 股票未上市或者退市
4. 股票不存在
5. 股票涨跌停
6. 为股票、基金开了空单
7. 选择了不存在的仓位号,如没有建立多个仓位,而设定pindex的数大于0

对于原因4, 我们会抛出异常停止运行, 因为我们认为这是您代码的bug.

注意:

  • 因为下列原因, 有时候实际买入或者卖出的股票数量跟您设置的不一样,这个时候我们会在您的log中添加警告信息。

    1. 买入时会根据您当前的现金来限制您买入的数量
    2. 卖出时会根据您持有股票的数量来限制您卖出的数量
    3. 我们会遵守A股交易规则: 每次交易数量只能是100的整数倍, 但是卖光所有股票时不受这个限制
  • 根据交易所规则, 每天结束时会取消所有未完成交易

order_target - 目标股数下单
order_target(security, amount, style=None, side='long', pindex=0)

买卖标的, 使最终标的的数量达到指定的amount

参数

  • security: 标的代码
  • amount: 期望的最终数量
  • style: 参见[order styles], None代表MarketOrder
  • side: ‘long’/’short’,平空单还是多单。默认为多单,股票、基金暂不支持开空单
  • pindex: 在使用set_subportfolios创建了多个仓位时,指定subportfolio 的序号, 从 0 开始, 比如 0为 指定第一个 subportfolio, 1 为指定第二个 subportfolio,默认为0

返回
Order对象或者None, 如果创建委托成功, 则返回Order对象, 失败则返回None

示例

# 卖出平安银行所有股票
order_target('000001.XSHE', 0)
# 买入平安银行所有股票到100股
order_target('000001.XSHE', 100)
order_value - 按价值下单
order_value(security, value, style=None, side='long', pindex=0)

买卖价值为value的股票,金融期货暂不支持该API

参数

  • security: 股票名字
  • value: 股票价值
  • style: 参见[order styles], None代表MarketOrder
  • side: ‘long’/’short’,平空单还是多单。默认为多单,股票、基金暂不支持开空单
  • pindex: 在使用set_subportfolios创建了多个仓位时,指定subportfolio 的序号, 从 0 开始, 比如 0为 指定第一个 subportfolio, 1 为指定第二个 subportfolio,默认为0

返回
Order对象或者None, 如果创建委托成功, 则返回Order对象, 失败则返回None

示例

#卖出价值为10000元的平安银行股票
order_value('000001.XSHE', -10000)
#买入价值为10000元的平安银行股票
order_value('000001.XSHE', 10000)
order_target_value - 目标价值下单
order_target_value(security, value, style=None, side='long', pindex=0)

调整股票仓位到value价值,金融期货暂不支持该API

参数

  • security: 股票名字
  • value: 期望的股票最终价值
  • style: 参见[order styles], None代表MarketOrder
  • side: ‘long’/’short’,平空单还是多单。默认为多单,股票、基金暂不支持开空单
  • pindex: 在使用set_subportfolios创建了多个仓位时,指定subportfolio 的序号, 从 0 开始, 比如 0为 指定第一个 subportfolio, 1 为指定第二个 subportfolio,默认为0

返回
Order对象或者None, 如果创建委托成功, 则返回Order对象, 失败则返回None

示例

#卖出平安银行所有股票
order_target_value('000001.XSHE', 0)
#调整平安银行股票仓位到10000元价值
order_target_value('000001.XSHE', 10000)

3.3 order接口返回的order类的信息更新问题

调用 get_orders/get_trades/get_open_orders/context.portfolio/context.subporfolio这几个接口时,如果发现有委托更新,信息才会同步更新,而不是自动同步更新。

4.其他注意事项

4.1 替换代码的问题

如果需要替换自定义编写的函数,直接使用新函数回测,并替换代码即可。

实盘盘替换代码之后,恢复过程如下:

  1. 加载策略代码, 因为python是动态语言, 编译即运行, 所以全局的(在函数外写的)代码会被执行一遍.
  2. 使用保存的状态恢复 g, context, 和函数外定义的全局变量.
  3. 执行 process_initialize, 每次启动时都会执行这个函数.
  4. 如果策略代码和上一次运行时发生了修改,而且代码中定义了 [after_code_changed] 函数,则会运行 [after_code_changed] 函数.

重启后不再执行 initialize 函数, initialize 函数在整个实盘的生命周期中只执行一次. 即使是更改回测后, initialize 也不会执行.

实盘更改回测之后上述的全局变量(包括 g 和 context 中保存的)不会丢失, run_daily() 函数依然会执行. 新代码中 initialize 不会执行.

如果需要修改原来的值, 可以在 after_code_changed 函数里面修改。

如果需要指定新的定期执行的函数, 调用 unschedule_all 清除原有 run_daily() 运行时间,再重新指定 run_daily() 运行时间。

比如, 原来代码是:

def initialize(context):
    g.stock = '000001.XSHE'
    run_daily(buy_stock, 'open')

现在想修改g.stock = '000002.XSHE', run_daily 运行时间为 before_open,必须定义 after_code_changed:

def after_code_changed(context):
    unschedule_all()
    g.stock = '000002.XSHE'
    run_daily(buy_stock, 'before_open')

这样,程序便替换了。

4.2 更改资金密码会造成策略下单失败

下单失败的可能原因
  • 如果在开启实盘状态下,用户进行密码修改操作,会引起策略的下单失败;
  • 如果在开启实盘状态下,用户在手机APP或其他地方进行了卖出操作,可能会引起策略账户信息与资金账号信息不对称,造成下单失败;
  • 如果在开启实盘状态下,用户在手机APP或其他地方进行了资金转移操作,可能会引起策略账户信息与资金账号信息不对称,造成下单失败;

4.3实盘跟模拟盘不一致的地方

实盘提供功能: 是否回放。如果不能回放, 超过时间点就不运行对应时间点应该运行的代码. 比如:before_trading_start 在 9:00 运行, 超过9:00则不运行此函数。

有两个选项:
- 是否允许回放
live_replay_enabled = False
- 限制只允许从今天回放,需与 live_replay_enabled 配合使用
live_replay_limit_today = True