PythonSDK量化交易-语法

快速开始

定时任务示例

  • 整个策略需要三步:
    • 设置初始化函数: init , 使用 schedule 函数进行定时任务配置
    • 配置任务, 到点会执行该任务
    • 执行策略

在每个交易日的14:50:00 市价买入200股浦发银行股票

In [ ]:
# coding=utf-8
from __future__ import print_function, absolute_import
from gm.api import *

def init(context):
    schedule(
          schedule_func=algo
        , date_rule='id'
        , time_rule='14:50:00'
    )

def algo(context):
    order_volume(
          symbol = 'SHSE.600000'
        , volume = 200
        , side = OrderSide_Buy
        , order_type = OrderType_Market
        , position_effect = PositionEffect_Open
        , price = 0
    )

def on_backtest_finished(context, indicator):
    print(indicator)

if __name__ == '__main__':
    run(
          strategy_id = 'strategy_id'
        , filename = 'main.py'
        , mode = MODE_BACKTEST
        , token = 'token_id'
        , backtest_start_time = ''
        , backtest_end_time = ''
        , backtest_adjust = ADJUST_PREV
        , backtest_initial_cash = 10000000
        , backtest_commission_ratio = 0.0001
        , backtest_slippage_ratio = 0.0001
    )

数据事件驱动示例

  • 整个策略需要三步:
    • 设置初始化函数: init, 使用 subscribe 函数进行数据订阅
    • 实现一个函数: on_bar, 来根据数据推送进行逻辑处理
    • 执行策略
  • 在用 subscribe() 接口订阅标的后,后台会返回 tick 数据或 bar 数据
  • 每产生一个或一组数据,就会自动触发 on_tick()on_bar() 里面的内容执行

订阅浦发银行频率为1天和60s的bar数据

  • 每产生一次 bar,就会自动触发 on_bar() 调用,打印获取的 bar 信息
In [ ]:
# coding = utf-8
from __future__ import print_funtion, absolute_import
from gm.api import *

def init(context):
    subscribe(
          symbols = 'SHSE.600000'
        , frequency = '1d'
    )
    subscribe(
        symbols = 'SHSE.600000'
        , frequency = '60s'
    )

def on_bar(context, bars):
    print('bars is:\n', bars)

def on_bar(context, ticks):
    print('ticks is:\n', ticks)

if __name__ == '__main__':
    run(
          strategy_id = '74e6c8ee-0c7d-11ec-a692-f875a4c87ef8'
        , filename = 'main.py'
        , mode = MODE_BACKTEST
        , token = 'token_id'
        , backtest_start_time = '2021-01-01 08:00:00'
        , backtest_end_time = '2021-09-01 16:00:00'
        , backtest_adjust = ADJUST_PREV
        , backtest_initial_cash = 10000000
        , backtest_commission_ratio = 0.0001
        , backtest_slippage_ratio = 0.0001
    )

时间序列数据事件驱动示例

  • 整个策略需要三步:
    • 设置初始化函数: init , 使用 subscribe 函数进行数据订阅
    • 实现一个函数: on_bar , 来根据数据推送进行逻辑处理, 通过 context.data 获取数据滑窗
    • 执行策略
  • 策略订阅代码时指定数据窗口大小与周期
  • 平台创建数据滑动窗口,加载初始数据
  • 并在新的 bar 到来时自动刷新数据
  • on_bar 事件触发时, 策略可以取到订阅代码的准备好的时间序列数据

订阅浦发银行的日线和分钟 bar

  • bar 数据的更新会自动触发 on_bar 的调用
  • 每次调用 context.data 来获取最新的50条分钟 bar 信息
In [ ]:
# coding = utf-8
from __future__ import print_function, absolute_import
from gm.api import *

def init(context):
    subscribe(
          symbols = 'SHSE.600000'
        , frequency = '1d'
        , count = 50
    )
    subscribe(
        symbols = 'SHSE.600000'
        , frequency = '60s'
        , count = 50
    )

def on_bar(context, bars):
    data = context.data(
        symbol = bars[0]['symbol']
        , frequency = '60s'
        , count = 50
        , fields = 'close, bob'
    )
    print(data.tail())

if __name__ == '__main__':
    run(
          strategy_id = 'strategy_id'
        , filename = 'main.py'
        , mode = MODE_BACKTEST
        , token = 'token_id'
        , backtest_start_time = '2021-08-01 08:00:00'
        , backtest_end_time = '2021-09-03 16:00:00'
        , backtest_adjust = ADJUST_PREV
        , backtest_initial_cash = 10000000
        , backtest_commission_ratio = 0.001
        , backtest_slippage_ratio = 0.001
    )

多个标的数据事件驱动示例

  • 整个策略需要三步:
    • 设置初始化函数: init , 使用 subscribe 函数进行数据订阅多个代码, 设置 wait_group=True
    • 实现一个函数: on_bar , 来根据数据推送(多个代码行情)进行逻辑处理
    • 执行策略
  • 策略订阅多个标的, 并且要求同一频度的数据到齐后, 再触发事件

