Class: MercadoBitcoin::TradeApi

Inherits:
Object
  • Object
show all
Defined in:
lib/mercado_bitcoin/trade_api.rb

Constant Summary collapse

BTC =
'BRLBTC'
LTC =
'BRLLTC'

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(key:, code:, debug: false) ⇒ TradeApi

Returns a new instance of TradeApi.



12
13
14
15
16
17
# File 'lib/mercado_bitcoin/trade_api.rb', line 12

def initialize(key:, code:, debug: false)
  @key = key
  @code = code
  @debug = debug
  @retries = 0
end

Instance Attribute Details

#codeObject

Returns the value of attribute code.



10
11
12
# File 'lib/mercado_bitcoin/trade_api.rb', line 10

def code
  @code
end

#keyObject

Returns the value of attribute key.



10
11
12
# File 'lib/mercado_bitcoin/trade_api.rb', line 10

def key
  @key
end

#last_tapi_nonceObject



115
116
117
# File 'lib/mercado_bitcoin/trade_api.rb', line 115

def last_tapi_nonce
  @last_tapi_nonce ||= (Time.new.to_f * 10).to_i
end

Instance Method Details

#base_params(method) ⇒ Object



189
190
191
192
193
# File 'lib/mercado_bitcoin/trade_api.rb', line 189

def base_params(method)
  {
    tapi_method: method
  }
end

#base_pathObject



173
174
175
# File 'lib/mercado_bitcoin/trade_api.rb', line 173

def base_path
  @base_path ||= "/tapi/v3/".freeze
end

#base_urlObject



177
178
179
# File 'lib/mercado_bitcoin/trade_api.rb', line 177

def base_url
  @base_url ||= "https://www.mercadobitcoin.net#{base_path}".freeze
end

#cancel_order(coin_pair: BTC, order_id:) ⇒ Object



80
81
82
83
84
85
# File 'lib/mercado_bitcoin/trade_api.rb', line 80

def cancel_order(coin_pair: BTC, order_id:)
  params = base_params('cancel_order')
  params[:coin_pair] = coin_pair
  params[:order_id] = order_id
  post(params)
end

#deal_with_errors(result) ⇒ Object



139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# File 'lib/mercado_bitcoin/trade_api.rb', line 139

def deal_with_errors(result)
  if result['status_code'] == 100
    @retries = 0
    return result
  end

  @retries += 1
  if @retries >= 6
    @retries = 0
    result[:_mb_gem] = { code: 1, retries: @retries, error: 'maximum retries reached' }
    return result
  end

  return deal_with_tapi_nonce(result) if result['status_code'] == 203

  deal_with_errors_not_treated(result)
end

#deal_with_errors_not_treated(result) ⇒ Object



167
168
169
170
171
# File 'lib/mercado_bitcoin/trade_api.rb', line 167

def deal_with_errors_not_treated(result)
  result[:_mb_gem] = { code: 0, retries: @retries, error: 'not treated' }
  @retries = 0
  result
end

#deal_with_tapi_nonce(result) ⇒ Object



157
158
159
160
161
162
163
164
165
# File 'lib/mercado_bitcoin/trade_api.rb', line 157

def deal_with_tapi_nonce(result)
  if result['error_message'] =~ /utilizado: (\d+)/
    self.last_tapi_nonce = $1.to_i
    raise MercadoBitcoin::TonceAlreadyUsed.new
  else
    result[:_mb_gem] = { code: 2, retries: @retries, error: 'last tapi_nonce not found.' }
    result
  end
end

#get_account_infoObject



19
20
21
22
# File 'lib/mercado_bitcoin/trade_api.rb', line 19

def 
  params = base_params('get_account_info')
  post(params)
end

#get_order(pair: BTC, order_id:) ⇒ Object



29
30
31
32
33
34
# File 'lib/mercado_bitcoin/trade_api.rb', line 29

def get_order(pair: BTC, order_id:)
  params = base_params('get_order')
  params[:order_id]  = order_id
  params[:coin_pair] = pair
  post(params)
end

#get_withdrawal(coin: 'BTC', withdrawal_id:) ⇒ Object



87
88
89
90
91
92
# File 'lib/mercado_bitcoin/trade_api.rb', line 87

def get_withdrawal(coin: 'BTC', withdrawal_id:)
  params = base_params('get_withdrawal')
  params[:coin] = coin.upcase
  params[:withdrawal_id] = withdrawal_id
  post(params)
end

#header(signature) ⇒ Object



181
182
183
184
185
186
187
# File 'lib/mercado_bitcoin/trade_api.rb', line 181

