Class: CoinSync::Importers::BinanceAPI

Inherits:
Base
  • Object
show all
Defined in:
lib/coinsync/importers/binance_api.rb

Defined Under Namespace

Classes: HistoryEntry

Constant Summary collapse

BASE_URL =
"https://api.binance.com/api"
BASE_COINS =
['BTC', 'ETH', 'BNB', 'USDT']

Instance Method Summary collapse

Methods inherited from Base

#can_build?, register_commands, register_importer, registered_commands

Constructor Details

#initialize(config, params = {}) ⇒ BinanceAPI

Returns a new instance of BinanceAPI.



52
53
54
55
56
57
58
59
# File 'lib/coinsync/importers/binance_api.rb', line 52

def initialize(config, params = {})
  super

  # only "Read Info" permission is required for the key
  @api_key = params['api_key']
  @secret_key = params['secret_key']
  @traded_pairs = params['traded_pairs']
end

Instance Method Details

#can_import?(type) ⇒ Boolean

Returns:

  • (Boolean)


61
62
63
# File 'lib/coinsync/importers/binance_api.rb', line 61

def can_import?(type)
  @api_key && @secret_key && [:balances, :transactions].include?(type)
end

#find_all_pairsObject



128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
# File 'lib/coinsync/importers/binance_api.rb', line 128

def find_all_pairs
  info_response = make_request('/v1/exchangeInfo', {}, false)

  if !info_response.is_a?(Net::HTTPSuccess)
    raise "Binance importer: Bad response: #{info_response.body}"
  end

  info_json = JSON.parse(info_response.body)

  found = []

  info_json['symbols'].each do |data|
    symbol = data['symbol']
    trades_response = make_request('/v3/myTrades', limit: 1, symbol: symbol)

    case trades_response
    when Net::HTTPSuccess
      trades_json = JSON.parse(trades_response.body)

      if trades_json.length > 0
        print '*'
        found << symbol
      else
        print '.'
      end
    else
      raise "Binance importer: Bad response: #{trades_response.body}"
    end
  end

  puts
  puts "Trading pairs found:"
  puts found.sort
end

#import_balancesObject



101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/coinsync/importers/binance_api.rb', line 101

def import_balances
  response = make_request('/v3/account')

  case response
  when Net::HTTPSuccess
    json = JSON.parse(response.body)

    if json['code'] || !json['balances']
      raise "Binance importer: Invalid response: #{response.body}"
    end

    return json['balances'].select { |b|
      b['free'].to_f > 0 || b['locked'].to_f > 0
    }.map { |b|
      Balance.new(
        CryptoCurrency.new(b['asset']),
        available: BigDecimal.new(b['free']),
        locked: BigDecimal.new(b['locked'])
      )
    }
  when Net::HTTPBadRequest
    raise "Binance importer: Bad request: #{response}"
  else
    raise "Binance importer: Bad response: #{response}"
  end
end

#import_transactions(filename) ⇒ Object



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/coinsync/importers/binance_api.rb', line 65

def import_transactions(filename)
  @traded_pairs or raise "Please add a traded_pairs parameter"

  transactions = []

  @traded_pairs.uniq.each do |pair|
    lastId = 0

    loop do
      response = make_request('/v3/myTrades', limit: 500, fromId: lastId + 1, symbol: pair)

      case response
      when Net::HTTPSuccess
        json = JSON.parse(response.body)

        if !json.is_a?(Array)
          raise "Binance importer: Invalid response: #{response.body}"
        elsif json.empty?
          break
        else
          json.each { |tx| tx['symbol'] = pair }
          lastId = json.map { |j| j['id'] }.sort.last

          transactions.concat(json)
        end
      when Net::HTTPBadRequest
        raise "Binance importer: Bad request: #{response} (#{response.body})"
      else
        raise "Binance importer: Bad response: #{response}"
      end
    end
  end

  File.write(filename, JSON.pretty_generate(transactions.sort_by { |tx| [tx['time'], tx['id']] }))
end

#read_transaction_list(source) ⇒ Object



163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
# File 'lib/coinsync/importers/binance_api.rb', line 163

def read_transaction_list(source)
  json = JSON.parse(source.read)
  transactions = []

  json.each do |hash|
    entry = HistoryEntry.new(hash)

    if entry.buyer
      transactions << Transaction.new(
        exchange: 'Binance',
        time: entry.time,
        bought_amount: entry.quantity - entry.commission,
        bought_currency: entry.asset,
        sold_amount: entry.price * entry.quantity,
        sold_currency: entry.currency
      )
    else
      transactions << Transaction.new(
        exchange: 'Binance',
        time: entry.time,
        bought_amount: entry.price * entry.quantity - entry.commission,
        bought_currency: entry.currency,
        sold_amount: entry.quantity,
        sold_currency: entry.asset
      )
    end
  end

  transactions
end