Class: Ubea::OrderBook

Inherits:
Object
  • Object
show all
Defined in:
lib/ubea/order_book.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(hash) ⇒ OrderBook

Returns a new instance of OrderBook.

Raises:

  • (ArgumentError)


6
7
8
9
10
11
# File 'lib/ubea/order_book.rb', line 6

def initialize(hash)
  @asks = hash.delete(:asks).sort_by(&:price).freeze # buy
  @bids = hash.delete(:bids).sort_by(&:price).freeze # sell

  raise ArgumentError unless hash.empty?
end

Instance Attribute Details

#asksObject (readonly)

Returns the value of attribute asks.



3
4
5
# File 'lib/ubea/order_book.rb', line 3

def asks
  @asks
end

#bidsObject (readonly)

Returns the value of attribute bids.



3
4
5
# File 'lib/ubea/order_book.rb', line 3

def bids
  @bids
end

#marketObject

Returns the value of attribute market.



4
5
6
# File 'lib/ubea/order_book.rb', line 4

def market
  @market
end

#updated_atObject

Returns the value of attribute updated_at.



4
5
6
# File 'lib/ubea/order_book.rb', line 4

def updated_at
  @updated_at
end

Instance Method Details

#best_offer_price_for_fiat_amount(type, fiat_amount, fiat_currency) ⇒ Object



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/ubea/order_book.rb', line 55

def best_offer_price_for_fiat_amount(type, fiat_amount, fiat_currency)
  total_fiat_amount = 0
  good_offers = []

  offers = public_send(type).dup # asks or bids
  offers.reverse! if type == :bids

  offers.each do |offer|
    break if total_fiat_amount >= fiat_amount

    offer = offer.dup # NOTE: dup because we're gonna mess with its volume below
    offer.price = offer.price.exchange_to(fiat_currency)
    good_offers << offer
    total_fiat_amount += offer.price * offer.volume
  end

  if total_fiat_amount > fiat_amount
    substract_fiat = total_fiat_amount - fiat_amount
    substract_volume = substract_fiat / good_offers.last.price
    good_offers.last.volume -= substract_volume
  end

  total_weight_price = good_offers.map { |offer| offer.price * offer.volume }.inject(:+) || 0
  total_volume = good_offers.map(&:volume).inject(:+)
  weighted_price = total_weight_price / total_volume

  Offer.new(
    price: good_offers.last.price,
    volume: total_volume,
    weighted_price: weighted_price,
  )
end

#highest_bidObject



17
18
19
# File 'lib/ubea/order_book.rb', line 17

def highest_bid
  bids.last
end

#lowest_askObject



21
22
23
# File 'lib/ubea/order_book.rb', line 21

def lowest_ask
  asks.first
end

#max_bid_price_for_volume(min_price, max_volume) ⇒ Object



44
45
46
47
48
49
50
51
52
53
# File 'lib/ubea/order_book.rb', line 44

def max_bid_price_for_volume(min_price, max_volume)
  filter = if min_price
    ->(price) { price >= min_price }
  else
    ->(_) { true }
  end

  interesting_bids = interesting_offers(bids, filter).reverse # reverse to start from most expensive
  best_offer_price_for_volume(interesting_bids, max_volume)
end

#min_ask_price_for_volume(max_price, max_volume) ⇒ Object



33
34
35
36
37
38
39
40
41
42
# File 'lib/ubea/order_book.rb', line 33

def min_ask_price_for_volume(max_price, max_volume)
  filter = if max_price
    ->(price) { price <= max_price }
  else
    ->(_) { true }
  end

  interesting_asks = interesting_offers(asks, filter)
  best_offer_price_for_volume(interesting_asks, max_volume)
end

#to_paramObject



13
14
15
# File 'lib/ubea/order_book.rb', line 13

def to_param
  market.to_param
end

#weighted_asks_up_to(max_price) ⇒ Object



25
26
27
# File 'lib/ubea/order_book.rb', line 25

def weighted_asks_up_to(max_price)
  weighted_offers(asks, ->(price) { price <= max_price })
end

#weighted_bids_down_to(min_price) ⇒ Object



29
30
31
# File 'lib/ubea/order_book.rb', line 29

def weighted_bids_down_to(min_price)
  weighted_offers(bids, ->(price) { price >= min_price })
end