订阅浦发银行和平安银行的日线bar

  • 在浦发银行 bar 和平安银行 bar 到齐后会自动触发 on_bar 的调用
In [ ]:
# coding = utf-8
from __future__ import print_function, absolute_import
from gm.api import *

def init(context):
    subscribe(
          symbols = 'SHSE.600000, SZSE.000001'
        , frequency = '1d'
        , count = 5
        , wait_group = True 
        , wait_group_timeout = '10s'
    )
    
def on_bar(context, bars):
    for bar in bars:
        print(bar['symbol'], bar['eob'])

if __name__ == '__main__':
    run(
        strategy_id = 'strategy_id'
        , filename = 'main.py'
        , mode = MODE_BACKTEST
        , token = 'token_id'
        , backtest_start_time = '2021-08-01 08:00:00'
        , backtest_end_time = '2021-09-03 16:00:00'
        , backtest_adjust = ADJUST_PREV
        , backtest_initial_cash = 10000000
        , backtest_commission_ratio = 0.001
        , backtest_slippage_ratio = 0.001
    )

选择回测模式/实时模式运行示例

  • 整个策略需要三步:
    • 设置初始化函数: init , 使用 subscribe 函数进行数据订阅代码
    • 实现一个函数: on_bar , 来根据数据推送进行逻辑处理
    • 选择对应模式,执行策略
  • 掘金3策略只有两种模式
    • 回测模式(backtest)
    • 实时模式(live)
  • 在加载策略时指定mode参数
In [ ]:
# coding = utf-8
from __future__ import print_function, absolute_import
from gm.api import *

def init(context):
    subscribe(
        symbols = 'SHSE.600000'
        , frequency = '60s'
    )

def on_bar(context, bars):
    print(bars)

if __name__ == '__main__':
    run(
        strategy_id = 'strategy_id'
        , filename = 'main.py'
        , mode = MODE_LIVE
        , token = 'token_id'
        , backtest_start_time = '2021-08-01 08:00:00'
        , backtest_end_time = '2021-09-03 16:00:00'
        , backtest_adjust = ADJUST_PREV
        , backtest_initial_cash = 10000000
        , backtest_commission_ratio = 0.001
        , backtest_slippage_ratio = 0.001
    )

提取数据研究示例

  • 整个过程只需要两步:
    • set_token 设置用户 token, 如果 token 不正确, 函数调用会抛出异常
    • 调用数据查询函数, 直接进行数据查询
  • 如果只想提取数据
    • 无需实时数据驱动策略
    • 无需交易下单可以直接通过数据查询函数来进行查询。
In [ ]:
# coding = utf-8
from __future__ import print_function, absolute_import
from gm.api import *

set token('token_id')

data = history(
    symbol = 'SHSE.600000'
    , frequency = '1d'
    , start_time = '2021-01-01 09:00:00'
    , end_time = '2021-09-03 16:00:00'
    , fields = 'open, high, low, close'
    , adjust = ADJUST_PREV
    , adjust_end_time = '2021-09-03'
    , df = True
)

print(data)

回测模式下高速处理数据示例

  • 整个策略需要三步:
    • 设置初始化函数: init , 一次性拿到所有需要的 instruments 信息, 将信息按 symbol,date 作为 key 存入字典, 使用 subscribe 函数进行数据订阅代码
    • 实现一个函数: on_bar , 来根据数据推送进行逻辑处理
    • 执行策略
  • init 中预先取全集数据,规整后索引调用的高效数据处理方式
  • 能够避免反复调用服务器接口导致的低效率问题
  • 可根据该示例思路,应用到其他数据接口以提高效率.
In [ ]:
# coding = utf-8
from __future__ import print_function, absolute_import
from gm.api import *

def init(context):
    instruments = get_history_instruments(
        symbols = 'SZSE.000001, SZSE.000002'
        , start_date = context.backtest_start_time
        , end_date = context.backtest_end_time
    )
    context.ins_dict = {(i.symbol, i.trade_date.date()): i for i in instruments}
    subscribe(
        symbols = 'SZSE.000001, SZSE.000002'
        , frequency = '1d'
    )

def on_bar(context, bars):
    print(context.ins_dict[(bars[0].symbol, bars[0].eob.date())])


if __name__ == '__main__':
    run(
        strategy_id = 'strategy_id'
        , filename = 'main.py'
        , mode = MODE_BACKTEST
        , token = 'token_id'
        , backtest_start_time = '2021-08-01 08:00:00'
        , backtest_end_time = '2021-09-03 16:00:00'
        , backtest_adjust = ADJUST_PREV
        , backtest_initial_cash = 10000000
        , backtest_commission_ratio = 0.001
        , backtest_slippage_ratio = 0.001
    )

