Provides a wrapper around the talib-ruby library which is a ruby wrapper for the ta-lib 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.
Requires the talib-ruby gem. The examples require the yahoofinance gem.
Install via gem using:
gem install ta-indicator
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 ...
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
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
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]
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]
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]
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).
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 © 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.