Ccxt: HitBTC: transfer between accounts using unified API

Created on 26 Oct 2017  ·  45Comments  ·  Source: ccxt/ccxt

Hello,

I'm having hard times figuring out how to use unified API params to transfer between accounts. For example, I want to move assets between main&trading accounts on hitbtc using this endpoints: /api/1/payment/transfer_to_trading and /api/1/payment/transfer_to_main (https://hitbtc.com/api#transfer)

How does my ccxt call should look like? Could you please provide a python example?

Thank you,

duplicate question

Most helpful comment

First of, thank you for reporting this!

And you're not wasting my time, no worries at all.
In fact, I'm collecting those artefacts, so, thank you again! )

Let us know if you have any other difficulties with it! Cheers!

All 45 comments

Hi, @Fcl69!

Ready? Here you go:

hitbtc.payment_post_transfer_to_trading ({
   'amount': 0.01,
   'currency_code': 'BTC',
})

hitbtc.payment_post_transfer_to_main ({
   'amount': 0.01,
   'currency_code': 'BTC',
})

↑ from here: https://github.com/ccxt-dev/ccxt/issues/286#issuecomment-334932900

Also, please note, that the transferring API is not unified yet, because most of exchanges don't have it. We will consider unifying it later, when we have the order API unified.

It was easy. I've tested it, and it seems to work fine.

On a side note, where is it possible to see a list of all the methods?
Since, for example, hitbtc calls "transfer_to_trading", but ccxt calls "payment_post_transfer_to_trading"
One would never know. Having a list could help it.

Thanks,

Here:

https://github.com/ccxt-dev/ccxt/wiki/Manual#api-method-naming-conventions

console.log (new ccxt.kraken ())   // JavaScript
print (dir (ccxt.hitbtc ()))        # Python
var_dump (new \ccxt\okcoinusd ()); // PHP

api_methods

My bad. Missed it when read manual. Thanks again for your prompt reply!

no-problemo

Hello,

It seems like this has stopped working.
Code:
exch = ccxt.hitbtc({ 'apiKey': 'key', 'secret': 'sec', 'enableRateLimit': True, 'verbose': True, }) return exch order = exch.payment_post_transfer_to_trading ({'amount': 0.02, 'currency_code': 'ETH',})

Output:

http://api.hitbtc.com/api/1/payment/transfer_to_main?apikey=api&nonce=1511884495558 POST http://api.hitbtc.com/api/1/payment/transfer_to_main?apikey=key&nonce=1511884495558
.0-h1.1-b0.3-
Request: {'X-Signature': 'sig', 'Content-Type': 'application/x-www-form-urlencoded', 'Accept-Encoding': 'gzip, deflate', 'User-Agent': 'ccxt/1.10.247 (+https://github.com/ccxt/ccxt) Python/3.5.2'} currency_code=ETH&apikey=api&nonce=1511884495558&amount=0.02
hitbtc POST http://api.hitbtc.com/api/1/payment/transfer_to_main?apikey=api&nonce=1511884495558 503 Service Unavailable

503 Service Unavailable


No server is available to handle this request.

If I'm using
hitbtc2 in the same code
it says:




Error

Cannot POST /api/2/transfer_to_main


@Fcl69 thanks for reporting this. Looks like they are switching v1 → v2, I'll fix for this asap.

Thank you, and let me know if I should use v1 or v2 in this case, and if methods remain their naming.

@Fcl69 ok, from now on you should use v2 in the following way:


hitbtc = ccxt.hitbtc2({'apiKey': 'YOUR_API_KEY', 'secret': 'YOUR_SECRET', 'enableRateLimit': True})

# balances (unified API)

hitbtc.fetch_balance({'type':'trading'})
hitbtc.fetch_balance({'type':'account'})

# transfers (custom private API)

hitbtc.private_post_account_transfer({'currency': 'BTC', 'amount': 1.0, 'type': 'bankToExchange'})
hitbtc.private_post_account_transfer({'currency': 'BTC', 'amount': 1.0, 'type': 'exchangeToBank'})

