class Ubea::Exchange::BitcoinCoIdIdr

Constants

BadResponseError

Public Instance Methods

balance() click to toggle source
# File lib/ubea/exchanges/bitcoin_co_id_idr.rb, line 30
def balance
  balance = post_private("getInfo")

  OpenStruct.new(
    fiat: Money.new(balance["balance"][fiat_currency.downcase].to_s, fiat_currency),
    xbt: BigDecimal.new(balance["balance"]["btc"].to_s),
  ).freeze
end
fiat_currency() click to toggle source
# File lib/ubea/exchanges/bitcoin_co_id_idr.rb, line 12
def fiat_currency
  "IDR"
end
name() click to toggle source
# File lib/ubea/exchanges/bitcoin_co_id_idr.rb, line 8
def name
  "Bitcoin.co.id (#{fiat_currency})"
end
open_orders() click to toggle source
# File lib/ubea/exchanges/bitcoin_co_id_idr.rb, line 59
def open_orders
  post_private("openOrders")["orders"]
end
open_orders?() click to toggle source
# File lib/ubea/exchanges/bitcoin_co_id_idr.rb, line 63
def open_orders?
  !open_orders.nil?
end
refresh_order_book!() click to toggle source
# File lib/ubea/exchanges/bitcoin_co_id_idr.rb, line 20
def refresh_order_book!
  json = get_json("https://vip.bitcoin.co.id/api/btc_#{fiat_currency.downcase}/depth") or return

  asks = format_asks_bids(json["sell"])
  bids = format_asks_bids(json["buy"])

  mark_as_refreshed
  @order_book = OrderBook.new(asks: asks, bids: bids)
end
trade!(args) click to toggle source
# File lib/ubea/exchanges/bitcoin_co_id_idr.rb, line 39
def trade!(args)
  amount_key, amount_value = if args.fetch(:type) == "buy"
    idr = Money.new(args.fetch(:price), fiat_currency) * BigDecimal.new(args.fetch(:volume))
    [:idr, idr.to_s(with_currency: false)]
  else
    [:btc, args.fetch(:volume)]
  end

  params = {
    pair: "btc_#{fiat_currency.downcase}",
    type: args.fetch(:type),
    price: args.fetch(:price),
    amount_key => amount_value,
  }

  Log.debug params
  trade = post_private("trade", params)
  Log.info trade
end
trade_fee() click to toggle source
# File lib/ubea/exchanges/bitcoin_co_id_idr.rb, line 16
def trade_fee
  BigDecimal.new("0.003").freeze # 0.3%
end

Private Instance Methods

encode_params(params) click to toggle source
# File lib/ubea/exchanges/bitcoin_co_id_idr.rb, line 141
def encode_params(params)
  uri = Addressable::URI.new
  uri.query_values = params
  uri.query
end
format_asks_bids(json) click to toggle source
# File lib/ubea/exchanges/bitcoin_co_id_idr.rb, line 69
def format_asks_bids(json)
  json.map do |price, volume|
    price_idr = Money.new(price.to_s, fiat_currency)
    price_normalized = price_idr.exchange_to(Ubea.config.default_fiat_currency)

    Offer.new(
      price: price_normalized,
      volume: volume
    ).freeze
  end
end
generate_hmac(key, message) click to toggle source
# File lib/ubea/exchanges/bitcoin_co_id_idr.rb, line 137
def generate_hmac(key, message)
  OpenSSL::HMAC.hexdigest('sha512', key, message)
end
generate_message(params) click to toggle source
# File lib/ubea/exchanges/bitcoin_co_id_idr.rb, line 133
def generate_message(params)
  encode_params(params)
end
generate_signature(params) click to toggle source
# File lib/ubea/exchanges/bitcoin_co_id_idr.rb, line 127
def generate_signature(params)
  key = Ubea.config.exchange_settings[:bitcoin_co_id_idr][:api_secret]
  message = generate_message(params)
  generate_hmac(key, message)
end
nonce() click to toggle source
# File lib/ubea/exchanges/bitcoin_co_id_idr.rb, line 113
def nonce
  now = Time.now.to_f

  if (@nonce || 0) + 1 > now.to_i
    Log.warn "Throttling API call for 1s to #{self}"
    sleep 1
    now = Time.now.to_f
  end

  @nonce = now.to_i

  sprintf("%.6f", now).sub(".", "")
end
post_private(method, params = {}) click to toggle source
# File lib/ubea/exchanges/bitcoin_co_id_idr.rb, line 81
def post_private(method, params = {})
  params['method'] = method
  params['nonce'] = nonce

  response = retryable_http_request do
    http_adapter("https://vip.bitcoin.co.id").post(url_path, params) do |request|
      request.headers['Key'] = Ubea.config.exchange_settings[:bitcoin_co_id_idr][:api_key]
      request.headers['Sign'] = generate_signature(params)
    end
  end

  raise BadResponseError if response.body.empty?

  begin
    json = JSON.parse(response.body)
    unless json["success"] == 1
      raise BadResponseError if json["error"] == "Invalid nonce"

      p json
      raise "OOPS"
    end
    json["return"]

  rescue JSON::ParserError
    raise BadResponseError
  end

rescue BadResponseError
  Log.warn "BadResponseError for #{self}, retrying..."
  retry
end
url_path() click to toggle source
# File lib/ubea/exchanges/bitcoin_co_id_idr.rb, line 147
def url_path
  "/tapi"
end