-
Notifications
You must be signed in to change notification settings - Fork 24
Testing technical analysis functions
Testing in MarketTechnicals relies on two separate packages: FactCheck and MarketData. FactCheck provides the testing framework, including macros, to organize the tests. MarketData provides time series objects for testing.
The main time series objects from MarketData used in testing include cl
(closing prices), ohlc
(open high low close prices) and ohlcv
(open high low close prices with volume). These objects are created from Apple Computer, Inc. historical stock prices (AAPL), taken from Jan 1, 2000 to Dec 31, 2001. This object is easy to reproduce in other technical analysis packages, and values from other packages are used to test MarketTechnical's implementation for correctness.
The primary source of reliable algorithm implementation is R's TTR package. To get the MarketData test objects into R, the quantmod
package needs to be installed.
> require(quantmod)
Loading required package: quantmod
Loading required package: Defaults
Loading required package: xts
Loading required package: zoo
Attaching package: ‘zoo’
The following objects are masked from ‘package:base’:
as.Date, as.Date.numeric
Loading required package: TTR
Version 0.4-0 included new data defaults. See ?getSymbols.
This loading banner includes information that TTR has been loaded. To get the AAPL stock prices, the following call to getSymbols
is made:
> getSymbols('AAPL', from='2000-1-1', to='2001-12-31')
As of 0.4-0, ‘getSymbols’ uses env=parent.frame() and
auto.assign=TRUE by default.
This behavior will be phased out in 0.5-0 when the call will
default to use auto.assign=FALSE. getOption("getSymbols.env") and
getOptions("getSymbols.auto.assign") are now checked for alternate defaults
This message is shown once per session and may be disabled by setting
options("getSymbols.warning4.0"=FALSE). See ?getSymbol for more details
[1] "AAPL"
From there it's easy to reproduce the MarketData test objects
> cl <- Cl(AAPL)
> ohlc <- OHLC(AAPL)
> ohlcv <- OHLCV(AAPL)
Find the anticipated correct values for a simple moving average of cl
(closing AAPL prices from Jan 1, 2000 to Dec 31, 2001)
> sma20 <- na.omit(SMA(cl, 20)) # TTR prepends with `NA`s while MarketTechnicals naturally omits these values
> head(sma20, 3)
AAPL.Close.SMA.20
2000-01-31 103.3595
2000-02-01 102.7750
2000-02-02 102.5905
> tail(sma20, 3)
AAPL.Close.SMA.20
2001-12-27 21.5645
2001-12-28 21.6650
2001-12-31 21.6950
Now suppose we've written the sma
method from scratch. To test against the TTR values, we add a code block to the existing test/movingaverages.jl
file. The code block should be put inside the following facts
block:
facts("Moving Averages") do
.
.
.
end
Each new test suite should have a reasonable context facts
block to live inside. If one doesn't exist, you can always create a new block. Once inside the facts
block, the tests need to have a context
wrapper.
context("my practice sma") do
.
.
.
end
This is where the actual assertions are made, and they are formatted with the @fact
macro in this manner:
@fact sma(cl, 20).values[1] => roughly(103.3595) # TTR value is 103.3595
To run this test from repl:
using FactCheck
@runtest MarketTechnicals movingaverages
This will run the entire test suite from the test/movingaverages.jl
file, including the new test we added.
Once tests are passing, you can submit a PR for the new technical analysis algorithm along with passing tests!
TTR is not the only acceptable source of correct implementation, but some other source needs to be documented for each test suite.