[英]Ta-Lib ATR function always returns 0
我在C#中使用Ta-Lib,并且在大多数情况下它都很好用。 我用它来计算许多移动平均线,并且它们计算得很好。
调用ATR函数时,它将始终返回0。 我使用与SMA相同的参数(重叠的参数),但仍为0。这是有问题的代码。 成员变量Period是一个整数。 队列中的数据多于我要求它计算的时间段,并且队列中的数据是干净的,我对此进行了三重检查。 返回码为成功,但返回值为0。
int outbegldx = 0;
int outnbelement = 0;
Queue<double> inputHigh = new Queue<double>();
Queue<double> inputLow = new Queue<double>();
Queue<double> inputClose = new Queue<double>();
//This is in a loop
inputHigh.Enqueue(Convert.ToDouble(rdr.GetDecimal(5)));
inputLow.Enqueue(Convert.ToDouble(rdr.GetDecimal(6)));
inputClose.Enqueue(Convert.ToDouble(rdr.GetDecimal(7)));
double[] outreal = new double[inputHigh.Count];
retCode = TicTacTec.TA.Library.Core.Atr(0, inputHigh.Count - 1, inputHigh.ToArray(), inputLow.ToArray(), inputClose.ToArray(), this.Period, out outbegldx, out outnbelement, outreal);
if (retCode == Core.RetCode.Success)
{
this.Output = new AverageTrueRangeOutput(this.Period, outreal[0], outbegldx, outnbelement);
}
好吧,我想通了,终于经过了许多小时。 在我的循环中,我正在检查以确保数组具有与Period相同数量的元素,如果是,则执行计算。 实际上,该数组需要Period + 1个元素来执行计算。 这是我的全部功能。
public override void Calculate()
{
int outbegldx = 0;
int outnbelement = 0;
int marketID = 0;
TicTacTec.TA.Library.Core.RetCode retCode;
//Queue<OHLC> input = new Queue<OHLC>();
Queue<double> inputHigh = new Queue<double>();
Queue<double> inputLow = new Queue<double>();
Queue<double> inputClose = new Queue<double>();
using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.DB_CONNECTION_STRING))
{
using (SqlCommand cmd = new SqlCommand("[Data].[proc_GetHistoricalData]", conn))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("@StartIndex", SqlDbType.Int);
cmd.Parameters.Add("@EndIndex", SqlDbType.Int);
cmd.Parameters.Add("@Weekly", SqlDbType.Bit);
cmd.Parameters["@StartIndex"].Value = this.startIndex;
cmd.Parameters["@EndIndex"].Value = this.endIndex;
cmd.Parameters["@Weekly"].Value = (int)this.TimeFrame;
conn.Open();
using (SqlDataReader rdr = cmd.ExecuteReader())
{
while (rdr.Read())
{
Console.WriteLine(rdr.GetInt64(0));
if (marketID != rdr.GetInt32(2))
{
marketID = rdr.GetInt32(2);
inputHigh.Clear();
inputLow.Clear();
inputClose.Clear();
}
//input.Enqueue(new OHLC(rdr.GetDecimal(4), rdr.GetDecimal(5), rdr.GetDecimal(6), rdr.GetDecimal(7)));
inputHigh.Enqueue(Convert.ToDouble(rdr.GetDecimal(5)));
inputLow.Enqueue(Convert.ToDouble(rdr.GetDecimal(6)));
inputClose.Enqueue(Convert.ToDouble(rdr.GetDecimal(7)));
//We have enough data to calculate the ATR so do so
if (inputHigh.Count >= this.Period + 1)
{
double[] outreal = new double[inputHigh.Count - 1];
int lookBack = Core.AtrLookback(this.Period);
retCode = Core.Atr(0, inputHigh.Count - 1, inputHigh.ToArray(), inputLow.ToArray(), inputClose.ToArray(), lookBack, out outbegldx, out outnbelement, outreal);
//Calculated the ATR, now write it to the database
if (retCode == Core.RetCode.Success)
{
this.Output = new AverageTrueRangeOutput(this.Period, outreal[0], outbegldx, outnbelement);
//Now insert into db
using (SqlCommand cmdInsert = new SqlCommand("[Data].[proc_InsertHistoricalIndicator]", conn))
{
cmdInsert.CommandType = CommandType.StoredProcedure;
cmdInsert.Parameters.Add("@MarketID", SqlDbType.Int);
cmdInsert.Parameters.Add("@IndicatorID", SqlDbType.Int);
cmdInsert.Parameters.Add("@Date", SqlDbType.Date);
cmdInsert.Parameters.Add("@Value", SqlDbType.Xml);
cmdInsert.Parameters.Add("@Weekly", SqlDbType.Bit);
cmdInsert.Parameters["@MarketID"].Value = rdr.GetInt32(2);
cmdInsert.Parameters["@IndicatorID"].Value = this.Id;
cmdInsert.Parameters["@Weekly"].Value = (int)this.TimeFrame;
cmdInsert.Parameters["@Date"].Value = rdr.GetDateTime(3); //IBLib.Util.GetDate(
cmdInsert.Parameters["@Value"].Value = this.Output.toXML().OuterXml;
cmdInsert.ExecuteNonQuery();
}
}
inputHigh.Dequeue();
inputLow.Dequeue();
inputClose.Dequeue();
}
}
rdr.Close();
}
}
}
}
问题所在的行是这一行-“ if(inputHigh.Count> = this.Period + 1)”,而以前我只有“ if(inputHigh.Count> = this.Period)”
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.