2015-04-20 71 views
1

我试图建立一个类来创建Aroon系列。但似乎我不明白这些步骤。我不确定我必须使用period参数的目的。计算Aroon指标系列

这是我第一次尝试:

/// <summary> 
/// Aroon 
/// </summary> 
public class Aroon : IndicatorCalculatorBase 
{ 
    public override List<Ohlc> OhlcList { get; set; } 
    public int Period { get; set; } 

    public Aroon(int period) 
    { 
     this.Period = period; 
    } 

    /// <summary> 
    /// Aroon up: {((number of periods) - (number of periods since highest high))/(number of periods)} x 100 
    /// Aroon down: {((number of periods) - (number of periods since lowest low))/(number of periods)} x 100 
    /// </summary> 
    /// <see cref="http://www.investopedia.com/ask/answers/112814/what-aroon-indicator-formula-and-how-indicator-calculated.asp"/> 
    /// <returns></returns> 
    public override IIndicatorSerie Calculate() 
    { 
     AroonSerie aroonSerie = new AroonSerie(); 

     int indexToProcess = 0; 

     while (indexToProcess < this.OhlcList.Count) 
     { 
      List<Ohlc> tempOhlc = this.OhlcList.Skip(indexToProcess).Take(Period).ToList(); 
      indexToProcess += tempOhlc.Count; 

      for (int i = 0; i < tempOhlc.Count; i++) 
      { 
       int highestHighIndex = 0, lowestLowIndex = 0; 
       double highestHigh = tempOhlc.Min(x => x.High), lowestLow = tempOhlc.Max(x => x.Low); 
       for (int j = 0; j < i; j++) 
       { 
        if (tempOhlc[j].High > highestHigh) 
        { 
         highestHighIndex = j; 
         highestHigh = tempOhlc[j].High; 
        } 

        if (tempOhlc[j].Low < lowestLow) 
        { 
         lowestLowIndex = j; 
         lowestLow = tempOhlc[j].Low; 
        } 
       } 

       int up = ((this.Period - (i - highestHighIndex))/this.Period) * 100; 
       aroonSerie.Up.Add(up); 

       int down = ((this.Period - (i - lowestLowIndex))/this.Period) * 100; 
       aroonSerie.Down.Add(down); 
      } 
     } 

     return aroonSerie; 
    } 
} 

是否有其他人想这样做之前?

下面是CSV文件我用:

https://drive.google.com/file/d/0Bwv_-8Q17wGaRDVCa2FhMWlyRUk/view

但结果集阿隆上下不阿隆功能的TTR包的结果R.

table <- read.csv("table.csv", header = TRUE, sep = ",") 
trend <- aroon(table[,c("High", "Low")], n=5) 
View(trend) 
匹配

截图ř结果:

enter image description here

在此先感谢,

+0

扩大你的问题,以添加你正在遇到的问题。你给了什么投入?你的预期产出是什么?你的实际产出是多少? –

+0

@SteveMitcham我已经更新了我的问题。 – anilca

+0

你的结果与R结果有什么不同?我不是这里的专家,但你提供的信息越多,就越有可能有人能够明白为什么会有差异。 –

回答

1

@anilca, 充分披露添加实现方法HighestBarNum和LowestBarnum的,我学到了很多事情来回答你的问题(我也不知道,在Finetec ......)。谢谢!这是一个有趣的体验!

有几个问题在您的实现:

  1. 文中陈述:

我 - highestHighIndex

我 - 1 owestLowIndex

变量 “i” 小于或等于highestHighIndex,lowestLowIndex 所以语句:

this.Period - (I - highestHighIndex)

this.Period - (i - lowestLowIndex)

