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

ctaengine里面加上

from vnpy.trader.event import (EVENT_TICK, EVENT_ORDER, EVENT_TRADE, EVENT_POSITION, EVENT_ACCOUNT)
    #--------------------------------------------------------------------------------------
    def process_account_event(self,event: Event):
        """
        收到账户事件推送
        """
        account = event.data
        for strategy_name in self.strategies.keys():
            strategy = self.strategies[strategy_name]        
            self.call_strategy_func(strategy, strategy.on_account, account)
    #------------------------------------------------------------------------------------
    def register_event(self):
        """       
        注册事件监听
        """
        self.event_engine.register(EVENT_TICK, self.process_tick_event)
        self.event_engine.register(EVENT_ORDER, self.process_order_event)
        self.event_engine.register(EVENT_TRADE, self.process_trade_event)
        self.event_engine.register(EVENT_POSITION, self.process_position_event)
        self.event_engine.register(EVENT_ACCOUNT, self.process_account_event)

cta_strategy\template.py里面加上

    #----------------------------------------------------------------------
    @virtual
    def on_account(self, account):
        """
        账户信息推送
        """
        pass

策略里面加上

    #------------------------------------------------------------------------------------
    def on_account(self,account):  
        """
        账户信息balance:总资金, available:可用资金, commission:今日手续费,pre_balance上个交易日总资金
        """
        self.account = account
Member
avatar
加入于:
帖子: 141
声望: 57

使用账户资金比例下单回测很烂,还是固定手数的好

Administrator
avatar
加入于:
帖子: 4500
声望: 320

哈哈哈,有点鸡肋的功能是不是~~~本质上因为账户的资金情况对未来行情的预测没有任何帮助(收益),加上只是进一步增加量化交易这件事的不确定性(风向)

Member
avatar
加入于:
帖子: 141
声望: 57

把账户信息打印出来发送到手机上面还是不错的😁

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

请问下,调用onAccount method的时候,要输入一个account参数,这个参数是模拟的账号或者是实际的账号吗?就是connect setting里面那个账号吗?

Member
avatar
加入于:
帖子: 141
声望: 57

洪仁东 wrote:

请问下,调用onAccount method的时候,要输入一个account参数,这个参数是模拟的账号或者是实际的账号吗?就是connect setting里面那个账号吗?
登录的账户

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

从逻辑上来讲,变动手数的策略也是一定不行。如果你知道何时胜率*盈亏比之积高以及何时低,那你应该在高时做而在低时不做,仍然是固定手数。

Member
avatar
加入于:
帖子: 24
声望: 8

我觉得动态资金仓位最大的意义是在控制回撤,假设遇上策略短暂失效期,一直在回撤,如果是固定仓位的话,会亏到惨死,而动态仓位则会不停地降低仓位,保证你能活下来。

Member
avatar
加入于:
帖子: 24
声望: 8

用Python的交易员 wrote:

哈哈哈,有点鸡肋的功能是不是~~~本质上因为账户的资金情况对未来行情的预测没有任何帮助(收益),加上只是进一步增加量化交易这件事的不确定性(风向)

还是希望在2.0版本里能加上查看账户资金的功能。

Member
加入于:
帖子: 7
声望: 0

上弦之月 wrote:

ctaengine里面加上

#----------------------------------------------------------------------
def processAccountEvent(self,event):
    """处理账户推送"""
    account = event.dict_['data']
    for name in list(self.strategyDict.keys()):
        strategy = self.strategyDict[name]
        self.callStrategyFunc(strategy, strategy.onAccount, account)    
def registerEvent(self):
    """注册事件监听"""
    self.eventEngine.register(EVENT_ACCOUNT, self.processAccountEvent)    

ctaTemplate里面加上

#----------------------------------------------------------------------
def onAccount(self, account):
    """收到账户信息推送(必须由用户继承实现)"""
    raise NotImplementedError

