Торговля: как вы объявляете интерфейс индикатора
Я пытался задать этот вопрос в "количественных финансах", но, похоже, это лучшее место, потому что вопрос больше о программировании, чем о торговле
Как вы заявляете Indicator
интерфейс? Как правильно моделировать "Индикатор"?
Я использую C#, и я хочу объявить Indicator
интерфейс, как это:
interface Indicator
{
double Value { get; }
event Action<Void> ValueUpdated;
}
или, возможно, даже так:
interface Indicator
{
event Action<Double> ValueUpdated;
}
Я считаю "чистую цену" также тривиальным показателем:
class PriceIndicator : Indicator {
PriceIndicator(string ticker) {
....
}
}
Пример МА:
class MovingAverage : Indicator {
private PriceIndicator price;
public MovingAverage(PriceIndicator price, int period) {
....
}
// when price.ValueUpdated event occurs need to recalculate MA and raise ValueUpdated event
}
Как вы думаете? Любые предложения приветствуются!
3 ответа
Насколько я понимаю, Индикатор должен выполнить какое-то действие после чего-то интересного, как это произошло в рыночных данных. Это означает, что интерфейс должен быть предупрежден обо всех интересных событиях, это могут быть события чисто рыночных данных или события, вызванные другими индикаторами. У меня был бы очень простой интерфейс, который принимает событие рыночных данных и возвращает какое-то событие в интерпретацию какой-либо другой части системы. Это событие будет отправлено в большую внутреннюю очередь событий.
interface Indicator {
Event processEvent(MarketDataEvent e);
}
Таким образом, поток MarketDataEvents поступает либо непосредственно из рынка, либо из какого-либо другого индикатора, а затем, как только определенное пороговое значение или условие встречается в методе processEvent, метод возвращает ненулевое событие, которое должно быть развернуто во внутреннем очередь событий, в противном случае этот метод просто возвращает нулевые значения.
Я бы хотел что-то подобное
public interface IIndicator
{
double Calculate();
}
Таким образом, составленный индикатор может быть
public class CompositeIndicator: IIndicator
{
private MovingAverage _ma;
public CompositeIndicator(/* your parameters here */)
{
_ma = new MovingAverage();
}
public double Calculate()
{
var mavalue = _ma.Calculate();
//do more stuff
return mavalue;
}
}
Тогда компонент, который знает все индикаторы, которые необходимо рассчитать, будет вызывать этот метод каждый раз, когда изменяется цена, и отображать это на графике или где-то еще.
Действительно, эта проблема уже решена во многих существующих приложениях, некоторые примеры, которые вы можете проверить, это Ninjatrader (реализовано в C#) или Metatrader (реализовано с c)
Во-первых, я бы начал с выяснения, действительно ли у вас есть проблема, требующая решения. Интерфейс - это контракт, который гарантирует наличие определенных функций (методов, свойств и т. Д.) При вызове потребителем.
Так что, если вам на самом деле не нужен интерфейс, я бы не стал его использовать. Однако в качестве рабочего примера в NinjaTrader мы создали специальный инструмент DrawingTool под названием «TradeZone». Этот инструмент рисования имеет определенные функции, которые должны быть доступны другим индикаторам.
Единственный способ гарантировать, что проверяемый инструмент рисования имеет необходимую функциональность, - это использовать интерфейс. Например, посмотрите на следующий код, который выполняет итерацию по объектам в диаграмме.
for (int i = chartControl.ChartObjects.Count - 1; i >= 0; i--)
{
Gui.NinjaScript.IChartObject chartObject = chartControl.ChartObjects[i];
if ((chartObject is DrawingTool) == false) continue;
if (chartObject is ITradeZone)
{
ITradeZone tradeZone = chartObject as ITradeZone;
if (tradeZone.CreatedByTradeManager)
{
// Do stuff with the tradeZone object...
}
}
}
Сначала мы проверяем, является ли это DrawingTool. В противном случае мы игнорируем это.
Затем мы проверяем, реализует ли он наш интерфейс ITradeZone. Если это так, то мы знаем, что можем вызывать определенные функции, гарантированные этим взаимодействием, в данном случае свойство CreatedByTradeManager .
(Обратите внимание, что можно также проверить имя типа или даже значение тега экземпляра объекта, но тег может быть изменен пользователем, и если имя объекта когда-либо изменится, это также может быть неудачным условием.)