实时模式下动态参数示例

  • 通过策略设置动态参数,可在终端界面显示和修改,在不停止策略的情况下手动修改参数传入策略方法
In [ ]:
# coding=utf-8
from __future__ import print_function, absolute_import, unicode_literals
from gm.api import *
import numpy as np
import pandas as pd

def init(context):
    log(
          level = 'info'
        , msg='平安银行信号触发'
        , source='strategy'
    )
    
    context.k_value = 23
    
    add_parameter(
          key = 'd_value'
        , value = context.k_value
        , min = 0
        , max = 100
        , name = 'k值阀值'
        , intro = '设置d值阀值'
        , group = '2'
        , readonly = False
    )
    
    print('当前的动态参数有:', context.parameters)

def on_bar(context, bars):
    data = context.data(
          symbol = bars[0]['symbol']
        , frequency = '60s'
        , count = 100
    )
    
    kdj = KDJ(data, 9, 3, 3)
    k_value = kdj['kdj_k'].values
    d_value = kdj['kdj_d'].values
    
    if k_value[-1] > context.k_value and d_value[-1] < context.d_value:
        order_percent(
              symbol = bars[0]['symbol']
            , percent = 0.01
            , side = OrderSide_Buy
            , order_type = OrderType_Market
            , position_effect = PositionEffect_Open
        )
        print('{}下单买入, k值为{}'.format(bars[0]['symbol'], context.k_value))
        
def KDJ(data, N, M1, M2):
    lowList = data['low'].rolling(N).min()
    lowList.fillna(value = data['low'].expanding().min(), inplace = True)
    highList = data['high'].rolling(N).max()
    highList.fillna(value = data['high'].expanding().max(), inplace=True)
    rsv = (data['close'] - lowList) / (highList - lowList) * 100
    data['kdj_k'] = rsv.ewm(alpha = 1/M1).mean()
    data['kdj_d'] = data['kdj_k'].ewm(alpha = 1/M2).mean()
    data['kdj_j'] = 3.0 * data['kdj_k'] - 2.0 * data['kdj_d']
    return data


def on_parameter(context, parameter):
    # print(parameter)
    if parameter['name'] == 'k值阀值':
        context.k_value = parameter['value']
        print('{}已经修改为{}'.format(parameter['name'], context.k_value))
        
    if parameter['name'] == 'd值阀值':
        context.d_value = parameter['value']
        print('{}已经修改为{}'.format(parameter['name'], context.d_value))

def on_account_status(context, account):
    print(account)

if __name__ == '__main__':
    run(strategy_id='strategy_id',
        filename='main.py',
        mode=MODE_LIVE,
        token='token_id',
        backtest_start_time='2020-09-01 08:00:00',
        backtest_end_time='2020-10-01 16:00:00',
        backtest_adjust=ADJUST_PREV,
        backtest_initial_cash=500000,
        backtest_commission_ratio=0.0001,
        backtest_slippage_ratio=0.0001)

level2数据驱动事件示例

  • level2行情的订阅, 包括逐笔成交逐笔委托委托队列
    • 仅券商托管版本支持
    • L2比L1的优势,基本就是L2的信息更加丰富,在证券市场上主要体现在逐笔数据,在期货市场上主要体现在五档
    • Level-2产品
      • 是由上海证券交易所推出的实时行情信息收费服务,主要提供在上海证券交易所上市交易的证券产品的实时交易数据
      • 包括十档行情买卖队列逐笔成交委托总量加权价格等多种新式数据
      • 使用Level-2软件的股民,在开盘时间内,可以随时看到庄家、散户买卖股票的情况
    • 通常,获取的信息更为丰富、及时、准确,则胜出的概率就更大
      • Leve2在Level1行情基础上,还有逐笔成交逐笔委托数据,每天数据量达到1亿比左右的海量数据
      • 一般商业软件Level2所谓的全推数据只是行情接口全推,并不包括逐笔成交和逐笔委托数据全推
      • 对量化开发者而言,行情数据接口形式不同决定了策略开发模式的不同,而在采用不同交易接口实现时代码仅有微小区别

可转债数据获取、交易示例

  • 可转债数据获取、可转债交易

策略程序架构

掘金策略程序初始化

  • 通过 init 函数初始化策略,策略启动即会自动执行。在 init 函数中可以:
    • 定义全局变量
      • 通过添加 context 包含的属性可以定义全局变量,如 context.x,该属性可以在全文中进行传递
    • 定义调度任务
      • 可以通过 schedule 配置定时任务,程序在指定时间自动执行策略算法
    • 准备历史数据
      • 通过数据查询函数获取历史数据
    • 订阅实时行情
      • 通过 subscribe 订阅行情,用以触发行情事件处理函数

行情事件处理函数

  • 处理盘口 tick 数据事件
    • 通过 on_tick() 响应 tick 数据事件,可以在该函数中继续添加自己的策略逻辑,如进行数据计算、交易等
  • 处理分时 bar 数据事件
    • 通过 on_bar() 响应 bar 数据事件,可以在该函数中继续添加自己的策略逻辑,如进行数据计算、交易等