策略里面加上
def onAccount(self,account):
'''账户信息account.balance:总资金, available:可用资金, commission:今日手续费,preBalance上个交易日总资金'''

    #更多参数打印(account.__dict__)
        # 发出状态更新事件
        self.putEvent()

我找到它。如何使用它来查询acount.balance

Member
avatar
加入于:
帖子: 141
声望: 57

@toku
策略里面
def onAccount(self,account):
self.balance = account.balance #账户总资金

Member
加入于:
帖子: 7
声望: 0

self.eventEngine.register ==> false . repalce with self.event_engine.register

but:

test: Trigger exception has stopped
Traceback (most recent call last):
  File "E:\WARTER\python\python.v3_portable\App\lib\site-packages\vnpy\app\cta_strategy\engine.py", line 576, in call_strategy_func
    func()
  File "E:\WARTER\python\python.v3_portable\App\lib\site-packages\vnpy\app\cta_strategy\strategies\atr_rsi_strategy.py", line 56, in on_init
    print(self.balance)
AttributeError: 'AtrRsiStrategy' object has no attribute 'balance'

my strategy script :


from vnpy.app.cta_strategy import (
    CtaTemplate,
    StopOrder,
    TickData,
    BarData,
    TradeData,
    OrderData,
    BarGenerator,
    ArrayManager,
)


class AtrRsiStrategy(CtaTemplate):
    """"""

    author = "用Python的交易员"

    atr_length = 22
    atr_ma_length = 10
    rsi_length = 5
    rsi_entry = 16
    trailing_percent = 0.8
    fixed_size = 1

    atr_value = 0
    atr_ma = 0
    rsi_value = 0
    rsi_buy = 0
    rsi_sell = 0
    intra_trade_high = 0
    intra_trade_low = 0

    parameters = ["atr_length", "atr_ma_length", "rsi_length",
                  "rsi_entry", "trailing_percent", "fixed_size"]
    variables = ["atr_value", "atr_ma", "rsi_value", "rsi_buy", "rsi_sell"]

    def __init__(self, cta_engine, strategy_name, vt_symbol, setting):
        """"""
        super(AtrRsiStrategy, self).__init__(
            cta_engine, strategy_name, vt_symbol, setting
        )
        self.bg = BarGenerator(self.on_bar)
        self.am = ArrayManager()

    def on_init(self):
        """
        Callback when strategy is inited.
        """
        self.write_log("Strategy initialization")

        self.rsi_buy = 50 + self.rsi_entry
        self.rsi_sell = 50 - self.rsi_entry

        self.load_bar(10)

        print(self.balance)

    def on_start(self):
        """
        Callback when strategy is started.
        """
        self.write_log("Strategy start")

    def on_stop(self):
        """
        Callback when strategy is stopped.
        """
        self.write_log("Strategy stop")

    def on_tick(self, tick: TickData):
        """
        Callback of new tick data update.
        """
        self.bg.update_tick(tick)

    def on_bar(self, bar: BarData):
        """
        Callback of new bar data update.
        """
        self.cancel_all()

        am = self.am
        am.update_bar(bar)
        if not am.inited:
            return

        atr_array = am.atr(self.atr_length, array=True)
        self.atr_value = atr_array[-1]
        self.atr_ma = atr_array[-self.atr_ma_length:].mean()
        self.rsi_value = am.rsi(self.rsi_length)

        if self.pos == 0:
            self.intra_trade_high = bar.high_price
            self.intra_trade_low = bar.low_price

            if self.atr_value > self.atr_ma:
                if self.rsi_value > self.rsi_buy:
                    self.buy(bar.close_price + 5, self.fixed_size)
                elif self.rsi_value < self.rsi_sell:
                    self.short(bar.close_price - 5, self.fixed_size)

        elif self.pos > 0:
            self.intra_trade_high = max(self.intra_trade_high, bar.high_price)
            self.intra_trade_low = bar.low_price

            long_stop = self.intra_trade_high * \
                (1 - self.trailing_percent / 100)
            self.sell(long_stop, abs(self.pos), stop=True)

        elif self.pos < 0:
            self.intra_trade_low = min(self.intra_trade_low, bar.low_price)
            self.intra_trade_high = bar.high_price

            short_stop = self.intra_trade_low * \
                (1 + self.trailing_percent / 100)
            self.cover(short_stop, abs(self.pos), stop=True)

        self.put_event()

    def on_order(self, order: OrderData):
        """
        Callback of new order data update.
        """
        pass

    def on_trade(self, trade: TradeData):
        """
        Callback of new trade data update.
        """

        self.put_event()

    def on_stop_order(self, stop_order: StopOrder):
        """
        Callback of stop order update.
        """
        pass

    def onAccount(self,account):
        #'''Account information account.balance: Total funds, available: Available funds, commission: Today's handling fee, preBalance last trading day total funds '''

        #More parameter printing(account.__dict__)
            # Issue a status update event
        self.balance = account.balance
        self.putEvent()
