Событийный подход

Событийный подход
Atom
3/28/2011
poilka


Доброго всем дня, особенно Михаилу :). Начал осваивать событийный подход, забуксовал.

Подскажите, пожалуйста, как правильно запускать стратегию наподобие той, что приведена в примере (class MyOwnStrategy : ActionStrategy)? Нужно ли добавлять в нее конструктор и отдельно передавать Security?

Сейчас запускаю на ФОРТС так:

_strategy = new MyOwnStrategy() { Volume = 1 };
_manager.Register(_strategy, this.Portfolios.SelectedPortfolio, _rts);
if (_strategy.ProcessState == StrategyProcessStates.Stopped)
	{
	_strategy.Start();
	}
	else
	{
	_strategy.Stop();
	}

Стратегия нормально запускается и останавливается из GUI примера SampleSMA, лог пишется, но сделок не происходит на любом таймфрейме.

Лог обычно такой: MOS 20:34:52.0212958 Стратегия запущена. MOS 20:36:11.3213772 Стратегия останавливается. MOS 20:36:11.6273947 Стратегия остановлена.

Событийную стратегию взял из мануала, без изменений, версия 3.0. Буду признателен за помощь.

Весь запускающий код, кроме самой стратегии из примера:

namespace SampleSMA
{
	using System;
	using System.Collections.Generic;
	using System.Linq;
	using System.ComponentModel;
	using System.Globalization;
	using System.IO;
	using System.Threading;
	using System.Windows;
	using System.Windows.Forms;
	using MessageBox = System.Windows.MessageBox;
	using AmCharts.Windows.Stock;
    using Ecng.Collections;
	using Ecng.Common;
	using Ecng.ComponentModel;
	using Ecng.Trading.Algo;
	using Ecng.Trading.Algo.Candles;
    using Ecng.Trading.Algo.Logging;
	using Ecng.Trading.Algo.Reporting;
	using Ecng.Trading.Algo.Strategies;
	using Ecng.Trading.BusinessEntities;
	using Ecng.Trading.Quik;
	using Ecng.Trading.Xaml;
	using Ecng.Xaml;

	public partial class MainWindow
	{
		private readonly TimeSpan _timeFrame = TimeSpan.FromMinutes(1);
		private QuikTrader _trader;
		private MyOwnStrategy _strategy;
		private RealTimeStrategyManager _manager;
		private bool _isDdeStarted;
		private Security _rts;
        public CandleManager _candleManager;

		public MainWindow()
		{
			 InitializeComponent();

			// изменяет текущий формат, чтобы нецелое числа интерпритировалось как разделенное точкой.
			 var cci = new CultureInfo(Thread.CurrentThread.CurrentCulture.Name) { NumberFormat = { NumberDecimalSeparator = "." } };
		     Thread.CurrentThread.CurrentCulture = cci;

			}

		private void _orders_OrderSelected(object sender, EventArgs e)
		{
			this.CancelOrders.IsEnabled = _orders.SelectedOrders.Count() > 0;
		}

		 protected override void OnClosing(CancelEventArgs e)
		{
			if (_trader != null)
			{
				_manager.Dispose();

				if (_isDdeStarted)
					StopDde();

				_trader.Dispose();
			}

			base.OnClosing(e);
		}    

