Skip to content

Commit

Permalink
Add Aroon Indicator (Up, Down, Oscillator) with Unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
jasonlam604 committed Apr 2, 2017
1 parent c69cff6 commit 0c71dd0
Show file tree
Hide file tree
Showing 2 changed files with 170 additions and 0 deletions.
58 changes: 58 additions & 0 deletions src/com/jasonlam604/stocktechnicals/indicators/Aroon.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package com.jasonlam604.stocktechnicals.indicators;

import java.math.BigDecimal;

import com.jasonlam604.stocktechnicals.util.HighestHigh;
import com.jasonlam604.stocktechnicals.util.LowestLow;
import com.jasonlam604.stocktechnicals.util.NumberFormatter;

/**
* Aroon is an indicator system that determines whether a stock is trending or
* not and how strong the trend is.
*
* More info on Aroon here
* http://stockcharts.com/school/doku.php?id=chart_school:technical_indicators:aroon
*
*/
public class Aroon {

public double[] calculateAroonUp(double[] high, int range) {
double[] aroonUp = new double[high.length];

for (int i = range - 1; i < high.length; i++) {
HighestHigh highestHigh = new HighestHigh();
highestHigh.find(high, i - range + 1, range);
aroonUp[i] = this.calcAroon(range, (i - highestHigh.getIndex()));
}
return aroonUp;
}

public double[] calculateAroonDown(double[] low, int range) {
double[] aroonDown = new double[low.length];

for (int i = range - 1; i < low.length; i++) {
LowestLow lowestLow = new LowestLow();
lowestLow.find(low, i - range + 1, range);
aroonDown[i] = this.calcAroon(range, (i - lowestLow.getIndex()));
}
return aroonDown;
}

public double[] calculateAroonOscillator(double[] high, double[] low, int range) {
double[] aroonUp = this.calculateAroonUp(high, range);
double[] aroonDown = this.calculateAroonDown(low, range);
double[] aroonOscillator = new double[high.length];

for (int i = range - 1; i < high.length; i++) {
aroonOscillator[i] = NumberFormatter.round(aroonUp[i] - aroonDown[i]);
}

return aroonOscillator;
}

private double calcAroon(int range, int marker) {
return NumberFormatter.round(100 * (BigDecimal.valueOf((range - marker)).divide(BigDecimal.valueOf(range), 2,
BigDecimal.ROUND_UNNECESSARY)).doubleValue());
}

}
112 changes: 112 additions & 0 deletions test/com/jasonlam604/stocktechnicals/indicators/AroonTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
package com.jasonlam604.stocktechnicals.indicators;

import org.apache.commons.lang3.ArrayUtils;
import org.junit.Assert;
import org.junit.Test;

