Cобытия по изменению состояния ордеров приходят только в режиме эмуляции

Cобытия по изменению состояния ордеров приходят только в режиме эмуляции
Atom
2/21/2013


S# 4.1.6
Работа с Quik. Брокер Уралсиб.
В режиме RealTimeEmlationTrader
ордера выставляются,
и информация о их выполнении поступает в лог,
strategy.PositionManager.Position показывает позицию.

Когда переключаюсь с эмулятора на реальный QuikTrader.
Ордер выставляется, но похоже события изменения состояния не вызываются,
соответственно strategy.PositionManager.Position показывает 0.
Может кто подать идею, в какой стороне мне копать?

И при работе через эмулятор похоже часть событий не активируется
по крайней мере NewMyTrade, но так как strategy.PositionManager.Position
обновляется работать можно.

Tags:


Thanks:


1 2  >
VassilSanych

Avatar
Date: 2/21/2013
Reply


kahuna Go to
события изменения состояния не вызываются,

На слух как-то плохо воспринимается.
Thanks:

kahuna

Avatar
Date: 2/22/2013
Reply


например событие strategy.OrderChanged.

И следующий код никогда не исполняется (то что внутри цикла foreach)
хотя ордера выставляются.
Code
_trader.NewMyTrades += myTrades => this.GuiAsync(() =>
      {
        if (_strategy != null)
        {
          // найти те сделки, которые совершила стратегия 
          myTrades = myTrades.Where(t => _strategy.Orders.Any(o => o == t.Order));

          _trades.Trades.AddRange(myTrades);
        }
        foreach (var myTrade in myTrades)
        {
          var trade = myTrade.Trade;
          Status.Text = "Сделка {0} по цене {1} по бумаге {2} по объему {3} в {4}." + 
          System.Convert.ToString(trade.Id) + System.Convert.ToString(trade.Price) +
          System.Convert.ToString(trade.Security.Code) + 
          System.Convert.ToString(trade.Volume) + System.Convert.ToString(trade.Time);
         }
       });


такое впечатление что у меня событийная модель не работает.

Попробую сделать упрощеный тестовый примерчик.
Thanks:

Moadip

Avatar
Date: 2/22/2013
Reply


Quote:
Когда переключаюсь с эмулятора на реальный QuikTrader.

Что подразумевается под "переключением"? Как вы это делаете, опишите подробнее, желательно с примером кода.
Thanks:

VassilSanych

Avatar
Date: 2/22/2013
Reply


kahuna Go to
_strategy.Orders.Any(o => o == t.Order))

Не уверен, что NewMyTrades и _strategy ссылаются на одни и те же экземпляры объектов заявок в памяти.
Thanks: kahuna

kahuna

Avatar
Date: 2/22/2013
Reply


Moadip Go to
Quote:
Когда переключаюсь с эмулятора на реальный QuikTrader.

Что подразумевается под "переключением"? Как вы это делаете, опишите подробнее, желательно с примером кода.

Если оставляю #define EMULATOR сделки совершаются и событие стратегии OrderChanged срабатывает в лог попадает сообщение "состояние ордера изменилось".
не показывает Status.Text = _strategy.ProcessState.ToString();
не показывает PnL.Content = _strategy.PnLManager.PnL;
не показывает Slippage.Content = _strategy.SlippageManager.Slippage;
показывает Position.Content = _strategy.PositionManager.Position;
не показываетLatency.Content = _strategy.Latency;


