class Trader::FakeBackend

Attributes

asks[R]
bids[R]
pair[R]
verbose[R]

Public Class Methods

instance() click to toggle source
# File lib/trade-o-matic/adapters/fake_backend.rb, line 36
def self.instance
  @@instance ||= self.new
end
new(_config=nil) click to toggle source
Calls superclass method Trader::BaseBackend::new
# File lib/trade-o-matic/adapters/fake_backend.rb, line 44
def initialize(_config=nil)
  super :fake
  get_session(_config) unless _config.nil?
end
reset_instance() click to toggle source
# File lib/trade-o-matic/adapters/fake_backend.rb, line 40
def self.reset_instance
  @@instance = nil
end

Public Instance Methods

available_base_balance() click to toggle source
# File lib/trade-o-matic/adapters/fake_backend.rb, line 57
def available_base_balance
  @base_balance
end
available_quote_balance() click to toggle source
# File lib/trade-o-matic/adapters/fake_backend.rb, line 61
def available_quote_balance
  @quote_balance
end
cancel_order(_session, _order_id) click to toggle source
# File lib/trade-o-matic/adapters/fake_backend.rb, line 146
def cancel_order(_session, _order_id)
  order = find_order_by_id(_order_id)

  info "Closing #{order[:instruction]} order for #{order[:pend_volume] + order[:traded_volume]} #{pair.base} @ #{order[:price]} #{pair.quote}", :red

  if order[:status] == AccountOrder::OPEN
    if order[:instruction] == Order::ASK
      @base_balance += order[:pend_volume]
    else
      @quote_balance += order[:pend_volume] * order[:price]
    end
    order[:status] = AccountOrder::CANCELED
  end

  FakeOrder.new order.clone
end
create_order(_session, _pair, _volume, _price, _instruction) click to toggle source
# File lib/trade-o-matic/adapters/fake_backend.rb, line 108
def create_order(_session, _pair, _volume, _price, _instruction)
  not_supported 'market' unless _pair == pair
  not_supported 'market order' if _price.nil? && @market_price.nil?

  unless _price.nil?
    if _instruction == Order::ASK
      raise 'Not enough funds' if _volume > @base_balance
      @base_balance -= _volume
    else
      raise 'Not enough funds' if _volume * _price > @quote_balance
      @quote_balance -= _volume * _price
    end
  end

  info "Creating #{_instruction} order for #{_volume} #{pair.base} @ #{_price} #{pair.quote}", :green

  raw_order = {
    id: @id.to_s,
    pair: pair,
    instruction: _instruction,
    status: AccountOrder::OPEN,
    price: _price,
    pend_volume: _volume,
    traded_volume: 0.0
  }

  execute_fake_market_order raw_order if _price.nil?

  @id += 1
  (_instruction == Order::ASK ? @asks : @bids) << raw_order

  FakeOrder.new raw_order.clone
end
fetch_order(_session, _order_id) click to toggle source
# File lib/trade-o-matic/adapters/fake_backend.rb, line 142
def fetch_order(_session, _order_id)
  FakeOrder.new find_order_by_id(_order_id).clone
end
fill_book(_book) click to toggle source
# File lib/trade-o-matic/adapters/fake_backend.rb, line 53
def fill_book(_book)
  # TODO
end
get_available_markets() click to toggle source
# File lib/trade-o-matic/adapters/fake_backend.rb, line 49
def get_available_markets
  [@pair]
end
get_balance(_session, _currency) click to toggle source
# File lib/trade-o-matic/adapters/fake_backend.rb, line 93
def get_balance(_session, _currency)
  if _currency == pair.base
    FakeBalance.new(total_base_balance, available_base_balance)
  elsif _currency == pair.quote
    FakeBalance.new(total_quote_balance, available_quote_balance)
  else
    raise 'currency not supported'
  end
end
get_orders(_session, _pair) click to toggle source
# File lib/trade-o-matic/adapters/fake_backend.rb, line 103
def get_orders(_session, _pair)
  return [] unless _pair == pair
  (@bids + @asks).map { |o| FakeOrder.new o.clone }
end
get_session(_config) click to toggle source
# File lib/trade-o-matic/adapters/fake_backend.rb, line 73
def get_session(_config)
  raise ArgumentError, 'must provide login information' if _config.nil?

  if @config.nil?
    @pair = CurrencyPair.for_code(_config[:base], _config[:quote])
    @base_balance = _config[:base_balance]
    @quote_balance = _config[:quote_balance]
    @market_price = _config[:market_price]
    @verbose = !!_config[:verbose]
    @config = _config
    @bids = []
    @asks = []
    @id = 1
  elsif @config != _config
    raise ArgumentError, 'invalid credentials'
  end

  nil
