1

我在 C# 中使用 Ta-Lib,并且在大多数情况下它工作得很好。我用它来计算一些移动平均线,它们计算得很好。

调用 ATR 函数时,它总是返回 0。我使用与 SMA 相同的参数(重叠的参数),但仍然为 0。这是有问题的代码。成员变量 Period 是一个整数。我在队列中的数据比我要求它计算的时间多,而且我在队列中的数据是干净的,我已经三次检查过了。返回码为 Success,但返回值为 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);
    }
4

1 回答 1

2

好的,我想通了,最后经过很多很多小时。在我的循环中,我正在检查以确保数组具有与 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)”

于 2016-02-13T15:09:58.397 回答