Skip to content
This repository has been archived by the owner on Feb 15, 2022. It is now read-only.

Commit

Permalink
Parabolic SAR strategy (#246)
Browse files Browse the repository at this point in the history
* experimental sar strat

* fix sar description

* default 1m period for sar

* sar indicator grey

* less noisy "vs our price" debug msgs
  • Loading branch information
Carlos Rodriguez authored and DeviaVir committed Jun 9, 2017
1 parent eb14db9 commit 1f5a50d
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 0 deletions.
6 changes: 6 additions & 0 deletions extensions/strategies/sar/_codemap.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module.exports = {
_ns: 'zenbot',

'strategies.sar': require('./strategy'),
'strategies.list[]': '#strategies.sar'
}
86 changes: 86 additions & 0 deletions extensions/strategies/sar/strategy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
var z = require('zero-fill')
, n = require('numbro')

module.exports = function container (get, set, clear) {
return {
name: 'sar',
description: 'Parabolic SAR',

getOptions: function () {
this.option('period', 'period length', String, '1m')
this.option('min_periods', 'min. number of history periods', Number, 52)
this.option('sar_af', 'acceleration factor for parabolic SAR', Number, 0.025)
this.option('sar_max_af', 'max acceleration factor for parabolic SAR', Number, 0.55)
},

calculate: function (s) {
if (s.lookback.length >= s.options.min_periods) {
if (!s.trend) {
if (s.period.high > s.lookback[s.lookback.length - 1].high) {
// start with uptrend
s.trend = 'up'
s.sar = Math.min(s.lookback[1].low, s.lookback[0].low)
s.sar_ep = s.period.high
s.sar_af = s.options.sar_af
for (var idx = 0; idx < s.lookback.length; idx++) {
s.sar_ep = Math.max(s.sar_ep, s.lookback[idx].high)
}
}
else {
s.trend = 'down'
s.sar = Math.max(s.lookback[1].high, s.lookback[0].high)
s.sar_ep = s.period.low
s.sar_af = s.options.sar_af
for (var idx = 0; idx < s.lookback.length; idx++) {
s.sar_ep = Math.min(s.sar_ep, s.lookback[idx].low)
}
}
}
}
},

onPeriod: function (s, cb) {
if (typeof s.sar === 'number') {
if (s.trend === 'up') {
s.sar = Math.min(s.lookback[1].low, s.lookback[0].low, s.sar + (s.sar_af * (s.sar_ep - s.sar)))
}
else {
s.sar = Math.max(s.lookback[1].high, s.lookback[0].high, s.sar - (s.sar_af * (s.sar - s.sar_ep)))
}
if (s.trend === 'down') {
if (s.period.high >= s.sar) {
s.trend = 'up'
s.signal = 'buy'
s.sar_ep = s.period.low
s.sar_af = s.options.sar_af
}
else if (s.period.low < s.sar_ep && s.sar_af < s.options.sar_max_af) {
s.sar_ep = s.period.low
s.sar_af += s.options.sar_af
}
}
else if (s.trend === 'up') {
if (s.period.low <= s.sar) {
s.trend = 'down'
s.signal = 'sell'
s.sar_ep = s.period.high
s.sar_af = s.options.sar_af
}
else if (s.period.high > s.sar_ep && s.sar_af < s.options.sar_max_af) {
s.sar_ep = s.period.high
s.sar_af += s.options.sar_af
}
}
}
cb()
},

onReport: function (s) {
var cols = []
if (typeof s.sar === 'number') {
cols.push(z(8, n(s.sar).subtract(s.period.close).divide(s.period.close).format('0.00%'), ' ').grey)
}
return cols
}
}
}

0 comments on commit 1f5a50d

Please sign in to comment.