Skip to content

Commit

Permalink
momentum: Implement stochastic oscillator (#96)
Browse files Browse the repository at this point in the history
  • Loading branch information
iblislin authored Jun 18, 2017
2 parents cfd2eb4 + dbdd0a3 commit a66ea84
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 1 deletion.
13 changes: 13 additions & 0 deletions docs/src/momentum.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,3 +77,16 @@ using MarketTechnicals
roc(cl, 5)
```

## Stochastic Oscillator

```@docs
stoch_osc
```

```@repl
using MarketData
using MarketTechnicals
stoch_osc(ohlc)
```
2 changes: 1 addition & 1 deletion src/MarketTechnicals.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export sma, ema, kama,
bollingerbands, truerange, atr, keltnerbands, chaikinvolatility, donchian_channels,
obv, vwap, adl,
doji,
rsi, macd, cci, roc, adx, chaikin_osc,
rsi, macd, cci, roc, adx, stoch_osc, chaikin_osc,
floorpivots, woodiespivots,
typical

Expand Down
45 changes: 45 additions & 0 deletions src/momentum.jl
Original file line number Diff line number Diff line change
Expand Up @@ -173,3 +173,48 @@ function adx{T,N}(ohlc::TimeArray{T,N}, n::Integer=14;

rename(merge(adx, merge(dx, di)), ["adx", "dx", "+di", "-di"])
end

doc"""
stoch_osc(ohlc, n=14, fast_d=3, slow_d=3; h="High", l="Low", c="Close")
**Stochastic Oscillator**
A.k.a *%K%D*, or *KD*
**Parameter**
- `n`: period of fast(raw) `%K`
- `fast_d`: MA period of fast `%D`
- `slow_d`: MA period of slow `%D`
**Formula**
```math
\begin{align*}
fast\ \%K & = \frac{Close_t - \max(High_{t-n}, \dots, High_t)}
{\max(High_{t-n}, \dots, High_t) - \min(Low_{t-n}, \dots, Low_t)}
\times 100 \\
fast\ \%D & = SMA(fast\ \%K) \\
slow\ \%D & = SMA(fast\ \%D)
\end{align*}
```
**Reference**
- [Wikipedia]
(https://en.wikipedia.org/wiki/Stochastic_oscillator)
- [FMLabs]
(http://www.fmlabs.com/reference/default.htm?url=StochasticOscillator.htm)
"""
function stoch_osc(ohlc::TimeArray, n::Integer=14, fast_d::Integer=3,
slow_d::Integer=3; h="High", l="Low", c="Close")
high = moving(ohlc[h], maximum, n)
low = moving(ohlc[l], minimum, n)
fast_k = rename((ohlc[c] .- low) ./ (high .- low) * 100, "fast_k")
fast_d = rename(sma(fast_k, fast_d), "fast_d")
slow_d = rename(sma(fast_d, slow_d), "slow_d")
merge(merge(fast_k, fast_d), slow_d)
end
25 changes: 25 additions & 0 deletions test/momentum.jl
Original file line number Diff line number Diff line change
Expand Up @@ -95,4 +95,29 @@ facts("Momentum") do
@fact ta.values[1, 4] --> roughly(23.4383, atol=.01)
@fact ta.timestamp[1] --> Date(2000, 2, 10)
end

context("stochastic osc") do
"""
Quote from TTR
> stoch(x[, c("High", "Low", "Close")], maType=SMA)
fastK fastD slowD
[18,] 0.671428571 0.69466667 0.67441270
[19,] 0.432000000 0.59342857 0.64901587
[20,] 0.492857143 0.53209524 0.60673016
[21,] 0.392857143 0.43923810 0.52158730
[22,] 0.217586207 0.36776683 0.44636672
[23,] 0.326296296 0.31224655 0.37308382
[24,] 0.500000000 0.34796083 0.34265807
[25,] 0.724444444 0.51691358 0.39237365
[26,] 0.754814815 0.65975309 0.50820917
[27,] 0.801061008 0.76010676 0.64559114
[28,] 0.839964633 0.79861349 0.73949111
"""
ta = stoch_osc(ohlc)
@fact ta.colnames --> ["fast_k", "fast_d", "slow_d"]
@fact ta.timestamp --> ohlc[18:end].timestamp
@fact ta.values[1, 1] --> roughly(67.142857, atol=.01)
@fact ta.values[1, 2] --> roughly(69.466667, atol=.01)
@fact ta.values[1, 3] --> roughly(67.441270, atol=.01)
end
end

0 comments on commit a66ea84

Please sign in to comment.