The above is already available in current version of ccxt (you most likely don't need to update if you have a fresh install of it). We will be thankful if you report back whether it does the job for you and if you have any difficulties with it. Thx!

This one in particular seems to be resolved, but it looks like withdraw stopped working. Trying to find out the cause:

Traceback (most recent call last):
File "/home/fcl/.local/lib/python3.5/site-packages/ccxt/base/exchange.py", line 310, in fetch
response = opener.open(request, timeout=int(self.timeout / 1000))
File "/usr/lib/python3.5/urllib/request.py", line 472, in open
response = meth(req, response)
File "/usr/lib/python3.5/urllib/request.py", line 582, in http_response
'http', request, response, code, msg, hdrs)
File "/usr/lib/python3.5/urllib/request.py", line 510, in error
return self._call_chain(args)
File "/usr/lib/python3.5/urllib/request.py", line 444, in _call_chain
result = func(
args)
File "/usr/lib/python3.5/urllib/request.py", line 590, in http_error_default
raise HTTPError(req.full_url, code, msg, hdrs, fp)
urllib.error.HTTPError: HTTP Error 400: Bad Request

@Fcl69 can you enable verbose output?

sure...

code:

    exch = ccxt.hitbtc2({
        'apiKey': 'key',
        'secret': 'sec',
        'password': 'passphrase',
        'enableRateLimit': True,
        'verbose': True,
        })
        order1 = exch.private_post_account_transfer({'currency': 'ETH', 'amount': 7.98, 'type': 'exchangeToBank'})
       time.sleep(1.5)
       order = exch.withdraw('ETH', 7.98, 'wallet')

output:

https://api.hitbtc.com/api/2/account/transfer POST https://api.hitbtc.com/api/2/account/transfer
Request: {'Authorization': 'Basic ooooo=', 'Content-Type': 'application/json', 'Accept-Encoding': 'gzip, deflate', 'User-Agent': 'ccxt/1.10.247 (+https://github.com/ccxt/ccxt) Python/3.5.2'} {"amount":7.98,"currency":"ETH","type":"exchangeToBank"}
POST https://api.hitbtc.com/api/2/account/transfer
Response: Content-Type: application/json; charset=utf-8
Content-Length: 45
Date: Tue, 28 Nov 2017 23:49:24 GMT
Connection: close

{"id":"id1"}
{'id': 'id1'}

i.e. it moved succesfully. Then:

https://api.hitbtc.com/api/2/account/crypto/withdraw POST https://api.hitbtc.com/api/2/account/crypto/withdraw
Request: {'Authorization': 'Basic oooooo=', 'Content-Type': 'application/json', 'Accept-Encoding': 'gzip, deflate', 'User-Agent': 'ccxt/1.10.247 (+https://github.com/ccxt/ccxt) Python/3.5.2'} {"address":"wallet","currency":"ETH","amount":"7.98"}
hitbtc2 Insufficient funds

@Fcl69 is that all the output that is printed with verbose: True? There should be a response for the withdraw call somewhere nearby...

'verbose': True,

and it's all i got:

https://api.hitbtc.com/api/2/account/crypto/withdraw POST https://api.hitbtc.com/api/2/account/crypto/withdraw
Request: {'Authorization': 'Basic ooooooo=', 'User-Agent': 'ccxt/1.10.247 (+https://github.com/ccxt/ccxt) Python/3.5.2', 'Content-Type': 'application/json', 'Accept-Encoding': 'gzip, deflate'} {"amount":"7.98","address":"wallet","currency":"ETH"}
hitbtc2 Insufficient funds

@Fcl69 ok, thanks for the feedback, i'll debug it and will get back to you with a fix, hopefully, very soon.

Btw, hitbtc api v1 also doesn't work with the same - 503 Service Unavailable - error.
So, I'd appreciate some prompt feedback. Thank you!

@Fcl69 hold on, please, working on it! Will let you know, thx!

@Fcl69 Are you sure you're not exceeding your withdrawal limits with HitBTC, btw?

No, since I can withdraw manually.

Can you try HitBTC v2 withdraw (the same way you did before) with ccxt version 1.10.257 (most recent one)?

I will sir. In few hours. In an airplane now :)

tested. It's all the same :(

https://api.hitbtc.com/api/2/account/crypto/withdraw POST https://api.hitbtc.com/api/2/account/crypto/withdraw
Request: {'Accept-Encoding': 'gzip, deflate', 'User-Agent': 'ccxt/1.10.257 (+https://github.com/ccxt/ccxt) Python/3.5.2', 'Authorization': 'Basic=', 'Content-Type': 'application/json'} {"currency":"ETH","amount":9.9,"address":"wallet"}
hitbtc2 Insufficient funds

PS verbose is on; money moves from main and trading accounts no problem. balance is sufficient.

