class Devilicious::OrderBook
Attributes
asks[R]
bids[R]
market[RW]
Public Class Methods
new(hash)
click to toggle source
# File lib/devilicious/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
Public Instance Methods
highest_bid()
click to toggle source
# File lib/devilicious/order_book.rb, line 13 def highest_bid bids.last end
lowest_ask()
click to toggle source
# File lib/devilicious/order_book.rb, line 17 def lowest_ask asks.first end
max_bid_price_for_volume(min_price, max_volume)
click to toggle source
# File lib/devilicious/order_book.rb, line 34 def max_bid_price_for_volume(min_price, max_volume) interesting_bids = interesting_offers(bids, ->(price) { price >= min_price }).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)
click to toggle source
# File lib/devilicious/order_book.rb, line 29 def min_ask_price_for_volume(max_price, max_volume) interesting_asks = interesting_offers(asks, ->(price) { price <= max_price }) best_offer_price_for_volume(interesting_asks, max_volume) end
weighted_asks_up_to(max_price)
click to toggle source
# File lib/devilicious/order_book.rb, line 21 def weighted_asks_up_to(max_price) weighted_offers(asks, ->(price) { price <= max_price }) end
weighted_bids_down_to(min_price)
click to toggle source
# File lib/devilicious/order_book.rb, line 25 def weighted_bids_down_to(min_price) weighted_offers(bids, ->(price) { price >= min_price }) end
Private Instance Methods
best_offer_price_for_volume(offers, max_volume)
click to toggle source
# File lib/devilicious/order_book.rb, line 58 def best_offer_price_for_volume(offers, max_volume) total_volume = 0 good_offers = [] offers.each do |offer| if total_volume <= max_volume good_offers << offer.dup # NOTE: dup because we're gonna mess with its volume below total_volume += offer.volume end end if total_volume > max_volume substract_volume = total_volume - max_volume good_offers.last.volume -= substract_volume total_volume -= substract_volume end total_weight_price = good_offers.map { |offer| offer.price * offer.volume }.inject(:+) || 0 weighted_price = total_weight_price / total_volume Offer.new( price: good_offers.last.price, volume: total_volume, weighted_price: weighted_price, ) end
currency()
click to toggle source
# File lib/devilicious/order_book.rb, line 85 def currency lowest_ask.price.currency end
interesting_offers(offers, condition)
click to toggle source
# File lib/devilicious/order_book.rb, line 41 def interesting_offers(offers, condition) offers.select { |offer| condition.call(offer.price) } end
weighted_offers(offers, condition)
click to toggle source
# File lib/devilicious/order_book.rb, line 45 def weighted_offers(offers, condition) interesting_offers = interesting_offers(offers, condition) total_volume = interesting_offers.map(&:volume).inject(:+) || 0 total_weight_price = interesting_offers.map { |offer| offer.price * offer.volume }.inject(:+) || 0 weighted_price = total_weight_price / total_volume Offer.new( price: Money.new(weighted_price, currency), volume: total_volume ) end