def header(signature)
  {
    'Content-Type' => 'application/x-www-form-urlencoded',
    'TAPI-ID' => key,
    'TAPI-MAC' => signature
  }
end

#list_orderbook(coin_pair: BTC, full: nil) ⇒ Object



57
58
59
60
61
62
# File 'lib/mercado_bitcoin/trade_api.rb', line 57

def list_orderbook(coin_pair: BTC, full: nil)
  params = base_params('list_orderbook')
  params[:coin_pair] = coin_pair
  params[:full] = full if full != nil
  post(params)
end

#list_orders(coin_pair: BTC, order_type: nil, status_list: nil, has_fills: nil, from_id: nil, to_id: nil, from_timestamp: nil, to_timestamp: nil) ⇒ Object



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/mercado_bitcoin/trade_api.rb', line 36

def list_orders(
  coin_pair: BTC,
  order_type: nil,
  status_list: nil,
  has_fills: nil, # com ou sem execução
  from_id: nil,
  to_id: nil,
  from_timestamp: nil,
  to_timestamp: nil)
  params = base_params('list_orders')
  params[:coin_pair] = coin_pair
  params[:order_type] = parse_order_type(order_type) if order_type
  params[:status_list] = parse_status_list(status_list) if status_list
  params[:has_fills] = has_fills if has_fills != nil
  params[:from_id] = from_id if from_id
  params[:to_id] = to_id if to_id
  params[:from_timestamp] = from_timestamp if from_timestamp
  params[:to_timestamp] = to_timestamp if to_timestamp
  post(params)
end

#list_system_messagesObject



24
25
26
27
# File 'lib/mercado_bitcoin/trade_api.rb', line 24

def list_system_messages
  params = base_params('list_system_messages')
  post(params)
end

#place_buy_order(coin_pair: BTC, quantity:, limit_price:) ⇒ Object



64
65
66
67
68
69
70
# File 'lib/mercado_bitcoin/trade_api.rb', line 64

def place_buy_order coin_pair: BTC, quantity:, limit_price:
  params = base_params('place_buy_order')
  params[:coin_pair] = coin_pair
  params[:quantity] = quantity
  params[:limit_price] = limit_price
  post(params)
end

#place_sell_order(coin_pair: BTC, quantity:, limit_price:) ⇒ Object



72
73
74
75
76
77
78
# File 'lib/mercado_bitcoin/trade_api.rb', line 72

def place_sell_order coin_pair: BTC, quantity:, limit_price:
  params = base_params('place_sell_order')
  params[:coin_pair] = coin_pair
  params[:quantity] = quantity
  params[:limit_price] = limit_price
  post(params)
end

#post(params) ⇒ Object



123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/mercado_bitcoin/trade_api.rb', line 123

def post(params)
  params[:tapi_nonce] = tapi_nonce
  signature = sign(params)
  puts params.to_query_string if debug?
  result = JSON.parse(
    RestClient.post(
      base_url,
      params.to_query_string,
      header(signature)
    )
  )
  deal_with_errors(result)
rescue MercadoBitcoin::TonceAlreadyUsed
  retry
end

#sign(string_or_hash, path = nil) ⇒ Object



195
196
197
198
199
200
# File 'lib/mercado_bitcoin/trade_api.rb', line 195

def sign(string_or_hash, path = nil)
  path ||= base_path
  string_or_hash = path + '?' + string_or_hash.to_query_string if string_or_hash.is_a?(Hash)
  hmac = OpenSSL::HMAC.new(code, OpenSSL::Digest.new('sha512'))
  hmac.update(string_or_hash).to_s
end

#tapi_nonceObject



119
120
121
# File 'lib/mercado_bitcoin/trade_api.rb', line 119

def tapi_nonce
  self.last_tapi_nonce += 1
end

#withdraw_coin(coin: 'BTC', quantity:, description: nil, **opts) ⇒ Object



94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/mercado_bitcoin/trade_api.rb', line 94

def withdraw_coin(coin: 'BTC', quantity:, description: nil, **opts)
  params = base_params('withdraw_coin')
  params[:quantity] = quantity
  params[:coin] = coin.upcase
  params[:description] = description if description

  if params[:coin] == 'BRL'
    params[:account_ref] = opts[:account_ref] || (raise MissingParameter.new('account_ref is missing for coin BRL'))
  else
    params[:address] = opts[:address]
    if params[:coin] == 'BTC'
      params[:tx_fee]         = opts[:tx_fee] || 0.00005
      params[:tx_aggregate]   = opts[:tx_aggregate]   unless opts[:tx_aggregate].nil?
      params[:via_blockchain] = opts[:via_blockchain] unless opts[:via_blockchain].nil?
    end
  end
  post(params)
end