JoinQuant-PM 发布于2016-10-27
回复 76
浏览 21030
44
### 内容概述
1. 替换自己定义的函数
1. 修改变量值
2. 修改run_daily 运行时间
3. process_initialize 函数说明
### 正文
如果需要替换自定义编写的函数,直接使用新函数回测,并替换代码即可。
模拟盘替换代码之后,恢复过程如下,具体参看[模拟盘注意事项]:
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() 运行时间。
比如, 原来代码是:
```python
def initialize(context):
g.stock = '000001.XSHE'
run_daily(buy_stock, 'open')
```
现在想修改`g.stock = '000002.XSHE'`, run_daily 运行时间为 `before_open`,必须定义 after_code_changed:
```python
def after_code_changed(context):
unschedule_all()
g.stock = '000002.XSHE'
run_daily(buy_stock, 'before_open')
```
这样,程序便替换了。
-------
下面再讲讲解一下`process_initialize(context)`函数:
现在模拟交易中 initialize 函数在整个模拟盘的生命周期中只执行一次,重启后不再执行,而一些初始化的数据不能被通过pickle序列化, 在模拟交易时进程重启后会丢失状态。因此我们构建了该函数。
[process_initialize] 函数会在每次模拟盘/回测进程重启时执行, **一般用来初始化一些不能持久化保存的内容.(如 get_fundamentals 中的 query 对象)**
执行顺序是在 initialize 后执行.
因为模拟盘会每天重启, 所以这个函数会每天都执行.
**示例:**
```python
def process_initialize(context):
# query 对象不能被 pickle 序列化, 所以不能持久保存, 所以每次进程重启时对它初始化
# 以两个下划线开始, 系统序列化 [g] 时就会自动忽略这个变量, 更多信息, 请看 [g] 和 [模拟盘注意事项]
g.__q = query(valuation
).filter(valuation.code == '000001.XSHE'
))
def handle_data(context, data):
get_fundamentals(g.__q)
```
这样,g.__q 每天都会被初始化一遍,在 handle_data 中调用 get_fundamentals 不会出错。
[after_code_changed]: https://www.joinquant.com/api#after_code_changed
[unschedule_all]: https://www.joinquant.com/api#unschedule_all
[process_initialize]: https://www.joinquant.com/api#process_initialize
[盘注意事项]: https://www.joinquant.com/api#模拟盘注意事项
评论
如果修改程度很大怎么办?不能添加全局变量吗?
2016-10-28
@WeQuant_chrisCY 修改和全局变量没关系
2016-10-28
@JoinQuant-PM 我的意思是模拟盘更新代码后,新的全局变量不能用,是不是只能初始化一次的原因?
2016-10-28
@WeQuant_chrisCY 这个我文章讲的很清楚,initialize 只运行一会。因此你修改的代码是在initialize 中加入新的全局变量没有用。
针对initialize 只启动一次的情况,才引入了 after_code_changed 和 process_initialize ,具体看你情况。是要重新初始化一会,还是每天都要初始化。前者应 after_code_changed ,后者用process_initialize
2016-10-28
@JoinQuant-PM 哦,我明白了,谢谢啊!
2016-10-28
问题已经解决。(由于无法删除,只能用这段说明覆盖老内容。)
2016-10-30
如果在研究中写一个class, 在策略中导入,模拟交易开启时,更改研究中的代码,会在模拟交易中生效吗,及时生效还是第二天生效
2016-11-23
看你是何时读入这个文件了呗
你要卸载inti里,那只会读取一次。
2016-11-24
@JoinQuant-PM 使用get_index_stocks(index_symbol, date=None) 接口,只能选取成份股,不是成份股的股票怎么没有了??
比如,读取中小板的全部股票,而不是仅仅中小板指包含的成份股股票
比如,读取创业板的全部股票,而不是仅仅创业板指包含的成份股股票
比如,读取上证板块的全部股票,而不是仅仅上证指包含的成份股股票
2017-03-03
@哥布林 这个函数就是获取指数成分股的股票,功能就是做这个用的。
创业板你可以判断下300开头的。
中小板不知道你如何定义,咱不晓得如何取。
上证取000002.XSHG,或者全股票取出来在判断一下开头或者结尾就可以了。
参看一下信息:
https://www.joinquant.com/api#getallsecurities-获取所有标的信息
https://www.joinquant.com/post/912?tag=python
2017-03-03
在模拟交易中怎么获取实时的股票价格信息?
2017-03-13
@KT基金 按天频率的话,使用get_current_data()获取开盘价即可,因为我们是开盘撮合,所以开盘价就是最新价。
按分钟频率的话,获取上一分钟的close即可,因为程序是在每一分钟的开始执行
2017-03-13
@JoinQuant-PM 你好,咨询个问题哈。我在聚宽上自己的模拟交易昨天开始不运行了,也没有推送消息。经查看,并不是程序错误退出了。昨天13日的行情也没更新,请问咋回事呢?
2017-03-14
@martin2350 昨天上午数据同步出现了一些问题。这个问题昨天中午就修复了。
今天有数据么?
2017-03-14
@JoinQuant-PM 其中一个已经有数据了,但是另外两个没数据。两个没数据的模拟交易现在是空仓跑的,是不是跟这个有关系?
2017-03-14
@martin2350 应该是你策略没有交易。
2017-03-14
@martin2350 只要在发生买卖的时候才会推送消息。
2017-03-14
建议加一下:替换代码后,修改了代码中的import的py文件名称,放在哪里会在下个周期执行
2017-03-25
@蛋蛋-zy 需要reload一下
2017-03-25