public class AroonTest {

@Test
public void testAroonDown() {

// Amazon data from April 1, 2017 and 100 data points back
double[] low = { 876.65, 871.66, 859.02, 850.10, 833.50, 843.53, 844.80, 839.05, 841.31, 851.01, 850.64, 850.51,
847.11, 847.55, 851.71, 851.72, 850.31, 846.79, 843.75, 841.12, 846.27, 847.28, 849.01, 842.05, 839.67,
837.75, 848.00, 852.18, 847.25, 840.73, 839.38, 832.82, 831.45, 828.55, 822.85, 819.71, 812.50, 807.50,
803.00, 804.00, 828.26, 824.94, 819.56, 816.38, 829.44, 833.00, 825.29, 814.50, 805.08, 806.26, 807.32,
804.27, 803.44, 811.40, 799.50, 789.51, 789.54, 791.77, 778.48, 760.26, 754.20, 747.70, 748.28, 760.85,
770.50, 761.20, 757.99, 763.02, 765.70, 767.71, 756.16, 754.00, 760.31, 762.81, 762.00, 757.20, 765.34,
765.19, 755.82, 757.25, 742.00, 736.70, 738.03, 750.25, 761.32, 764.24, 777.90, 773.12, 781.00, 765.11,
757.64, 748.00, 735.61, 725.99, 710.10, 728.90, 717.70, 760.09, 779.10, 770.94 };

Aroon aroon = new Aroon();

try {

ArrayUtils.reverse(low);

double results[] = aroon.calculateAroonDown(low, 25);

// Should match 84, based the value seen at stockcharts.com for
// Amzn, last index
Assert.assertEquals(84, results[results.length - 1], 0);

} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

@Test
public void testAroonUp() {

// Amazon data from April 1, 2017 and 100 data points back

double[] high = { 890.35, 877.06, 876.44, 858.46, 850.30, 851.80, 850.89, 849.37, 862.80, 857.80, 853.83,
855.50, 854.45, 853.75, 855.69, 857.35, 856.40, 853.07, 848.46, 848.49, 851.99, 854.82, 854.83, 854.09,
852.50, 845.81, 860.86, 858.43, 857.98, 847.27, 845.00, 842.81, 838.31, 843.00, 828.00, 825.00, 821.48,
816.16, 810.72, 818.30, 842.49, 833.78, 826.99, 833.50, 839.70, 843.84, 837.42, 823.99, 818.50, 816.02,
813.51, 811.73, 816.00, 821.65, 814.13, 799.50, 798.00, 801.77, 799.44, 782.40, 759.68, 758.76, 767.40,
773.40, 780.00, 774.65, 766.50, 771.21, 771.22, 774.39, 770.50, 765.13, 769.10, 780.86, 782.46, 766.89,
770.25, 773.79, 770.42, 768.24, 761.49, 748.49, 753.37, 768.09, 769.89, 777.00, 786.75, 781.75, 792.40,
780.35, 767.74, 757.50, 749.87, 746.78, 746.00, 743.26, 778.83, 777.50, 791.74, 787.73 };

Aroon aroon = new Aroon();

try {

ArrayUtils.reverse(high);

double results[] = aroon.calculateAroonUp(high, 25);

// Should match 100, based the value seen at stockcharts.com for
// Amzn, last index
Assert.assertEquals(100, results[results.length - 1], 0);

} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

@Test
public void testAroonOscillator() {

// Amazon data from April 1, 2017 and 100 data points back
double[] low = { 876.65, 871.66, 859.02, 850.10, 833.50, 843.53, 844.80, 839.05, 841.31, 851.01, 850.64, 850.51,
847.11, 847.55, 851.71, 851.72, 850.31, 846.79, 843.75, 841.12, 846.27, 847.28, 849.01, 842.05, 839.67,
837.75, 848.00, 852.18, 847.25, 840.73, 839.38, 832.82, 831.45, 828.55, 822.85, 819.71, 812.50, 807.50,
803.00, 804.00, 828.26, 824.94, 819.56, 816.38, 829.44, 833.00, 825.29, 814.50, 805.08, 806.26, 807.32,
804.27, 803.44, 811.40, 799.50, 789.51, 789.54, 791.77, 778.48, 760.26, 754.20, 747.70, 748.28, 760.85,
770.50, 761.20, 757.99, 763.02, 765.70, 767.71, 756.16, 754.00, 760.31, 762.81, 762.00, 757.20, 765.34,
765.19, 755.82, 757.25, 742.00, 736.70, 738.03, 750.25, 761.32, 764.24, 777.90, 773.12, 781.00, 765.11,
757.64, 748.00, 735.61, 725.99, 710.10, 728.90, 717.70, 760.09, 779.10, 770.94 };

double[] high = { 890.35, 877.06, 876.44, 858.46, 850.30, 851.80, 850.89, 849.37, 862.80, 857.80, 853.83,
855.50, 854.45, 853.75, 855.69, 857.35, 856.40, 853.07, 848.46, 848.49, 851.99, 854.82, 854.83, 854.09,
852.50, 845.81, 860.86, 858.43, 857.98, 847.27, 845.00, 842.81, 838.31, 843.00, 828.00, 825.00, 821.48,
816.16, 810.72, 818.30, 842.49, 833.78, 826.99, 833.50, 839.70, 843.84, 837.42, 823.99, 818.50, 816.02,
813.51, 811.73, 816.00, 821.65, 814.13, 799.50, 798.00, 801.77, 799.44, 782.40, 759.68, 758.76, 767.40,
773.40, 780.00, 774.65, 766.50, 771.21, 771.22, 774.39, 770.50, 765.13, 769.10, 780.86, 782.46, 766.89,
770.25, 773.79, 770.42, 768.24, 761.49, 748.49, 753.37, 768.09, 769.89, 777.00, 786.75, 781.75, 792.40,
780.35, 767.74, 757.50, 749.87, 746.78, 746.00, 743.26, 778.83, 777.50, 791.74, 787.73 };

Aroon aroon = new Aroon();

try {
ArrayUtils.reverse(low);
ArrayUtils.reverse(high);

double results[] = aroon.calculateAroonOscillator(high, low, 25);

// Aroon Oscillator value is 16 based on chart value at
// StockCharts.com, April 1, 2017
Assert.assertEquals(16, results[results.length - 1], 0);

} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

}

0 comments on commit 0c71dd0

Please sign in to comment.