返回介绍

开始入门

操作指引

SDK

数据文档

常见问题

量化工具

其他

其他

快速开始

发布于 2024-06-22 12:53:28 字数 17725 浏览 0 评论 0 收藏 0

常见的策略结构主要包括 3 类,如下图所示。

用户可以根据策略需求选择相应的策略结构,具体可以参考经典策略

定时任务示例

以下代码的内容是:在每个交易日的 14:50:00 市价买入 200 股浦发银行股票:

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


def init(context):
    # 每天14:50 定时执行algo任务,
    # algo执行定时任务函数,只能传context参数
    # date_rule执行频率,目前暂时支持1d、1w、1m,其中1w、1m仅用于回测,实时模式1d以上的频率,需要在algo判断日期
    # time_rule执行时间, 注意多个定时任务设置同一个时间点,前面的定时任务会被后面的覆盖
    schedule(schedule_func=algo, date_rule='1d', time_rule='14:50:00')



def algo(context):
    # 以市价购买200股浦发银行股票, price在市价类型不生效
    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__':
    '''
        strategy_id策略ID, 由系统生成
        filename文件名, 请与本文件名保持一致
        mode运行模式, 实时模式:MODE_LIVE回测模式:MODE_BACKTEST
        token绑定计算机的ID, 可在系统设置-密钥管理中生成
        backtest_start_time回测开始时间
        backtest_end_time回测结束时间
        backtest_adjust股票复权方式, 不复权:ADJUST_NONE前复权:ADJUST_PREV后复权:ADJUST_POST
        backtest_initial_cash回测初始资金
        backtest_commission_ratio回测佣金比例
        backtest_slippage_ratio回测滑点比例
    '''
    run(strategy_id='strategy_id',
        filename='main.py',
        mode=MODE_BACKTEST,
        token='token_id',
        backtest_start_time='2020-11-01 08:00:00',
        backtest_end_time='2020-11-10 16:00:00',
        backtest_adjust=ADJUST_PREV,
        backtest_initial_cash=10000000,
        backtest_commission_ratio=0.0001,
        backtest_slippage_ratio=0.0001)

整个策略需要三步:

1、设置初始化函数: init , 使用 schedule 函数进行定时任务配置

2、配置任务, 到点会执行该任务

3、执行策略


数据事件驱动示例

在用 subscribe()接口订阅标的后,后台会返回 tick 数据或 bar 数据。每产生一个或一组数据,就会自动触发 on_tick()或 on_bar()里面的内容执行。比如以下范例代码片段,订阅浦发银行频率为 1 天和 60s 的 bar 数据,每产生一次 bar,就会自动触发 on_bar()调用,打印获取的 bar 信息:

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


def init(context):
    # 订阅浦发银行, bar频率为一天和一分钟
    # 订阅订阅多个频率的数据,可多次调用subscribe
    subscribe(symbols='SHSE.600000', frequency='1d')
    subscribe(symbols='SHSE.600000', frequency='60s')


def on_bar(context, bars):

    # 打印bar数据
    print(bars)


if __name__ == '__main__':
    '''
        strategy_id策略ID, 由系统生成
        filename文件名, 请与本文件名保持一致
        mode运行模式, 实时模式:MODE_LIVE回测模式:MODE_BACKTEST
        token绑定计算机的ID, 可在系统设置-密钥管理中生成
        backtest_start_time回测开始时间
        backtest_end_time回测结束时间
        backtest_adjust股票复权方式, 不复权:ADJUST_NONE前复权:ADJUST_PREV后复权:ADJUST_POST
        backtest_initial_cash回测初始资金
        backtest_commission_ratio回测佣金比例
        backtest_slippage_ratio回测滑点比例
    '''
    run(strategy_id='strategy_id',
        filename='main.py',
        mode=MODE_BACKTEST,
        token='token_id',
        backtest_start_time='2020-11-01 08:00:00',
        backtest_end_time='2020-11-10 16:00:00',
        backtest_adjust=ADJUST_PREV,
        backtest_initial_cash=10000000,
        backtest_commission_ratio=0.0001,
        backtest_slippage_ratio=0.0001)


整个策略需要三步:

1、设置初始化函数: init, 使用 subscribe 函数进行数据订阅

2、实现一个函数: on_bar, 来根据数据推送进行逻辑处理

3、执行策略


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

策略订阅代码时指定数据窗口大小与周期, 平台创建数据滑动窗口, 加载初始数据, 并在新的 bar 到来时自动刷新数据。

on_bar 事件触发时, 策略可以通过 context.data 取到订阅代码的准备好的时间序列数据。

