class Gekko::Tape

Records the trading engine messages sequentially

Constants

SECONDS_IN_24H

The number of seconds in 24h

Attributes

cursor[R]
high_24h[R]
last_trade_price[RW]
logger[RW]
low_24h[R]
open_24h[R]
var_24h[R]
volume_24h[R]

Public Class Methods

from_hash(hsh) click to toggle source

Loads a Tape object from a hash

@param hsh [Hash] The Tape data

# File lib/gekko/tape.rb, line 179
def self.from_hash(hsh)
  tape = Tape.new

  tape.instance_variable_set(:@cursor, hsh[:cursor])

  hsh[:events].each do |evt|
    e = symbolize_keys(evt)
    e[:type] = e[:type].to_sym
    tape << e
  end

  tape
end
new(opts = {}) click to toggle source
# File lib/gekko/tape.rb, line 16
def initialize(opts = {})
  @logger = opts[:logger]

  @cursor           = 0
  @cursor_24h       = 0
  @volume_24h       = 0
  @quote_volume_24h = 0
end

Public Instance Methods

<<(message) click to toggle source

Prints a message on the tape

@param message [Hash] The message to record

Calls superclass method
# File lib/gekko/tape.rb, line 30
def <<(message)
  message.merge!({
    sequence: length,
    time:     Time.now.to_f
  })

  logger && logger.info(message)

  super(message)

  if message[:type] == :execution
    update_ticker(message)
  end
end
fall_out_of_24h_window(execution) click to toggle source

Updates the low, high, and volumes when an execution falls out of the rolling previous 24h window

# File lib/gekko/tape.rb, line 143
def fall_out_of_24h_window(execution)
  @volume_24h       -= execution[:base_size]
  @quote_volume_24h -= execution[:quote_size]
  @open_24h         = execution[:price]
  @var_24h          = @last_trade_price && ((@last_trade_price - @open_24h) / @open_24h.to_f)

  if [@high_24h, @low_24h].include?(execution[:price])
    recalc_high_low_24h!
  end
end
move_24h_cursor!() click to toggle source

Moves the cursor pointing to the first trade that happened during the last 24h. Every execution getting out of the 24h rolling window is passed to Tape#fall_out_of_24h_window

# File lib/gekko/tape.rb, line 129
def move_24h_cursor!
  while(self[@cursor_24h] && (self[@cursor_24h][:time] < time_24h_ago))
    if self[@cursor_24h][:type] == :execution
      fall_out_of_24h_window(self[@cursor_24h])
    end

    @cursor_24h += 1
  end
end
next() click to toggle source

Returns the next unread element from the tape

@return [Hash] The next unread element

# File lib/gekko/tape.rb, line 50
def next
  if @cursor < length
    n = self[@cursor]
    @cursor += 1
    n
  end
end
quote_volume_24h() click to toggle source

Returns the traded amount of quote currency in the last 24h

@return [Fixnum] The last 24h quote currency volume

# File lib/gekko/tape.rb, line 86
def quote_volume_24h
  @quote_volume_24h
end
recalc_high_low_24h!() click to toggle source

Recalculates the previous 24h high and low

# File lib/gekko/tape.rb, line 61
def recalc_high_low_24h!
  @high_24h = nil
  @low_24h  = nil

  # Work backwards from current position until the cursor points to an event
  # that's older than 24h
  tmp_cursor  = (length - 1)
  evt         = self[tmp_cursor]

  while (evt && (evt[:time] >= time_24h_ago)) do
    if evt[:type] == :execution
      @high_24h = ((@high_24h.nil? || (evt[:price] > @high_24h)) && evt[:price]) || @high_24h
      @low_24h  = ((@low_24h.nil?  || (evt[:price] < @low_24h))  && evt[:price]) || @low_24h
    end

    tmp_cursor -= 1
    evt = (tmp_cursor >= 0) && self[tmp_cursor]
  end
end
time_24h_ago() click to toggle source

Returns the float timestamp of 24h ago

@return [Float] Yesterday’s cut-off timestamp

# File lib/gekko/tape.rb, line 120
def time_24h_ago
  Time.now.to_f - SECONDS_IN_24H
end
to_hash() click to toggle source

Returns this Tape object as a Hash for the purpose of serialization

@return [Hash] The JSON-friendly Hash representation

# File lib/gekko/tape.rb, line 159
def to_hash
  {
    cursor:             @cursor,
    cursor_24h:         @cursor_24h,
    volume_24h:         @volume_24h,
    high_24h:           @high_24h,
    low_24h:            @low_24h,
    open_24h:           @open_24h,
    var_24h:            @var_24h,
    quote_volume_24h:   @quote_volume_24h,
    last_trade_price:   @last_trade_price,
    events:             self
  }
end
update_ticker(execution) click to toggle source

Updates the ticker after an execution has been recorded

# File lib/gekko/tape.rb, line 93
def update_ticker(execution)
  price = execution[:price]

  # Keep last price up to date
  @last_trade_price = price

  # Keep 24h volume up to date
  @volume_24h       += execution[:base_size]
  @quote_volume_24h += execution[:quote_size]

  # Record new high/lows
  if @high_24h.nil? || (@high_24h < price)
    @high_24h = price
  end

  if @low_24h.nil? || (price < @low_24h)
    @low_24h = price
  end

  move_24h_cursor!
end