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);
}
我是编码新手,我正在尝试用 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);
}