以下的范例代码片段是一个非常简单的例子, 订阅浦发银行的日线和分钟 bar, bar 数据的更新会自动触发 on_bar 的调用, 每次调用context.data来获取最新的 50 条分钟 bar 信息:

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


def init(context):
    # 订阅浦发银行, bar频率为一天和一分钟
    # 指定数据窗口大小为50
    # 订阅订阅多个频率的数据,可多次调用subscribe
    subscribe(symbols='SHSE.600000', frequency='1d', count=50, format='df', fields='symbol, close, eob')
    subscribe(symbols='SHSE.600000', frequency='60s', count=50, format='df', fields='symbol, close, eob')


def on_bar(context, bars):
    # context.data提取缓存的数据滑窗, 可用于计算指标
    # 注意:context.data里的count要小于或者等于subscribe里的count,fields需要在subscribe的fields范围内
    data = context.data(symbol=bars[0]['symbol'], frequency='60s', count=50, fields='close,eob')
    # 计算均线
    data['ma5'] = data['close'].rolling(window=5).mean()
    # 打印最后5条bar数据(最后一条是最新的bar)
    print(data.tail())


if __name__ == '__main__':
    '''
        strategy_id策略ID, 由系统生成
        filename文件名, 请与本文件名保持一致
        mode运行模式, 实时模式:MODE_LIVE回测模式:MODE_BACKTEST
        token绑定计算机的ID, 可在系统设置-密钥管理中生成
        backtest_start_time回测开始时间
        backtest_end_time回测结束时间
        backtest_adjust股票复权方式, 不复权:ADJUST_NONE前复权:ADJUST_PREV后复权:ADJUST_POST
        backtest_initial_cash回测初始资金
        backtest_commission_ratio回测佣金比例
        backtest_slippage_ratio回测滑点比例
    '''
    run(strategy_id='strategy_id',
        filename='main.py',
        mode=MODE_BACKTEST,
        token='token_id',
        backtest_start_time='2020-11-01 08:00:00',
        backtest_end_time='2020-11-10 16:00:00',
        backtest_adjust=ADJUST_PREV,
        backtest_initial_cash=10000000,
        backtest_commission_ratio=0.0001,
        backtest_slippage_ratio=0.0001)

整个策略需要三步:

1、设置初始化函数: init , 使用 subscribe 函数进行数据订阅

2、实现一个函数: on_bar , 来根据数据推送进行逻辑处理, 通过 context.data 获取数据滑窗

3、执行策略


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

掘金 3 策略只有两种模式, 回测模式(backtest)与实时模式(live)。在加载策略时指定 mode 参数。

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


def init(context):
    # 订阅浦发银行的tick
    subscribe(symbols='SHSE.600000', frequency='60s')


def on_bar(context, bars):
    # 打印当前获取的bar信息
    print(bars)


if __name__ == '__main__':
    # 在终端仿真交易和实盘交易的启动策略按钮默认是实时模式,运行回测默认是回测模式,在外部IDE里运行策略需要修改成对应的运行模式
    # mode=MODE_LIVE 实时模式, 回测模式的相关参数不生效
    # mode=MODE_BACKTEST  回测模式

    '''
        strategy_id策略ID, 由系统生成
        filename文件名, 请与本文件名保持一致
        mode运行模式, 实时模式:MODE_LIVE回测模式:MODE_BACKTEST
        token绑定计算机的ID, 可在系统设置-密钥管理中生成
        backtest_start_time回测开始时间
        backtest_end_time回测结束时间
        backtest_adjust股票复权方式, 不复权:ADJUST_NONE前复权:ADJUST_PREV后复权:ADJUST_POST
        backtest_initial_cash回测初始资金
        backtest_commission_ratio回测佣金比例
        backtest_slippage_ratio回测滑点比例
    '''
    run(strategy_id='strategy_id',
        filename='main.py',
        mode=MODE_LIVE,
        token='token_id',
        backtest_start_time='2020-11-01 08:00:00',
        backtest_end_time='2020-11-10 16:00:00',
        backtest_adjust=ADJUST_PREV,
        backtest_initial_cash=10000000,
        backtest_commission_ratio=0.0001,
        backtest_slippage_ratio=0.0001)

整个策略需要三步:

1、设置初始化函数: init , 使用 subscribe 函数进行数据订阅代码

2、实现一个函数: on_bar , 来根据数据推送进行逻辑处理

3、选择对应模式,执行策略


提取数据研究示例

如果只想提取数据,无需实时数据驱动策略, 无需交易下单可以直接通过数据查询函数来进行查询。

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


# 可以直接提取数据,掘金终端需要打开,接口取数是通过网络请求的方式,效率一般,行情数据可通过subscribe订阅方式
# 设置token, 查看已有token ID,在用户-密钥管理里获取
set_token('your token_id')