Member
avatar
加入于:
帖子: 16
声望: 0

谢谢!再请教:
我看了您的onAccount() in ctaTemplate.py 以及processAccountEvent(self,event) in catEngine,我的理解是程序会不断收到account的数据推送,然后推送到ctaTemplae里面的onAccount method,我的理解对吗?如果我们再在ctaTemplate里面, 在onAccount下面加多一行self.available=account.available,调用这个self.available,就可以实现实时的可用资金,我这样理解对吗?

另外,我如果在processAccountEvent 加入time.sleep,会不会影响到其他数据的推送和处理?
def processAccountEvent(self,event):
"""处理账户推送"""
account = event.dict_['data']
for name in list(self.strategyDict.keys()):
strategy = self.strategyDict[name]
self.callStrategyFunc(strategy, strategy.onAccount, account)
time.sleep(60)

我说影响到其他数据的推送和处理,是指我让accountEvent每个推送后休息60秒,会不会影响到tick,trade或者order 等event的及时推送?

谢谢!

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

上弦之月 wrote:

ctaengine里面加上

#----------------------------------------------------------------------
def processAccountEvent(self,event):
    """处理账户推送"""
    account = event.dict_['data']
    for name in list(self.strategyDict.keys()):
        strategy = self.strategyDict[name]
        self.callStrategyFunc(strategy, strategy.onAccount, account)    
def registerEvent(self):
    """注册事件监听"""
    self.eventEngine.register(EVENT_ACCOUNT, self.processAccountEvent)    

ctaTemplate里面加上

#----------------------------------------------------------------------
def onAccount(self, account):
    """收到账户信息推送(必须由用户继承实现)"""
    raise NotImplementedError

策略里面加上
def onAccount(self,account):
'''账户信息account.balance:总资金, available:可用资金, commission:今日手续费,preBalance上个交易日总资金'''

    #更多参数打印(account.__dict__)
        # 发出状态更新事件
        self.putEvent()

我在2.07的vnstudio中添加了这几项,在回测中还是调不到账户信息,请问2.0以后如何操作才能获取账户,谢谢!

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

回测是怎么用的哇,回测没有办法推送account事件啊

Member
avatar
加入于:
帖子: 23
声望: 9

有这么麻烦?
用这两句不行吗

# In cta strategy
if isinstance(self.cta_engine, CtaEngine):
   self.acc_dict = self.cta_engine.main_engine.engines['oms'].accounts

或者直接用get_account

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

顶顶顶顶顶顶

Member
avatar
加入于:
帖子: 84
声望: 3

其实是需要的,有时候要根据止损的大小来调整开仓数量的大小。也可以在总资金回撤的时候,减小仓位。

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

VNPY_2.7.0 加了以上的语句,在策略里无法实现如下的功能:
self.balance = account.balance
如何才能解决?

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

许方文 wrote:

有这么麻烦?
用这两句不行吗

# In cta strategy
if isinstance(self.cta_engine, CtaEngine):
   self.acc_dict = self.cta_engine.main_engine.engines['oms'].accounts

或者直接用get_account

确实这一行代码就够了😂

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

沪公网安备 31011502017034号

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