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

Событийный подход
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: 4/26/2011
Reply


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

Если просто MakePeriodica(), то бесконечно. Если через перегруженный метод http://stocksharp.com/doc/help/html/O_T_Ecng_Trading_Algo_Strategies_ActionRule_MakePeriodical.htm Через то можно указывать критерий.

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

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

Мы опять вернулись к началу. Нужно использовать событийную модель. Как это сделать я показал в документации.

Thanks:

Roman0

Avatar
Date: 4/26/2011
Reply


Mikhail Sukhov:

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

Если просто MakePeriodica(), то бесконечно. Если через перегруженный метод http://stocksharp.com/doc/help/html/O_T_Ecng_Trading_Algo_Strategies_ActionRule_MakePeriodical.htm Через то можно указывать критерий.

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

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

Мы опять вернулись к началу. Нужно использовать событийную модель. Как это сделать я показал в документации.

Проблема, для меня по крайней мере, в том, что в документации фрагменты кода, а работающего примера нет. Спасибо за ответы!

Thanks:

Mikhail Sukhov

Avatar
Date: 4/26/2011
Reply


Roman0: Проблема, для меня по крайней мере, в том, что в документации фрагменты кода, а работающего примера нет. Спасибо за ответы!

У вас как с языком C#? Событийная модель построена на делегатах, Action и Func. Прочитайте что это такое и как используется. Я подозреваю, что вы просто подошли к задаче не с того конца.

Thanks:

Roman0

Avatar
Date: 4/27/2011
Reply


Mikhail Sukhov:

Roman0: Проблема, для меня по крайней мере, в том, что в документации фрагменты кода, а работающего примера нет. Спасибо за ответы!

У вас как с языком C#? Событийная модель построена на делегатах, Action и Func. Прочитайте что это такое и как используется. Я подозреваю, что вы просто подошли к задаче не с того конца. Я недавно начал разбираться со всем этим и вроде бы более менее разобрался, по крайней мере с Action и Func [smile] (прямо из закладок ссылки, может кому будет интересно [smile] http://msdn.microsoft.com/ru-ru/library/dd460699 http://msdn.microsoft.com/ru-ru/library/ms173171(v=VS.90).aspx http://msdn.microsoft.com/ru-ru/library/bb397687(v=VS.90).aspx

Все-таки было бы очень желательно, чтобы такие ключевые вещи имели более подробные объяснения (см. например http://stocksharp.com/forum/1287/ и http://stocksharp.com/forum/1214/ActionStrategy-chastota-provierki-1-siek/ ) и рабочие примеры с разнообразными вариантами применения. А уж с какой целью "делать событие периодичным" ( http://stocksharp.com/doc/help/html/8c0327db-494a-4fe0-aba8-0d4b93dea60e.htm ) и что и как конкретно делает MakePeriodical (про собственно период до сих пор ничего не известно [smile]) из описания малопонятно. Я подозреваю, что там все просто и логично, но из документации это сразу понять для начинающего все-таки сложновато (не претендую на суперсообразительность [smile]).

UPD Еще добавлю для ясности: я не использую импорт из таблицы всех сделок и CandleManager для формирования свечей. И вот эти два замечания несколько меня дезориентировали:

ustas: Так всё таки проверка выполнения условия When в ActionStrategy - происходит ежесекундно , а не по событию? Mikhail Sukhov: Да, ActionStrategy с некоторым периодом смотрит на появления сигналов от условий. Уменьшать такой период можно через Strategy.Interval.

Mikhail Sukhov: ActionToken - это структура, которая содержит условие и действие. ActionStrategy проверяет (периодически?) коллекцию таких токенов путем вызова условия Было бы хорошо, если бы механизм работы стратегии, в частности по обработке зарегистрированных условий, был бы где-то четко описан. Наверное для старожилов все уже с этим ясно, но ведь появляются и новички [smile]

Thanks:
< 1 2 

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

loading
clippy