意愿返回错误的值(大多数时间...)

  • 阿隆上下两个都是百分比,因此“INT”是一个错误的数据结构体。

  • 因为在所有的变量:

  • (this.Period - (I - highestHighIndex))/ this.Period)

    (( this.Period - (i - lowestLowIndex))/ this.Period)

    是整数,你不会收到正确的价值。

  • 一件事在Excel的号码从最新到最旧的排序。(它在R封装效果)
  • 我已经实现的算法根据你的代码(和你的数据顺序...)

    public class Aroon : IndicatorCalculatorBase 
    { 
    
        public override List<OhlcSample> OhlcList { get; set; } 
        private readonly int _period; 
    
        public int Period 
        { 
         get { return _period; } 
        } 
    
        public Aroon(int period) 
        { 
         _period = period; 
        } 
    
        public override IIndicatorSerie Calculate() 
        { 
         var aroonSerie = new AroonSerie(); 
         for (var i = _period; i < OhlcList.Count; i++) 
         { 
    
          var aroonUp = CalculateAroonUp(i); 
          var aroonDown = CalculateAroonDown(i); 
    
          aroonSerie.Down.Add(aroonDown); 
          aroonSerie.Up.Add(aroonUp); 
         } 
    
         return aroonSerie; 
        } 
    
        private double CalculateAroonUp(int i) 
        { 
         var maxIndex = FindMax(i - _period, i); 
    
         var up = CalcAroon(i - maxIndex); 
    
         return up; 
        } 
    
        private double CalculateAroonDown(int i) 
        { 
         var minIndex = FindMin(i - _period, i); 
    
         var down = CalcAroon(i - minIndex); 
    
         return down; 
        } 
    
        private double CalcAroon(int numOfDays) 
        { 
         var result = ((_period - numOfDays)) * ((double)100/_period); 
         return result; 
        } 
    
        private int FindMin(int startIndex, int endIndex) 
        { 
         var min = double.MaxValue; 
         var index = startIndex; 
         for (var i = startIndex; i <= endIndex; i++) 
         { 
          if (min < OhlcList[i].Low) 
           continue; 
    
          min = OhlcList[i].Low; 
          index = i; 
         } 
         return index; 
        } 
    
        private int FindMax(int startIndex, int endIndex) 
        { 
         var max = double.MinValue; 
         var index = startIndex; 
         for (var i = startIndex; i <= endIndex; i++) 
         { 
          if (max > OhlcList[i].High) 
           continue; 
    
          max = OhlcList[i].High; 
          index = i; 
         } 
         return index; 
        } 
    } 
    
    public abstract class IndicatorCalculatorBase 
    { 
        public abstract List<OhlcSample> OhlcList { get; set; } 
    
        public abstract IIndicatorSerie Calculate(); 
    } 
    
    public interface IIndicatorSerie 
    { 
        List<double> Up { get; } 
        List<double> Down { get; } 
    } 
    
    internal class AroonSerie : IIndicatorSerie 
    { 
        public List<double> Up { get; private set; } 
        public List<double> Down { get; private set; } 
    
        public AroonSerie() 
        { 
         Up = new List<double>(); 
         Down = new List<double>(); 
        } 
    
    
    } 
    
    public class OhlcSample 
    { 
    
        public double High { get; private set; } 
        public double Low { get; private set; } 
    
        public OhlcSample(double high, double low) 
        { 
         High = high; 
         Low = low; 
        } 
    
    } 
    

    在调试时使用这种测试方法:

    private Aroon _target; 
    
        [TestInitialize] 
        public void TestInit() 
        { 
         _target=new Aroon(5) 
         { 
          OhlcList = new List<OhlcSample> 
          { 
           new OhlcSample(166.90, 163.65), 
           new OhlcSample(165.00, 163.12), 
           new OhlcSample(165.91, 163.21), 
           new OhlcSample(167.29, 165.11), 
           new OhlcSample(169.99, 166.84), 
           new OhlcSample(170.92, 167.90), 
           new OhlcSample(168.47, 165.90), 
           new OhlcSample(167.75, 165.75), 
           new OhlcSample(166.14, 161.89), 
           new OhlcSample(164.77, 161.44), 
           new OhlcSample(163.19, 161.49), 
           new OhlcSample(162.50, 160.95), 
           new OhlcSample(163.25, 158.84), 
           new OhlcSample(159.20, 157.00), 
           new OhlcSample(159.33, 156.14), 
           new OhlcSample(160.00, 157.00), 
           new OhlcSample(159.35, 158.07), 
           new OhlcSample(160.70, 158.55), 
           new OhlcSample(160.90, 157.66), 
           new OhlcSample(164.38, 158.45), 
           new OhlcSample(167.75, 165.70), 
           new OhlcSample(168.93, 165.60), 
           new OhlcSample(165.73, 164.00), 
           new OhlcSample(167.00, 164.66), 
           new OhlcSample(169.35, 165.01), 
           new OhlcSample(168.12, 164.65), 
           new OhlcSample(168.89, 165.79), 
           new OhlcSample(168.65, 165.57), 
           new OhlcSample(170.85, 166.00), 
           new OhlcSample(171.61, 169.10) 
          } 
         }; 
        } 
    
    
        [TestMethod] 
        public void JustToHelpYou() 
        { 
         var result = _target.Calculate(); 
    
         var expectedUp = new List<double>() 
         { 
          100,80,60,40,20,0,0,0, 0,0,40,20,0,100,100,100,100,80, 60,100,80,60,40,100,100 
         }; 
    
         var expectedDown = new List<double> 
         { 
          20,0,0,100,100,80,100,100,100,100,80,60,40,20,0,0,40,20,0,0,40,20,0,40,20 
         }; 
    
         Assert.IsTrue(result.Up.SequenceEqual(expectedUp)); 
         Assert.IsTrue(result.Down.SequenceEqual(expectedDown)); 
    
        } 
    
    +0

    很好的回答。非常感谢!我在这里问了同样的问题:http://quant.stackexchange.com/questions/17421/technical-analysis-calculating-aroon-indicator-serie如果你想要,你也可以在那里添加你的答案。 – anilca

    +0

    @anilca,我加了我的答案,谢谢!祝你有个愉快的一周! –

    0

    刚刚从你的代码

    public class Aroon 
    { 
        public bool AroonDown 
        { 
         get; 
         set; 
        } 
        public double Period 
        { 
         get; 
         set; 
        } 
        public Aroon() 
        { 
        } 
        public IList<double> Execute(IList<double> src) 
        { 
         if (!this.AroonDown) 
         { 
          return this.ExecuteUp(src); 
         } 
         return this.ExecuteDown(src); 
        } 
        public IList<double> ExecuteDown(IList<double> src) 
        { 
         double[] period = new double[src.Count]; 
         for (int i = 1; i < src.Count; i++) 
         { 
          double num = LowestBarNum(src, i, Period); 
          period[i] = 100 * (Period - num)/Period; 
         } 
         return period; 
        } 
        public IList<double> ExecuteUp(IList<double> src) 
        { 
         double[] period = new double[src.Count]; 
         for (int i = 1; i < src.Count; i++) 
         { 
          double num = HighestBarNum(src, i, Period); 
          period[i] = 100 * ((Period - num)/Period; 
         } 
         return period; 
        }} 
    
    +0

    我不明白如何实现LowestBarNum和HighestBarNum方法。 – anilca

    0
    class AroonData 
    { 
        public double AroonUp; 
    
        public double AroonDown; 
    } 
    

    计算类:

    class AroonCalculationData 
    { 
        public double PeriodHigh; 
    
        public double PeriodLow; 
    
        public double SetAroonUp(List<MarketData> period, double lastHigh) 
        { 
    
         /*reverse the set so we can look at it from the current tick 
         on back, and ticksSinceHigh will set correctly*/ 
         period.Reverse(); 
    
         int ticksSinceHigh = 0; 
         double high = 0.0;//Set 0 so anything will be higher 
    
         for (int i = 0; i < period.Count; i++) 
         { 
          if (period[i].high > high) 
          { 
           high = period[i].high; 
           ticksSinceHigh = i; 
          } 
         } 
    
         /*This bit if for if the high just ticked out 
         of List<MarketData>. 
         Including the current tick (i = 0), List<MarketData> period 
         only looks back (period - 1) days. 
         This Checks to see if the last high is still in the set. if it's 
         not, and is still the high for the period, then ticksSinceHigh 
         is set to (period)*/ 
         PeriodHigh = high; 
         if (PeriodHigh < lastHigh) 
         { 
          ticksSinceHigh = period.Count; 
         } 
    
         /*Aroon-Up Formula*/ 
         return (double)(period.Count - ticksSinceHigh)/(double)period.Count * 100.0; 
        } 
    
        //ASIDE FROM LOOKING FOR LOWS INSTEAD OF HIGHS, SAME AS AROON-UP 
        public double SetAroonDown(List<MarketData> period, double lastLow) 
        { 
    
         period.Reverse(); 
    
         int daysSinceLow = 0; 
         double low = double.MaxValue;//Set max so anything will be lower 
    
         for (int i = 0; i < period.Count; i++) 
         { 
          if (period[i].low < low) 
          { 
           low = period[i].low; 
           daysSinceLow = i; 
          } 
         } 
    
         PeriodLow = low; 
         if (PeriodLow > lastLow) 
         { 
          daysSinceLow = period.Count; 
         } 
    
         return (double)(period.Count - daysSinceLow)/(double)period.Count * 100.0; 
        } 
    } 
    

    调用代码:

    public AroonData[] Aroon(List<MarketData> marketData, int period) 
    { 
        AroonCalculationData[] calculationData = new AroonCalculationData[marketData.Count] 
        AroonData[] aroon= new AroonData[marketData.Count] 
    
        for (int i = period; i < marketData.Count; i++) 
        { 
         /*GetRange(i - period + 1, period) add 1 so that the current tick is 
         included in look back. 
         For example, if (period = 10) the first loop (i = 10) then (i - 
         period + 1) = 1 the set will be marketData 1 - 10.*/ 
    
         /*calculationData[i - 1].PeriodHigh and calculationData[i - 1].PeriodLow 
         are for looking back at the last tick's look back period high and 
         low*/ 
    
         data[i].AroonUp = calculationData[i].SetAroonUp(marketData.GetRange(i - period + 1, period), calculationData[i - 1].PeriodHigh); 
         data[i].AroonDown = calculationData[i].SetAroonDown(marketData.GetRange(i - period + 1, period), calculationData[i - 1].PeriodLow); 
        } 
    } 
    

    旁注: 一个问题,我在我的比较数据TD Ameritrades阿隆,直到我想通了他们的期限是真的周期 - 1,所以如果你比较TD,请记住这一点。