C# 在 NinjaScript 的数组中查找 Min

C# find Min in an array for NinjaScript

我是编码新手,我正在尝试用 C# 为 NinjaScript / NinjaTrader 编写一些代码,希望有人能提供帮助。 我有一个变量“tovBullBar”,它在三分钟内计算某种类型的价格柱的一些值。在此期间可能会出现不止一个这样的柱状图。这些值都计算正确,我可以在输出 window 中看到它们。我正在尝试使用一个数组来识别具有该时段内最小计算值的柱,以便该值可能包含在我的 netLvtTOV 最终计算中。但是,我的最终计算始终以该期间的最后一个“tovBullBar”值结束,而不是具有最小值的那个。你能看看我的代码,看看你能不能告诉我哪里出错了?

我已经为数组中的最多 10 个元素编写了代码,但它们几乎肯定会更少,并且每 3 分钟会发生变化。看了这里的一些帖子后,我想我应该使用动态列表(稍后我将不得不考虑),但看不出为什么它不应该与数组一起使用只要我的元素数量define 超出了我的需要。

谢谢!

#region Using declarations
using System;
using System.Linq;
#endregion

#region Variables
//Declare an array that will hold data for tovBullBar
private double[] tovBull;
private int length = 10;
#endregion

protected override void Initialize()
{
    //specify the number of elements in the array, which is the
    integer called length
    tovBull = new double[length];
}

protected override void OnBarUpdate()
{
    //the array now contains the number length of object references that need to be set to instances of objects
   for (int count = 0; count<length; count++)
       tovBull[count]=tovBullBar;

   //Do a for loop to find the minimum for the tovBull
   double tovBullBarMin = tovBull[0];

   for (int count = 0; count < tovBull.Length; count++)
       if (tovBullBarMin > tovBull[count]) 
           tovBullBarMin = tovBull[count];  

   netLvtTOV = Math.Round((tovBearBar + tovBullBarMin + lvtBullBar)
   Print (Time.ToString()+" "+"ArrayLength:"+tovBull.Length);
}

查看 OnBarUpdate 方法开头的这段代码:

for (int count = 0; count<length; count++)
    tovBull[count]=tovBullBar;

这会将数组的所有成员设置为相同的值。

然后您遍历同一个数组以找到具有最低值的数组。

for (int count = 0; count < tovBull.Length; count++)
   if (tovBullBarMin > tovBull[count]) 
       tovBullBarMin = tovBull[count];  

所以当然他们最终都会得到相同的值...

我认为你想在方法开始时做的是 'push' 在你找到最新值之前将最新值放入数组中,方法是简单地将数组中的一个一个地洗牌,然后将最新的添加到数组的前面:

for (int count = 1; count<length; count++)
    tovBull[count]= tovBull[count - 1];

tovBull[0] = tovBullBar;

请注意,由于您没有初始化 tovBull 数组元素,因此它们一开始都将为零。所以你可能需要做这样的事情:

tovBull = new double[length];

for (int i = 0; i < tovBull.Length; i++)
    tovBull[i] = double.MaxValue;

那么最后的比较会给你正确的结果。

如果您只在最后 n 分钟内查看值时遇到问题,则需要多做一些工作。

首先你需要有一个小的class来记录时间和价值:

private class BarEvent
{
    public readonly DateTime Time;
    public readonly double Value;

    public BarEvent(double value)
    {
       Value = value;
       Time = DateTime.Now;
    }
}

然后,不要将 tovBull 作为双精度数组,而是将其更改为:

List<BarEvent> tovBull = new List<BarEvent>();

并按如下方式更改 OnBarUpdate:

protected override void OnBarUpdate()
{
   // first remove all items more than 3 minutes old
   DateTime oldest = DateTime.Now - TimeSpan.FromMinutes(3);
   tovBull.RemoveAll(be => be.Time < oldest);

   // add the latest value
   tovBull.Add(new BarEvent(tovBullBar));

   //Find the minimum for the tovBull using linq
   double tovBullBarMin = tovBull.Min(be => be.Value);

  netLvtTOV = Math.Round((tovBearBar + tovBullBarMin + lvtBullBar)
  Print (Time.ToString()+" "+"ArrayLength:"+tovBull.Count);
}