请 [注册] 或 [登录]  | 返回主站

量化交易吧 /  量化平台 帖子:3365818 新帖:25

【API解析】怎样替换代码

Peace发表于:5 月 10 日 05:02回复(1)

目录

目录.JPG

1 概述

替换模拟交易的代码我们在使用模拟交易及实盘中经常遇到的一个需求,但是很多小伙伴在使用过程经常会遇到如下问题:

  • 要替换初始化中的全局变量,但是运行后,仍然是原来的值;
  • 更改了函数的代码,但是运行结果仍然不符合要求;
  • 修改了策略的运行时间,出现了多次下单或者提示。

今天通过这篇文章为大家一一解答。

2 正文

2.1 什么时候可以替换代码?

只要模拟交易是正常的,任何时间都可以替换代码

2.2 替换后什么时候生效及看到替换后的效果?

  • 替换代码之后,5分钟之后生效(一般1~2分钟即可);

  • 生效并不是马上可以看到效果,是您的策略运行时才能看到。具体什么时候可以看到效果和您替换代码的时间及策略运行频率有关,例如分钟策略在盘中替换,生效后立即可以看到替换后的效果;

  • 策略运行时生效中的策略指的是替换前的策略,时指的是原策略下一个运行时间,不是新替换代码的运行时间。例如8:00替换代码,原来策略下一个运行9:30运行,您替换代码设置9:00运行;替换后的当天策略9:00不会运行,9:30替换代码会生效,下一个交易日9:00会正常运行;

  • 盘后替换代码(15:00~16:00),会在16:00启动。

盘后更新16点启动.JPG

2.3 有关初始化函数 initialize 

例如要将初始值g.stock = '000001.XSHE'替换为g.stock = '000002.XSHE'

示例代码

# 初始化函数
def initialize(context):
    g.stock = '000001.XSHE'

# 替换初始化函数中的全局变量
def after_code_changed(context):
    g.stock = '000002.XSHE'

结论

  • 不可以替换初始化函数 initialize;
  • 替换代码后 initialize中的全局变量 g 和 context 中保存的数据仍然存在,如果要替换或者新加全局变量数据,请在after_code_changed中重新修改。

2.4 替换代码,添加一个新的运行函数

例如要运行新的函数high_limit_filter
示例代码

# 初始化函数
def initialize(context):
    g.stock = '000001.XSHE'

## >>>>>>>>>>>>>>>>>>>>>替换代码<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
# 替换初始化函数中的全局变量
def after_code_changed(context):
    run_daily(high_limit_filter, time='10:30')

## 过滤涨停股票
def high_limit_filter(context):
    print "过滤涨停股票"

结论

  • 直接在after_code_changed中添加即可。

2.5 替换代码,替换原来函数或运行时间

一定要关注after_code_changed和unschedule_all()函数

示例代码

# 初始化函数
def initialize(context):
    g.stock = '000001.XSHE'
    run_daily(high_limit_filter, time='every_bar')
    run_daily(paused_filter, time='9:30')

## 过滤涨停股票
def high_limit_filter(context):
    print "过滤涨停股票"

## 过滤停牌股票
def paused_filter(context):
    print "过滤停牌股票"
    print '-'*50

# ## >>>>>>>>>>>>>>>>>>>>>>>>替换代码<<<<<<<<<<<<<<<<<<<<<<<<<<<<
# def after_code_changed(context):
#     now = context.current_dt.time()
#     print("{0}替换了代码".format(now))
#     unschedule_all()
#     run_daily(high_limit_filter, time='every_bar')
#     run_daily(paused_filter, time='every_bar')

# ## 过滤涨停股票
# def high_limit_filter(context):
#     print "过滤涨停股票,在after_code_changed下面修改代码..."

下面分情况测试及运行。

2.5.1 取消所有的运行函数

使用场景

unschedule_all()是经常被忽略的一个方法,我们先看看在after_code_changed中使用该函数的效果。

示例代码

取消了所有的运行函数-代码.png

运行结果