# 查询历史行情, 采用定点复权的方式, adjust指定前复权,adjust_end_time指定复权时间点
data = history(symbol='SHSE.600000', frequency='1d', start_time='2020-01-01 09:00:00', end_time='2020-12-31 16:00:00',
               fields='open,high,low,close', adjust=ADJUST_PREV, adjust_end_time='2020-12-31', df=True)
print(data)

整个过程只需要两步:

1、set_token 设置用户 token, 如果 token 不正确, 函数调用会抛出异常

2、调用数据查询函数, 直接进行数据查询


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

本示例提供一种在 init 中预先取全集数据,规整后索引调用的高效数据处理方式,能够避免反复调用服务器接口导致的低效率问题,可根据该示例思路,应用到其他数据接口以提高效率.

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


def init(context):
	# 在init中一次性拿到所有需要的instruments信息
    instruments = get_history_symbol(symbol='SZSE.000001', start_date=context.backtest_start_time,end_date=context.backtest_end_time)
	# 将信息按symbol,date作为key存入字典
    context.ins_dict = {(i.symbol, i.trade_date.date()): i for i in instruments}
    subscribe(symbols='SZSE.000001', frequency='1d')

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


if __name__ == '__main__':
    '''
        strategy_id策略ID, 由系统生成
        filename文件名, 请与本文件名保持一致
        mode运行模式, 实时模式:MODE_LIVE回测模式:MODE_BACKTEST
        token绑定计算机的ID, 可在系统设置-密钥管理中生成
        backtest_start_time回测开始时间
        backtest_end_time回测结束时间
        backtest_adjust股票复权方式, 不复权:ADJUST_NONE前复权:ADJUST_PREV后复权:ADJUST_POST
        backtest_initial_cash回测初始资金
        backtest_commission_ratio回测佣金比例
        backtest_slippage_ratio回测滑点比例
    '''
    run(strategy_id='strategy_id',
        filename='main.py',
        mode=MODE_BACKTEST,
        token='token_id',
        backtest_start_time='2020-11-01 08:00:00',
        backtest_end_time='2020-11-10 16:00:00',
        backtest_adjust=ADJUST_PREV,
        backtest_initial_cash=10000000,
        backtest_commission_ratio=0.0001,
        backtest_slippage_ratio=0.0001)

整个策略需要三步:

1、设置初始化函数: init , 一次性拿到所有需要的 instruments 信息, 将信息按 symbol,date 作为 key 存入字典, 使用 subscribe 函数进行数据订阅代码

2、实现一个函数: on_bar , 来根据数据推送进行逻辑处理

3、执行策略


实时模式下动态参数示例

本示例提供一种通过策略设置动态参数,可在终端界面显示和修改,在不停止策略的情况下手动修改参数传入策略方法.

# coding=utf-8
from __future__ import print_function, absolute_import, unicode_literals
from gm.api import *
import numpy as np
import pandas as pd


'''动态参数,是指在不终止策略的情况下,掘金终端UI界面和策略变量做交互,
    通过add_parameter在策略代码里设置动态参数,终端UI界面会显示对应参数
'''


def init(context):
    # log日志函数,只支持实时模式,在仿真交易和实盘交易界面查看,重启终端log日志会被清除,需要记录到本地可以使用logging库
    log(level='info', msg='平安银行信号触发', source='strategy')
    # 设置k值阀值作为动态参数
    context.k_value = 23
    # add_parameter设置动态参数函数,只支持实时模式,在仿真交易和实盘交易界面查看,重启终端动态参数会被清除,重新运行策略会重新设置
    add_parameter(key='k_value', value=context.k_value, min=0, max=100, name='k值阀值', intro='设置k值阀值',
                  group='1', readonly=False)

    # 设置d值阀值作为动态参数
    context.d_value = 20
    add_parameter(key='d_value', value=context.d_value, min=0, max=100, name='d值阀值', intro='设置d值阀值',
                  group='2', readonly=False)

    print('当前的动态参数有', context.parameters)
    # 订阅行情
    subscribe(symbols='SZSE.002400', frequency='60s', count=120)


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))


