Class: RbtcArbitrage::Trader

Inherits:
Object
  • Object
show all
Includes:
RbtcArbitrage::TraderHelpers::Logger, RbtcArbitrage::TraderHelpers::Notifier
Defined in:
lib/rbtc_arbitrage/trader.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from RbtcArbitrage::TraderHelpers::Logger

#log_info, #logger

Methods included from RbtcArbitrage::TraderHelpers::Notifier

#notification, #notify, #setup_pony

Constructor Details

#initialize(config = {}) ⇒ Trader

Returns a new instance of Trader.



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# 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
  set_key opts, :notify, false
  exchange = opts[:buyer] || :bitstamp
  @buy_client = client_for_exchange(exchange)
  exchange = opts[:seller] || :campbx
  @sell_client = client_for_exchange(exchange)
  self
end

Instance Attribute Details

#buy_clientObject (readonly)

Returns the value of attribute buy_client.



6
7
8
# File 'lib/rbtc_arbitrage/trader.rb', line 6

def buy_client
  @buy_client
end

#buyerObject

Returns the value of attribute buyer.



7
8
9
# File 'lib/rbtc_arbitrage/trader.rb', line 7

def buyer
  @buyer
end

#optionsObject

Returns the value of attribute options.



7
8
9
# File 'lib/rbtc_arbitrage/trader.rb', line 7

def options
  @options
end

#receivedObject (readonly)

Returns the value of attribute received.



6
7
8
# File 'lib/rbtc_arbitrage/trader.rb', line 6

def received
  @received
end

#sell_clientObject (readonly)

Returns the value of attribute sell_client.



6
7
8
# File 'lib/rbtc_arbitrage/trader.rb', line 6

def sell_client
  @sell_client
end

#sellerObject

Returns the value of attribute seller.



7
8
9
# File 'lib/rbtc_arbitrage/trader.rb', line 7

def seller
  @seller
end

Instance Method Details

#client_for_exchange(market) ⇒ Object



105
106
107
108
109
110
111
112
113
114
115
116
117
# 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_tradeObject

Raises:

  • (SecurityError)


64
65
66
67
68
69
70
71
72
73
74
# 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_pricesObject



76
77
78
79
80
81
82
83
# 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_balanceObject



85
86
87
88
# 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) ⇒ Object



33
34
35
# File 'lib/rbtc_arbitrage/trader.rb', line 33

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

#tradeObject



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# 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_againObject



56
57
58
59
60
61
62
# 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_envObject



90
91
92
93
94
95
96
97
98
99
100
101
102
103
# 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