Если на реальном Quik (снят комментарий с
#undef EMULATOR) то сделки совершаются но событие OrderChanged не срабатывает.
не показывает Status.Text = _strategy.ProcessState.ToString();
не показывает PnL.Content = _strategy.PnLManager.PnL;
не показывает Slippage.Content = _strategy.SlippageManager.Slippage;
не показывает Position.Content = _strategy.PositionManager.Position;
не показывает Latency.Content = _strategy.Latency;

Основной код:
Code

#define EMULATOR
//#undef EMULATOR

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Forms;
using System.Drawing;
using System.Diagnostics;
using MessageBox = System.Windows.MessageBox;
using System.Threading;
using System.Linq;
using System.Xml;
using Xceed.Wpf.Toolkit;

using Ecng.Common;
using Ecng.Collections;
using Ecng.Xaml;
using Ecng.ComponentModel;

using StockSharp.BusinessEntities;
using StockSharp.Algo.Reporting;
using StockSharp.Quik;
using StockSharp.Algo;
using StockSharp.Algo.Candles;
using StockSharp.Xaml;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Indicators.Trend;
using StockSharp.Logging;
using StockSharp.Algo.Testing;

namespace tryBot1
{
    /// <summary>
    /// Логика взаимодействия для MainWindow.xaml
    /// </summary>

    public partial class MainWindow : Window
   {


        private ConfigFile CfgFile;

#if EMULATOR
        private RealTimeEmulationTrader<QuikTrader> _trader;
#else
        private QuikTrader _trader;
#endif

        public static MarketDepth _depth;
        private tryStrategy _strategy;
        private bool _isDdeStarted;
        private MonitorWindow monitor;
        private LogManager _logManager;

        public static bool tryBuy = false;
        public static bool trySell = false;



        public MainWindow()
        {

            InitializeComponent();

            CfgFile = new ConfigFile("c:\\tryBot1\\","config.cfg");
            monitor = new MonitorWindow();
            monitor.Show();
            _logManager = new LogManager();
            //var fileListener = new FileLogListener("{0}_{1:00}_{2:00}.txt".Put(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day));
            //logManager.Listeners.Add(fileListener);
            _logManager.Listeners.Add(new GuiLogListener(monitor));


        }

        private void Connect_Click(object sender, RoutedEventArgs e)
        {
            //устанвавливаем элемент ComboBox на значение по умолчанию
            //прочитанное ранее из config.cnf
            String DefSecurity = CfgFile.ReadParam("Security");
            String DefPortfolio = CfgFile.ReadParam("Portfolio");
            //КОНЕЦ- устанвавливаем элемент ComboBox на значение по умолчанию
            //прочитанное ранее из config.cnf
            int i = 0;
            if (_trader == null || !_trader.IsConnected)
            {
                if (_trader == null)
                {
                    if (QuikTerminal.GetDefaultPath().IsEmpty())
                    {
                        MessageBox.Show(this, "Путь к Quik не выбран.");
                        return;
                    }
                    Status.Text = "Connecting with Quck. Please wait";

                    #if EMULATOR
                        _trader = new RealTimeEmulationTrader<QuikTrader>(new QuikTrader(QuikTerminal.GetDefaultPath()));
                    #else
                        _trader = new QuikTrader(QuikTerminal.GetDefaultPath()){ IsAsyncMode = true, SupportManualOrders = false };
                        _trader.IsAsyncMode = true;
                    #endif

                        _trader.Connected += () =>
                         {


                             _trader.NewSecurities += securities => this.GuiAsync(() =>
                                {
                                    Securities1.ItemsSource = _trader.Securities;

                                    i = 0;
                                    foreach (Object item in Securities1.Items)
                                    {
                                        Securities1.SelectedIndex = i;
                                        if (item.ToString().Equals(DefSecurity))
                                        {
                                            break;
                                        }
                                        i++;
                                    }
                                    // если инструмент и стакан уже появились 
                                     if (Securities1.SelectedItem != null)
                                    {
                                        Status.Text = "Инструмент появился.";

                                    }

                                });
                             _trader.NewPortfolios += portfolios => this.GuiAsync(() =>
                                 {
                                     Portfolios.ItemsSource = _trader.Portfolios;

                                     i = 0;
                                     foreach (Object item in Portfolios.Items)
                                     {
                                         Portfolios.SelectedIndex = i;
                                         if (item.ToString().Equals(DefPortfolio))
                                         {
                                             break;
                                         }
                                         i++;
                                     }
                                 });

                             // подписываемся на событие появления моих новых сделок
                             
                             _trader.NewMyTrades += myTrades => this.GuiAsync(() =>
                             {
                                 if (_strategy != null)
                                 {
                                     // найти те сделки, которые совершила стратегия 
                                     myTrades = myTrades.Where(t => _strategy.Orders.Any(o => o == t.Order));

                                     //_trades.Trades.AddRange(myTrades);
                                 }
                                 foreach (var myTrade in myTrades)
                                 {
                                     var trade = myTrade.Trade;
                                     Status.Text = "Сделка {0} по цене {1} по бумаге {2} по объему {3} в {4}." + System.Convert.ToString(trade.Id) + System.Convert.ToString(trade.Price) +
                                     System.Convert.ToString(trade.Security.Code) + System.Convert.ToString(trade.Volume) + System.Convert.ToString(trade.Time);
                                 }
                             });
                             

                             // подписываемся на событие обновления стакана
                             _trader.MarketDepthsChanged += depths => this.GuiAsync(() =>
                             {
                                 if (_depth == null && Securities1.SelectedItem != null)
                                 {
                                     _depth = depths.FirstOrDefault(d => d.Security.Equals( (Security)Securities1.SelectedItem ));


                                     while (_depth == null) ;
                                           Status.Text = "Стакан появился.";
                                 }
                             });


                         };//КОНЕЦ _trader.Conected

                    _trader.ConnectionError += ex =>
                            {
                                if (ex != null)
                                    this.GuiAsync(() => MessageBox.Show(this, ex.ToString()));
                            };

                    this.GuiAsync(() =>
                            {
                                Connect.IsEnabled = false;
                                ExportDde.IsEnabled = true;
                                Report.IsEnabled = true;
                            });

                    // подписываемся на событие о неудачной регистрации заявок 
                    this._trader.OrdersRegisterFailed += OrdersFailed;
                    // подписываемся на событие о неудачном снятии заявок 
                    this._trader.OrdersCancelFailed += OrdersFailed;

                    // подписываемся на событие о неудачной регистрации стоп-заявок 
                    this._trader.StopOrdersRegisterFailed += OrdersFailed;
                    // подписываемся на событие о неудачном снятии стоп-заявок 
                    this._trader.StopOrdersCancelFailed += OrdersFailed;

                    // запускаем экспорт по DDE
                    _trader.Connect();

                    while (!_trader.IsConnected) { }
                    Status.Text = "Connected with Quik terminal";
                    StartDde();

                    #if EMULATOR
                    _trader.UnderlyingTrader.LogLevel = LogLevels.Debug;
                    _logManager.Sources.Add(_trader.UnderlyingTrader);
                    #else
                      _trader.LogLevel = LogLevels.Debug;
                      _logManager.Sources.Add(_trader);
                    #endif
                }
                else
                    _trader.Disconnect();
            }
        }

        private void OrdersFailed(IEnumerable<OrderFail> fails)
        {
            this.GuiAsync(() =>
            {
                foreach (var fail in fails)
                    MessageBox.Show(this, fail.Error.ToString(), "Ошибка регистрации заявки");
            });
        }

        private void StartDde()
		{
			_trader.StartExport();
			_isDdeStarted = true;
   		}

		private void StopDde()
		{
			_trader.StopExport();
			_isDdeStarted = false;
		}

        private void OnStrategyPropertyChanged(object sender, PropertyChangedEventArgs e)
		{
			this.GuiAsync(() =>
			{
				//Status.Content = _strategy.ProcessState;
                Status.Text = _strategy.ProcessState.ToString();
                PnL.Content = _strategy.PnLManager.PnL;
                Slippage.Content = _strategy.SlippageManager.Slippage;
				Position.Content = _strategy.PositionManager.Position;
                Latency.Content = _strategy.Latency;
			});
		}


        private void SwitchOn_Click(object sender, RoutedEventArgs e)
        {

            if (_strategy == null )
            {

                // создаем торговую стратегию, 
                _strategy = new tryStrategy()
                {
                    Volume = 1,     
                    Security = (Security)Securities1.SelectedItem,
                    Portfolio = (Portfolio)Portfolios.SelectedItem,
                    Trader = _trader
                };
                _strategy.PropertyChanged += OnStrategyPropertyChanged;
                _logManager.Sources.Add(_strategy);



                if (_strategy.ProcessState == ProcessStates.Stopped)
                {
                    // запускаем процесс получения стакана, необходимый для работы алгоритма котирования
                    _trader.RegisterMarketDepth(_strategy.Security);
                    _strategy.Start();
                    Status.Text = "Старт";
                }
                else
                {
                    _trader.UnRegisterMarketDepth(_strategy.Security);
                    _strategy.Stop();
                    Status.Text = "Стоп";
                }
            }
        }

        
        private void ExportDde_Click(object sender, RoutedEventArgs e)
        {
            if (_isDdeStarted)
				StopDde();
			else
				StartDde();
        }
        


        private void Report_Click(object sender, RoutedEventArgs e)
        {
            
            // сгерерировать отчет по прошедшему тестированию
			new ExcelStrategyReport(_strategy, "try.xls").Generate();

			// открыть отчет
			Process.Start("try.xls");
        }



        private void button2_Click(object sender, RoutedEventArgs e)
        {
            tryBuy = true;
            trySell = false;

        }

        private void button3_Click(object sender, RoutedEventArgs e)
        {
            tryBuy = false;
            trySell = true;           
        }

        protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
        {


            base.OnClosing(e);
            if (_trader != null)
            {
                //_candleManager.Stop(_series);  //????????
                _trader.UnRegisterMarketDepth(_strategy.Security);
                _strategy.Stop();
                Status.Text = "Стоп";
                // останавливаем экспорт по DDE
                #if EMULATOR
                //ниже две сторчки для работы на эмуляторе
                    _trader.UnderlyingTrader.StopExport(new[] { _trader.UnderlyingTrader.SecuritiesTable, _trader.UnderlyingTrader.MyTradesTable, _trader.UnderlyingTrader.EquityPositionsTable,
                        _trader.UnderlyingTrader.EquityPortfoliosTable, _trader.UnderlyingTrader.OrdersTable });
                 #else
                    _trader.StopExport(new[] { _trader.SecuritiesTable, _trader.MyTradesTable, _trader.EquityPositionsTable,
                        _trader.EquityPortfoliosTable, _trader.OrdersTable });
                #endif

                if (_trader.IsConnected) _trader.Disconnect();
                //_trader.Dispose();

                CfgFile.WriteParam("Portfolio", Portfolios.SelectedItem.ToString());
                CfgFile.WriteParam("Security", Securities1.SelectedItem.ToString());

            }
            base.OnClosing(e);
        }

    }
}

Код стратегии (выставляет ордера по нажатии кнопок в форме ) :
Code

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using Ecng.Collections;
using Ecng.Common;
using StockSharp.Algo;
using StockSharp.Algo.Candles;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Indicators.Trend;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Logging;
using StockSharp.Quik;





namespace tryBot1
{


        /// <summary> 
        /// Стратегия для проверки работы коннектора. Ручной запуск трейдов по состоянию cтатических 
        /// переменных базового окна tryBuy или trySell, там они меняются кнопками.
        /// </summary> 
    public class tryStrategy :  Strategy //
        {
        private DateTime StartTime = DateTime.Now;
        private Order myOrder;
        public decimal _StopLoss = 200; //strategy stop loss
        public decimal _TakeProfit = 700; //strategy stop loss



        public tryStrategy() { }

		protected override void OnStarted()
		{

            Security
                .WhenChanged()
                .Do(TryMakeTrade).Apply(this); //когда меняется цена по инструменту проверяем "не выставить ли ордер"
            
            //следующие события должны бы выполняться но не выполняются с чем и боремся
            this.WhenNewMyTrades().Do(OnNewOrderTrades).Apply(this);
            this.WhenOrderChanged().Do( ()=>
                { 
                    this.write("состояние ордера изменилось");
                }).Apply(this);

            //это надо для того чтобы на фьючах рабтали заявки по рынку. 
            this.Security.MaxPrice = 1000000;
            this.Security.MinPrice = 0;

			base.OnStarted();
		}



         /// <summary>
        /// проверяем условия и пытаемся выполнить трейд
        /// </summary>
        /// <param name="candle"></param>
        private void TryMakeTrade()
        {

            // если наша стратегия в процессе остановки
            if (ProcessState == ProcessStates.Stopping)
            {
                // отменяем активные заявки
                CancelActiveOrders();
                return;
            }


            if (tryBot1.MainWindow._depth != null)
            {

                if ( tryBot1.MainWindow.tryBuy )
                {
                    //отменяем все несработавшие
                        foreach (Strategy s in this.ChildStrategies)
                        {
                            s.CancelActiveOrders();
                        }
                        this.CancelActiveOrders();

                    this.write("buy Volume=" + Volume.ToString());
                    decimal _price = Security.BestAsk.Price + Security.MinStepSize;
                    myOrder = this.CreateOrder(OrderDirections.Buy, _price, Volume);
                    RegisterOrder(myOrder);
                    tryBot1.MainWindow.tryBuy = false;
                }
                if (tryBot1.MainWindow.trySell)
                {
                    //отменяем все несработавшие
                        foreach (Strategy s in this.ChildStrategies)
                        {
                            s.CancelActiveOrders();
                        }
                        this.CancelActiveOrders();

                    this.write("sell Volume=" + Volume.ToString());
                    decimal _price = Security.BestBid.Price - Security.MinStepSize;
                    myOrder = this.CreateOrder(OrderDirections.Sell, _price, Volume);
                    RegisterOrder(myOrder);
                    tryBot1.MainWindow.trySell = false;
                }

                foreach (Strategy s in this.ChildStrategies)
                {
                    s.Security.MaxPrice = 1000000;
                    s.Security.MinPrice = 0;
                }
            } //end if __depth
        }


        private void OnNewOrderTrades(IEnumerable<MyTrade> trades)
        {
            this.write("новый трейд");
            /*
            // для каждой сделки добавляем защитную пару стратегии 
            var protectiveStrategies = trades.Select(t =>
            {
                // выставляет тейк-профит в 40 пунктов 
                var takeProfit = new TakeProfitStrategy(t, _TakeProfit);

                // выставляет стоп-лосс в 20 пунктов 
                var stopLoss = new StopLossStrategy(t, _StopLoss);
                return new TakeProfitStopLossStrategy(takeProfit, stopLoss);
            });
            protectiveStrategies.ForEach( strategy => this.ChildStrategies.Add(strategy) );
            */
        }


        /*
        override protected void OnNewMyTrades(IEnumerable<MyTrade> trades)
        {
            foreach(MyTrade trd in trades)
            {
            this.write("Trade time=" + trd.Trade.Time);
            }

            //aprotect.ProcessNewMyTrades(trades);
            base.OnNewMyTrades(trades);
        }*/

        public void write(String mes)
        {
            LogMessage logMessage = new LogMessage(this, DateTime.Now, LogLevels.Info, mes);
            RaiseLog(logMessage);
        }
 
    }
}

Thanks:

kahuna

Avatar
Date: 2/22/2013
Reply


VassilSanych Go to
kahuna Go to
_strategy.Orders.Any(o => o == t.Order))