@Fcl69 sorry for asking this, but... do you have "withdraw" enabled for that API key? If that is all fine, I will put some money on HitBTC and will test extensively on my side then, will get back to you on this asap. Let me know if you have all permissions set up correctly. Thx!

Don't be sorry. It'd be a bummer to find out that I screwed up, so I'm willing to test whatever. Yes, it's on: https://cl.ly/3b1p470X1616

PS Dude, do you ever sleep? ;)

Yes, it's on

Just as I thought... That was mostly a wrong random guess. Ok, it seems, that we need some heavy artillery here, so I'll do the testing and hope to finally resolve this in the coming hours. Will notify you of course.

PS Dude, do you ever sleep? ;)

Oh, shoot, I forgot about that, will fix for that as well %))

Tried this JavaScript code and it worked. So this is most likely a Python dict-ordering problem. Almost done fixing it.

"use strict";

const ccxt      = require ('../../ccxt.js')
const asTable   = require ('as-table')
const log       = require ('ololog').configure ({ locate: false })

require ('ansicolor').nice;

const getPositiveAccounts = function (balance) {
    const result = {}
    Object.keys (balance)
        .filter (currency => balance[currency] && (balance[currency] > 0))
        .forEach (currency => {
            result[currency] = balance[currency]
        })
    return result
}

;(async () => {

    // instantiate the exchange
    let exchange = new ccxt.hitbtc2  ({
        "apiKey": "MYKEY",
        "secret": "MYSECRET",
        "enableRateLimit": true,
    })

    try {

        let tradingBalance = await exchange.fetchBalance ()
        let accountBalance = await exchange.fetchBalance ({ type: 'account' })

        log.cyan    ('Trading balance:', getPositiveAccounts (tradingBalance.total))
        log.magenta ('Account balance:', getPositiveAccounts (accountBalance.total))

        // withdraw
        let withdraw = await exchange.withdraw ('ETH', 0.01, '0x811DCfeb6dC0b9ed825808B6B060Ca469b83fB81')

        // output the result
        log (exchange.name.green, 'withdraw', withdraw)

    } catch (e) {

        if (e instanceof ccxt.DDoSProtection || e.message.includes ('ECONNRESET')) {
            log.bright.yellow ('[DDoS Protection] ' + e.message)
        } else if (e instanceof ccxt.RequestTimeout) {
            log.bright.yellow ('[Request Timeout] ' + e.message)
        } else if (e instanceof ccxt.AuthenticationError) {
            log.bright.yellow ('[Authentication Error] ' + e.message)
        } else if (e instanceof ccxt.ExchangeNotAvailable) {
            log.bright.yellow ('[Exchange Not Available Error] ' + e.message)
        } else if (e instanceof ccxt.ExchangeError) {
            log.bright.yellow ('[Exchange Error] ' + e.message)
        } else if (e instanceof ccxt.NetworkError) {
            log.bright.yellow ('[Network Error] ' + e.message)
        } else {
            throw e;
        }
    }

}) ()

Also, tried this Python example... and... it worked for me.

# -*- coding: utf-8 -*-

from pprint import pprint

import os
import sys

import ccxt  # noqa: E402

def get_positive_accounts(balance):
    result = {}
    currencies = list(balance.keys())
    for currency in currencies:
        if balance[currency] and balance[currency] > 0:
            result[currency] = balance[currency]
    return result


exchange = ccxt.hitbtc2({
    "apiKey": "a34ca826b430bdfcca969241b0f7bd2d",
    "secret": "7b28d6b17aea18ae39903add0dae048a",
    "enableRateLimit": True,
})


trading_balance = exchange.fetch_balance()
account_balance = exchange.fetch_balance({'type': 'account'})

pprint('Trading balance:')
pprint(get_positive_accounts(trading_balance['total']))
pprint('Account balance:')
pprint(get_positive_accounts(account_balance['total']))

withdraw = exchange.withdraw('ETH', 0.01, '0x811DCfeb6dC0b9ed825808B6B060Ca469b83fB81')

pprint('Withdraw:')
pprint(withdraw)

screen shot 2017-11-30 at 20 19 29

Are you sure, your keys are ok?

