интерфейс 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