интерфейс ICandleSource
Atom
02.05.2011
Дмитрий


Доброе время суток. Можете показать пример реализации интерфейса ICandleSource?


Теги:


Спасибо:


Mikhail Sukhov

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


Дмитрий: Доброе время суток. Можете показать пример реализации интерфейса ICandleSource?

Посмотрите те, что идут стандартно в S#. Какое поведение хотите добиться?

Спасибо:

Дмитрий

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


Мне надо на график выводить данные из массива (не из объекта trader). В примерах есть что-то подобное? Я не совсем понимаю, как реализовать методы addTrade и getTrades. Да и с событием не совсем понятно ) Как его фаерить, если у меня массив на входе?

Может у Вас были похожие задачи, где этот интерфес реализовывался для каких-то целей? Кусок кода бы...

Спасибо:

Mikhail Sukhov

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


Дмитрий: Мне надо на график выводить данные из массива (не из объекта trader). В примерах есть что-то подобное? Я не совсем понимаю, как реализовать методы addTrade и getTrades. Да и с событием не совсем понятно ) Как его фаерить, если у меня массив на входе?

Может у Вас были похожие задачи, где этот интерфес реализовывался для каких-то целей? Кусок кода бы...

Как-то так:

class MySource : ICandleSource
{
   public void AddTrades(Trade[] array)
   {
      /* нужно куда то сохранить для ICandleSource.Trades */
      NewTrades.SafeInvoke(array);
   }
}

и из кода соответственно вызывать метод AddTrades

Спасибо:

Дмитрий

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


А можете релизацию этого интерфейса в объекте trader показать? Пусть даже сильно обрезанную. Чтобы все методы и событие интерфейса были описаны. Честно говоря, из этого кода по-прежнему не ясно, что делать.

Я правильно понял, что мой класс будет забирать данные из массива, и класть их в MySource.Trades именно в методе AddTrades? И какая специфика есть в SafeInvoke? Что-то с многопоточностью связанное?

Спасибо:

Mikhail Sukhov

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


Дмитрий: А можете релизацию этого интерфейса в объекте trader показать? Пусть даже сильно обрезанную. Чтобы все методы и событие интерфейса были описаны. Честно говоря, из этого кода по-прежнему не ясно, что делать.

Я правильно понял, что мой класс будет забирать данные из массива, и класть их в MySource.Trades именно в методе AddTrades? И какая специфика есть в SafeInvoke? Что-то с многопоточностью связанное?


namespace Ecng.Trading.Algo.Candles
{
	using System;
	using System.Collections.Generic;
	using System.Linq;
	using System.Threading;

	using Ecng.Collections;
	using Ecng.Common;
	using Ecng.Trading.BusinessEntities;

	/// <summary>
	/// Базовый источник тиковых сделок для <see cref="CandleManager"/>, получаемых через событие <see cref="ITrader.NewTrades"/>.
	/// </summary>
	public abstract class TraderCandleSource : Disposable, ICandleSource
	{
		private readonly int _maxTradeCount;
		private readonly int _maxCandleCount;
		private readonly SynchronizedList<Trade> _trades;
		private readonly SynchronizedDictionary<Candle, SynchronizedList<Trade>> _candleTrades;

		/// <summary>
		/// Инициализировать <see cref="TraderCandleSource"/>.
		/// </summary>
		/// <param name="trader">Торговый шлюз, у которого используется событие <see cref="ITrader.NewTrades"/>.</param>
		/// <param name="maxTradeCount">Максимальное количество сделок, которые нужно хранить.</param>
		/// <param name="maxCandleCount">Максимальное количество свечек, которые нужно хранить.</param>
		protected TraderCandleSource(ITrader trader, int maxTradeCount, int maxCandleCount)
		{
			if (trader == null)
				throw new ArgumentNullException("trader");

			this.Trader = trader;
			this.Trader.NewTrades += OnNewTrades;

			_maxTradeCount = maxTradeCount;
			_maxCandleCount = maxCandleCount;
			_trades = new SynchronizedList<Trade>(100000);
			_candleTrades = new SynchronizedDictionary<Candle, SynchronizedList<Trade>>(1000);
		}

		/// <summary>
		/// Шлюз к торговой системе.
		/// </summary>
		public ITrader Trader { get; private set; }

		/// <summary>
		/// Событие появления всех новых сделок.
		/// </summary>
		public event Action<IEnumerable<Trade>> NewTrades;

		/// <summary>
		/// Все накопленные сделки.
		/// </summary>
		public virtual IEnumerable<Trade> Trades
		{
			get { return _trades.SyncGet(c => c.ToArray()); }
		}

		/// <summary>
		/// Добавить сделку для свечки.
		/// </summary>
		/// <param name="candle">Свечка, для которой нужно добавить сделку.</param>
		/// <param name="trade">Новая сделка.</param>
		public void AddTrade(Candle candle, Trade trade)
		{
			_candleTrades.SafeAdd(candle).Add(trade);

			if (_candleTrades.Count > _maxCandleCount * 1.5)
			{
				_candleTrades.SyncDo(c =>
				{
					var elapsed = c.Skip(_maxCandleCount / 2).ToArray();
					c.Clear();
					c.AddRange(elapsed);
				});
			}
		}