# 计算KDJ
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__':
    '''
    strategy_id策略ID,由系统生成
    filename文件名,请与本文件名保持一致
    mode实时模式:MODE_LIVE回测模式:MODE_BACKTEST
    token绑定计算机的ID,可在系统设置-密钥管理中生成
    backtest_start_time回测开始时间
    backtest_end_time回测结束时间
    backtest_adjust股票复权方式不复权:ADJUST_NONE前复权:ADJUST_PREV后复权:ADJUST_POST
    backtest_initial_cash回测初始资金
    backtest_commission_ratio回测佣金比例
    backtest_slippage_ratio回测滑点比例
    '''
    run(strategy_id='07c08563-a4a8-11ea-a682-7085c223669d',
        filename='main.py',
        mode=MODE_LIVE,
        token='2c4e3c59cde776ebc268bf6d7b4c457f204482b3',
        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 行情的订阅, 包括逐笔成交、逐笔委托、委托队列 仅券商托管版本支持

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


def init(context):
    # 查询历史L2 Tick行情
    history_l2tick=get_history_l2ticks('SHSE.600519', '2020-11-23 14:00:00', '2020-11-23 15:00:00', fields=None,
                        skip_suspended=True, fill_missing=None,
                        adjust=ADJUST_NONE, adjust_end_time='', df=False)
    print(history_l2tick[0])

    # 查询历史L2 Bar行情
    history_l2bar=get_history_l2bars('SHSE.600000', '60s', '2020-11-23 14:00:00', '2020-11-23 15:00:00', fields=None,
                       skip_suspended=True, fill_missing=None,
                       adjust=ADJUST_NONE, adjust_end_time='', df=False)
    print(history_l2bar[0])

    # 查询历史L2 逐笔成交
    history_transactions = get_history_l2transactions('SHSE.600000', '2020-11-23 14:00:00', '2020-11-23 15:00:00', fields=None, df=False)
    print(history_transactions[0])

    # 查询历史L2 逐笔委托
    history_order=get_history_l2orders('SZSE.000001', '2020-11-23 14:00:00', '2020-11-23 15:00:00', fields=None, df=False)
    print(history_order[0])

    # 查询历史L2 委托队列
    history_order_queue = get_history_l2orders_queue('SZSE.000001', '2020-11-23 14:00:00', '2020-11-23 15:00:00', fields=None, df=False)
    print(history_order_queue[0])
    
    # 订阅浦发银行的逐笔成交数据
    subscribe(symbols='SHSE.600000', frequency='l2transaction')
    # 订阅平安银行的逐笔委托数据
    subscribe(symbols='SZSE.000001', frequency='l2order')


def on_l2order(context, order):
    # 打印逐笔成交数据
    print(order)


def on_l2transaction(context, transition):
    # 打印逐笔委托数据
    print(transition)



if __name__ == '__main__':
    '''
        strategy_id策略ID, 由系统生成
        filename文件名, 请与本文件名保持一致
        mode运行模式, 实时模式:MODE_LIVE回测模式:MODE_BACKTEST
        token绑定计算机的ID, 可在系统设置-密钥管理中生成
        backtest_start_time回测开始时间
        backtest_end_time回测结束时间
        backtest_adjust股票复权方式, 不复权:ADJUST_NONE前复权:ADJUST_PREV后复权:ADJUST_POST
        backtest_initial_cash回测初始资金
        backtest_commission_ratio回测佣金比例
        backtest_slippage_ratio回测滑点比例
    '''
    run(strategy_id='strategy_id',
        filename='main.py',
        mode=MODE_BACKTEST,
        token='token_id',
        backtest_start_time='2020-11-01 08:00:00',
        backtest_end_time='2020-11-10 16:00:00',
        backtest_adjust=ADJUST_PREV,
        backtest_initial_cash=10000000,
        backtest_commission_ratio=0.0001,
        backtest_slippage_ratio=0.0001)


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

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

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


def init(context):

    # 获取可转债基本信息,输入可转债代码即可
    infos = get_symbol_infos(sec_type1=1030, symbols='SHSE.113038', df=True)

    # 输入可转债标的代码,可以获取到历史行情
    history_data = history(symbol='SHSE.113038', frequency='60s', start_time='2021-02-24 14:50:00',
                                end_time='2021-02-24 15:30:30', adjust=ADJUST_PREV, df=True)


    # 可转债回售、转股、转股撤销,需要券商实盘环境,仿真回测不可用。
    # bond_convertible_call('SHSE.110051', 100, 0)
    # bond_convertible_put('SHSE.183350', 100, 0)
    # bond_convertible_put_cancel('SHSE.183350', 100)

    # 可转债下单,仅将symbol替换为可转债标的代码即可
    order_volume(symbol='SZSE.128041', volume=100, side=OrderSide_Buy, order_type=OrderType_Limit, position_effect=PositionEffect_Open, price=340)

    # 直接获取委托,可以看到相应的可转债委托,普通买卖通过标的体现可转债交易,转股、回售、回售撤销通过order_business字段的枚举值不同来体现。
    order_list = get_orders()

    # 订阅可转债行情。与股票无异
    subscribe(symbols='SHSE.113038', frequency='tick', count=2)


def on_tick(context, tick):
    # 打印频率为tick,可转债最新tick
    print(tick)


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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文