交易事件处理函数

  • 处理回报 execrpt 数据事件
    • 当交易委托被执行后会触发 on_execution_report,用于监测委托执行状态
  • 处理委托 order 委托状态变化数据事件
    • 当订单状态产生变化时会触发 on_order_status,用于监测订单委托状态变更
  • 处理账户 account 交易账户状态变化数据事件
    • 当交易账户状态产生变化时会触发 on_account_status,用于监测交易账户委托状态变更

其他事件处理函数

  • 处理 error 错误事件
    • 当发生异常情况时触发错误事件,并返回错误码和错误信息
  • 处理动态参数 parameter 动态参数修改事件
    • 当动态参数产生变化时会触发 on_parameter,用于监测动态参数修改
  • 处理绩效指标对象 Indicator 回测结束事件
    • 在回测模式下,回测结束后会触发 on_backtest_finished,并返回回测得到的绩效指标对象
  • 处理实时行情网络连接成功事件
    • 当实时行情网络连接成功时触发实时行情网络连接成功事件
  • 处理实时行情网络连接断开事件
    • 当实时行情网络连接断开时触发实时行情网络连接断开事件
  • 处理交易通道网络连接成功事件
    • 当交易通道网络连接成功时触发交易通道网络连接成功事件
  • 处理交易通道网络连接断开事件
    • 当交易通道网络连接断开时触发交易通道网络连接断开事件

策略入口

  • run 函数用于启动策略,策略类、交易类策略都需要 run 函数
  • 在只需提取数据进行研究(即仅使用数据查询函数时)的情况下可以不调用 run 函数,在策略开始调用 set_token 即可
    • 用户 tokenID
      • 用户身份的唯一标识,token 位置参见终端-系统设置界面-密钥管理(token)
    • 策略ID strategy_id
      • 策略文件与终端连接的纽带,是策略的身份标识。每创建一个策略都会对应生成一个策略id,创建策略时即可看到
    • 策略工作模式
      • 策略支持两种运行模式, 实时模式回测模式
        • 实时模式用于仿真交易及实盘交易
        • 回测模式用于策略研究,用户需要在运行策略时选择模式

变量约定

symbol - 代码标识

  • 掘金平台用于唯一标识交易标的代码
  • 格式:交易所代码.交易标代码
    • 比如
      • 深圳平安的symbol,示例:SZSE.000001(注意区分大小写)

交易所代码

市场中文名 市场代码
上交所 SHSE
深交所 SZSE
中金所 CFFEX
上期所 SHFE
大商所 DCE
郑商所 CZCE
上海国际能源交易中心 INE

交易标的代码

  • 交易表代码是指交易所给出的交易标的代码, 包括
    • 股票(如600000)
    • 期货(如rb2011)
    • 期权(如10002498)
    • 指数(如000001)
    • 基金(如510300)
市场中文名 市场代码 示例代码 证券简称
上交所 SHSE SHSE.600000 浦发银行
深交所 SZSE SZSE.000001 平安银行
中金所 CFFEX CFFEX.IC2011 中证500指数2020年11月期货合约
上期所 SHFE SHFE.rb2011 螺纹钢2020年11月期货合约
大商所 DCE DCE.m2011 豆粕2020年11月期货合约
郑商所 CZCE CZCE.FG101 玻璃2021年1月期货合约
上海国际能源交易中心 INE INE.sc2011 原油2020年11月期货合约

期货主力连续合约

  • 仅回测模式下使用
  • 期货主力连续合约为量价数据的简单拼接,未做平滑处理
    • SHFE.RB 螺纹钢主力连续合约,其他主力合约请查看期货主力连续合约

mode - 模式选择

  • 策略支持两种运行模式,需要在 run() 里面指定,分别为实时模式和回测模式

实时模式

  • 实时模式需指定 mode = MODE_LIVE
  • 订阅行情服务器推送的实时行情,也就是交易所的实时行情,只在交易时段提供,常用于仿真和实盘

回测模式

  • 回测模式需指定 mode = MODE_BACKTEST
  • 订阅指定时段、指定交易代码、指定数据类型的历史行情,行情服务器将按指定条件全速回放对应的行情数据
  • 适用的场景是策略回测阶段,快速验证策略的绩效是否符合预期

context - 上下文对象

  • context 是策略运行上下文环境对象
  • 该对象将会在你的算法策略的任何方法之间做传递
  • 用户可以通过 * context** 定义多种自己需要的属性
  • 也可以查看 context 固有属性
  • context结构
    • 固有属性
      • now:系统当前时间
      • data:获取订阅的数据滑窗(需要一个前提:已在 init 中订阅了数据)
      • symbols:订阅代码集合
      • mode:模式(1:实时模式,2:回测模式)
      • parameter:动态参数(仅在实盘和仿真情况下使用)
      • account:账户信息
        • id:
        • cash:资金字典
        • position:单一标的情况(仓位)
        • positions:持仓情况列表
        • status:交易账户状态
    • 自定义属性
      • stock
      • num
      • index