end
open_asks() click to toggle source
# File lib/trade-o-matic/adapters/fake_backend.rb, line 28
def open_asks
  asks.select { |o| o[:status] == AccountOrder::OPEN }
end
open_bids() click to toggle source
# File lib/trade-o-matic/adapters/fake_backend.rb, line 24
def open_bids
  bids.select { |o| o[:status] == AccountOrder::OPEN }
end
open_orders() click to toggle source
# File lib/trade-o-matic/adapters/fake_backend.rb, line 32
def open_orders
  open_bids + open_asks
end
simulate_buy(_price, _volume) click to toggle source
# File lib/trade-o-matic/adapters/fake_backend.rb, line 163
def simulate_buy(_price, _volume)
  ordered_asks = @asks.sort { |b| b[:price] * -1 }
  ordered_asks.each do |order|
    if order[:status] == AccountOrder::OPEN && order[:price] <= _price && _volume > 0
      if order[:pend_volume] > _volume
        @quote_balance += _volume * order[:price]
        order[:pend_volume] -= _volume
        order[:traded_volume] += _volume
        _volume = 0
      else
        @quote_balance += order[:pend_volume] * order[:price]
        _volume -= order[:pend_volume]
        order[:traded_volume] += order[:pend_volume]
        order[:pend_volume] = 0
      end

      if order[:pend_volume] == 0
        order[:status] = AccountOrder::CLOSED
      end
    end
  end
end
simulate_sell(_price, _volume) click to toggle source
# File lib/trade-o-matic/adapters/fake_backend.rb, line 186
def simulate_sell(_price, _volume)
  ordered_bids = @bids.sort { |b| b[:price] }
  ordered_bids.each do |order|
    if order[:status] == AccountOrder::OPEN && order[:price] >= _price && _volume > 0
      if order[:pend_volume] > _volume
        @base_balance += _volume
        order[:pend_volume] -= _volume
        order[:traded_volume] += _volume
        _volume = 0
      else
        @base_balance += order[:pend_volume]
        _volume -= order[:pend_volume]
        order[:traded_volume] += order[:pend_volume]
        order[:pend_volume] = 0
      end

      if order[:pend_volume] == 0
        order[:status] = AccountOrder::CLOSED
      end
    end
  end
end
total_base_balance() click to toggle source
# File lib/trade-o-matic/adapters/fake_backend.rb, line 65
def total_base_balance
  @base_balance + frozen_base
end
total_quote_balance() click to toggle source
# File lib/trade-o-matic/adapters/fake_backend.rb, line 69
def total_quote_balance
  @quote_balance + frozen_quote
end

Private Instance Methods

execute_fake_market_order(_raw) click to toggle source
# File lib/trade-o-matic/adapters/fake_backend.rb, line 237
def execute_fake_market_order(_raw)
  traded_volume = 0.0
  if _raw[:instruction] == Order::ASK
    traded_volume = [ @base_balance, _raw[:pend_volume] ].min
    @base_balance -= traded_volume
    @quote_balance += @market_price * traded_volume
  else
    traded_volume = [ @quote_balance/@market_price, _raw[:pend_volume] ].min
    @base_balance += traded_volume
    @quote_balance -= @market_price * traded_volume
  end

  _raw[:traded_volume] = traded_volume
  _raw[:pend_volume] -= traded_volume
  _raw[:status] = AccountOrder::CLOSED
end
find_order_by_id(_id) click to toggle source
# File lib/trade-o-matic/adapters/fake_backend.rb, line 231
def find_order_by_id(_id)
  order = @bids.find { |o| o[:id] == _id }
  order = @asks.find { |o| o[:id] == _id } if order.nil?
  order
end
frozen_base() click to toggle source
# File lib/trade-o-matic/adapters/fake_backend.rb, line 217
def frozen_base
  @asks.inject(0) do |r, order|
    next r if order[:status] != AccountOrder::OPEN
    r + order[:pend_volume]
  end
end
frozen_quote() click to toggle source
# File lib/trade-o-matic/adapters/fake_backend.rb, line 224
def frozen_quote
  @bids.inject(0) do |r, order|
    next r if order[:status] != AccountOrder::OPEN
    r + (order[:pend_volume] * order[:price])
  end
end
info(_msg, _color=:white) click to toggle source
# File lib/trade-o-matic/adapters/fake_backend.rb, line 211
def info(_msg, _color=:white)
  if verbose
    puts "FakeEx: #{_msg}".color(_color)
  end
end