		/// <summary>
		/// Получить все сделки по свечке.
		/// </summary>
		/// <param name="candle">Свечка, по которой нужно найти сделки.</param>
		/// <returns>Найденные сделки.</returns>
		public IEnumerable<Trade> GetTrades(Candle candle)
		{
			var trades = _candleTrades.TryGetValue(candle);
			return trades != null ? trades.SyncGet(c => c.ToArray()) : new Trade[0];
		}

		/// <summary>
		/// Обработчик события <see cref="ITrader.NewTrades"/>.
		/// </summary>
		/// <param name="trades">Новые сделки.</param>
		protected virtual void OnNewTrades(IEnumerable<Trade> trades)
		{
			_trades.AddRange(trades);

			if (_trades.Count > _maxTradeCount * 1.5)
			{
				_trades.SyncDo(c =>
				{
					var elapsed = c.Skip(_maxTradeCount / 2).ToArray();
					c.Clear();
					c.AddRange(elapsed);
				});
			}
		}

		/// <summary>
		/// Вызвать событие <see cref="NewTrades"/>.
		/// </summary>
		/// <param name="trades">Новые сделки.</param>
		protected void RaiseNewTrades(IEnumerable<Trade> trades)
		{
			this.NewTrades.SafeInvoke(trades);
		}

		/// <summary>
		/// Освободить занятые ресурсы.
		/// </summary>
		protected override void DisposeManaged()
		{
			this.Trader.NewTrades -= OnNewTrades;
			base.DisposeManaged();
		}
	}

	/// <summary>
	/// Источник тиковых сделок для <see cref="CandleManager"/>, получаемых через событие <see cref="ITrader.NewTrades"/>, 
	/// и отправляемый в <see cref="CandleManager"/> с определенным интервалом.
	/// </summary>
	public class ParallelTraderCandleSource : TraderCandleSource
	{
		private readonly SynchronizedList<Trade> _newTrades = new SynchronizedList<Trade>();

		private bool _isInProcess;
		private readonly Timer _timer;

		/// <summary>
		/// Создать <see cref="ParallelTraderCandleSource"/>.
		/// </summary>
		/// <param name="trader">Торговый шлюз, у которого используется событие <see cref="ITrader.NewTrades"/>.</param>
		public ParallelTraderCandleSource(ITrader trader)
			: this(trader, TimeSpan.FromMilliseconds(300))
		{
		}

		/// <summary>
		/// Создать <see cref="ParallelTraderCandleSource"/>.
		/// </summary>
		/// <param name="trader">Торговый шлюз, у которого используется событие <see cref="ITrader.NewTrades"/>.</param>
		/// <param name="interval">Интервал отправки новых сделок.</param>
		public ParallelTraderCandleSource(ITrader trader, TimeSpan interval)
			: base(trader, int.MaxValue, int.MaxValue)
		{
			if (trader == null)
				throw new ArgumentNullException("trader");

			_timer = interval.CreateTimer(OnProcessTrades);
		}

		/// <summary>
		/// Обработчик события <see cref="ITrader.NewTrades"/>.
		/// </summary>
		/// <param name="trades">Новые сделки.</param>
		protected override void OnNewTrades(IEnumerable<Trade> trades)
		{
			base.OnNewTrades(trades);

			_newTrades.AddRange(trades);
		}

		private void OnProcessTrades()
		{
			if (_isInProcess)
				return;

			_isInProcess = true;

			try
			{
				var newTrades = _newTrades.SyncGet(c =>
				{
					var retVal = c.ToArray();
					c.Clear();
					return retVal;
				});

				if (newTrades.Length > 0)
					base.RaiseNewTrades(newTrades);
			}
			finally
			{
				_isInProcess = false;
			}
		}

		/// <summary>
		/// Освободить занятые ресурсы.
		/// </summary>
		protected override void DisposeManaged()
		{
			_timer.Dispose();
			base.DisposeManaged();
		}
	}

	/// <summary>
	/// Источник тиковых сделок для <see cref="CandleManager"/>, получаемых через событие <see cref="ITrader.NewTrades"/>,
	/// и хранящий последние полученные сделки за определенный период.
	/// </summary>
	public class SyncTraderCandleSource : TraderCandleSource
	{
		/// <summary>
		/// Создать <see cref="SyncTraderCandleSource"/>.
		/// </summary>
		/// <param name="trader">Торговый шлюз, у которого используется событие <see cref="ITrader.NewTrades"/>.</param>
		public SyncTraderCandleSource(ITrader trader)
			: this(trader, 100000, 1000)
		{
		}

		/// <summary>
		/// Создать <see cref="SyncTraderCandleSource"/>.
		/// </summary>
		/// <param name="trader">Торговый шлюз, у которого используется событие <see cref="ITrader.NewTrades"/>.</param>
		/// <param name="maxTradeCount">Максимальное количество сделок, которые нужно хранить.</param>
		/// <param name="maxCandleCount">Максимальное количество свечек, которые нужно хранить.</param>
		public SyncTraderCandleSource(ITrader trader, int maxTradeCount, int maxCandleCount)
			: base(trader, maxTradeCount, maxCandleCount)
		{
		}

		/// <summary>
		/// Обработчик события <see cref="ITrader.NewTrades"/>.
		/// </summary>
		/// <param name="trades">Новые сделки.</param>
		protected override void OnNewTrades(IEnumerable<Trade> trades)
		{
			base.OnNewTrades(trades);
			base.RaiseNewTrades(trades);
		}
	}
}

Спасибо:

Дмитрий

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


Спасибо большое! Буду разбираться..

Спасибо:


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

loading
clippy