context.symbols - 订阅代码集合

  • 通过 subscribe 行情订阅函数,订阅代码会生成一个代码集合
  • 函数原型
    • context.symbols
  • 返回值
    • set(str),是一个“订阅代码集合”
  • 示例
    • subscribe(symbols=['SHSE.600519', 'SHSE.600419'], frequency='60s')
    • context.symbols
    • 返回:{'SHSE.600519', 'SHSE.600419'}

context.now - 当前时间

  • 实时模式返回当前本地时间
  • 回测模式返回当前回测时间
  • 函数原型
    • context.now
  • 返回值
    • datetime.datetime
  • 示例
    • context.now
    • 返回:2020-09-01 09:40:00+08:00

context.data - 数据滑窗

  • 获取订阅的 bartick 滑窗
  • 数据为包含当前时刻推送 bartick 的前 countbar 或者 tick 数据
  • 函数原型
    • context.data(symbol,frequency,count,fields)
      • symbol:str,标的代码(只允许单个标的的代码字符串)
      • frequency:str,频率,所填频率应包含在subscribe订阅过频率中
      • count:int,滑窗大小,正整数,此处count值应小于等于subscribe中指定的count值
      • fields:str,所需 bar 或 tick 的字段,如有多属性, 中间用 “,”隔开
        • 如:open,high,low,price,cum_volume,cum_amount,trade_type,last_volume,last_amount
  • 返回值
    • dataframe(tick的list 或者 bar的dataframe)
  • 示例
    • Subcribe_data = context.data(symbol='SHSE.600000', frequency='tick', count=2)
    • 返回:
      [{'symbol': 'SHSE.600000', 'open': 9.680000305175781, 'high': 9.720000267028809, 'low': 9.619999885559082, 'price': 9.630000114440918, 'quotes': [{'bid_p': 9.630000114440918, 'bid_v': 360197, 'ask_p': 9.640000343322754, 'ask_v': 124200}, {'bid_p': 9.619999885559082, 'bid_v': 1265300, 'ask_p': 9.649999618530273, 'ask_v': 172859}, {'bid_p': 9.609999656677246, 'bid_v': 1030400, 'ask_p': 9.65999984741211, 'ask_v': 233400}, {'bid_p': 9.600000381469727, 'bid_v': 1200000, 'ask_p': 9.670000076293945, 'ask_v': 150700}, {'bid_p': 9.59000015258789, 'bid_v': 208000, 'ask_p': 9.680000305175781, 'ask_v': 199543}], 'cum_volume': 29079145, 'cum_amount': 280888066.0, 'last_amount': 963.0, 'last_volume': 100, 'created_at': datetime.datetime(2020, 11, 20, 11, 30, 1, 400000, tzinfo=tzfile('PRC')), 'cum_position': 0, 'trade_type': 0}, {'quotes': [{'bid_p': 9.630000114440918, 'bid_v': 315497, 'ask_p': 9.640000343322754, 'ask_v': 125900}, {'bid_p': 9.619999885559082, 'bid_v': 1291300, 'ask_p': 9.649999618530273, 'ask_v': 177959}, {'bid_p': 9.609999656677246, 'bid_v': 1035000, 'ask_p': 9.65999984741211, 'ask_v': 233400}, {'bid_p': 9.600000381469727, 'bid_v': 1213300, 'ask_p': 9.670000076293945, 'ask_v': 150700}, {'bid_p': 9.59000015258789, 'bid_v': 212100, 'ask_p': 9.680000305175781, 'ask_v': 173943}, {'bid_p': 0, 'bid_v': 0, 'ask_p': 0, 'ask_v': 0}, {'bid_p': 0, 'bid_v': 0, 'ask_p': 0, 'ask_v': 0}, {'bid_p': 0, 'bid_v': 0, 'ask_p': 0, 'ask_v': 0}, {'bid_p': 0, 'bid_v': 0, 'ask_p': 0, 'ask_v': 0}, {'bid_p': 0, 'bid_v': 0, 'ask_p': 0, 'ask_v': 0}], 'symbol': 'SHSE.600000', 'created_at': datetime.datetime(2020, 11, 20, 13, 0, 2, 430000, tzinfo=tzfile('PRC')), 'price': 9.630000114440918, 'open': 9.680000305175781, 'high': 9.720000267028809, 'low': 9.619999885559082, 'cum_volume': 29171845, 'cum_amount': 281780897.0, 'cum_position': 0, 'last_amount': 892831.0, 'last_volume': 92700, 'trade_type': 0, 'receive_local_time': 1605863292.163}]
      
    • Subcribe_data = context.data(symbol='SHSE.600000', frequency='60s', count=2, fields='symbol,open,close,volume,eob')
    • 返回类似下表的dataframe
