Algorithmischer Handel für .NET und Python✦86+ Konnektoren · Börsen · Broker · Krypto✦S#.Designer · Backtest · optimieren · live gehen✦Eine Community von 31,467+ Tradern und Entwicklern✦Algorithmischer Handel für .NET und Python✦86+ Konnektoren · Börsen · Broker · Krypto✦S#.Designer · Backtest · optimieren · live gehen✦Eine Community von 31,467+ Tradern und Entwicklern✦
Мне надо на график выводить данные из массива (не из объекта trader).
В примерах есть что-то подобное?
Я не совсем понимаю, как реализовать методы addTrade и getTrades. Да и с событием не совсем понятно ) Как его фаерить, если у меня массив на входе?
Может у Вас были похожие задачи, где этот интерфес реализовывался для каких-то целей? Кусок кода бы...
Дмитрий:
Мне надо на график выводить данные из массива (не из объекта trader).
В примерах есть что-то подобное?
Я не совсем понимаю, как реализовать методы addTrade и getTrades. Да и с событием не совсем понятно ) Как его фаерить, если у меня массив на входе?
Может у Вас были похожие задачи, где этот интерфес реализовывался для каких-то целей? Кусок кода бы...
Как-то так:
class MySource : ICandleSource
{
public void AddTrades(Trade[] array)
{
/* нужно куда то сохранить для ICandleSource.Trades */
NewTrades.SafeInvoke(array);
}
}
А можете релизацию этого интерфейса в объекте trader показать? Пусть даже сильно обрезанную. Чтобы все методы и событие интерфейса были описаны.
Честно говоря, из этого кода по-прежнему не ясно, что делать.
Я правильно понял, что мой класс будет забирать данные из массива, и класть их в MySource.Trades именно в методе AddTrades? И какая специфика есть в SafeInvoke? Что-то с многопоточностью связанное?
Дмитрий:
А можете релизацию этого интерфейса в объекте 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);
}
}
}
Wir verwenden Cookies, um die beste Erfahrung auf unserer Website zu gewährleisten. Durch die weitere Nutzung unserer Seite stimmen Sie der Verwendung von Cookies zu.
Kommentare (6)
Anmelden oder Konto erstellen, Melden Sie sich an oder registrieren Sie sich, um einen Kommentar zu hinterlassen
Посмотрите те, что идут стандартно в S#. Какое поведение хотите добиться?
Мне надо на график выводить данные из массива (не из объекта trader). В примерах есть что-то подобное? Я не совсем понимаю, как реализовать методы addTrade и getTrades. Да и с событием не совсем понятно ) Как его фаерить, если у меня массив на входе?
Может у Вас были похожие задачи, где этот интерфес реализовывался для каких-то целей? Кусок кода бы...
Как-то так:
и из кода соответственно вызывать метод AddTrades
А можете релизацию этого интерфейса в объекте trader показать? Пусть даже сильно обрезанную. Чтобы все методы и событие интерфейса были описаны. Честно говоря, из этого кода по-прежнему не ясно, что делать.
Я правильно понял, что мой класс будет забирать данные из массива, и класть их в MySource.Trades именно в методе AddTrades? И какая специфика есть в SafeInvoke? Что-то с многопоточностью связанное?
Спасибо большое! Буду разбираться..