IB-Technical-Analysis
A library for performing technical analysis
This Gem is inspired by the intrinio package. However, IB-Technical-Analysis
focusses on
calculation of indicators from a stream of data.
It fits perfectly into the IB-Ruby suite, but can be used isolated, too.
Indicator classes
Indicators live in the TechnicalAnalysis
namespace:
TechnicalAnalysis::MovingAverage::SimpleMA
TechnicalAnalysis::MovingAverage::EspMA
TechnicalAnalysis::MovingAverage::Wma
TechnicalAnalysis::MovingAverage::KaMA
TechnicalAnalysis::Momentum::Rsi
TechnicalAnalysis::Momentum::Tsi
TechnicalAnalysis::Momentum::Lane
Additional calculations on single Bars are defined as extension of IB::Bar
:
- typical_price
- pivot
- true_range
Common Interface
The indicators are initialized by
indicator = TechnicalAnalysis::MovingAverage::KaMA.new period: 30, fast: 5, slow: 15, data: {an Array}
If an Array is passed, the indicator is calculated immediately.
Subsequent data elements are passed by indicator.add_item {value}
.
The calculated indicator is returned for further processing.
Perform calculation on time-series
IB-Technical-Analysis
calculations are embedded in the Enumerator
-class.
The List is simply iterated.
Thus
require 'bundler/setup'
require 'ib-gateway'
require 'ib/eod'
require 'ib/symbols'
require 'technical-analysis'
using TASupport
z = Symbols::Futures.mini_dax.eod( duration: '50 d').each
zz= z.calculate( :ema, period: 15 , use: :close
zz.first
=> #<struct TechnicalAnalysis::MovingAverage::EMA time=Wed, 10 Mar 2021, value=0.149524e5>
calculates the Exponential Moving Average on the close property of each item in the
Enumerator returned by the contract.eod method.
The same using a conventional array:
u = z.map( &:close ).each
uu= u.calculate( :ema, period: 15 )
uu.first
=> 0.149524e5
Signals and Backtesting
The calculate
-method of Enumerator passes raw-data and calculated indicator-values to an optional block.
This enables the formulation of signal generators.
buffer=[]
zz= z.calculate( :ema, period: 5, use: :typical_price ) do | raw, struct |
buffer << struct.value
buffer.shift if buffer.size >2
momentum_indicator = (buffer.first - buffer.last) <=> 0
crossing = case momentum_indicator
when +1
buffer.first > raw.close && buffer.last < raw.close
when -1
buffer.first < raw.close && buffer.last > raw.close
end
buy_or_sell = momentum_indicator == 1 ? "buy" : "sell"
puts "#{buy_or_sell}-Signal: EMA-Indicator-Crossing @ #{struct.time}" if crossing
end
Implemented Indicators
zz = z.calculate :sma, period: 15, use: :close
- Exponential Moving Average
zz = z.calculate :ema, period: 15
zz = z.calculate :wma, period: 15
zz = z.calculate :kama, period: 15, fast: 10, slow: 3
zz = z.calculate :rsi, period: 15
zz = z.calculate :tsi, high: 15, low: 7
zz = z.calculate :lane, period: 10, fast: 3, slow: 3 , use: :wap
(work in progress)