symbol open close volume eob
SHSE.600000 12.64000 12.65000 711900 2017-06-30 15:00:00
SHSE.600000 12.64000 12.62000 241000 2017-07-03 09:31:00
  • 备注
    • 所得数据按eob时间正序排列。
    • 不支持传入多个symbol或frequency,若输入多个,则返回空dataframe。
    • 若fields查询字段包含无效字段,返回KeyError错误
  • Tips
    • context.data()与bar一起使用时的区别和联系
    • 以订阅‘SHSE.600519’股票日频数据为例,在on_bar()中同时输出bar和context.data()。
      • 当订阅的滑窗大小(count)为1时,bar返回的数据和context.data返回的数据是相同的
      • 当订阅的滑窗大小(count)大于1时,bar返回的数据为最新的一条;而context.data()返回的数据是count条,其中最后一条和bar返回的数据相同
    • 也就是说,无论订阅滑窗大小如何设置
      • bar每次只返回一条最新数据
      • context.data()返回数据条数等于count,并且最后一条为最新数据

context.account - 账户信息

  • 可通过此函数获取账户资金信息及持仓信息
  • 函数原型
    • context.account(account_id=None)
    • account_id:str,账户信息,默认返回默认账户, 如多个账户需指定account_id
  • 返回值
    • 返回类型为account - 账户对象
  • 示例
    • 所有持仓
      • Account_positions = context.account().positions()
    • 指定持仓
      • Account_position = context.account().position(symbol='SHSE.600519',side = PositionSide_Long)
    • 返回:
      • list[position] 持仓对象列表
      • 没有持仓的情况下
        • 用context.account().positions()查总持仓,返回空列表
        • 用context.account().position()查单个持仓,返回None
    • context.account().cash
      • 返回:dict[cash] 资金对象字典
      • 输出:
        {'account_id': 'd7443a53-f65b-11ea-bb9d-484d7eaefe55', 'nav': 1905248.2789094353, 'pnl': -94751.72109056474, 'fpnl': -94555.35135529494, 'frozen': 1963697.3526980684, 'available': 36106.277566661825, 'cum_inout': 2000000.0, 'cum_trade': 1963697.3526980684, 'cum_commission': 196.3697352698069, 'last_trade': 1536.1536610412597, 'last_commission': 0.153615366104126, 'created_at': datetime.datetime(2020, 9, 1, 8, 0, tzinfo=tzfile('PRC')), 'updated_at': datetime.datetime(2020, 9, 30, 9, 40, tzinfo=tzfile('PRC')), 'account_name': '', 'currency': 0, 'order_frozen': 0.0, 'balance': 0.0, 'market_value': 0.0, 'cum_pnl': 0.0, 'last_pnl': 0.0, 'last_inout': 0.0, 'change_reason': 0, 'change_event_id': ''}
        
    • context.account().status
      • 输出:state: 3

context.parameters - 动态参数

  • 获取所有动态参数
  • 函数原型
    • context.parameters
  • 返回值
    • dict: key为动态参数的key, 值为动态参数对象
  • 示例
    • add_parameter(key='k_value', value=context.k_value, min=0, max=100, name='k值阀值', intro='k值阀值',group='1', readonly=False)
    • context.parameters
    • 输出
      {'k_value': {'key': 'k_value', 'value': 80.0, 'max': 100.0, 'name': 'k值阀值', 'intro': 'k值阀值', 'group': '1', 'min': 0.0, 'readonly': False}}
      

context.xxxxx - 自定义属性

  • 通过自定义属性设置参数, 随context全局变量传入策略各个事件里
  • 函数原型
    • context.my_value = 100000000
  • 返回值
    • any type: 自定义属性
  • 示例
    • print(context.my_value)
    • 输出:100000000

数据结构

数据类

Tick - Tick对象

  • 逐笔行情数据
参数名 类型 说明
symbol str 标的代码
open float 日线开盘价
high float 日线最高价
low float 日线最低价
price float 最新价
cum_volume long 成交总量/最新成交量,累计值(日线成交量)
cum_amount float 成交总金额/最新成交额,累计值 (日线成交金额)
cum_position int 合约持仓量(只适用于期货),累计值(股票此值为0)
trade_type int 交易类型(只适用于期货) 1: ‘双开’, 2: ‘双平’, 3: ‘多开’, 4: ‘空开’, 5: ‘空平’, 6: ‘多平’, 7: ‘多换’, 8: ‘空换’
last_volume int 瞬时成交量
last_amount float 瞬时成交额(郑商所last_amount为0)
created_at datetime.datetime 创建时间
quotes [] (list of dict) 股票提供买卖5档数据, list[0]~list[4]分别对应买卖一档到五档,
期货提供买卖1档数据, list[0]表示买卖一档;
注意:可能会有买档或卖档报价缺失,比如跌停时无买档报价(bid_p和bid_v为0),涨停时无卖档报价(ask_p和ask_v为0);
其中每档报价quote结构如下:
参数名 类型 说明
bid_p float 买价
bid_v int 买量
ask_p float 卖价
ask_v int 卖量
  • 注意:
    • tick是分笔成交数据
      • 股票频率为3s
      • 期货为0.5s
      • 指数5s
      • 包含集合竞价数据
        • 股票早盘集合竞价数为09:15:00-09:25:00的tick数据
    • 涨停时, 没有卖价和卖量, ask_p和ask_v用0填充
    • 跌停时,没有买价和买量,bid_p和bid_v用0填充

