Module: Moneymarket

Defined in:
lib/moneymarket.rb,
lib/moneymarket/core/ask.rb,
lib/moneymarket/core/bid.rb,
lib/moneymarket/core/book.rb,
lib/moneymarket/core/match.rb,
lib/moneymarket/core/order.rb,
lib/moneymarket/core/slope.rb,
lib/moneymarket/core/market.rb,
lib/moneymarket/core/account.rb,
lib/moneymarket/utils/command.rb,
lib/moneymarket/utils/calculator.rb,
lib/moneymarket/core/account_provider.rb

Defined Under Namespace

Modules: Calculator, Command Classes: Account, AccountProvider, Ask, Bid, Market, Match, Order, Slope

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.bookObject



18
19
# File 'lib/moneymarket.rb', line 18

def self.book()
end

Instance Method Details

#adjust_market_order(_matches, _order) ⇒ Object



62
63
64
65
# File 'lib/moneymarket/core/book.rb', line 62

def adjust_market_order(_matches, _order)
  limit = market.(_order).available_amount
  LimitMatches.for matches: _matches, limit: limit
end

#BookObject



2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
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
# 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.(_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

#cancel(_order) ⇒ Object



36
37
38
39
40
41
# File 'lib/moneymarket/core/book.rb', line 36

def cancel(_order)
  if _order.open?

    slope_for(_order).remove _order
  end
end

#check_solvent(_order) ⇒ Object



53
54
55
# File 'lib/moneymarket/core/book.rb', line 53

def check_solvent(_order)
  CheckOrderSolvent.for market: market, order: _order
end

#execute_match(_match) ⇒ Object



67
68
69
# File 'lib/moneymarket/core/book.rb', line 67

def execute_match(_match)
  @events << ExecuteMatch.for(market: market, match: _match)
end

#flush_eventsObject



11
12
13
14
15
# File 'lib/moneymarket/core/book.rb', line 11

def flush_events
  flushed = @events
  @events = []
  flushed
end

#initialize(_market) ⇒ Object



5
6
7
8
9
# 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

#match_to_slope(_order) ⇒ Object



57
58
59
60
# 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) ⇒ Object



49
50
51
# File 'lib/moneymarket/core/book.rb', line 49

def oposite_slope(_order)
  if order.bid? then asks else bids end
end

#preload_balances(_matches) ⇒ Object



71
72
73
74
# 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) ⇒ Object



17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# 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) ⇒ Object



45
46
47
# File 'lib/moneymarket/core/book.rb', line 45

def slope_for(_order)
  if order.bid? then bids else asks end
end