Class: Gekko::Book

Inherits:
Object
  • Object
show all
Defined in:
lib/gekko/book.rb

Overview

An order book consisting of a bid side and an ask side

Constant Summary collapse

DEFAULT_TICK_SIZE =

The default minimum price increment accepted for placed orders

1000

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(pair, opts = {}) ⇒ Book

Returns a new instance of Book.



21
22
23
24
25
26
27
28
29
# File 'lib/gekko/book.rb', line 21

def initialize(pair, opts = {})
  self.pair       = pair
  self.bids       = BookSide.new(:bid)
  self.asks       = BookSide.new(:ask)
  self.tape       = Tape.new(opts[:logger])

  self.tick_size  = opts[:tick_size] || DEFAULT_TICK_SIZE
  raise "Tick size must be a positive integer if provided" if tick_size && (!tick_size.is_a?(Fixnum) || tick_size <= 0)
end

Instance Attribute Details

#asksObject

Returns the value of attribute asks.



19
20
21
# File 'lib/gekko/book.rb', line 19

def asks
  @asks
end

#bidsObject

Returns the value of attribute bids.



19
20
21
# File 'lib/gekko/book.rb', line 19

def bids
  @bids
end

#pairObject

Returns the value of attribute pair.



19
20
21
# File 'lib/gekko/book.rb', line 19

def pair
  @pair
end

#tapeObject

Returns the value of attribute tape.



19
20
21
# File 'lib/gekko/book.rb', line 19

def tape
  @tape
end

#tick_sizeObject

Returns the value of attribute tick_size.



19
20
21
# File 'lib/gekko/book.rb', line 19

def tick_size
  @tick_size
end

Instance Method Details

#askObject

Returns the current best ask price or nil if there are currently no asks



83
84
85
# File 'lib/gekko/book.rb', line 83

def ask
  asks.top
end

#bidObject

Returns the current best bid price or nil if there are currently no bids



91
92
93
# File 'lib/gekko/book.rb', line 91

def bid
  bids.top
end

#receive_order(order) ⇒ Object

Receives an order and executes it

Parameters:

  • order (Order)

    The order to execute

Raises:



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/gekko/book.rb', line 36

def receive_order(order)

  raise Gekko::TickSizeMismatch unless (order.price % tick_size).zero?

  order_side    = order.bid? ? bids : asks
  opposite_side = order.bid? ? asks : bids
  next_match    = opposite_side.first

  while !order.filled? && order.crosses?(next_match)

    trade_price   = next_match.price
    base_size   = [next_match.remaining, order.remaining].min

    quoted_size = base_size / trade_price

    tape << {
      type:             :execution,
      price:            trade_price,
      base_size:        base_size,
      quoted_size:      quoted_size,
      maker_order_id:   next_match.id,
      taker_order_id:   order.id,
      time:             Time.now.to_f,
      tick:             order.bid? ? :up : :down
    }

    order.remaining       -= base_size
    next_match.remaining  -= base_size

    if next_match.filled?
      tape << opposite_side.shift.message(:done, reason: :filled)
      next_match = opposite_side.first
    end
  end

  if order.filled?
    tape << order.message(:done, reason: :filled)
  else
    order_side.insert_order(order)
    tape << order.message(:open)
  end
end

#spreadObject

Returns the current spread if at least a bid and an ask are present, returns nil otherwise



99
100
101
# File 'lib/gekko/book.rb', line 99

def spread
  ask && bid && (ask - bid)
end