VeighNa量化社区
你的开源社区量化交易平台
Member
avatar
加入于:
帖子: 12
声望: 1

策略类中在def init 之前定义的list变量和在init中定义的list变量的区别是什么?

在def init 之前定义的list变量:

class stocktestStrategy(CtaTemplate):
"""基于布林通道的交易策略"""
className = 'stocktestStrategy'
author = u'dofish'
actionMark=[]

如果有两个策略使用同一个策略类:
actionMark会应为一个策略改变而同时改变

log:
{'Tora.10': <vnxtp.trader.app.ctaStrategy.strategy.strategyTest.stocktestStrategy object at 0x7f1cf9205450>}
(u'TickTest1111', 0, '510050', 'startegy in order', 'Tora.10', ['Tora.10', 0])
(u'TickTest1111', 0, '510050', 'startegy in order', 'Tora.10', ['Tora.10', 0])
(0, '601009', 46800L, [], 4, u'TickTest222', ['Tora.10', 0])
(0, '601009', 46800L, ['Tora.10'], 5, u'TickTest1111', ['Tora.10', 0])
(0, '510050', 305900L, [], 4, u'TickTest222', ['Tora.10', 0])
{'Tora.10': <vnxtp.trader.app.ctaStrategy.strategy.strategyTest.stocktestStrategy object at 0x7f1cf9205450>, 'Tora.11': <vnxtp.trader.app.ctaStrategy.strategy.strategyTest.stocktestStrategy object at 0x7f1cf9658b50>}

log中<tickTest1111>触发下单修改actionMark 这个list对象,结果同类的另外策略<u'TickTest222> actionMark同时也变更了。

Member
avatar
加入于:
帖子: 12
声望: 1

init 中定义的变量list:

def __init__(self, ctaEngine, setting):
    """Constructor"""
    super(stocktestStrategy, self).__init__(ctaEngine, setting)

    self.actionMark = [0,0]

两个同类策略就不会有干扰

log:
{'Tora.30': <vnxtp.trader.app.ctaStrategy.strategy.strategyTest.stocktestStrategy object at 0x7f40133844d0>}
(u'TickTest1111', 0, '510050', 'startegy in order', 'Tora.30', ['Tora.30', 0])
(u'TickTest1111', 0, '510050', 'startegy in order', 'Tora.30', ['Tora.30', 0])
no tick data return
(0, '510050', 1725100L, ['Tora.30'], 5, u'TickTest1111', ['Tora.30', 0])
(0, '601009', 13800L, [], 4, u'TickTest222', [0, 0])
(0, '601009', 13800L, ['Tora.30'], 6, u'TickTest1111', ['Tora.30', 0])

Member
avatar
加入于:
帖子: 12
声望: 1

而其他类型变量没有发现这种问题,只有list是发现是这样

Administrator
avatar
加入于:
帖子: 4501
声望: 321
  1. list/dict/set等数据容器,在Python中属于可变对象,与之对立的是int/float/str/bool等不可变对象。
  2. 使用类创建一个对象实例的时候,每个类中的属性,都会在实例中有一份复制。
  3. 对于可变对象,所有实例中的这个属性(也就是Python中的基础变量),都会指向类中定义的那个容器。
  4. 这样就会导致于多个策略实例之间的数据错乱,RB、IF策略都在往同一个列表中添加和读取东西。
  5. 所以需要在init函数中对这些可变对象字段重新初始化,使得每个策略实例的字段是一个只属于自己的容器。
Member
avatar
加入于:
帖子: 12
声望: 1

用Python的交易员 wrote:

  1. list/dict/set等数据容器,在Python中属于可变对象,与之对立的是int/float/str/bool等不可变对象。
  2. 使用类创建一个对象实例的时候,每个类中的属性,都会在实例中有一份复制。
  3. 对于可变对象,所有实例中的这个属性(也就是Python中的基础变量),都会指向类中定义的那个容器。
  4. 这样就会导致于多个策略实例之间的数据错乱,RB、IF策略都在往同一个列表中添加和读取东西。
  5. 所以需要在init函数中对这些可变对象字段重新初始化,使得每个策略实例的字段是一个只属于自己的容器。

老板的回答就是精辟

Member
avatar
加入于:
帖子: 28
声望: 1

具体的使用的话就是如果是 int float 这些类型的变量,在 init 前和内定义效果并无区别,但是如果是 List Dict 这些变量如果在init前定义,并在后续的函数里用 append 操作,结果是不同的 instances 也会分享相同的一个 List或Dict 的内容,简单的说就是串了,但是如果用的不是 append 操作而是直接赋值,比如 instance A:_list[0] = 1 instance B: _list[0] = 2 那么结果是两个实例的 _list[0] 并不会互相影响,这个你可以在 jupyter notebook 里玩一下试一试。实在想理解透的话可以看这个 https://stackoverflow.com/questions/7548546/python-class-attributes-and-instance-attributes 里面的回答很详细

Member
avatar
加入于:
帖子: 25
声望: 0

用Python的交易员 wrote:

  1. list/dict/set等数据容器,在Python中属于可变对象,与之对立的是int/float/str/bool等不可变对象。
  2. 使用类创建一个对象实例的时候,每个类中的属性,都会在实例中有一份复制。
  3. 对于可变对象,所有实例中的这个属性(也就是Python中的基础变量),都会指向类中定义的那个容器。
  4. 这样就会导致于多个策略实例之间的数据错乱,RB、IF策略都在往同一个列表中添加和读取东西。
  5. 所以需要在init函数中对这些可变对象字段重新初始化,使得每个策略实例的字段是一个只属于自己的容器。

那在只开了一个策略实例的情况下,如果盘后停止并关闭策略,数据是缓存在实例属性[ ] 列表中,还是缓存在类属性[ ]列表中?
应该是缓存在类列表中了吧? 停止并关闭,实例属性列表中的数据就没有了吧。。。??

Member
avatar
加入于:
帖子: 1464
声望: 105

按照正常操作,在图形界面停止策略并关闭程序,策略引擎会在停止时自动将策略Variables列表中字段对应的策略成员变量保存到json缓存文件中,在下次运行程序后启动策略时自动读取还原策略状态

Member
avatar
加入于:
帖子: 25
声望: 0

MTF wrote:

按照正常操作,在图形界面停止策略并关闭程序,策略引擎会在停止时自动将策略Variables列表中字段对应的策略成员变量保存到json缓存文件中,在下次运行程序后启动策略时自动读取还原策略状态

感谢指点~

Member
avatar
加入于:
帖子: 227
声望: 0

class trade_i(CtaTemplate):
""""""
author = "期货交易员"

parameters = []
variables = []

在策略中parameters 和variables会在各实例中共享吗

Member
avatar
加入于:
帖子: 4669
声望: 285

不会,只有类定义下的参数和变量数值会共享,但是初始化策略之后会被各个策略实例缓存的json里的数值覆盖

© 2015-2022 上海韦纳软件科技有限公司
备案服务号:沪ICP备18006526号

沪公网安备 31011502017034号

【用户协议】
【隐私政策】
【免责条款】