Class: RbtcArbitrage::Trader

Inherits:
Object
  • Object
show all
Defined in:
lib/rbtc_arbitrage/trader.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(config = {}) ⇒ Trader

Returns a new instance of Trader.



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# File 'lib/rbtc_arbitrage/trader.rb', line 6

def initialize config={}
  @buyer   = {}
  @seller  = {}
  @options = {}
  set_key config, :volume, 0.01
  set_key config, :cutoff, 2
  set_key config, :logger, Logger.new(STDOUT)
  set_key config, :verbose, true
  set_key config, :live, false
  exchange = config[:buyer] || :bitstamp
  @buy_client = client_for_exchange(exchange)
  exchange = config[:seller] || :mtgox
  @sell_client = client_for_exchange(exchange)
  self
end

Instance Attribute Details

#buy_clientObject (readonly)

Returns the value of attribute buy_client.



3
4
5
# File 'lib/rbtc_arbitrage/trader.rb', line 3

def buy_client
  @buy_client
end

#buyerObject

Returns the value of attribute buyer.



4
5
6
# File 'lib/rbtc_arbitrage/trader.rb', line 4

def buyer
  @buyer
end

#optionsObject

Returns the value of attribute options.



4
5
6
# File 'lib/rbtc_arbitrage/trader.rb', line 4

def options
  @options
end

#receivedObject (readonly)

Returns the value of attribute received.



3
4
5
# File 'lib/rbtc_arbitrage/trader.rb', line 3

def received
  @received
end

#sell_clientObject (readonly)

Returns the value of attribute sell_client.



3
4
5
# File 'lib/rbtc_arbitrage/trader.rb', line 3

def sell_client
  @sell_client
end

#sellerObject

Returns the value of attribute seller.



4
5
6
# File 'lib/rbtc_arbitrage/trader.rb', line 4

def seller
  @seller
end

Instance Method Details

#client_for_exchange(market) ⇒ Object



93
94
95
96
97
98
99
100
101
# File 'lib/rbtc_arbitrage/trader.rb', line 93

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
  clazz = RbtcArbitrage::Clients.const_get(clazz)
  clazz.new @options
end

#execute_tradeObject

Raises:

  • (SecurityError)


39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/rbtc_arbitrage/trader.rb', line 39

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]
    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
  else
    logger.info "Not trading live because cutoff is higher than profit." if @options[:verbose]
  end
end

#fetch_pricesObject



58
59
60
61
62
63
64
65
66
# File 'lib/rbtc_arbitrage/trader.rb', line 58

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]]
  @paid = prices.min * 1.005 * @options[:volume]
  @received = prices.max * 0.994 * @options[:volume]
  @percent = ((received/@paid - 1) * 100).round(2)
end

#get_balanceObject



78
79
80
81
# File 'lib/rbtc_arbitrage/trader.rb', line 78

def get_balance
  @seller[:btc], @seller[:usd] = @sell_client.balance
  @buyer[:btc], @buyer[:usd] = @buy_client.balance
end

#log_infoObject



68
69
70
71
72
73
74
75
76
# File 'lib/rbtc_arbitrage/trader.rb', line 68

def log_info
  lower_ex = @buy_client.exchange.to_s.capitalize
  higher_ex = @sell_client.exchange.to_s.capitalize
  logger.info "#{lower_ex}: $#{buyer[:price].round(2)}"
  logger.info "#{higher_ex}: $#{seller[:price].round(2)}"
  logger.info "buying #{@options[:volume]} btc from #{lower_ex} for $#{@paid.round(2)}"
  logger.info "selling #{@options[:volume]} btc on #{higher_ex} for $#{@received.round(2)}"
  logger.info "profit: $#{(@received - @paid).round(2)} (#{@percent.round(2)}%)"
end

#loggerObject



83
84
85
# File 'lib/rbtc_arbitrage/trader.rb', line 83

def logger
  @options[:logger]
end

#set_key(config, key, default) ⇒ Object



22
23
24
# File 'lib/rbtc_arbitrage/trader.rb', line 22

def set_key config, key, default
  @options[key] = config.has_key?(key) ? config[key] : default
end

#tradeObject



26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/rbtc_arbitrage/trader.rb', line 26

def trade
  fetch_prices
  log_info if options[:verbose]

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

  execute_trade if options[:live]

  self
end

#validate_envObject



87
88
89
90
91
# File 'lib/rbtc_arbitrage/trader.rb', line 87

def validate_env
  [@sell_client, @buy_client].each do |client|
    client.validate_env
  end
end