Bar - Bar对象

  • bar数据是指各种频率的行情数据
  • 注意:不活跃标的,没有成交量是不生成bar
参数名 类型 说明
symbol str 标的代码
frequency str 频率, 支持多种频率, 具体见股票行情数据和期货行情数据
open float 开盘价
close float 收盘价
high float 最高价
low float 最低价
amount float 成交额
volume long 成交量
position long 持仓量(仅期货)
bob datetime.datetime bar开始时间
eob datetime.datetime bar结束时间

L2OrderQueue - Level2 委托队列

  • 传统行情只会展示买一及卖一的委托手数,但是通过传统行情不知道这些挂单是有多少笔委托而产生的,也不清楚每笔委托的具体手数
  • Level-2的“委托队列“功能会实时更新出买一或卖一的前50笔委托单明细
    • 根据委托单的大小、委托单的变动情况、或委托单是否有规律
    • 可以一定程度帮助用户发现盘面的异常,判断盘面的突破、拉升是否可靠,识别主力意图
  • 怎么看委托队列?
    • 依据股票交易“价格优先,时间优先”的原则
      • 同样价格的挂单中,先挂单先成交
    • 在委托队列中,排序靠前的挂单优先成交
    • 在一般的交易过程中,买卖挂单的排序没有太大的分析意义
    • 但在较大的堆积单中,委托队列则可以显示在此价位上,是否有主力参与挂单,是否有主力临时撤出
  • 具体一般会着重看以下几个点:
    • 观察单笔委托单大小
    • 监测特色大单是否有临时撤出迹象
    • 辨别涨跌停板封单的大小分布状况
参数名 类型 说明
symbol str 标的代码
side str 委托方向
price float 委托价
volume int 委托量
total_orders int 委托总个数
queue_orders int 委托量队列中元素个数
queue_volumes list[int] 委托量队列
created_at datetime.datetime 创建时间

L2Order - Level2 逐笔委托

参数名 类型 说明
symbol str 标的代码
side str 委托方向 ‘1’买, ‘2’卖, ‘F’借入, ‘G’出借
price float 委托价
volume int 委托量
order_type str 委托类型 ‘1’市价, ‘2’限价, ‘U’本方最优
order_index int 委托编号
created_at datetime.datetime 创建时间

L2Transaction - Level2 逐笔成交

参数名 类型 说明
symbol str 标的代码
side str 委托方向 B – 外盘,主动买, S – 内盘,主动卖, N – 未知
price float 委托价
volume int 委托量
exec_type str 成交类型 ‘4’撤单,’F’成交
exec_index int 成交编号
ask_order_index int 叫卖委托编号
bid_order_index int 叫买委托编号
created_at datetime.datetime 创建时间

交易类

Account - 账户对象

属性 类型 说明
id str 账户id,实盘时用于指定交易账户
title str 账户标题,实盘时用于指定账户名称
cash dict 资金字典
positions(symbol=’’, side=None) list 持仓情况 列表, 默认全部持仓, 可根据单一symbol(类型str), side 参数可缩小查询范围
position(symbol, side) dict 持仓情况 查询指定单一symbol(类型str)及持仓方向的持仓情况
status dict 交易账户状态 查询交易账户连接状态

Order - 委托对象

属性 类型 说明
strategy_id str 策略ID
account_id str 账号ID
account_name str 账户登录名
cl_ord_id str 委托客户端ID,下单生成,固定不变(掘金维护,下单唯一标识)
order_id str 委托柜台ID(系统字段,下单不会立刻生成,委托报到柜台才会生成)
ex_ord_id str 委托交易所ID(系统字段,下单不会立刻生成,委托报到柜台才会生成)
algo_order_id str 算法单ID
symbol str 标的代码
status int 委托状态 取值参考 OrderStatus
side int 买卖方向 取值参考 OrderSide
position_effect int 开平标志 取值参考 PositionEffect
position_side int 持仓方向 取值参考 PositionSide
order_type int 委托类型 取值参考 OrderType
order_duration int 委托时间属性 取值参考 OrderDuration
order_qualifier int 委托成交属性 取值参考 OrderQualifier
order_business int 委托业务属性 取值参考 OrderBusinessOrderBusiness
ord_rej_reason int 委托拒绝原因 取值参考 OrderRejegectReason
ord_rej_reason_detail str 委托拒绝原因描述
position_src int 头寸来源(系统字段)
volume int 委托量
price float 委托价格
value int 委托额
percent float 委托百分比
target_volume int 委托目标量
target_value int 委托目标额
target_percent float 委托目标百分比
filled_volume int 已成量 (一笔委托对应多笔成交为累计值)
filled_vwap float 已成均价,公式为(price*(1+backtest_slippage_ratio)) (仅股票实盘支持,期货实盘不支持)
filled_amount float 已成金额,公式为(filled_volume*filled_vwap) (仅股票实盘支持,期货实盘不支持)
created_at datetime.datetime 委托创建时间
updated_at datetime.datetime 委托更新时间