		private void FindPath_Click(object sender, RoutedEventArgs e)
		{
			var dlg = new FolderBrowserDialog();

			if (!this.Path.Text.IsEmpty())
				dlg.SelectedPath = this.Path.Text;

			if (dlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
			{
				this.Path.Text = dlg.SelectedPath;
			}
		}

		private void Connect_Click(object sender, RoutedEventArgs e)
		{
			if (_trader == null || !_trader.IsConnected)
			{
				if (_trader == null)
				{
					if (this.Path.Text.IsEmpty())
					{
						MessageBox.Show(this, "Путь к Quik не выбран.");
						return;
					}

					// создаем шлюз
					_trader = new QuikTrader(this.Path.Text);

					// создаем менеджер стратегий
					_manager = new RealTimeStrategyManager(_trader);

					this.Portfolios.Trader = _trader;

					_trader.Connected += () =>
					{
                        _candleManager = new CandleManager(_trader);

                        _trader.NewSecurities += securities => this.GuiAsync(() =>
						{
							// находим нужную бумагу
							var rts = securities.FirstOrDefault(s => s.Code == "RIM1");

							if (rts != null)
							{
								_rts = rts;

								this.GuiAsync(() =>
								{
									this.Start.IsEnabled = true;
								});
							}
						});

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

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

				_trader.Connect();
			}
			else
				_trader.Disconnect();
		}

       	private void OnNewOrder(Order order)
		{
			_orders.Orders.Add(order);
			this.GuiAsync(() => _chart.Orders.Add(order));
		}

		private void OnLog(Strategy strategy, StrategyErrorStates errorState, string message)
		{
			// если стратегия вывела не просто сообщение, то вывести на экран.
			if (errorState != StrategyErrorStates.None)
				this.GuiAsync(() => MessageBox.Show(this, message));
		}

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

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

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

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

		private void CancelOrders_Click(object sender, RoutedEventArgs e)
		{
			_orders.SelectedOrders.ForEach(_trader.CancelOrder);
		}

		private void Start_Click(object sender, RoutedEventArgs e)
		{
			if (_strategy == null)
			{
				if (this.Portfolios.SelectedPortfolio == null)
				{
					MessageBox.Show(this, "Портфель не выбран.");
					return;
				}

				
				// создаем стратегию
				_strategy = new MyOwnStrategy() { Volume = 1 };
				_strategy.Log += OnLog;
				_strategy.NewOrder += OnNewOrder;
				_strategy.PropertyChanged += OnStrategyPropertyChanged;

				// регистрируем стратегию, чтобы она начала обрабатываться
				_manager.Register(_strategy, this.Portfolios.SelectedPortfolio, _rts);

				var fileLogger = new FileStrategyLogger("{0}_{1:00}_{2:00}.txt".Put(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day));
                
                fileLogger.Strategies.Add(_strategy);
                
                this.Report.IsEnabled = true;

			}
            
			if (_strategy.ProcessState == StrategyProcessStates.Stopped)
			{
				_strategy.Start();
				this.Start.Content = "Хватит";
			}
			else
			{
				_strategy.Stop();
				this.Start.Content = "Понеслась";
			}
		}
        
        private void Report_Click(object sender, RoutedEventArgs e)
		{
			var fileName = "report_{0}_{1}.xls".Put(_strategy.Security.Code, DateTime.Now.ToString("yyyy_MM_dd_HH_mm"));
			new ExcelStrategyReport(_strategy, System.IO.Path.Combine(Directory.GetCurrentDirectory(), fileName)).Generate();
		}
	}
}

Tags:


Thanks:


1 2  >
Mikhail Sukhov

Avatar
Date: 3/28/2011
Reply


poilka: Стратегия нормально запускается и останавливается из GUI примера SampleSMA, лог пишется, но сделок не происходит на любом таймфрейме.

Точка останова, дебаггер и вперед.[smile]

Thanks:

poilka

Avatar
Date: 3/28/2011
Reply


Спасибо, буду ковыряться.

Thanks:

poilka

Avatar
Date: 3/28/2011
Reply


Попробовал и с конструктором, и без - говорит, что не может получить значение _candleBounds. Хотя _candleManager на месте, и на остальные поля не ругается. Вот такой неуспех.

Thanks:

Mikhail Sukhov

Avatar
Date: 3/28/2011
Reply


poilka: Попробовал и с конструктором, и без - говорит, что не может получить значение _candleBounds. Хотя _candleManager на месте, и на остальные поля не ругается.

Потому что там лямбда выражение стоит. Прочитайте, как эта вещь работает. И бряку ставьте во внутрь.

Thanks:

poilka

Avatar
Date: 3/28/2011
Reply


Ай, сильно не хотелось в лямбды лезть, теперь придется. Спасибо, пойду подтягивать матчасть.

Thanks:

Roman0

Avatar
Date: 4/25/2011
Reply


Чтобы не плодить сущности напишу здесь ) Есть ли вообще возможность запускать очередную итерацию стратегии не периодически, а именно по событию? Хотелось бы воспользоваться преимуществами оформления кода с виде Strategy, но не очень нравится исполнение по времени.

PS Только начал разбираться, извините, если что пропустил.

Thanks:

Mikhail Sukhov

Avatar
Date: 4/25/2011
Reply


Roman0: Есть ли вообще возможность запускать очередную итерацию стратегии не периодически, а именно по событию?

Не итерацию, а действие. Так же, как и выше написал, через событийную модель.

Thanks:

Roman0

Avatar
Date: 4/25/2011
Reply


Mikhail Sukhov:

Roman0: Есть ли вообще возможность запускать очередную итерацию стратегии не периодически, а именно по событию?

Не итерацию, а действие. Так же, как и выше написал, через событийную модель. Я правильно понял, что условие в When проверяется с периодичностью Strategy.Interval? Если нет, то каков смысл MakePeriodical? Вопрос такой: можно ли запускать код внутри стратегии по событию? Т.е. пришли новые данные -> очередная проверка условия. Вроде бы это можно сделать запуская всю стратегию (ActionStrategy.Start) по событию без MakePeriodical? Если все это можно сделать как-то еще, то пожалуйста, расскажите как. Как я уже писал, хотелось бы использовать преимущества стратегий. Большое спасибо!

Thanks:

Mikhail Sukhov

Avatar
Date: 4/26/2011
Reply


Roman0:

Mikhail Sukhov:

Roman0: Есть ли вообще возможность запускать очередную итерацию стратегии не периодически, а именно по событию?

Не итерацию, а действие. Так же, как и выше написал, через событийную модель. Я правильно понял, что условие в When проверяется с периодичностью Strategy.Interval? Если нет, то каков смысл MakePeriodical?

Сделать действие периодичным (будет вызвано более одного раза).

Roman0: Вопрос такой: можно ли запускать код внутри стратегии по событию? Т.е. пришли новые данные -> очередная проверка условия. Вроде бы это можно сделать запуская всю стратегию (ActionStrategy.Start) по событию без MakePeriodical? Если все это можно сделать как-то еще, то пожалуйста, расскажите как. Как я уже писал, хотелось бы использовать преимущества стратегий. Большое спасибо!

Через ActionStrategy и добавления событий... Вопрос уже содержит ответ. Или я видимо что-то не понимаю в вопросе, или вы не до конца мысль расписываете. Как предложение, попробуйте написать практический пример с событиями.

Thanks:

Roman0

Avatar
Date: 4/26/2011
Reply


Большое спасибо за ответ!

Mikhail Sukhov:

Roman0: каков смысл MakePeriodical?

Сделать действие периодичным (будет вызвано более одного раза).

Вопрос как\где контролируется с какой периодичностью (и сколько раз?) будет выполняться действие?

Mikhail Sukhov:

Roman0: Вопрос такой: можно ли запускать код внутри стратегии по событию? Т.е. пришли новые данные -> очередная проверка условия. Вроде бы это можно сделать запуская всю стратегию (ActionStrategy.Start) по событию без MakePeriodical? Если все это можно сделать как-то еще, то пожалуйста, расскажите как. Как я уже писал, хотелось бы использовать преимущества стратегий. Большое спасибо!

Через ActionStrategy и добавления событий... Вопрос уже содержит ответ.

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

Mikhail Sukhov: Или я видимо что-то не понимаю в вопросе, или вы не до конца мысль расписываете. Вопрос очень прост: как выполнять вычисления по собственной стратегии (и в результате выставлять заявки, выдавать какие-то сообщения и т.п.) по событию (не периодически!) появления или изменения свечей используя Strategy и преимущества такого подхода (как это сделать без привлечения Strategy понятно)?. Такое возможно? Если кто-то напишет пример или даже без кода, но с названиями классов\методов опишет как это сделать буду очень благодарен )

Thanks:
1 2  >

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

loading
clippy