indicator icon indicating copy to clipboard operation
indicator copied to clipboard

Higher level wrapper around the talib_ruby project

= Technical Analysis Indicator Library

== Overview

Provides a wrapper around the talib-ruby[https://github.com/rivella50/talib-ruby] library which is a ruby wrapper for the ta-lib[http://ta-lib.org/] library.

This library has been designed to make interfacing with the ta-lib functions easy by wrapping each function in a ruby class.

The wrappers are autogenerated from the xml function description provided with the ta-lib project.

== Usage

Requires the talib-ruby gem. The examples require the yahoofinance gem.

Install via gem using:

gem install ta-indicator

=== Simple Example The easiest way to use the indicator library is to include the indicator mixin module. This module extends the Array class with the Indicator::Mixin module allowing quick calculations to be performed:

require 'indicator/mixin'

data = [1, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3] results = data.indicator(:sma, :time_period => 5) results = data.indicator(:sma, 5) results = data.indicator(:sma_5)

All perform a simple moving average with time period of 5 and produce the same results:

=> [nil, nil, nil, nil, 2.2, 2.4, 2.6, 2.4, 2.6, 2.4, 2.6]

More complex indicators can also be used

result = data.indicator(:macd_12_26_9)

This performs a macd calculation using a slow period of 12, fast period of 26 and signal period of 9.

The list of available indicators can be retrieved via

Indicator.list

Information about each indicator including a list of arguments can be retrieved via:

Indicator.info :sma Indicator.info :macd ...

== Details The base Indicator functions are located in the Indicator module and the auto generated classed are located in the Indicator::AutoGen module. All of the following examples assume these modules have been included:

require 'indicator' include Indicator include Indicator::AutoGen

=== Class Construction

All ta-lib functions are wrapped in a class named using the camel class name of the function: SMA is Sma, AVGPRICE is AvgPrice, etc. The constructor takes the optional arguments either as a hash or argument list. For example the Macd class takes three arguments, fast_period, slow_period and signal_period. They can be initialised in any of the following ways:

sma = Sma.new 5 macd = Macd.new 12,26,9 or sma = Sma.new :time_period => 5 macd = Macd.new :fast_period => 12, :slow_period => 26, :signal_period => 9

If a parameter is not passed in then it will be initialised to the default value as specified by the ta-lib interface.

The Indicator module also supports factory style functions to simplify class creation.

sma = Indicator.create :sma sma = Indicator.create :sma, 5 sma = Indicator.create :sma, time_period => 5

macd = Indicator.create :macd macd = Indicator.create :macd, 12,26,9 macd = Indicator.create :macd, :fast_period => 12, :slow_period => 26, :signal_period => 9

If a indicator is to be constructed using only integer parameters then an indicator can be constructed using the create_named factory function. The create_named function expects the indicator name optionally followed by it's arguments joined by an underscore.

sma = Indicator.create_named :sma_5 macd = Indicator.create_named :macd_12_26_9

=== Argument attributes

All arguments can be updated through attributes: macd.fast_period => 12 macd.slow_period = 30 => 30

A list of all the arguments that a particular class takes can be be retrieved using the class method 'arguments'. Macd.arguments => [:fast_period, :slow_period, :signal_period] Sma.arguments => [:time_period]

=== Running The Indicators Each indicator defines a run method that takes in each input array to be processed as a List. An example of an indicator that takes one input: sma = Indicator.create_named :sma_5 sma.run [1,2,3,4,3,2,3,2,3,2,3,2] => [nil, nil, nil, nil, 2.6, 2.8, 3.0, 2.8, 2.6, 2.4, 2.6, 2.4]

An example of an indicator that takes two inputs: add = Indicator.create_named :add add.run [1,2,3,4,5], [5,4,3,2,1] => [6.0, 6.0, 6.0, 6.0, 6.0]

Some indicators require OHLC (and optionally V) price inputs. An example of an indicator that takes price inputs: avg = AvgPrice.new

AvgPrice run function takes open, high, low, close

avg.run [1,2,1,2], [2,1,2,1], [3,1,3,1], [1,3,1,3] => [1.75, 1.75, 1.75, 1.75]

A list of inputs that a indicator run function requires can be retrieved using the class method 'inputs'. Sma.inputs => [:in_real] Add.inputs => [:in_real0, in_real1] AvgPrice.inputs => [:open, :high, :low, :close] AdOsc.inputs => [:open, :high, :low, :close, :volume]

=== Outputs The run function returns an array containing the results if there is only one List to return otherwise it returns a hash that maps each output List to it's name. For eample: sma = Sma.new(5) sma.run [1,2,3,4,3,2,3,2,3,2,3,2] => [nil, nil, nil, nil, 2.6, 2.8, 3.0, 2.8, 2.6, 2.4, 2.6, 2.4] macd = Macd.new 3,4,1 result = macd.run [1,2,3,4,4,3] puts results[:out_macd] => [nil, nil, -3.785768566076978e-270, 0.5, nil, nil] puts result[:out_macd_signal] => [nil, nil, 0.399999999999999, 0.189999999999999, nil, nil], puts result[:out_macd_hist] => [nil, nil, -0.3999999999999999, 0.31000000000000005, nil, nil]

A list of outputs that an indicator run function returns can be retrieved using the class method 'outputs'. Sma.outputs => [:out_real] Macd.outputs => [:out_macd, :out_macd_signal, :out_macd_hist]

=== Data Mapping The run function also accepts a DataMapping::Map structure which can be used to extract data from an enumerable collection.

Assume historical_data is a list of hashes with the following keys

:open, :high, :low, :close, :volume

sma = Sma.new 5 sma_results = sma.run(DataMapper::Map.new(historical_data, :open))

When the above example is run the DataMapper will attempt to extract data from the historical_data collection by either calling a function called open or retrieving a hash value using the key :open. You can also directly pass in a lambda function if a more complex mapping function is required. To reduce the amount of code required a helper function called new_map is available:

sma = Sma.new 5 sma_results = sma.run new_map(historical_data, :open) sma_results = sma.run new_map(historical_data, lambda => |b| { b[:open] / 2 })

By default the run function will attempt to use a default getter of :open, so the following is also valid:

sma = Sma.new 5 sma_results = sma.run historical_data

Calculates the sma by accessing [:open] on each element of historical_data

The default getter can be changed: sma = Sma.new 5 sma.default_getter :high sma_results = sma.run historical_data

Calculates the sma by accessing [:high] on each element of historical_data

The same mapping system works for functions requiring price data as an input. The AvgPrice function can be called using either of the following syntax:

ap = AvgPrice.new ap.run( new_map(historical_data, :open), new_map(historical_data, :high), new_map(historical_data, :low), new_map(historical_data, :close))

or

ap = AvgPrice.new ap.run historical_data

The run function will again attempt to use sensible default mappings of :open, :high, :low, :close and :volume (if required).

== Regenerating the wrappers

The wrappers can be regenerated using the gen_wrapper.rb file in the tools directory:

ruby gen_wrapper.rb

This script must be run from the tools directory as it uses realtive paths. The gen_wrapper.rb script uses the erb library to generate code from the defined templates.

== Copyright

Copyright (c) 2012 Michael Lamb. See LICENSE for details.

The files ta_func_api.xml and ta_func_api.xsd are from the talib library. The license details are contained within LICENSE-ta-lib.