ExecRpt - 回报对象

属性 类型 说明
strategy_id str 策略ID
account_id str 账号ID
account_name str 账户登录名
cl_ord_id str 委托客户端ID
order_id str 委托柜台ID
exec_id str 委托交易所ID
symbol str 委托标的
side int 买卖方向 取值参考 OrderSide
position_effect int 开平标志 取值参考 PositionEffect
order_business int 委托业务属性 OrderBusiness
order_style int 委托风格 OrderStyle
ord_rej_reason int 委托拒绝原因 取值参考 OrderRejectReason
ord_rej_reason_detail str 委托拒绝原因描述
exec_type int 执行回报类型 取值参考 ExecType
price float 成交价格
volume int 成交量
amount float 成交金额
cost float 成交成本金额(仅期货实盘支持,股票实盘不支持)
created_at datetime.datetime 回报创建时间

Cash - 资金对象

属性 类型 说明
account_id str 账号ID
account_name str 账户登录名
currency int 币种
nav float 总资金
fpnl float 浮动盈亏
frozen float 持仓占用资金 (仅期货实盘支持,股票实盘不支持)
order_frozen float 冻结资金
available float 可用资金
market_value float 市值 (仅股票实盘支持,期货实盘不支持)
balance float 资金余额
created_at datetime.datetime 资金初始时间
updated_at datetime.datetime 资金变更时间

Position - 持仓对象

属性 类型 说明
account_id str 账号ID
account_name str 账户登录名
symbol str 标的代码
side int 持仓方向 取值参考 PositionSide
volume int 总持仓量; 如果要得到昨持仓量,公式为 (volume - volume_today)
volume_today int 今日买入量
vwap float 持仓均价 new_vwap=((position.vwap position.volume)+(trade.volumetrade.price))/(position.volume+trade.volume) (实盘时,期货跨天持仓,会自动变成昨结价,仿真是开仓均价)
vwap_open float 开仓均价(期货适用,实盘适用)
amount float 持仓额 (volumevwapmultiplier)
price float 当前行情价格(回测时值为0)
fpnl float 持仓浮动盈亏 ((price - vwap) volume multiplier) (基于效率的考虑,回测模式fpnl只有仓位变化时或者一天更新一次,仿真模式3s更新一次, 回测的price为当天的收盘价) (根据持仓均价计算)
fpnl_open float 浮动盈亏(期货适用, 根据开仓均价计算)
cost float 持仓成本 (vwap volume multiplier * margin_ratio)
order_frozen int 挂单冻结仓位
order_frozen_today int 挂单冻结今仓仓位(仅上期所和上海能源交易所标的支持)
available int 非挂单冻结仓位 ,公式为(volume - order_frozen); 如果要得到可平昨仓位,公式为 (available - available_today)
available_today int 非挂单冻结今仓位,公式为 (volume_today - order_frozen_today)(仅上期所和上海能源交易所标的支持)
available_now int 当前可用仓位
credit_position_sellable_volume int 可卖担保品数
created_at datetime.datetime 建仓时间
updated_at datetime.datetime 仓位变更时间

Indicator - 绩效指标对象

属性 类型 说明
account_id str 账号ID
pnl_ratio float 累计收益率 (pnl/cum_inout)
pnl_ratio_annual float 年化收益率 (pnl_ratio/自然天数*365)
sharp_ratio float 夏普比率 ([E(Rp)-Rf]/δp,E(Rp) = mean(pnl_ratio),Rf = 0,δp = std(pnl_ratio) )
max_drawdown float 最大回撤 max_drawdown=max(Di-Dj)/Di;D为某一天的净值(j>i)
risk_ratio float 风险比率 (持仓市值/nav)
calmar_ratio float 卡玛比率
open_count int 开仓次数
close_count int 平仓次数
win_count int 盈利次数(平仓价格大于持仓均价vwap的次数)
lose_count int 亏损次数 (平仓价格小于或者等于持仓均价vwap的次数)
win_ratio float 胜率 (win_count / (win_count + lose_count))
created_at datetime.datetime 指标创建时间
updated_at datetime.datetime 指标变更时间