【问题标题】:trading: how do you declare `Indicator` interface交易:如何声明`Indicator`接口
【发布时间】:2011-12-11 13:35:59
【问题描述】:

我曾尝试在“量化金融”上问这个问题,但似乎这是一个更好的地方,因为这个问题更多地是关于编程而不是交易

Indicator接口如何声明?建模“指标”的正确方法是什么?

我正在使用 c#,我想像这样声明Indicator 接口:

interface Indicator
{
    double Value { get; }
    event Action<Void> ValueUpdated;
}

或者甚至可能是这样的:

interface Indicator
{
    event Action<Double> ValueUpdated;
}

我认为“纯价格”也是微不足道的指标:

class PriceIndicator : Indicator {
    PriceIndicator(string ticker) {
        ....
    }
}

MA 示例:

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
}

你怎么看?欢迎提出任何建议!

【问题讨论】:

  • 好的,但是你的问题是什么?你的代码不起作用吗?
  • 我一定遗漏了一些东西——真正的问题是什么?您发布的接口声明很好。
  • 问题是如何声明Indicator接口和对应的实现(例如Moving Average)。将“纯价格”视为指标是否好。使用event 通知值已更新好还是使用某种计时器或其他技术更好
  • 如果有人知道一些已经在 C# 链接上声明 Indicator Moving average 等的代码的链接,非常欢迎
  • 你可能想看看 Ninjatrader 看看它是如何在那里实现的。我不会因为某个事件而使指标自动更新,而是有另一个类来执行它,指标的抽象意味着它知道如何计算一个值,但它不需要知道何时执行它的责任.但如果没有更多关于您的解决方案的背景信息,真的很难说

标签: c# trading algorithmic-trading domain-data-modelling


【解决方案1】:

我想要这样的东西

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 实现)

【讨论】:

  • 谢谢!但是如何解决“过度计算”的问题呢?假设我有 100 个策略,每个策略都使用相同的指标(sp500 上的 MA 就是一个很好的例子)。当新的一堆数据到达时,所有 100 个策略都需要新值,这将导致对相同数据进行 100 次计算,这在 hft 中是相当糟糕的......
  • 那么您可以像在您的示例中那样在构造函数中发送实例,并为所有指标仅使用一个。或者您可以使用缓存(因此如果当前柱还没有值,MA 只会重新计算自身)
  • 在 MA 的情况下,也不清楚计算的工作原理。当我在收到新值时更新值时,我只需要丢弃最旧的值并添加新值,这是O(1) 操作。在你的情况下,MA 将是 O(n) 和更糟糕的 const - 实际上是 100 * O(n) 而不是 1 * O(1)
  • 我刚刚发布了一个示例,当然指标需要以某种方式共享价格序列数据。我再次建议您看看指标是如何在 metatrader 中实现的。
  • 我不知道在哪里下载 metatrader 或 ninjatrader 源文件,我在想这是有私人来源的私人项目
【解决方案2】:

就我的理解而言,指标应该在市场数据中发生有趣的事情之后执行一些操作。这意味着界面必须对所有有趣的事件发出警报,这些事件可能是纯市场数据事件或由其他指标触发的事件。我只有一个非常简单的界面,它接收市场数据事件并返回一些事件以由系统的其他部分解释。此事件将被分派到一个大型内部事件队列。

 interface Indicator {
     Event processEvent(MarketDataEvent e);
 } 

因此,MarketDataEvents 流要么直接来自市场,要么来自其他指标,然后一旦在 processEvent 方法中满足某个阈值或条件,该方法将返回要部署的非空事件到内部事件队列,否则这个方法只会返回空值。

【讨论】:

    【解决方案3】:

    首先,我会先弄清楚您是否真的有需要解决的问题。接口是保证在消费者调用时存在特定功能(方法、属性等)的契约。

    因此,如果您实际上不需要接口,我就不会使用。然而,作为 NinjaTrader 中的一个工作示例,我们创建了一个名为“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...
            }
        }
    }
    

    我们首先检查它是否是绘图工具。如果没有,我们忽略它。

    然后我们检查它是否实现了我们的 ITradeZone 接口。如果是这样,那么我们知道我们可以调用该接口所保证的特定功能,在本例中为 CreatedByTradeManager 属性。

    (请注意,也可以检查对象实例的类型名称甚至标签值,但标签可以由用户更改,如果对象的名称发生更改,那么这也可能是失败的条件.)

    【讨论】:

      猜你喜欢
      • 2012-03-19
      • 1970-01-01
      • 2022-07-23
      • 2016-12-24
      • 2017-04-21
      • 2018-01-19
      • 2010-09-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多