S#

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


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


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

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

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

Теги:


Спасибо:




14 Ответов
VassilSanych

Фотография
Дата: 21.02.2013
Ответить


kahuna Перейти
события изменения состояния не вызываются,

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

kahuna

Фотография
Дата: 21.02.2013
Ответить


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

И следующий код никогда не исполняется (то что внутри цикла foreach)
хотя ордера выставляются.
Код
_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);
         }
       });


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

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

Moadip

Фотография
Автор статей Программист
Дата: 21.02.2013
Ответить


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

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

VassilSanych

Фотография
Дата: 22.02.2013
Ответить


kahuna Перейти
_strategy.Orders.Any(o => o == t.Order))

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

kahuna

Фотография
Дата: 22.02.2013
Ответить


Moadip Перейти
Цитата:
Когда переключаюсь с эмулятора на реальный 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;

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

#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);
        }

    }
}

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

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);
        }
 
    }
}

Автор топика
Спасибо:

kahuna

Фотография
Дата: 22.02.2013
Ответить


VassilSanych Перейти
kahuna Перейти
_strategy.Orders.Any(o => o == t.Order))

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


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

Moadip

Фотография
Автор статей Программист
Дата: 22.02.2013
Ответить


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

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

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

private ITrader _trader;


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

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

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

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

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

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


Код

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

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


Код

 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);

Можно заменить на
Код

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



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

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

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

                //ниже две сторчки для работы на эмуляторе
                    _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();


Код

        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); Не смертельно, но все же.


Код

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

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

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

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

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

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

kahuna

Фотография
Дата: 22.02.2013
Ответить


Цитата:

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

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


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);
        }

    }
}



для стратегии:
Код

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);
        }
 
    }
}

Автор топика
Спасибо:

VassilSanych

Фотография
Дата: 23.02.2013
Ответить


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

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

kahuna

Фотография
Дата: 25.02.2013
Ответить


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

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


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

kahuna

Фотография
Дата: 26.02.2013
Ответить


Может это как то проясняет дело. Простейший код в котором просто соединение с Quik
выдает страную ошибку про какой-то инструментBlink

Код


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using System.Windows;
using System.Windows.Controls;
using System.Diagnostics;
using MessageBox = System.Windows.MessageBox;
using System.Threading;
using System.Linq;
using System.Xml;
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.Xaml;
using StockSharp.Logging;
using StockSharp.Algo.Testing;

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

    public partial class MainWindow : Window
   {
        private QuikTrader _trader;
        private LogManager _logManager;

        public MainWindow()
        {
            InitializeComponent();

            _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);

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

            _trader.LogLevel = LogLevels.Debug;
            _logManager.Sources.Add(_trader);

                    _trader.Connected += () =>
                     {
                         _trader.AddDebugLog("Соединились");
                     };

                    _trader.Connect();
                    

                    while (!_trader.IsConnected) { }
                    _trader.StartExport();
  
        }
    }
}

Ошибка в лог валится такая:
2013/02/26 14:43:51.544|Debug |QuikTrader|Соединились
2013/02/26 14:43:53.367|Error |QuikTrader|System.InvalidOperationException: Инструмент с кодом RU000A0JPWC3 для бумажной позиции не найден.
в StockSharp.Quik.QuikTrader.#=qjrOBFov$lIae$ZMCQLx7P1fQAe2X2s16$DxZRnv$aqU=.#=qjGe1xZF5fvarq_$jrR3XCQ==(IList`1 #=qKG6nGjj9uhl1Ndb5IDukAw==, Func`2 #=qdrbWxV4uORvFCQd5d$c6og==)
в #=qU8C8kAMUmJ0kPIeEJrF68f3NMymXDukMNgL4Dc7ffmr7PRgVzknJ3atY_n0PucT4.#=qB09_IBYvsxLb_dLzMi2NWQ==(DdeTable #=qOgXoydWCvsq2gXlddKoo0w==, IList`1 #=qMeYWUEb44NrXcAvbPuNfiQ==, Action`2 #=qolGBgTssErk3vXo538xxsQ==, Action`1 #=qIfmNdbFGgLtG9ybpXuosbQ==, Boolean #=qe3W9$GyIKMHUi59wvLuQeA==)
2013/02/26 14:43:53.441| |QuikTrader|Экспорт запущен.

Мистика. Cursing
Автор топика
Спасибо:

kahuna

Фотография
Дата: 26.02.2013
Ответить


Понял, сам дурак. Просто давно завис в облигациях РБК. Валяются в портфеле. А в таблицах (сделок, заявок и т.п) облигации отфильтрованы.
Автор топика
Спасибо:

kahuna

Фотография
Дата: 26.02.2013
Ответить


Включил фильтр на таблицу позиции по бумагам. Оставил одни фьючи.
Ура. Все заработало.
События на которые жаловался стали прилетать.
Автор топика
Спасибо:

VassilSanych

Фотография
Дата: 26.02.2013
Ответить


Похоже у вас не логируются исключения фоновых потоков.
Это можно делать например так:
Спасибо: kahuna


Добавить файлы через драг-н-дроп, , или вставить из буфера обмена.

loading
clippy