module Moneymarket
Public Class Methods
book()
click to toggle source
# File lib/moneymarket.rb, line 18 def self.book() end
new(_market)
click to toggle source
# File lib/moneymarket/core/book.rb, line 5 def initialize(_market) @market = _market @bids = Slope.new { |a, b| a.limit_cents <=> b.limit_cents } @asks = Slope.new { |a, b| b.limit_cents <=> a.limit_cents } end
Public Instance Methods
Book()
click to toggle source
# File lib/moneymarket/core/book.rb, line 2 def Book attr_reader :asks, :bids def initialize(_market) @market = _market @bids = Slope.new { |a, b| a.limit_cents <=> b.limit_cents } @asks = Slope.new { |a, b| b.limit_cents <=> a.limit_cents } end def flush_events flushed = @events @events = [] flushed end def push(_order) # TODO: check market(currency) if _order.new? raise ArgumentError, 'insolvent order' unless check_solvent _order matches = match_to_slope _order matches = adjust_market_order matches, _order if _order.market_order? preload_balances matches matches.each { |tx| execute_match tx } _order.flag_as_open freeze_source_balance _order # TODO: execute_triggers (stop-loss, take-profit, etc) end slope_for(_order).add _order if _order.open? end def cancel(_order) if _order.open? slope_for(_order).remove _order end end private def slope_for(_order) if order.bid? then bids else asks end end def oposite_slope(_order) if order.bid? then asks else bids end end def check_solvent(_order) CheckOrderSolvent.for market: market, order: _order end def match_to_slope(_order) slope = oposite_slope(_order) MatchOrderToSlope.for slope: slope, order: _order end def adjust_market_order(_matches, _order) limit = market.source_account(_order).available_amount LimitMatches.for matches: _matches, limit: limit end def execute_match(_match) @events << ExecuteMatch.for(market: market, match: _match) end def preload_balances(_matches) users = _matches.map { |m| [m.bid.user, m.ask.user] }.flatten.uniq market.preload_user_balances users end end
adjust_market_order(_matches, _order)
click to toggle source
# File lib/moneymarket/core/book.rb, line 62 def adjust_market_order(_matches, _order) limit = market.source_account(_order).available_amount LimitMatches.for matches: _matches, limit: limit end
cancel(_order)
click to toggle source
# File lib/moneymarket/core/book.rb, line 36 def cancel(_order) if _order.open? slope_for(_order).remove _order end end
check_solvent(_order)
click to toggle source
# File lib/moneymarket/core/book.rb, line 53 def check_solvent(_order) CheckOrderSolvent.for market: market, order: _order end
execute_match(_match)
click to toggle source
# File lib/moneymarket/core/book.rb, line 67 def execute_match(_match) @events << ExecuteMatch.for(market: market, match: _match) end
flush_events()
click to toggle source
# File lib/moneymarket/core/book.rb, line 11 def flush_events flushed = @events @events = [] flushed end
match_to_slope(_order)
click to toggle source
# File lib/moneymarket/core/book.rb, line 57 def match_to_slope(_order) slope = oposite_slope(_order) MatchOrderToSlope.for slope: slope, order: _order end
oposite_slope(_order)
click to toggle source
# File lib/moneymarket/core/book.rb, line 49 def oposite_slope(_order) if order.bid? then asks else bids end end
preload_balances(_matches)
click to toggle source
# File lib/moneymarket/core/book.rb, line 71 def preload_balances(_matches) users = _matches.map { |m| [m.bid.user, m.ask.user] }.flatten.uniq market.preload_user_balances users end
push(_order)
click to toggle source
# File lib/moneymarket/core/book.rb, line 17 def push(_order) # TODO: check market(currency) if _order.new? raise ArgumentError, 'insolvent order' unless check_solvent _order matches = match_to_slope _order matches = adjust_market_order matches, _order if _order.market_order? preload_balances matches matches.each { |tx| execute_match tx } _order.flag_as_open freeze_source_balance _order # TODO: execute_triggers (stop-loss, take-profit, etc) end slope_for(_order).add _order if _order.open? end
slope_for(_order)
click to toggle source
# File lib/moneymarket/core/book.rb, line 45 def slope_for(_order) if order.bid? then bids else asks end end