-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add Aroon Indicator (Up, Down, Oscillator) with Unit tests
- Loading branch information
1 parent
c69cff6
commit 0c71dd0
Showing
2 changed files
with
170 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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
112
test/com/jasonlam604/stocktechnicals/indicators/AroonTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | ||
} | ||
} | ||
|
||
} |