取消了所有的运行函数-结果.png

结论

  • 使用unschedule_all()后,所有run_daily中的函数都不会再运行;
  • 使用unschedule_all()后,初始化中的run_daily函数需要在after_code_changed重新写一遍。

2.5.2 修改运行时间

使用场景

需要修改run_daily中函数的运行时间,例如想退后点定时运行或者每分钟都运行。

示例代码

修改运行函数-代码.png

运行结果

修改运行时间-效果.png

结论

  • 修改运行时间一定要使用unschedule_all(),不然后两个时间点都运行,可能造成多次下单等情况;
  • 再重复一遍,没有修改运行时间的函数,也需要在after_code_changed中的run_daily再写一遍,否则不运行。

2.5.3 修改运行函数

使用场景

修改运行函数中的内容。可以在原代码基础上改,也可以在after_code_change下面重新定义个同名函数。

示例代码1

修改运行函数1-代码.png

运行结果1

修改运行函数1-效果.png

示例代码2

修改运行函数2-代码.png

运行结果2

修改运行函数2-效果.png

结论

  • 在原函数及after_code_change下面重新定义个同名函数都可以可以实现修改运行函数,建议使用后者。

2.5.4 直接在原函数上替换代码

使用场景

下面是个反例,不使用unschedule_all()及after_code_change,直接在原函数修改代码或者运行时间。

示例代码

直接在原函数上替换代码-代码.png

运行结果

直接在原函数上替换代码-效果.png

结论

  • 由运行结果可以看定时运行函数失效,设置只有9:30运行,但是实际结果是每分钟都在运行;
  • 直接修改原函数,没有使用unschedule_all()及after_code_change,仍然生效,但是不建议这么做;
  • 这是个反例不要这样替换代码。

3 替换代码实战

3.1 在对应策略中编写替换代码,并运行回测

找到需要替换代码模拟交易对应的策略(生成模拟交易后切记不可以删除该策略),并在after_code_change中编写修改代码,并运行回测。找不到的话,可以在模拟交易的设置页面找到对应回测,然后对此回测点击编辑策略。

操作-1.png

3.2 打开模拟交易替换代码的页面,点击替换代码

操作-2.png

3.3 选择对应的回测替换,一般最新的回测在最上面

操作-3.png

3.4 查看替换后的代码及日志

操作-4.png

4 结论

通过上面的说明及测试结果,我们可以得到下面的结论:

  • 修改初始化变量或添加运行函数一定要使用after_code_change;
  • 修改运行时间一定要使用unschedule_all();
  • 修改运行函数,建议在after_code_change下面重写同名函数,不要直接修改原来的;
  • 使用unschedule_all()后,一定要记得把之前的run_daily(fun, time)在after_code_change中再写一遍;
  • 具体的替换步骤及相关内容,请参考下面的链接。

5 常见问题

5.1 如何通过替换代码修改模拟交易的日志

在after_code_changed中重新设置日志级别
级别.png

# 初始化函数,设定基准等等
def initialize(context):
    # 开启动态复权模式(真实价格)
    set_option('use_real_price', True)
    # 过滤掉order系列API产生的比error级别低的log
    log.set_level('order', 'error')
    # 开盘时运行
    run_daily(market_open, time='open', reference_security='000300.XSHG')

## 开盘时运行函数
def market_open(context):
    log.info('函数运行时间(market_open):' str(context.current_dt.time()))

## 替换代码,重新设置日志级别
def after_code_changed(context):
    # 将日志级别设置为info
    log.set_level('order', 'info')

5.2 发现替换后策略有重复运行

检查下是不是没有使用unschedule_all()引起的。

5.3 发现替换后策略仍然没有运行

查看下策略在替换代码前,是否暂停或者运行失败了,是的话需要点击策略右上角的重启按钮。

6 相关教程链接

官网API,模拟盘注意事项
【有用功】模拟盘替换代码注意事项
一创实盘:替换代码及注意事项

全部回复

0/140

达人推荐

量化课程

    移动端课程