class RbtcArbitrage::Trader

Attributes

buy_client[R]
buyer[RW]
options[RW]
received[R]
sell_client[R]
seller[RW]

Public Class Methods

new(config={}) click to toggle source
# File lib/rbtc_arbitrage/trader.rb, line 9
def initialize config={}
  opts = {}
  config.each do |key, val|
    opts[(key.to_sym rescue key) || key] = val
  end
  @buyer   = {}
  @seller  = {}
  @options = {}
  set_key opts, :volume, 0.01
  set_key opts, :cutoff, 2
  default_logger = Logger.new($stdout)
  default_logger.datetime_format = "%^b %e %Y %l:%M:%S %p %z"
  set_key opts, :logger, default_logger
  set_key opts, :verbose, true
  set_key opts, :live, false
  set_key opts, :repeat, nil
  exchange = opts[:buyer] || :btce
  set_key opts, :notify, false
  @buy_client = client_for_exchange(exchange)
  exchange = opts[:seller] || :campbx
  @sell_client = client_for_exchange(exchange)
  self
end

Public Instance Methods

client_for_exchange(market) click to toggle source
# File lib/rbtc_arbitrage/trader.rb, line 105
def client_for_exchange market
  market = market.to_sym unless market.is_a?(Symbol)
  clazz = RbtcArbitrage::Clients.constants.find do |c|
    clazz = RbtcArbitrage::Clients.const_get(c)
    clazz.new.exchange == market
  end
  begin
    clazz = RbtcArbitrage::Clients.const_get(clazz)
    clazz.new @options
  rescue TypeError => e
    raise ArgumentError, "Invalid exchange - '#{market}'"
  end
end
execute_trade() click to toggle source
# File lib/rbtc_arbitrage/trader.rb, line 64
def execute_trade
  fetch_prices unless @paid
  validate_env
  raise SecurityError, "--live flag is false. Not executing trade." unless options[:live]
  get_balance
  if @percent > @options[:cutoff]
    buy_and_transfer!
  else
    logger.info "Not trading live because cutoff is higher than profit." if @options[:verbose]
  end
end
fetch_prices() click to toggle source
# File lib/rbtc_arbitrage/trader.rb, line 76
def fetch_prices
  logger.info "Fetching exchange rates" if @options[:verbose]
  buyer[:price] = @buy_client.price(:buy)
  seller[:price] = @sell_client.price(:sell)
  prices = [buyer[:price], seller[:price]]

  calculate_profit
end
get_balance() click to toggle source
# File lib/rbtc_arbitrage/trader.rb, line 85
def get_balance
  @seller[:btc], @seller[:usd] = @sell_client.balance
  @buyer[:btc], @buyer[:usd] = @buy_client.balance
end
set_key(config, key, default) click to toggle source
# File lib/rbtc_arbitrage/trader.rb, line 33
def set_key config, key, default
  @options[key] = config.has_key?(key) ? config[key] : default
end
trade() click to toggle source
# File lib/rbtc_arbitrage/trader.rb, line 37
def trade
  fetch_prices
  log_info if options[:verbose]

  if options[:live] && options[:cutoff] > @percent
    raise SecurityError, "Exiting because real profit (#{@percent.round(2)}%) is less than cutoff (#{options[:cutoff].round(2)}%)"
  end

  execute_trade if options[:live]

  notify

  if @options[:repeat]
    trade_again
  end

  self
end
trade_again() click to toggle source
# File lib/rbtc_arbitrage/trader.rb, line 56
def trade_again
  sleep @options[:repeat]
  logger.info " - " if @options[:verbose]
  @buy_client = @buy_client.class.new(@options)
  @sell_client = @sell_client.class.new(@options)
  trade
end
validate_env() click to toggle source
# File lib/rbtc_arbitrage/trader.rb, line 90
def validate_env
  [@sell_client, @buy_client].each do |client|
    client.validate_env
  end
  if options[:notify]
    ["PASSWORD","USERNAME","EMAIL"].each do |key|
      key = "SENDGRID_#{key}"
      unless ENV[key]
        raise ArgumentError, "Exiting because missing required ENV variable $#{key}."
      end
    end
    setup_pony
  end
end

Private Instance Methods

buy_and_transfer!() click to toggle source
# File lib/rbtc_arbitrage/trader.rb, line 127
def buy_and_transfer!
  if @paid > buyer[:usd] || @options[:volume] > seller[:btc]
    raise SecurityError, "Not enough funds. Exiting."
  else
    logger.info "Trading live!" if options[:verbose]
    @buy_client.buy
    @sell_client.sell
    @buy_client.transfer @sell_client
  end
end
calculate_profit() click to toggle source
# File lib/rbtc_arbitrage/trader.rb, line 121
def calculate_profit
  @paid = buyer[:price] * 1.006 * @options[:volume]
  @received = seller[:price] * 0.994 * @options[:volume]
  @percent = ((received/@paid - 1) * 100).round(2)
end