← Назад

Работа с собственными правилами

При вызове метода StrategyRule.Activate() "изнутри" кода собственного правила не всегда вызывается прикрепленное к нему действие (.Do(MyAction)), но если перед вызовом StrategyRule.Activate() поставить задержку ~200mls, действие (MyAction) будет вызываться гарантированно. Как уйти от этой неопределенности

Комментарии (4)

Вход или Создать аккаунт, Войдите или зарегистрируйтесь, чтобы оставить комментарий

esper
esper

Покажите код, который воспроизводит эту проблему.

VassilSanych
VassilSanych

Код невозможно читать. Отформатируйте пожалуйста (шестая кнопка в редакторе сообщения).

bogoslovsvb
bogoslovsvb Автор

//Правило регистрации заявки с подтверждением ее регистрации и получения сделок
//после регистрации заявки вызывется метод Activate(_close) но прикрепленное действие активируется через раз если не ставить задержку sleep(220)
 // какие то проблемы в синхронизации ?
// версия s# - 4.0.23
        private sealed class RegisterOrderRule : StrategyRule<CloseOrder> //CloseOrder, EMAIO - собственные классы
        {
            private CloseOrder _Close;
            private bool terminated = false;
            private readonly AutoResetEvent ev = new AutoResetEvent(false);
            private Thread _thread;
            private EMAIO emaIO
            {
                get { return (EMAIO)_Close.Strat.Fantom; }
            }

            public RegisterOrderRule(CloseOrder Close)
            {
                _Close = Close;
                init();
            }

            protected override void DisposeManaged()
            {
                terminated = true;
                _isfail = true;
                _isregistry = true;
                IsNewTrade = true;
                //_Close.IsTerminate = true;
                //_Close.Strat.Trader.PositionsChanged -= PosChange;
                ev.Set();
                if (emaIO.IsTraining)
                    _Close.OnChange -= Emulate;
                foreach (var rule in rules)
                    try
                    {
                        if (_Close.Strat.Rules.FirstOrDefault(p => p == rule) != null)
                            _Close.Strat.Rules.Remove(rule);
                        rule.Dispose();
                    }
                    catch
                    {
                    }
                
                base.DisposeManaged();
            }

            public void RegisterOrder(Order order)
            {
                MethodInfo met = _Close.Strat.GetType().GetMethod("Register_Order", BindingFlags.Instance | BindingFlags.Public);
                if (met != null)
                    met.Invoke(_Close.Strat, new object[] { order });
            }

            bool IsNewTrade = false;
            bool _isregistry = false;
            bool _isfail = false;
            private readonly object sync = new object();
            List<IStrategyRule> rules = new List<IStrategyRule>();
            private void init()
            {
                if (!emaIO.IsTraining)
                {
                    //Регистрируются правила на регистрацию заявки и на получение сделок   
                    rules.Add(_Close.Strat.When(_Close.order.Registered())
                       .Do(ReactRegistry).Periodical(() => _isregistry));
                    rules.Add(_Close.Strat.When(_Close.order.RegisterFailed())
                       .Do(ReactRegistryFail).Periodical(() => _isfail));
                    IsNewTrade = false;
                    rules.Add(_Close.Strat.When(_Close.order.NewTrades())
                        .Do(ReactNewTrades).Periodical(() => IsNewTrade));
                    _Close.Strat.Trader.RegisterOrder(_Close.order);
                }
            }
            private void Actives()
            {
                lock (sync)
                    try
                    {
                        this.Activate(_Close);
                    }
                    catch
                    {
                    }
            }

            private void ReactNewTrades(IEnumerable<MyTrade> trades)
            {
                foreach (var my in trades)
                    my.ExtensionInfo.Clear();
                _Close.MyTrades = _Close.MyTrades == null ? trades.ToList() : _Close.MyTrades.Union(trades.ToList()).ToList();

                decimal sum = _Close.MyTrades.Sum(p => p.Trade.Volume);
                if (sum >= _Close.order.Volume)
                {
                    _Close.IsTerminate = true;
                    _Close.IsAbort = false;
                    IsNewTrade = true;
                    _Close.TypAction = TypeActionClose.CreateOrderInfo | TypeActionClose.CreateProfitLoss;
                    _Close.ResultTrade = TypeBalance.All;
                }
                else
                {
                    sum = 0;
                    _Close.ResultTrade = TypeBalance.Partial;
                }
                lock (syncSave)
                    try
                    {
                        _Close.IsAbort = false;
                        _Close.StatusProcess = StatusMarketOrder.Trade;
                        Actives();
                    }
                    catch (Exception ex)
                    {
                        _Close.Strat.AddErrorLog(ex);
                    }
            }
            private readonly object syncSave = new object();
            private bool _saved = false;
            private void ReactRegistry(Order order)
            {
                _isregistry = true;
                _Close.StatusProcess = StatusMarketOrder.Register;
                TimeSpan.FromMilliseconds(220).Sleep();
       //после регистрации заявки вызывется метод Activate(_close) но прикрепленное действие активируется через раз если не ставить задержку sleep(220)
       // какие то проблемы в синхронизации ?
                Actives();
            }

esper
esper

Версия 4.0.23 уже давно не поддерживается, текущая актуальная версия - 4.1.8. При переходе на 4.1 было множество изменений в правилах.

Если нет возможности перейти на последнюю версию, попробуйте упростить ваш код, т.к. в нем много различных объектов синхронизации, возможно из-за них и возникают дедлоки.