Shit :(

I'll try to get a brand new key & run with the code above. I'll keep you posted.

@Fcl69 to me it seems like a key / limit issue. I don't have 7-9 ETH on HitBTC to test your particular settings, but in general, we might even need to ping their support team to see if there's an implicit limit on API withdrawals on your account... Also make sure your installed ccxt version is up to date.

@Fcl69 HitBTC also has a known yet undocumented bug with their keys, so, in general, you should disable them and re-enable them or just recreate them in order for the keys to make it into their database properly. However, this seems more like a limit problem, not a key problem to me, because previous transfer calls worked for you. So this might be a "withdraw permission problem" as well. Anyway, let's rule out all possible reasons one by one.

The most likely reason for the above to me: your transfer didn't make it to the general account in 1.5 seconds of your delay, before you tried to withdraw it, thinking that it has arrived. Therefore the "Insufficient funds". Maybe, a longer sleep or a balance-check will help in your particular situation (after the transfer, before the withdraw). As you see in the above example I'm testing pure withdraw only without doing the transfer first.

I really don't think it's the case, but I'll test it as well. Give me 2-3 hours please

@Fcl69 try breaking it into smaller pieces, do a withdraw first, verify it works, then do a transfer+withdraw, then transfer+longer wait+withdraw, etc... well, you know...

I think I found the issue. So...
I was trying to withdraw the full amount I had on the main account. It said "Insufficient funds". I've tried to withdraw lower amount, it worked. The problem was that it had withdrawn the full amount + it took fees for withdrawal from the main account as well. Prior to that, hitbtc was taken withdrawal fees from the withdrawal amount itself. :-\ Bitches...
I'll need to update my code logic.
And I'm terribly sorry for wasting your time here.

First of, thank you for reporting this!

And you're not wasting my time, no worries at all.
In fact, I'm collecting those artefacts, so, thank you again! )

Let us know if you have any other difficulties with it! Cheers!

Hi,

I don't know if it's ok protocol to respond to a closed question but if it's not please let me know and I will create a new question. Is there a way to know when you look at the exchanges code that a private/custom method exists. So for example with this one and trading between main account and trade account.

In the definition I see:
'post': [ 'order', # Create new order 'account/crypto/withdraw', # Withdraw crypro 'account/crypto/address/{currency}', # Create new deposit crypro address 'account/transfer', # Transfer amount to trading

But then I don't know how to use it or to find the method that you mention above.

I know it's a newbie question and maybe it was answered some where before. Just point me to the link if it has.

Thanks,

Josiah

@ballaj2001

hi!

But then I don't know how to use it or to find the method that you mention above.

https://github.com/ccxt/ccxt/wiki/Manual#implicit-api-methods

Ohhh thanks.

I think I read that part of the manual but i didn't realize what it meant at the time. That's awesome.

Hello! Can someone list what exchanges are using

exchange.payment_post_transfer_to_trading ({
   'amount': 0.01,
   'currency_code': 'BTC',
})  

??

I read that not all exchanges use them.

@Firiyuu hi, that particular method is purely a HitBTC-specific method (HitBTC-only). More about those methods: https://github.com/ccxt/ccxt/wiki/Manual#implicit-api-methods

What would be an API to verify whenever transfer between balance <> trading accounts is disabled, to prevent error?

@pinpins this aspect isn't completely unified (we're still a work in progress), but we will wrap the support for it in an exchange-agnostic manner within exchange.currencies. In the meantime you can still access it within the currency to check for that in hitbtc2-specific way:

mbp:ccxt igorkroitor$ node examples/js/cli hitbtc2 currency ETH
hitbtc2.currency (ETH)
{        id:   "ETH",
       code:   "ETH",
       type:   "crypto",
      payin:    true,
     payout:    true,
   transfer:    true,  # ←-------------------------------- HERE
       info: {                 id: "ETH",
                         fullName: "Ethereum",
                           crypto:  true,
                     payinEnabled:  true,
                   payinPaymentId:  false,
               payinConfirmations:  2,
                    payoutEnabled:  true,
                payoutIsPaymentId:  false,
                  transferEnabled:  true,  # ←-------------------------------- HERE
                         delisted:  false,
                        payoutFee: "0.00958"   },
       name:   "Ethereum",
     active:    true,
        fee:    0.00958,
  precision:    8,
     limits: {   amount: { min: 1e-8, max: 100000000 },
                  price: { min: 1e-8, max: 100000000 },
                   cost: { min: undefined, max: undefined },
               withdraw: { min: undefined, max: 100000000 }  } }
mbp:ccxt igorkroitor$
Was this page helpful?
0 / 5 - 0 ratings

Related issues

scoshil picture scoshil  ·  39Comments

janeCMD picture janeCMD  ·  35Comments

albatarnik picture albatarnik  ·  40Comments

synchronizing picture synchronizing  ·  51Comments

barthr picture barthr  ·  37Comments