Не уверен, что NewMyTrades и _strategy ссылаются на одни и те же экземпляры объектов заявок в памяти.


Откуда то срисовал.
Поменял на _trader.Orders.Any(o => o == t.Order),
но все равно результат тот же,
так как само событие NewMyTrades не вызывается.
Thanks:

Moadip

Avatar
Date: 2/22/2013
Reply


Несколько замечаний по коду.

Quote:
Если оставляю #define EMULATOR сделки совершаются и событие стратегии OrderChanged срабатывает в лог попадает сообщение "состояние ордера изменилось".
Если на реальном Quik (снят комментарий с
#undef EMULATOR) то сделки совершаются но событие OrderChanged не срабатывает.

Как то сложно, да и лениво каждый раз комментить/раскомментить директивы препроцессора.
Объявите поле _trader типа ITrader.
Code

private ITrader _trader;


Добавьте на форму ComboBox с двумя Item. Что нибудь типа:
Code

<ComboBox Name="cmbTrader" >
	<ComboBoxItem Content="Эмуляция" />
	<ComboBoxItem Content="Реал" />
</ComboBox>

И потом в коде, в зависимости от того что выбранно создавать или QuikTrader или RTET<QuikTrader>
Code

//Выбор шлюза
switch (cmbTrader.SelectedIndex)
{
	case 0:
		_trader= new RealTimeEmulationTrader<QuikTrader>(new QuikTrader(QuikTerminal.GetDefaultPath()));
		break;

	case 1:
		_trader = new QuikTrader(QuikTerminal.GetDefaultPath())
		break;
}

Рекомендую прочитать серию статей от FinDirector, почерпнете для себя много интересного.


Code

_trader = new QuikTrader(QuikTerminal.GetDefaultPath()){ IsAsyncMode = true, SupportManualOrders = false };
_trader.IsAsyncMode = true;

В инициализаторе уже задано значение св-ва IsAsyncMode, нет смысла делать это еще раз.


Code

 Status.Text = "Сделка {0} по цене {1} по бумаге {2} по объему {3} в {4}." + System.Convert.ToString(trade.Id) + System.Convert.ToString(trade.Price) +
 System.Convert.ToString(trade.Security.Code) + System.Convert.ToString(trade.Volume) + System.Convert.ToString(trade.Time);

Можно заменить на
Code

Status.Text = "Сделка {Id} по цене {Price} по бумаге {Security.Code} по объему {Volume} в {Time}.".PutEx(trade)



Запуск/остановка экспорта
Code

        private void StartDde()
        {
            _trader.StartExport();
            _isDdeStarted = true;
        }
 
        private void StopDde()
        {
            _trader.StopExport();
            _isDdeStarted = false;
        }

Если на экспорт запускаются все таблицы StartExport(), то нет смысла потом перечислять какие именно надо таблицы остановить.
Code

                //ниже две сторчки для работы на эмуляторе
                    _trader.UnderlyingTrader.StopExport(new[] { _trader.UnderlyingTrader.SecuritiesTable, _trader.UnderlyingTrader.MyTradesTable, _trader.UnderlyingTrader.EquityPositionsTable,
                        _trader.UnderlyingTrader.EquityPortfoliosTable, _trader.UnderlyingTrader.OrdersTable });
                 #else
                    _trader.StopExport(new[] { _trader.SecuritiesTable, _trader.MyTradesTable, _trader.EquityPositionsTable,
                        _trader.EquityPortfoliosTable, _trader.OrdersTable });
                #endif

Проще вызвать StopDde() или напрямую _trader.StopExport();


Code

        protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
        {
 
 
            base.OnClosing(e);
            if (_trader != null)
            {
                //_candleManager.Stop(_series);  //????????
                _trader.UnRegisterMarketDepth(_strategy.Security);
                _strategy.Stop();
                Status.Text = "Стоп";
                // останавливаем экспорт по DDE
                #if EMULATOR
                //ниже две сторчки для работы на эмуляторе
                    _trader.UnderlyingTrader.StopExport(new[] { _trader.UnderlyingTrader.SecuritiesTable, _trader.UnderlyingTrader.MyTradesTable, _trader.UnderlyingTrader.EquityPositionsTable,
                        _trader.UnderlyingTrader.EquityPortfoliosTable, _trader.UnderlyingTrader.OrdersTable });
                 #else
                    _trader.StopExport(new[] { _trader.SecuritiesTable, _trader.MyTradesTable, _trader.EquityPositionsTable,
                        _trader.EquityPortfoliosTable, _trader.OrdersTable });
                #endif
 
                if (_trader.IsConnected) _trader.Disconnect();
                //_trader.Dispose();
 
                CfgFile.WriteParam("Portfolio", Portfolios.SelectedItem.ToString());
                CfgFile.WriteParam("Security", Securities1.SelectedItem.ToString());
 
            }
            base.OnClosing(e);
        }

Дублируется base.OnClosing(e); Не смертельно, но все же.


Code

            //это надо для того чтобы на фьючах рабтали заявки по рынку.
            this.Security.MaxPrice = 1000000;
            this.Security.MinPrice = 0;

Сначала подумал что в этом причина почему не срабатывает событие NewMyTrade, т.к. не совершается сделка.
По идее не должно работать. Должно прийти сообщение об ошибке, что то типа цена ордера вне диапазона.
Чтобы были цены планок лучше добавить соответствующие колонки в квик таблице "Инструменты" и потом добавить их в коде. Экспорт доп. колонок

Потом увидел что ценник выставляется по другому
Code
_price = Security.BestBid.Price - Security.MinStepSize;

И методы BuyAtmarket и SellAtMarket не используются.
Да и вы пишете что сделки совершаются.

Тогда не понятно в чем может быть причина.

Попробуйте максимально упростить код, чтобы проверить отрабатывает ли событие NewMyTrade. Один шлюз, минимум кода в стратегии.
Попробуйте на последней сборке с codeplex, возможно причина в S#.
Thanks: kahuna

kahuna

Avatar
Date: 2/22/2013
Reply


Quote:

Попробуйте максимально упростить код, чтобы проверить отрабатывает ли событие NewMyTrade. Один шлюз, минимум кода в стратегии.
Попробуйте на последней сборке с codeplex, возможно причина в S#.

Попробовл без изменения кода перейти на 4.1.8 , стало еще веселее, теперь Positions не показывается и в режиме эмулятора. То есть событие OrderChanged тоже не прилетает.
Verifier про настройку Quik говорит - все в порядке.
Упростил код. Дальше уже кажется некуда. Картина сохранилась. [confused]
основной:
Code


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Forms;
using System.Drawing;
using System.Diagnostics;
using MessageBox = System.Windows.MessageBox;
using System.Threading;
using System.Linq;
using System.Xml;
using Xceed.Wpf.Toolkit;

using Ecng.Common;
using Ecng.Collections;
using Ecng.Xaml;
using Ecng.ComponentModel;

using StockSharp.BusinessEntities;
using StockSharp.Algo.Reporting;
using StockSharp.Quik;
using StockSharp.Algo;
using StockSharp.Algo.Candles;
using StockSharp.Xaml;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Indicators.Trend;
using StockSharp.Logging;
using StockSharp.Algo.Testing;

namespace test
{
    /// <summary>
    /// Логика взаимодействия для MainWindow.xaml
    /// </summary>

    public partial class MainWindow : Window
   {




        private RealTimeEmulationTrader<QuikTrader> _trader;
        //private QuikTrader _trader;


        public static MarketDepth _depth;
        private tryStrategy _strategy;
        private MonitorWindow monitor;
        private LogManager _logManager;
        private String DefSecurity = "RIH3@RTS";
        private String DefPortfolio = "SPBFUTXXXX";


        public static bool tryBuy = false;
        public static bool trySell = false;



        public MainWindow()
        {

            InitializeComponent();

            monitor = new MonitorWindow();
            monitor.Show();
            _logManager = new LogManager();
            //var fileListener = new FileLogListener("{0}_{1:00}_{2:00}.txt".Put(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day));
            //logManager.Listeners.Add(fileListener);
            _logManager.Listeners.Add(new GuiLogListener(monitor));


        }

        private void Connect_Click(object sender, RoutedEventArgs e)
        {


            if (_trader == null || !_trader.IsConnected)
            {
                if (_trader == null)
                {
                    if (QuikTerminal.GetDefaultPath().IsEmpty())
                    {
                        MessageBox.Show(this, "Путь к Quik не выбран.");
                        return;
                    }
                    Status.Text = "Connecting with Quck. Please wait";

                    _trader = new RealTimeEmulationTrader<QuikTrader>(new QuikTrader(QuikTerminal.GetDefaultPath()) { IsAsyncMode = true, SupportManualOrders = false });
                     //   _trader = new QuikTrader(QuikTerminal.GetDefaultPath()){ IsAsyncMode = true, SupportManualOrders = false };


                        _trader.Connected += () =>
                         {

                             // подписываемся на событие появление инструментов
                             _trader.NewSecurities += securities => this.GuiAsync(() =>
                             {
                                 Securities1.ItemsSource = _trader.Securities;

                                 int i = 0;
                                 foreach (Object item in Securities1.Items)
                                 {
                                     Securities1.SelectedIndex = i;
                                     if (item.ToString().Equals(DefSecurity))
                                     {
                                         break;
                                     }
                                     i++;
                                 }
                                 // если инструмент и стакан уже появились 
                                 if (Securities1.SelectedItem != null)
                                 {
                                    Status.Text = "Инструмент появился.";
                                 }

                             });
                             _trader.NewPortfolios += portfolios => this.GuiAsync(() =>
                             {
                                 Portfolios.ItemsSource = _trader.Portfolios;

                                 int i = 0;
                                 foreach (Object item in Portfolios.Items)
                                 {
                                     Portfolios.SelectedIndex = i;
                                     if (item.ToString().Equals(DefPortfolio))
                                     {
                                         break;
                                     }
                                     i++;
                                 }
                             });


                             // подписываемся на событие появления моих новых сделок
                             _trader.NewMyTrades += myTrades => this.GuiAsync(() =>
                             {
                                 if (_strategy != null)
                                 {
                                     // найти те сделки, которые совершила стратегия 
                                     //myTrades = myTrades.Where(t => _strategy.Orders.Any(o => o == t.Order));
                                     myTrades = myTrades.Where(t => _trader.Orders.Any(o => o == t.Order));
                                 }
                                 foreach (var myTrade in myTrades)
                                 {
                                    var trade = myTrade.Trade;
                                    Status.Text = "Сделка {Id} по цене {Price} по бумаге {Security.Code} по объему {Volume} в {Time}.".PutEx(trade);
                                 }
                             });
                             

                             // подписываемся на событие обновления стакана
                             _trader.MarketDepthsChanged += depths => this.GuiAsync(() =>
                             {
                                 if (_depth == null && DefSecurity != null)
                                 {
                                     _depth = depths.FirstOrDefault(d => d.Security.Equals( (Security) this.Securities1.SelectedItem ));
                                     while (_depth == null) ;
                                         Status.Text = "Стакан появился.";
                                 }
                             });


                         };//КОНЕЦ _trader.Conected

                    _trader.ConnectionError += ex =>
                            {
                                if (ex != null)
                                    this.GuiAsync(() => MessageBox.Show(this, ex.ToString()));
                            };

                    this.GuiAsync(() =>
                            {
                                Connect.IsEnabled = false;
                                Report.IsEnabled = true;
                            });

                    // подписываемся на событие о неудачной регистрации заявок 
                    this._trader.OrdersRegisterFailed += OrdersFailed;
                    // подписываемся на событие о неудачном снятии заявок 
                    this._trader.OrdersCancelFailed += OrdersFailed;

                    // подписываемся на событие о неудачной регистрации стоп-заявок 
                    this._trader.StopOrdersRegisterFailed += OrdersFailed;
                    // подписываемся на событие о неудачном снятии стоп-заявок 
                    this._trader.StopOrdersCancelFailed += OrdersFailed;

                    // запускаем экспорт по DDE
                    _trader.Connect();
                    

                    while (!_trader.IsConnected) { }
                    Status.Text = "Connected with Quik terminal";
                    StartDde();

                    #if EMULATOR
                        _trader.UnderlyingTrader.LogLevel = LogLevels.Debug;
                        _logManager.Sources.Add(_trader.UnderlyingTrader);
                    #else
                        _trader.LogLevel = LogLevels.Debug;
                        _logManager.Sources.Add(_trader);
                    #endif
                }
                else
                    _trader.Disconnect();
            }
        }

        private void OrdersFailed(IEnumerable<OrderFail> fails)
        {
            this.GuiAsync(() =>
            {
                foreach (var fail in fails)
                    MessageBox.Show(this, fail.Error.ToString(), "Ошибка регистрации заявки");
            });
        }

        private void StartDde()
		{
			_trader.StartExport();
   		}

	private void StopDde()
		{
			_trader.StopExport();
		}

        private void OnStrategyPropertyChanged(object sender, PropertyChangedEventArgs e)
		{
            _trader.AddInfoLog("OnStrategyPropertyChanged");
			this.GuiAsync(() =>
			{
				//Status.Content = _strategy.ProcessState;
                Status.Text = _strategy.ProcessState.ToString();
                PnL.Content = _strategy.PnLManager.PnL;
                Slippage.Content = _strategy.SlippageManager.Slippage;
				Position.Content = _strategy.PositionManager.Position;
                Latency.Content = _strategy.Latency;
			});
		}


        private void SwitchOn_Click(object sender, RoutedEventArgs e)
        {

            if (_strategy == null )
            {

                // создаем торговую стратегию, 
                _strategy = new tryStrategy()
                {
                    Volume = 1,     
                    Security = (Security)this.Securities1.SelectedItem,
                    Portfolio = (Portfolio)this.Portfolios.SelectedItem,
                    Trader = _trader
                };
                _strategy.PropertyChanged += OnStrategyPropertyChanged;
                _logManager.Sources.Add(_strategy);



                if (_strategy.ProcessState == ProcessStates.Stopped)
                {
                    // запускаем процесс получения стакана, необходимый для работы алгоритма котирования
                    _trader.RegisterMarketDepth((Security)this.Securities1.SelectedItem);
                    _strategy.Start();
                    Status.Text = "Старт";
                }
                else
                {
                    _trader.UnRegisterMarketDepth((Security)this.Securities1.SelectedItem);
                    _strategy.Stop();
                    Status.Text = "Стоп";
                }
            }
        }

        

        private void Report_Click(object sender, RoutedEventArgs e)
        {
            
            // сгерерировать отчет по прошедшему тестированию
			new ExcelStrategyReport(_strategy, "try.xls").Generate();

			// открыть отчет
			Process.Start("try.xls");
        }



        private void button2_Click(object sender, RoutedEventArgs e)
        {
            tryBuy = true;
            trySell = false;

        }

        private void button3_Click(object sender, RoutedEventArgs e)
        {
            tryBuy = false;
            trySell = true;           
        }

        protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
        {


            if (_trader != null)
            {
                _trader.UnRegisterMarketDepth(_strategy.Security);
                _strategy.Stop();
                Status.Text = "Стоп";
                // останавливаем экспорт по DDE
                StopDde();

                if (_trader.IsConnected) _trader.Disconnect();
                //_trader.Dispose();

            }
            base.OnClosing(e);
        }

    }
}



для стратегии:
Code

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using Ecng.Collections;
using Ecng.Common;
using StockSharp.Algo;
using StockSharp.Algo.Candles;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Indicators.Trend;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Logging;
using StockSharp.Quik;





namespace test
{


        /// <summary> 
        /// Стратегия для проверки работы коннектора. Ручной запуск трейдов по состоянию cтатических 
        /// переменных базового окна tryBuy или trySell, там они меняются кнопками.
        /// </summary> 
    public class tryStrategy :  Strategy //
        {
        private Order myOrder;

        public tryStrategy() { }

		protected override void OnStarted()
		{

            Security
                .WhenChanged()
                .Do(TryMakeTrade).Apply(this); //когда меняется цена по инструменту проверяем "не выставить ли ордер"
            
            //следующие события должны бы выполняться но не выполняются с чем и боремся
            this.WhenNewMyTrades().Do(OnNewOrderTrades).Apply(this);
            this.WhenOrderChanged().Do( ()=>
                { 
                    this.write("состояние ордера изменилось");
                }).Apply(this);
            this.WhenError().Do(() =>
            {
                this.write("прилетела ошибка");
            }).Apply(this);

            this.WhenOrderRegistered().Do(() =>
            {
                this.write("зарегистрирован ордер");
            }).Apply(this);

            this.WhenPnLChanged().Do(() =>
            {
                this.write("профит.лосс сменился");
            }).Apply(this);
            this.WhenWarning().Do(() =>
            {
                this.write("желтая карточка");
            }).Apply(this);

			base.OnStarted();
		}



         /// <summary>
        /// проверяем условия и пытаемся выполнить трейд
        /// </summary>
        /// <param name="candle"></param>
        private void TryMakeTrade()
        {

            // если наша стратегия в процессе остановки
            if (ProcessState == ProcessStates.Stopping)
            {
                // отменяем активные заявки
                CancelActiveOrders();
                return;
            }


            if (test.MainWindow._depth != null) //стакан работает?
            {

                if ( test.MainWindow.tryBuy )
                {
                    this.write("buy Volume=" + Volume.ToString());
                    decimal _price = Security.BestAsk.Price + Security.MinStepSize;
                    myOrder = this.CreateOrder(OrderDirections.Buy, _price, Volume);
                    RegisterOrder(myOrder);
                    test.MainWindow.tryBuy = false;
                }
                if (test.MainWindow.trySell)
                {
                    this.write("sell Volume=" + Volume.ToString());
                    decimal _price = Security.BestBid.Price - Security.MinStepSize;
                    myOrder = this.CreateOrder(OrderDirections.Sell, _price, Volume);
                    RegisterOrder(myOrder);
                    test.MainWindow.trySell = false;
                }


            } //end if __depth
        }


        private void OnNewOrderTrades(IEnumerable<MyTrade> trades)
        {
            this.write("новый трейд");
        }


        public void write(String mes)
        {
            LogMessage logMessage = new LogMessage(this, DateTime.Now, LogLevels.Info, mes);
            RaiseLog(logMessage);
        }
 
    }
}

Thanks:

VassilSanych

Avatar
Date: 2/23/2013
Reply


kahuna Go to
И следующий код никогда не исполняется (то что внутри цикла foreach)
хотя ордера выставляются.

Попробуйте всё-таки вставить строчку логирования перед foreach.
Возможно всё-таки косяк с фильтром.
Говоря о заявке в памяти, я подразумевал, что, может быть, лучше проверять какие-нибудь скалярные свойства ордеров, а не ссылки на объекты.
Thanks:

kahuna

Avatar
Date: 2/25/2013
Reply


VassilSanych Go to
kahuna Go to
И следующий код никогда не исполняется (то что внутри цикла foreach)
хотя ордера выставляются.

Попробуйте всё-таки вставить строчку логирования перед foreach.
Возможно всё-таки косяк с фильтром.
Говоря о заявке в памяти, я подразумевал, что, может быть, лучше проверять какие-нибудь скалярные свойства ордеров, а не ссылки на объекты.


Попробовал поставил, выполнение до цикла просто не доходит. Не вызывается совсем этот обработчик события NewMyTrades.
Thanks:
1 2  >

Attach files by dragging & dropping, , or pasting from the clipboard.

loading
clippy