class SignalTools::Technicals::AverageDirectionalIndex

Attributes

period[R]
stock_data[R]

Public Class Methods

new(stock_data, period) click to toggle source
# File lib/signal_tools/technicals/average_directional_index.rb, line 9
def initialize(stock_data, period)
  @stock_data = stock_data
  @period = period
end

Public Instance Methods

average_directional_indexes() click to toggle source
# File lib/signal_tools/technicals/average_directional_index.rb, line 19
def average_directional_indexes
  dxs = directional_indexes(plus_directional_index, minus_directional_index)
  adxs = EMA.new(dxs, period, :wilder).calculate
  adxs
end
calculate() click to toggle source
# File lib/signal_tools/technicals/average_directional_index.rb, line 14
def calculate
  # trim_data_to_range!(average_directional_indexes(period))
  average_directional_indexes
end
directional_indexes(plus_dis, minus_dis) click to toggle source
# File lib/signal_tools/technicals/average_directional_index.rb, line 25
def directional_indexes(plus_dis, minus_dis)
  SignalTools.truncate_to_shortest!(plus_dis, minus_dis)
  differences, sums = [], []
  index = 0
  while index < plus_dis.size
    differences << (plus_dis[index] - minus_dis[index]).abs
    sums << (plus_dis[index] + minus_dis[index])
    index += 1
  end
  quotients(differences, sums)
end
down_move(today, yesterday) click to toggle source

TODO: Pass in only the low prices to this method

Down move is yesterday_low - today_low
# File lib/signal_tools/technicals/average_directional_index.rb, line 91
def down_move(today, yesterday)
  diff = yesterday[SignalTools::StockData::Indexes[:low]] - today[SignalTools::StockData::Indexes[:low]]
  diff > 0 ? diff : 0
end
minus_directional_index() click to toggle source
# File lib/signal_tools/technicals/average_directional_index.rb, line 44
def minus_directional_index
  minus_dms = minus_directional_movement(@stock_data.raw_data)
  minus_dm_sums = period_sum_ema(minus_dms)
  true_range_sums = period_sum_ema(true_ranges(stock_data))
  quotients(minus_dm_sums, true_range_sums)
end
minus_directional_movement(data) click to toggle source
# File lib/signal_tools/technicals/average_directional_index.rb, line 72
def minus_directional_movement(data)
  minus_dm = []
  data.each_cons(2) do |two_days|
    um = up_move(two_days.last, two_days.first)
    dm = down_move(two_days.last, two_days.first)
    minus_dm << ((dm > um) ? dm : 0)
  end
  minus_dm
end
period_sum_ema(data) click to toggle source

Takes a period and array of data and calculates the sum ema over the period specified.

# File lib/signal_tools/technicals/average_directional_index.rb, line 97
def period_sum_ema(data)
  raise if data.size <= period
  sum_emas = [SignalTools.sum(data[0...period])]
  data[(period..-1)].each do |today|
    sum_emas << (sum_emas.last - (sum_emas.last / period) + today)
  end
  sum_emas
end
plus_directional_index() click to toggle source
# File lib/signal_tools/technicals/average_directional_index.rb, line 37
def plus_directional_index
  plus_dms = plus_directional_movement(@stock_data.raw_data)
  plus_dm_sums = period_sum_ema(plus_dms)
  true_range_sums = period_sum_ema(true_ranges(stock_data))
  quotients(plus_dm_sums, true_range_sums)
end
plus_directional_movement(data) click to toggle source
# File lib/signal_tools/technicals/average_directional_index.rb, line 62
def plus_directional_movement(data)
  plus_dm = []
  data.each_cons(2) do |two_days|
    um = up_move(two_days.last, two_days.first)
    dm = down_move(two_days.last, two_days.first)
    plus_dm << ((um > dm) ? um : 0)
  end
  plus_dm
end
quotients(first, second) click to toggle source
# File lib/signal_tools/technicals/average_directional_index.rb, line 51
def quotients(first, second)
  SignalTools.truncate_to_shortest!(first, second)
  index = 0
  quots = []
  while index < first.size
    quots << first[index] / second[index]
    index += 1
  end
  quots
end
up_move(today, yesterday) click to toggle source

TODO: Pass in only the high prices to this method

Up move is today_high - yesterday_high
# File lib/signal_tools/technicals/average_directional_index.rb, line 84
def up_move(today, yesterday)
  diff = today[SignalTools::StockData::Indexes[:high]] - yesterday[SignalTools::StockData::Indexes[:high]]
  diff > 0 ? diff : 0
end