forked from andredumas/techan.js
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- ADX - Aroon - Bollinger bands - Stochastic oscillator - Williams %R All indicators have tests. Original code taken from Fojt's branch and refactored for the lastest Techan master. Signed-off-by: Pekka Riikonen <[email protected]>
- Loading branch information
Showing
33 changed files
with
1,330 additions
and
12 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,49 @@ | ||
'use strict'; | ||
|
||
module.exports = function() { | ||
var date = function(d) { return d.date; }, | ||
adx = function(d) { return d.adx; }, | ||
plusDi = function(d) { return d.plusDi; }, | ||
minusDi = function(d) { return d.minusDi; }; | ||
|
||
function accessor(d) { | ||
return accessor.r(d); | ||
} | ||
|
||
// TODO use d3.rebind to obtain this from 'super class' | ||
accessor.date = function(_) { | ||
if (!arguments.length) return date; | ||
date = _; | ||
return bind(); | ||
}; | ||
|
||
accessor.adx = function(_) { | ||
if (!arguments.length) return adx; | ||
adx = _; | ||
return bind(); | ||
}; | ||
|
||
accessor.plusDi = function(_) { | ||
if (!arguments.length) return plusDi; | ||
plusDi = _; | ||
return bind(); | ||
}; | ||
|
||
accessor.minusDi = function(_) { | ||
if (!arguments.length) return minusDi; | ||
minusDi = _; | ||
return bind(); | ||
}; | ||
|
||
function bind() { | ||
// TODO These methods will need to know if the variables are functions or values and execute as such | ||
accessor.d = date; | ||
accessor.adx = adx; | ||
accessor.plusDi = plusDi; | ||
accessor.minusDi = minusDi; | ||
|
||
return accessor; | ||
} | ||
|
||
return bind(); | ||
}; |
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,73 @@ | ||
'use strict'; | ||
|
||
module.exports = function() { | ||
|
||
var date = function(d) { return d.date; }, | ||
up = function(d) { return d.up; }, | ||
down = function(d) { return d.down; }, | ||
oscillator = function(d) { return d.oscillator; }, | ||
overbought = function(d) { return d.overbought; }, | ||
oversold = function(d) { return d.oversold; }, | ||
middle = function(d) { return d.middle; }; | ||
|
||
function accessor(d) { | ||
return accessor.r(d); | ||
} | ||
|
||
// TODO use d3.rebind to obtain this from 'super class' | ||
accessor.date = function(_) { | ||
if (!arguments.length) return date; | ||
date = _; | ||
return bind(); | ||
}; | ||
|
||
accessor.up = function(_) { | ||
if (!arguments.length) return up; | ||
up = _; | ||
return bind(); | ||
}; | ||
accessor.down = function(_) { | ||
if (!arguments.length) return down; | ||
down = _; | ||
return bind(); | ||
}; | ||
|
||
accessor.oscillator = function(_) { | ||
if (!arguments.length) return oscillator; | ||
oscillator = _; | ||
return bind(); | ||
}; | ||
|
||
accessor.overbought = function(_) { | ||
if (!arguments.length) return overbought; | ||
overbought = _; | ||
return bind(); | ||
}; | ||
|
||
accessor.oversold = function(_) { | ||
if (!arguments.length) return oversold; | ||
oversold = _; | ||
return bind(); | ||
}; | ||
|
||
accessor.middle = function(_) { | ||
if (!arguments.length) return middle; | ||
middle = _; | ||
return bind(); | ||
}; | ||
|
||
function bind() { | ||
// TODO These methods will need to know if the variables are functions or values and execute as such | ||
accessor.d = date; | ||
accessor.up = up; | ||
accessor.down = down; | ||
accessor.oscillator = oscillator; | ||
accessor.ob = overbought; | ||
accessor.os = oversold; | ||
accessor.m = middle; | ||
|
||
return accessor; | ||
} | ||
|
||
return bind(); | ||
}; |
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,49 @@ | ||
'use strict'; | ||
|
||
module.exports = function() { | ||
var date = function(d) { return d.date; }, | ||
middle = function(d) { return d.middleBand; }, | ||
upper = function(d) { return d.upperBand; }, | ||
lower = function(d) { return d.lowerBand; }; | ||
|
||
function accessor(d) { | ||
return accessor.r(d); | ||
} | ||
|
||
// TODO use d3.rebind to obtain this from 'super class' | ||
accessor.date = function(_) { | ||
if (!arguments.length) return date; | ||
date = _; | ||
return bind(); | ||
}; | ||
|
||
accessor.middle = function(_) { | ||
if (!arguments.length) return middle; | ||
middle = _; | ||
return bind(); | ||
}; | ||
|
||
accessor.upper = function(_) { | ||
if (!arguments.length) return upper; | ||
upper = _; | ||
return bind(); | ||
}; | ||
|
||
accessor.lower = function(_) { | ||
if (!arguments.length) return lower; | ||
lower = _; | ||
return bind(); | ||
}; | ||
|
||
function bind() { | ||
// TODO These methods will need to know if the variables are functions or values and execute as such | ||
accessor.d = date; | ||
accessor.middle = middle; | ||
accessor.upper = upper; | ||
accessor.lower = lower; | ||
|
||
return accessor; | ||
} | ||
|
||
return bind(); | ||
}; |
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
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,64 @@ | ||
'use strict'; | ||
|
||
module.exports = function() { | ||
var date = function(d) { return d.date; }, | ||
stochasticK = function(d) { return d.stochasticK; }, | ||
stochasticD = function(d) { return d.stochasticD; }, | ||
overbought = function(d) { return d.overbought; }, | ||
oversold = function(d) { return d.oversold; }, | ||
middle = function(d) { return d.middle; }; | ||
|
||
function accessor(d) { | ||
return accessor.r(d); | ||
} | ||
|
||
// TODO use d3.rebind to obtain this from 'super class' | ||
accessor.date = function(_) { | ||
if (!arguments.length) return date; | ||
date = _; | ||
return bind(); | ||
}; | ||
|
||
accessor.stochasticK = function(_) { | ||
if (!arguments.length) return stochasticK; | ||
stochasticK = _; | ||
return bind(); | ||
}; | ||
accessor.stochasticD = function(_) { | ||
if (!arguments.length) return stochasticD; | ||
stochasticD = _; | ||
return bind(); | ||
}; | ||
|
||
accessor.overbought = function(_) { | ||
if (!arguments.length) return overbought; | ||
overbought = _; | ||
return bind(); | ||
}; | ||
|
||
accessor.oversold = function(_) { | ||
if (!arguments.length) return oversold; | ||
oversold = _; | ||
return bind(); | ||
}; | ||
|
||
accessor.middle = function(_) { | ||
if (!arguments.length) return middle; | ||
middle = _; | ||
return bind(); | ||
}; | ||
|
||
function bind() { | ||
// TODO These methods will need to know if the variables are functions or values and execute as such | ||
accessor.d = date; | ||
accessor.k = stochasticK; | ||
accessor.sd = stochasticD; | ||
accessor.ob = overbought; | ||
accessor.os = oversold; | ||
accessor.m = middle; | ||
|
||
return accessor; | ||
} | ||
|
||
return bind(); | ||
}; |
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,33 @@ | ||
'use strict'; | ||
|
||
module.exports = function() { | ||
var date = function(d) { return d.date; }, | ||
williams = function(d) { return d.williams; }; | ||
|
||
function accessor(d) { | ||
return accessor.r(d); | ||
} | ||
|
||
// TODO use d3.rebind to obtain this from 'super class' | ||
accessor.date = function(_) { | ||
if (!arguments.length) return date; | ||
date = _; | ||
return bind(); | ||
}; | ||
|
||
accessor.williams = function(_) { | ||
if (!arguments.length) return williams; | ||
williams = _; | ||
return bind(); | ||
}; | ||
|
||
function bind() { | ||
// TODO These methods will need to know if the variables are functions or values and execute as such | ||
accessor.d = date; | ||
accessor.w = williams; | ||
|
||
return accessor; | ||
} | ||
|
||
return bind(); | ||
}; |
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,74 @@ | ||
'use strict'; | ||
|
||
module.exports = function(indicatorMixin, accessor_ohlc, indicator_ema) { // Injected dependencies | ||
return function() { // Closure function | ||
var p = {}, // Container for private, direct access mixed in variables | ||
period = 14; | ||
|
||
function indicator(data) { | ||
var plusDmEma = indicator_ema().accessor(indicator.accessor()).period(period).init(), | ||
minusDmEma = indicator_ema().accessor(indicator.accessor()).period(period).init(), | ||
trEma = indicator_ema().accessor(indicator.accessor()).period(period).init(), | ||
adxEma = indicator_ema().accessor(indicator.accessor()).period(period).init(); | ||
|
||
period = parseInt(period); | ||
return data.map(function(d, i) { | ||
if(i < 1) return datum(p.accessor.d(d)); | ||
|
||
var upMove = p.accessor.h(data[i]) - p.accessor.h(data[i-1]); | ||
var downMove = p.accessor.l(data[i-1]) - p.accessor.l(data[i]); | ||
var plusDM = 0; | ||
if(upMove > downMove && upMove>0){ | ||
plusDM = upMove; | ||
} | ||
|
||
var minusDM = 0; | ||
if(downMove > upMove && downMove > 0){ | ||
minusDM = downMove; | ||
} | ||
|
||
var TR = d3.max([ | ||
(p.accessor.h(d) - p.accessor.l(d)), | ||
Math.abs(p.accessor.h(d) - p.accessor.c(data[i-1])),Math.abs(p.accessor.l(d) - p.accessor.c(data[i-1])) | ||
]); | ||
|
||
var plusDmAverage = plusDmEma.average(plusDM), | ||
minusDmAverage = minusDmEma.average(minusDM), | ||
trEmaAverage = trEma.average(TR); | ||
if(i>period) { | ||
var plusDi = 100 * plusDmAverage / trEmaAverage, | ||
minusDi = 100 * minusDmAverage / trEmaAverage, | ||
adxValue = 0; | ||
|
||
if(plusDi - minusDi !== 0){ | ||
adxValue = Math.abs( (plusDi - minusDi)/(plusDi + minusDi) ); | ||
} | ||
var adx = 100 * adxEma.average(adxValue); | ||
|
||
if(i >= period*2) { | ||
return datum(p.accessor.d(d), adx, plusDi, minusDi); | ||
}else return datum(p.accessor.d(d)); | ||
}else return datum(p.accessor.d(d)); | ||
}).filter(function(d) { return d.adx; }); | ||
} | ||
|
||
indicator.period = function(_) { | ||
if (!arguments.length) return period; | ||
period = _; | ||
return indicator; | ||
}; | ||
|
||
// Mixin 'superclass' methods and variables | ||
indicatorMixin(indicator, p).accessor(accessor_ohlc()); | ||
|
||
return indicator; | ||
}; | ||
}; | ||
|
||
function datum(date, adx, plusDi, minusDi) { | ||
if(plusDi) { | ||
return { date: date, adx: adx, plusDi: plusDi, minusDi: minusDi }; | ||
}else{ | ||
return { date: date, adx: null, plusDi: null, minusDi: null }; | ||
} | ||
} |
Oops, something went wrong.