diff --git a/README.md b/README.md index ef896c28..459a9e37 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ Join our slack to discuss all things related to GoCryptoTrader! [GoCryptoTrader | COINUT | Yes | No | NA | | GDAX(Coinbase) | Yes | Yes | No| | Gemini | Yes | NA | NA | -| Huobi | Yes | Yes |No | +| Huobi.Pro | Yes | No |No | | ItBit | Yes | NA | NA | | Kraken | Yes | NA | NA | | LakeBTC | Yes | No | NA | diff --git a/config_example.json b/config_example.json index e2272224..97c29215 100644 --- a/config_example.json +++ b/config_example.json @@ -19,7 +19,7 @@ { "Address": "3Nxwenay9Z8Lc9JBiywExpnEFiLp6Afp8v", "CoinType": "BTC", - "Balance": 78348.33579495, + "Balance": 83348.33579495, "Description": "" }, { @@ -31,7 +31,7 @@ { "Address": "0xb794f5ea0ba39494ce839613fffba74279579268", "CoinType": "ETH", - "Balance": 2075000.2917679, + "Balance": 2000000.289943, "Description": "" } ] @@ -90,7 +90,7 @@ "AuthenticatedAPISupport": false, "APIKey": "Key", "APISecret": "Secret", - "AvailablePairs": "BTCUSD,LTCUSD,LTCBTC,ETHUSD,ETHBTC,ETCBTC,ETCUSD,RRTUSD,RRTBTC,ZECUSD,ZECBTC,XMRUSD,XMRBTC,DSHUSD,DSHBTC,BTCEUR,XRPUSD,XRPBTC,IOTUSD,IOTBTC,IOTETH,EOSUSD,EOSBTC,EOSETH,SANUSD,SANBTC,SANETH,OMGUSD,OMGBTC,OMGETH,BCHUSD,BCHBTC,BCHETH,NEOUSD,NEOBTC,NEOETH,ETPUSD,ETPBTC,ETPETH,QTMUSD,QTMBTC,QTMETH,AVTUSD,AVTBTC,AVTETH,EDOUSD,EDOBTC,EDOETH,BTGUSD,BTGBTC,DATUSD,DATBTC,DATETH,QSHUSD,QSHBTC,QSHETH,YYWUSD,YYWBTC,YYWETH,GNTUSD,GNTBTC,GNTETH,SNTUSD,SNTBTC,SNTETH,IOTEUR,BATUSD,BATBTC,BATETH,MNAUSD,MNABTC,MNAETH,FUNUSD,FUNBTC,FUNETH,ZRXUSD,ZRXBTC,ZRXETH,TNBUSD,TNBBTC,TNBETH,SPKUSD,SPKBTC,SPKETH", + "AvailablePairs": "BTCUSD,LTCUSD,LTCBTC,ETHUSD,ETHBTC,ETCBTC,ETCUSD,RRTUSD,RRTBTC,ZECUSD,ZECBTC,XMRUSD,XMRBTC,DSHUSD,DSHBTC,BTCEUR,XRPUSD,XRPBTC,IOTUSD,IOTBTC,IOTETH,EOSUSD,EOSBTC,EOSETH,SANUSD,SANBTC,SANETH,OMGUSD,OMGBTC,OMGETH,BCHUSD,BCHBTC,BCHETH,NEOUSD,NEOBTC,NEOETH,ETPUSD,ETPBTC,ETPETH,QTMUSD,QTMBTC,QTMETH,AVTUSD,AVTBTC,AVTETH,EDOUSD,EDOBTC,EDOETH,BTGUSD,BTGBTC,DATUSD,DATBTC,DATETH,QSHUSD,QSHBTC,QSHETH,YYWUSD,YYWBTC,YYWETH,GNTUSD,GNTBTC,GNTETH,SNTUSD,SNTBTC,SNTETH,IOTEUR,BATUSD,BATBTC,BATETH,MNAUSD,MNABTC,MNAETH,FUNUSD,FUNBTC,FUNETH,ZRXUSD,ZRXBTC,ZRXETH,TNBUSD,TNBBTC,TNBETH,SPKUSD,SPKBTC,SPKETH,TRXUSD,TRXBTC,TRXETH,RCNUSD,RCNBTC,RCNETH,RLCUSD,RLCBTC,RLCETH,AIDUSD,AIDBTC,AIDETH,SNGUSD,SNGBTC,SNGETH,REPUSD,REPBTC,REPETH,ELFUSD,ELFBTC,ELFETH", "EnabledPairs": "BTCUSD,LTCUSD,LTCBTC,ETHUSD,ETHBTC", "BaseCurrencies": "USD", "AssetTypes": "SPOT", @@ -133,7 +133,7 @@ "AuthenticatedAPISupport": false, "APIKey": "Key", "APISecret": "Secret", - "AvailablePairs": "BTC-LTC,BTC-DOGE,BTC-VTC,BTC-PPC,BTC-FTC,BTC-RDD,BTC-NXT,BTC-DASH,BTC-POT,BTC-BLK,BTC-EMC2,BTC-XMY,BTC-AUR,BTC-EFL,BTC-GLD,BTC-SLR,BTC-PTC,BTC-GRS,BTC-NLG,BTC-RBY,BTC-XWC,BTC-MONA,BTC-THC,BTC-ENRG,BTC-ERC,BTC-VRC,BTC-CURE,BTC-XMR,BTC-CLOAK,BTC-START,BTC-KORE,BTC-XDN,BTC-TRUST,BTC-NAV,BTC-XST,BTC-BTCD,BTC-VIA,BTC-PINK,BTC-IOC,BTC-CANN,BTC-SYS,BTC-NEOS,BTC-DGB,BTC-BURST,BTC-EXCL,BTC-DOPE,BTC-BLOCK,BTC-ABY,BTC-BYC,BTC-XMG,BTC-BLITZ,BTC-BAY,BTC-FAIR,BTC-SPR,BTC-VTR,BTC-XRP,BTC-GAME,BTC-COVAL,BTC-NXS,BTC-XCP,BTC-BITB,BTC-GEO,BTC-FLDC,BTC-GRC,BTC-FLO,BTC-NBT,BTC-MUE,BTC-XEM,BTC-CLAM,BTC-DMD,BTC-GAM,BTC-SPHR,BTC-OK,BTC-SNRG,BTC-PKB,BTC-CPC,BTC-AEON,BTC-ETH,BTC-GCR,BTC-TX,BTC-BCY,BTC-EXP,BTC-INFX,BTC-OMNI,BTC-AMP,BTC-AGRS,BTC-XLM,USDT-BTC,BTC-CLUB,BTC-VOX,BTC-EMC,BTC-FCT,BTC-MAID,BTC-EGC,BTC-SLS,BTC-RADS,BTC-DCR,BTC-BSD,BTC-XVG,BTC-PIVX,BTC-XVC,BTC-MEME,BTC-STEEM,BTC-2GIVE,BTC-LSK,BTC-PDC,BTC-BRK,BTC-WAVES,BTC-RISE,BTC-LBC,BTC-SBD,BTC-BRX,BTC-ETC,ETH-ETC,BTC-STRAT,BTC-UNB,BTC-SYNX,BTC-EBST,BTC-VRM,BTC-SEQ,BTC-REP,BTC-SHIFT,BTC-ARDR,BTC-XZC,BTC-NEO,BTC-ZEC,BTC-ZCL,BTC-IOP,BTC-GOLOS,BTC-UBQ,BTC-KMD,BTC-GBG,BTC-SIB,BTC-ION,BTC-LMC,BTC-QWARK,BTC-CRW,BTC-SWT,BTC-MLN,BTC-ARK,BTC-DYN,BTC-TKS,BTC-MUSIC,BTC-DTB,BTC-INCNT,BTC-GBYTE,BTC-GNT,BTC-NXC,BTC-EDG,BTC-LGD,BTC-TRST,ETH-GNT,ETH-REP,USDT-ETH,ETH-WINGS,BTC-WINGS,BTC-RLC,BTC-GNO,BTC-GUP,BTC-LUN,ETH-GUP,ETH-RLC,ETH-LUN,ETH-GNO,BTC-APX,BTC-HMQ,ETH-HMQ,BTC-ANT,ETH-TRST,ETH-ANT,BTC-SC,ETH-BAT,BTC-BAT,BTC-ZEN,BTC-1ST,BTC-QRL,ETH-1ST,ETH-QRL,BTC-CRB,ETH-CRB,ETH-LGD,BTC-PTOY,ETH-PTOY,BTC-MYST,ETH-MYST,BTC-CFI,ETH-CFI,BTC-BNT,ETH-BNT,BTC-NMR,ETH-NMR,ETH-LTC,ETH-XRP,BTC-SNT,ETH-SNT,BTC-DCT,BTC-XEL,BTC-MCO,ETH-MCO,BTC-ADT,ETH-ADT,BTC-FUN,ETH-FUN,BTC-PAY,ETH-PAY,BTC-STORJ,ETH-STORJ,BTC-ADX,ETH-ADX,ETH-DASH,ETH-SC,ETH-ZEC,USDT-ZEC,USDT-LTC,USDT-ETC,USDT-XRP,BTC-OMG,ETH-OMG,BTC-CVC,ETH-CVC,BTC-PART,BTC-QTUM,ETH-QTUM,ETH-XMR,ETH-XEM,ETH-XLM,ETH-NEO,USDT-XMR,USDT-DASH,ETH-BCC,USDT-BCC,BTC-BCC,BTC-DNT,ETH-DNT,USDT-NEO,ETH-WAVES,ETH-STRAT,ETH-DGB,ETH-FCT,USDT-OMG,BTC-ADA,BTC-MANA,ETH-MANA,BTC-SALT,ETH-SALT,BTC-TIX,ETH-TIX,BTC-RCN,ETH-RCN,BTC-VIB,ETH-VIB,BTC-MER,BTC-POWR,ETH-POWR,BTC-BTG,ETH-BTG,USDT-BTG,ETH-ADA,BTC-ENG,ETH-ENG,USDT-ADA,USDT-XVG,USDT-NXT,BTC-UKG,ETH-UKG", + "AvailablePairs": "BTC-LTC,BTC-DOGE,BTC-VTC,BTC-PPC,BTC-FTC,BTC-RDD,BTC-NXT,BTC-DASH,BTC-POT,BTC-BLK,BTC-EMC2,BTC-XMY,BTC-AUR,BTC-EFL,BTC-GLD,BTC-SLR,BTC-PTC,BTC-GRS,BTC-NLG,BTC-RBY,BTC-XWC,BTC-MONA,BTC-THC,BTC-ENRG,BTC-ERC,BTC-VRC,BTC-CURE,BTC-XMR,BTC-CLOAK,BTC-START,BTC-KORE,BTC-XDN,BTC-TRUST,BTC-NAV,BTC-XST,BTC-VIA,BTC-PINK,BTC-IOC,BTC-CANN,BTC-SYS,BTC-NEOS,BTC-DGB,BTC-BURST,BTC-EXCL,BTC-DOPE,BTC-BLOCK,BTC-ABY,BTC-BYC,BTC-XMG,BTC-BLITZ,BTC-BAY,BTC-FAIR,BTC-SPR,BTC-VTR,BTC-XRP,BTC-GAME,BTC-COVAL,BTC-NXS,BTC-XCP,BTC-BITB,BTC-FLDC,BTC-GRC,BTC-FLO,BTC-NBT,BTC-MUE,BTC-XEM,BTC-CLAM,BTC-DMD,BTC-GAM,BTC-SPHR,BTC-OK,BTC-SNRG,BTC-PKB,BTC-CPC,BTC-AEON,BTC-ETH,BTC-GCR,BTC-TX,BTC-BCY,BTC-EXP,BTC-INFX,BTC-OMNI,BTC-AMP,BTC-AGRS,BTC-XLM,USDT-BTC,BTC-CLUB,BTC-VOX,BTC-EMC,BTC-FCT,BTC-MAID,BTC-EGC,BTC-SLS,BTC-RADS,BTC-DCR,BTC-BSD,BTC-XVG,BTC-PIVX,BTC-XVC,BTC-MEME,BTC-STEEM,BTC-2GIVE,BTC-LSK,BTC-PDC,BTC-BRK,BTC-WAVES,BTC-RISE,BTC-LBC,BTC-SBD,BTC-BRX,BTC-ETC,ETH-ETC,BTC-STRAT,BTC-UNB,BTC-SYNX,BTC-EBST,BTC-VRM,BTC-SEQ,BTC-REP,BTC-SHIFT,BTC-ARDR,BTC-XZC,BTC-NEO,BTC-ZEC,BTC-ZCL,BTC-IOP,BTC-GOLOS,BTC-UBQ,BTC-KMD,BTC-GBG,BTC-SIB,BTC-ION,BTC-LMC,BTC-QWARK,BTC-CRW,BTC-SWT,BTC-MLN,BTC-ARK,BTC-DYN,BTC-TKS,BTC-MUSIC,BTC-DTB,BTC-INCNT,BTC-GBYTE,BTC-GNT,BTC-NXC,BTC-EDG,BTC-LGD,BTC-TRST,ETH-GNT,ETH-REP,USDT-ETH,ETH-WINGS,BTC-WINGS,BTC-RLC,BTC-GNO,BTC-GUP,BTC-LUN,ETH-GUP,ETH-RLC,ETH-LUN,ETH-GNO,BTC-HMQ,ETH-HMQ,BTC-ANT,ETH-TRST,ETH-ANT,BTC-SC,ETH-BAT,BTC-BAT,BTC-ZEN,BTC-1ST,BTC-QRL,ETH-1ST,ETH-QRL,BTC-CRB,ETH-CRB,ETH-LGD,BTC-PTOY,ETH-PTOY,BTC-CFI,ETH-CFI,BTC-BNT,ETH-BNT,BTC-NMR,ETH-NMR,ETH-LTC,ETH-XRP,BTC-SNT,ETH-SNT,BTC-DCT,BTC-XEL,BTC-MCO,ETH-MCO,BTC-ADT,ETH-ADT,BTC-FUN,ETH-FUN,BTC-PAY,ETH-PAY,BTC-STORJ,ETH-STORJ,BTC-ADX,ETH-ADX,ETH-DASH,ETH-SC,ETH-ZEC,USDT-ZEC,USDT-LTC,USDT-ETC,USDT-XRP,BTC-OMG,ETH-OMG,BTC-CVC,ETH-CVC,BTC-PART,BTC-QTUM,ETH-QTUM,ETH-XMR,ETH-XEM,ETH-XLM,ETH-NEO,USDT-XMR,USDT-DASH,ETH-BCC,USDT-BCC,BTC-BCC,BTC-DNT,ETH-DNT,USDT-NEO,ETH-WAVES,ETH-STRAT,ETH-DGB,ETH-FCT,USDT-OMG,BTC-ADA,BTC-MANA,ETH-MANA,BTC-SALT,ETH-SALT,BTC-TIX,ETH-TIX,BTC-RCN,ETH-RCN,BTC-VIB,ETH-VIB,BTC-MER,BTC-POWR,ETH-POWR,BTC-BTG,ETH-BTG,USDT-BTG,ETH-ADA,BTC-ENG,ETH-ENG,USDT-ADA,USDT-XVG,USDT-NXT,BTC-UKG,ETH-UKG", "EnabledPairs": "USDT-BTC", "BaseCurrencies": "USD", "AssetTypes": "SPOT", @@ -221,7 +221,7 @@ "APIKey": "Key", "APISecret": "Secret", "ClientID": "ClientID", - "AvailablePairs": "BCHBTC,BCHUSD,BTCEUR,BTCGBP,BTCUSD,ETHBTC,ETHEUR,ETHUSD,LTCBTC,LTCEUR,LTCUSD", + "AvailablePairs": "BCHBTC,BCHUSD,BTCEUR,BTCGBP,BTCUSD,ETHBTC,ETHEUR,ETHUSD,LTCBTC,LTCEUR,LTCUSD,BCHEUR", "EnabledPairs": "BTCUSD,BTCGBP,BTCEUR", "BaseCurrencies": "USD,GBP,EUR", "AssetTypes": "SPOT", @@ -264,12 +264,13 @@ "AuthenticatedAPISupport": false, "APIKey": "Key", "APISecret": "Secret", - "AvailablePairs": "BTCCNY,LTCCNY", - "EnabledPairs": "BTCCNY,LTCCNY", - "BaseCurrencies": "CNY", + "AvailablePairs": "OMG-USDT,LINK-BTC,NAS-ETH,EOS-ETH,SWFTC-BTC,XEM-USDT,ZEC-USDT,DASH-BTC,PAY-BTC,EVX-BTC,MDS-ETH,TNT-BTC,QASH-ETH,SMT-ETH,RUFF-ETH,BCH-BTC,IOST-ETH,TNB-BTC,GNX-ETH,THETA-BTC,SNT-USDT,DAT-BTC,SOC-ETH,EOS-USDT,CHAT-ETH,MANA-BTC,SMT-USDT,XRP-BTC,LTC-USDT,QTUM-USDT,LET-BTC,BCD-BTC,SNT-BTC,CVC-USDT,ELF-ETH,GNT-ETH,UTK-BTC,SBTC-BTC,NEO-USDT,MCO-BTC,OST-ETH,RCN-BTC,BT2-BTC,QUN-BTC,HSR-ETH,TOPC-ETH,SALT-ETH,AIDOC-ETH,WAX-BTC,CVC-ETH,DTA-ETH,BTC-USDT,MEE-ETH,POWR-ETH,GAS-ETH,ADX-ETH,NEO-BTC,SALT-BTC,BTM-BTC,EKO-ETH,BAT-ETH,EKO-BTC,APPC-BTC,CMT-BTC,VEN-ETH,QTUM-ETH,REQ-BTC,BIFI-BTC,BTM-ETH,ICX-BTC,ZEC-BTC,ACT-BTC,DGD-ETH,DAT-ETH,ETC-USDT,OST-BTC,IOST-USDT,MCO-ETH,STORJ-BTC,HSR-BTC,QUN-ETH,SOC-BTC,ELF-BTC,CMT-ETH,VEN-BTC,GNT-BTC,DBC-BTC,STORJ-USDT,WAX-ETH,POWR-BTC,DTA-BTC,ZIL-BTC,MEE-BTC,NAS-BTC,TNB-ETH,SWFTC-ETH,LTC-BTC,EOS-BTC,LINK-ETH,IOST-BTC,YEE-BTC,RUFF-BTC,RDN-BTC,GNX-BTC,LET-ETH,EVX-ETH,AST-BTC,ACT-ETH,BCH-USDT,DASH-USDT,ICX-ETH,BCX-BTC,PROPY-ETH,DGD-BTC,XRP-USDT,ZIL-ETH,ZRX-BTC,THETA-ETH,ETH-BTC,DBC-ETH,REQ-ETH,WICC-ETH,SMT-BTC,RPX-BTC,TNT-ETH,ETH-USDT,ITC-BTC,OMG-BTC,PAY-ETH,VEN-USDT,MDS-BTC,ADX-BTC,ETC-BTC,AIDOC-BTC,KNC-BTC,HSR-USDT,QTUM-BTC,CVC-BTC,QSP-BTC,QSP-ETH,BTG-BTC,BAT-BTC,QASH-BTC,ITC-ETH,XEM-BTC,MANA-ETH,GAS-BTC,CHAT-BTC,BT1-BTC,OMG-ETH,RCN-ETH,UTK-ETH,TOPC-BTC,MTL-BTC,GNT-USDT,APPC-ETH,PROPY-BTC,WICC-BTC,RDN-ETH,ELF-USDT,YEE-ETH", + "EnabledPairs": "BTC-USDT", + "BaseCurrencies": "USD", "AssetTypes": "SPOT", "ConfigCurrencyPairFormat": { - "Uppercase": true + "Uppercase": true, + "Delimiter": "-" }, "RequestCurrencyPairFormat": { "Uppercase": false @@ -351,7 +352,7 @@ "AuthenticatedAPISupport": false, "APIKey": "Key", "APISecret": "Secret", - "AvailablePairs": "TNT_BTC,VEN_BTC,REP_USDT,OMG_ETH,AST_ETH,SNM_BTC,NET_ETH,ZRX_USDT,TRX_BTC,DASH_BTC,SAN_USDT,OAX_BTC,AE_USDT,XID_USDT,PRO_ETH,KNC_ETH,SRN_ETH,EDG_BTC,BNT_USDT,IND_BTC,LTC_ETH,DASH_ETH,TAAS_ETH,ANT_BTC,BCC_USDT,RLC_USDT,BCC_ETH,STX_BTC,REQ_USDT,SRN_USDT,BAT_BTC,QRL_USDT,STORJ_USDT,XID_ETH,MLN_BTC,ADX_BTC,REP_BTC,TRST_ETH,DNT_ETH,AST_USDT,MGO_BTC,DGD_BTC,BMC_USDT,REQ_BTC,NEU_BTC,ANT_ETH,ADX_ETH,GNO_BTC,ANT_USDT,OMG_USDT,GUP_USDT,MGO_ETH,SNM_ETH,TNT_USDT,PRO_BTC,MYST_ETH,SNGLS_BTC,DNT_USDT,MANA_ETH,MLN_ETH,ETH_USDT,TAAS_BTC,MYST_USDT,SNT_ETH,XID_BTC,ETH_BTC,WAVES_USDT,GNO_USDT,KNC_BTC,TIME_ETH,DASH_USDT,PTOY_ETH,NET_BTC,AE_BTC,ENG_USDT,PTOY_BTC,BAT_ETH,MCO_USDT,STORJ_ETH,ZRX_BTC,TRX_ETH,AE_ETH,VEN_USDT,GNT_USDT,RLC_ETH,GUP_ETH,ICN_USDT,MCO_BTC,REQ_ETH,SNGLS_USDT,SALT_USDT,LTC_BTC,EDG_USDT,AST_BTC,QRL_BTC,BMC_ETH,ICN_ETH,BTC_USDT,REP_ETH,QRL_ETH,BMC_BTC,WAVES_ETH,EDG_ETH,TAAS_USDT,PTOY_USDT,DGD_USDT,TIME_BTC,TKN_BTC,GNT_BTC,WINGS_BTC,CFI_BTC,SAN_BTC,OAX_ETH,PAY_BTC,SAN_ETH,STX_USDT,PRO_USDT,MCO_ETH,MANA_USDT,TRST_BTC,WINGS_ETH,SNM_USDT,SNT_USDT,BNT_BTC,EOS_BTC,IND_USDT,NEU_USDT,PAY_ETH,ENG_ETH,TIME_USDT,BAT_USDT,MYST_BTC,STORJ_BTC,CVC_BTC,LTC_USDT,TKN_ETH,EOS_USDT,TKN_USDT,CFI_USDT,IND_ETH,TRST_USDT,CFI_ETH,NET_USDT,SNGLS_ETH,OMG_BTC,SRN_BTC,GUP_BTC,ZRX_ETH,TRX_USDT,STX_ETH,RLC_BTC,SALT_ETH,ICN_BTC,MANA_BTC,GNO_ETH,WINGS_USDT,TNT_ETH,VEN_ETH,KNC_USDT,SALT_BTC,ADX_USDT,PAY_USDT,DGD_ETH,BCC_BTC,DNT_BTC,SNT_BTC,CVC_USDT,BNT_ETH,EOS_ETH,WAVES_BTC,NEU_ETH,MLN_USDT,MGO_USDT,OAX_USDT,ENG_BTC,GNT_ETH,CVC_ETH", + "AvailablePairs": "NEU_USDT,ICN_BTC,CVC_USDT,TIME_BTC,BNT_ETH,CFI_ETH,TRX_USDT,GNT_ETH,STORJ_BTC,IND_ETH,GUP_BTC,DNT_USDT,ETH_USDT,EDG_ETH,MYST_ETH,NEU_BTC,GNO_USDT,PTOY_USDT,NEU_ETH,REQ_USDT,TKN_USDT,ZRX_USDT,MANA_ETH,ENG_ETH,TRX_BTC,DASH_ETH,TRST_BTC,EOS_BTC,STX_USDT,SALT_ETH,QRL_ETH,AE_BTC,AION_BTC,LTC_USDT,TAAS_USDT,NET_USDT,OMG_USDT,BNT_BTC,STORJ_ETH,PAY_BTC,PAY_ETH,VEN_USDT,TKN_BTC,PTOY_BTC,PAY_USDT,VEN_BTC,OAX_USDT,KNC_USDT,RLC_BTC,MYST_USDT,TAAS_ETH,MYST_BTC,DASH_USDT,TRST_USDT,ICN_USDT,QRL_USDT,PTOY_ETH,MCO_ETH,OMG_ETH,DNT_ETH,GUP_ETH,ENG_BTC,TRST_ETH,TNT_BTC,KNC_BTC,MLN_USDT,GUP_USDT,ADX_USDT,WAVES_USDT,GNO_ETH,CFI_USDT,ADX_ETH,IND_BTC,TRX_ETH,SAN_ETH,BCC_USDT,AE_USDT,SALT_BTC,DNT_BTC,DASH_BTC,GNT_BTC,SNGLS_ETH,MGO_BTC,ENG_USDT,BCC_BTC,TIME_ETH,SNT_ETH,OMG_BTC,DGD_ETH,XID_BTC,BTC_USDT,SNGLS_BTC,SNM_ETH,PRO_BTC,REQ_BTC,REQ_ETH,PRO_USDT,AST_ETH,CFI_BTC,KNC_ETH,BMC_ETH,ETH_BTC,BAT_USDT,BNT_USDT,NET_BTC,BCC_ETH,ZRX_ETH,AST_BTC,REP_ETH,WINGS_USDT,MGO_USDT,DGD_USDT,WAVES_ETH,ANT_USDT,GNT_USDT,TAAS_BTC,QRL_BTC,MLN_BTC,BMC_BTC,LTC_BTC,REP_BTC,BAT_BTC,SAN_USDT,OAX_ETH,REP_USDT,GNO_BTC,BMC_USDT,EDG_BTC,TKN_ETH,TNT_USDT,TIME_USDT,INS_BTC,INS_USDT,SRN_ETH,STX_ETH,SNM_USDT,STORJ_USDT,LTC_ETH,ANT_ETH,BAT_ETH,OAX_BTC,VEN_ETH,ANT_BTC,SNT_USDT,ADX_BTC,INS_ETH,DGD_BTC,AE_ETH,IND_USDT,EOS_USDT,MANA_BTC,STX_BTC,MLN_ETH,MCO_BTC,EOS_ETH,RLC_USDT,MGO_ETH,AST_USDT,AION_USDT,SNT_BTC,SAN_BTC,SRN_USDT,AION_ETH,WINGS_ETH,SNGLS_USDT,MCO_USDT,SNM_BTC,SRN_BTC,RLC_ETH,XID_ETH,XID_USDT,CVC_BTC,TNT_ETH,SALT_USDT,ICN_ETH,EDG_USDT,CVC_ETH,NET_ETH,WINGS_BTC,WAVES_BTC,MANA_USDT,PRO_ETH,ZRX_BTC", "EnabledPairs": "ETH_BTC,LTC_BTC,DASH_BTC", "BaseCurrencies": "USD", "AssetTypes": "SPOT", @@ -500,4 +501,4 @@ } } ] -} +} \ No newline at end of file diff --git a/exchanges/huobi/huobi.go b/exchanges/huobi/huobi.go index d1b52cf4..18dcd1aa 100644 --- a/exchanges/huobi/huobi.go +++ b/exchanges/huobi/huobi.go @@ -1,11 +1,12 @@ package huobi import ( + "bytes" + "errors" "fmt" "log" "net/url" "strconv" - "strings" "time" "github.com/thrasher-/gocryptotrader/common" @@ -15,8 +16,35 @@ import ( ) const ( - huobiAPIURL = "https://api.huobi.com/apiv2.php" - huobiAPIVersion = "2" + huobiAPIURL = "https://api.huobi.pro" + huobiAPIVersion = "1" + + huobiMarketHistoryKline = "market/history/kline" + huobiMarketDetail = "market/detail" + huobiMarketDetailMerged = "market/detail/merged" + huobiMarketDepth = "market/depth" + huobiMarketTrade = "market/trade" + huobiMarketTradeHistory = "market/history/trade" + huobiSymbols = "common/symbols" + huobiCurrencies = "common/currencys" + huobiTimestamp = "common/timestamp" + huobiAccounts = "account/accounts" + huobiAccountBalance = "account/accounts/%s/balance" + huobiOrderPlace = "order/orders/place" + huobiOrderCancel = "order/orders/%s/submitcancel" + huobiOrderCancelBatch = "order/orders/batchcancel" + huobiGetOrder = "order/orders/%s" + huobiGetOrderMatch = "order/orders/%s/matchresults" + huobiGetOrders = "order/orders" + huobiGetOrdersMatch = "orders/matchresults" + huobiMarginTransferIn = "dw/transfer-in/margin" + huobiMarginTransferOut = "dw/transfer-out/margin" + huobiMarginOrders = "margin/orders" + huobiMarginRepay = "margin/orders/%s/repay" + huobiMarginLoanOrders = "margin/loan-orders" + huobiMarginAccountBalance = "margin/accounts/balance" + huobiWithdrawCreate = "dw/withdraw/api/create" + huobiWithdrawCancel = "dw/withdraw-virtual/%s/cancel" ) // HUOBI is the overarching type across this package @@ -34,7 +62,7 @@ func (h *HUOBI) SetDefaults() { h.RESTPollingDelay = 10 h.RequestCurrencyPairFormat.Delimiter = "" h.RequestCurrencyPairFormat.Uppercase = false - h.ConfigCurrencyPairFormat.Delimiter = "" + h.ConfigCurrencyPairFormat.Delimiter = "-" h.ConfigCurrencyPairFormat.Uppercase = true h.AssetTypes = []string{ticker.Spot} } @@ -69,163 +97,628 @@ func (h *HUOBI) GetFee() float64 { return h.Fee } -// GetTicker returns the Huobi ticker -func (h *HUOBI) GetTicker(symbol string) (Ticker, error) { - resp := TickerResponse{} - path := fmt.Sprintf("https://api.huobi.com/staticmarket/ticker_%s_json.js", symbol) +// GetKline returns kline data +func (h *HUOBI) GetKline(symbol, period, size string) ([]Klines, error) { + vals := url.Values{} + vals.Set("symbol", symbol) - return resp.Ticker, common.SendHTTPGetRequest(path, true, h.Verbose, &resp) + if period != "" { + vals.Set("period", period) + } + + if size != "" { + vals.Set("size", size) + } + + type response struct { + Response + Data []Klines `json:"data"` + } + + var result response + url := fmt.Sprintf("%s/%s", huobiAPIURL, huobiMarketHistoryKline) + err := common.SendHTTPGetRequest(common.EncodeURLValues(url, vals), true, h.Verbose, &result) + + if result.ErrorMessage != "" { + return nil, errors.New(result.ErrorMessage) + } + return result.Data, err } -// GetOrderBook returns the Huobi current orderbook for a currency pair -func (h *HUOBI) GetOrderBook(symbol string) (Orderbook, error) { - path := fmt.Sprintf("https://api.huobi.com/staticmarket/depth_%s_json.js", symbol) - resp := Orderbook{} +// GetMarketDetailMerged returns the ticker for the specified symbol +func (h *HUOBI) GetMarketDetailMerged(symbol string) (DetailMerged, error) { + vals := url.Values{} + vals.Set("symbol", symbol) - return resp, common.SendHTTPGetRequest(path, true, h.Verbose, &resp) + type response struct { + Response + Tick DetailMerged `json:"tick"` + } + + var result response + url := fmt.Sprintf("%s/%s", huobiAPIURL, huobiMarketDetailMerged) + err := common.SendHTTPGetRequest(common.EncodeURLValues(url, vals), true, h.Verbose, &result) + + if result.ErrorMessage != "" { + return result.Tick, errors.New(result.ErrorMessage) + } + return result.Tick, err } -// GetAccountInfo returns account information -func (h *HUOBI) GetAccountInfo() { - err := h.SendAuthenticatedRequest("get_account_info", url.Values{}) +// GetDepth returns the depth for the specified symbol +func (h *HUOBI) GetDepth(symbol, depthType string) (Orderbook, error) { + vals := url.Values{} + vals.Set("symbol", symbol) - if err != nil { - log.Println(err) + if depthType != "" { + vals.Set("type", depthType) } + + type response struct { + Response + Depth Orderbook `json:"tick"` + } + + var result response + url := fmt.Sprintf("%s/%s", huobiAPIURL, huobiMarketDepth) + err := common.SendHTTPGetRequest(common.EncodeURLValues(url, vals), true, h.Verbose, &result) + + if result.ErrorMessage != "" { + return result.Depth, errors.New(result.ErrorMessage) + } + return result.Depth, err } -// GetOrders returns full list of orders -func (h *HUOBI) GetOrders(coinType int) { - values := url.Values{} - values.Set("coin_type", strconv.Itoa(coinType)) - err := h.SendAuthenticatedRequest("get_orders", values) +// GetTrades returns the trades for the specified symbol +func (h *HUOBI) GetTrades(symbol string) ([]Trade, error) { + vals := url.Values{} + vals.Set("symbol", symbol) - if err != nil { - log.Println(err) + type response struct { + Response + tick struct { + Data []Trade `json:"data"` + } `json:"tick"` } + + var result response + url := fmt.Sprintf("%s/%s", huobiAPIURL, huobiMarketTrade) + err := common.SendHTTPGetRequest(common.EncodeURLValues(url, vals), true, h.Verbose, &result) + + if result.ErrorMessage != "" { + return nil, errors.New(result.ErrorMessage) + } + return result.tick.Data, err } -// GetOrderInfo returns specific info on an order -func (h *HUOBI) GetOrderInfo(orderID, coinType int) { - values := url.Values{} - values.Set("id", strconv.Itoa(orderID)) - values.Set("coin_type", strconv.Itoa(coinType)) - err := h.SendAuthenticatedRequest("order_info", values) +// GetTradeHistory returns the trades for the specified symbol +func (h *HUOBI) GetTradeHistory(symbol, size string) ([]TradeHistory, error) { + vals := url.Values{} + vals.Set("symbol", symbol) - if err != nil { - log.Println(err) + if size != "" { + vals.Set("size", size) } + + type response struct { + Response + TradeHistory []TradeHistory `json:"data"` + } + + var result response + url := fmt.Sprintf("%s/%s", huobiAPIURL, huobiMarketTradeHistory) + err := common.SendHTTPGetRequest(common.EncodeURLValues(url, vals), true, h.Verbose, &result) + + if result.ErrorMessage != "" { + return nil, errors.New(result.ErrorMessage) + } + return result.TradeHistory, err } -// Trade opens a trade on the Huobi exchange -func (h *HUOBI) Trade(orderType string, coinType int, price, amount float64) { - values := url.Values{} - if orderType != "buy" { - orderType = "sell" - } - values.Set("coin_type", strconv.Itoa(coinType)) - values.Set("amount", strconv.FormatFloat(amount, 'f', -1, 64)) - values.Set("price", strconv.FormatFloat(price, 'f', -1, 64)) - err := h.SendAuthenticatedRequest(orderType, values) +// GetMarketDetail returns the ticker for the specified symbol +func (h *HUOBI) GetMarketDetail(symbol string) (Detail, error) { + vals := url.Values{} + vals.Set("symbol", symbol) - if err != nil { - log.Println(err) + type response struct { + Response + tick Detail `json:"tick"` } + + var result response + url := fmt.Sprintf("%s/%s", huobiAPIURL, huobiMarketDetail) + err := common.SendHTTPGetRequest(common.EncodeURLValues(url, vals), true, h.Verbose, &result) + + if result.ErrorMessage != "" { + return result.tick, errors.New(result.ErrorMessage) + } + return result.tick, err } -// MarketTrade initiates a market trade -func (h *HUOBI) MarketTrade(orderType string, coinType int, price, amount float64) { - values := url.Values{} - if orderType != "buy_market" { - orderType = "sell_market" +// GetSymbols returns an array of symbols supported by Huobi +func (h *HUOBI) GetSymbols() ([]Symbol, error) { + type response struct { + Response + Symbols []Symbol `json:"data"` } - values.Set("coin_type", strconv.Itoa(coinType)) - values.Set("amount", strconv.FormatFloat(amount, 'f', -1, 64)) - values.Set("price", strconv.FormatFloat(price, 'f', -1, 64)) - err := h.SendAuthenticatedRequest(orderType, values) - if err != nil { - log.Println(err) + var result response + url := fmt.Sprintf("%s/v%s/%s", huobiAPIURL, huobiAPIVersion, huobiSymbols) + err := common.SendHTTPGetRequest(url, true, h.Verbose, &result) + + if result.ErrorMessage != "" { + return nil, errors.New(result.ErrorMessage) } + return result.Symbols, err } -// CancelOrder cancels order by order ID -func (h *HUOBI) CancelOrder(orderID, coinType int) { - values := url.Values{} - values.Set("coin_type", strconv.Itoa(coinType)) - values.Set("id", strconv.Itoa(orderID)) - err := h.SendAuthenticatedRequest("cancel_order", values) - - if err != nil { - log.Println(err) +// GetCurrencies returns a list of currencies supported by Huobi +func (h *HUOBI) GetCurrencies() ([]string, error) { + type response struct { + Response + Currencies []string `json:"data"` } + + var result response + url := fmt.Sprintf("%s/v%s/%s", huobiAPIURL, huobiAPIVersion, huobiCurrencies) + err := common.SendHTTPGetRequest(url, true, h.Verbose, &result) + + if result.ErrorMessage != "" { + return nil, errors.New(result.ErrorMessage) + } + return result.Currencies, err } -// ModifyOrder modifies an order -func (h *HUOBI) ModifyOrder(orderType string, coinType, orderID int, price, amount float64) { - values := url.Values{} - values.Set("coin_type", strconv.Itoa(coinType)) - values.Set("id", strconv.Itoa(orderID)) - values.Set("amount", strconv.FormatFloat(amount, 'f', -1, 64)) - values.Set("price", strconv.FormatFloat(price, 'f', -1, 64)) - err := h.SendAuthenticatedRequest("modify_order", values) - - if err != nil { - log.Println(err) +// GetTimestamp returns the Huobi server time +func (h *HUOBI) GetTimestamp() (int64, error) { + type response struct { + Response + Timestamp int64 `json:"data"` } + + var result response + url := fmt.Sprintf("%s/v%s/%s", huobiAPIURL, huobiAPIVersion, huobiTimestamp) + err := common.SendHTTPGetRequest(url, true, h.Verbose, &result) + + if result.ErrorMessage != "" { + return 0, errors.New(result.ErrorMessage) + } + return result.Timestamp, err } -// GetNewDealOrders creates a new deal -func (h *HUOBI) GetNewDealOrders(coinType int) { - values := url.Values{} - values.Set("coin_type", strconv.Itoa(coinType)) - err := h.SendAuthenticatedRequest("get_new_deal_orders", values) - - if err != nil { - log.Println(err) +// GetAccounts returns the Huobi user accounts +func (h *HUOBI) GetAccounts() ([]Account, error) { + type response struct { + Response + AccountData []Account `json:"data"` } + + var result response + err := h.SendAuthenticatedHTTPRequest("GET", huobiAccounts, url.Values{}, &result) + + if result.ErrorMessage != "" { + return nil, errors.New(result.ErrorMessage) + } + return result.AccountData, err } -// GetOrderIDByTradeID returns ORDERID by Trade ID -func (h *HUOBI) GetOrderIDByTradeID(coinType, orderID int) { - values := url.Values{} - values.Set("coin_type", strconv.Itoa(coinType)) - values.Set("trade_id", strconv.Itoa(orderID)) - err := h.SendAuthenticatedRequest("get_order_id_by_trade_id", values) - - if err != nil { - log.Println(err) +// GetAccountBalance returns the users Huobi account balance +func (h *HUOBI) GetAccountBalance(accountID string) ([]AccountBalance, error) { + type response struct { + Response + AccountData []AccountBalance `json:"list"` } + + var result response + endpoint := fmt.Sprintf(huobiAccountBalance, accountID) + err := h.SendAuthenticatedHTTPRequest("GET", endpoint, url.Values{}, &result) + + if result.ErrorMessage != "" { + return nil, errors.New(result.ErrorMessage) + } + return result.AccountData, err } -// SendAuthenticatedRequest sends an autheticated HTTP request to Huobi -func (h *HUOBI) SendAuthenticatedRequest(method string, v url.Values) error { +// PlaceOrder submits an order to Huobi +func (h *HUOBI) PlaceOrder(symbol, source, accountID, orderType string, amount, price float64) (int64, error) { + vals := url.Values{} + vals.Set("account-id", accountID) + vals.Set("amount", strconv.FormatFloat(amount, 'f', -1, 64)) + + // Only set price if order type is not equal to buy-market or sell-market + if orderType != "buy-market" && orderType != "sell-market" { + vals.Set("price", strconv.FormatFloat(price, 'f', -1, 64)) + } + + if source != "" { + vals.Set("source", source) + } + + vals.Set("symbol", symbol) + vals.Set("type", orderType) + + type response struct { + Response + OrderID int64 `json:"data,string"` + } + + var result response + err := h.SendAuthenticatedHTTPRequest("POST", huobiOrderPlace, vals, &result) + + if result.ErrorMessage != "" { + return 0, errors.New(result.ErrorMessage) + } + return result.OrderID, err +} + +// CancelOrder cancels an order on Huobi +func (h *HUOBI) CancelOrder(orderID int64) (int64, error) { + type response struct { + Response + OrderID int64 `json:"data,string"` + } + + var result response + endpoint := fmt.Sprintf(huobiOrderCancel, strconv.FormatInt(orderID, 10)) + err := h.SendAuthenticatedHTTPRequest("POST", endpoint, url.Values{}, &result) + + if result.ErrorMessage != "" { + return 0, errors.New(result.ErrorMessage) + } + return result.OrderID, err +} + +// CancelOrderBatch cancels a batch of orders -- to-do +func (h *HUOBI) CancelOrderBatch(orderIDs []int64) ([]CancelOrderBatch, error) { + type response struct { + Response + Data []CancelOrderBatch `json:"data"` + } + + var result response + err := h.SendAuthenticatedHTTPRequest("POST", huobiOrderCancelBatch, url.Values{}, &result) + + if result.ErrorMessage != "" { + return nil, errors.New(result.ErrorMessage) + } + return result.Data, err +} + +// GetOrder returns order information for the specified order +func (h *HUOBI) GetOrder(orderID int64) (OrderInfo, error) { + type response struct { + Response + Order OrderInfo `json:"data"` + } + + var result response + endpoint := fmt.Sprintf(huobiGetOrder, strconv.FormatInt(orderID, 10)) + err := h.SendAuthenticatedHTTPRequest("GET", endpoint, url.Values{}, &result) + + if result.ErrorMessage != "" { + return result.Order, errors.New(result.ErrorMessage) + } + return result.Order, err +} + +// GetOrderMatchResults returns matched order info for the specified order +func (h *HUOBI) GetOrderMatchResults(orderID int64) ([]OrderMatchInfo, error) { + type response struct { + Response + Orders []OrderMatchInfo `json:"data"` + } + + var result response + endpoint := fmt.Sprintf(huobiGetOrderMatch, strconv.FormatInt(orderID, 10)) + err := h.SendAuthenticatedHTTPRequest("GET", endpoint, url.Values{}, &result) + + if result.ErrorMessage != "" { + return nil, errors.New(result.ErrorMessage) + } + return result.Orders, err +} + +// GetOrders returns a list of orders +func (h *HUOBI) GetOrders(symbol, types, start, end, states, from, direct, size string) ([]OrderInfo, error) { + type response struct { + Response + Orders []OrderInfo `json:"data"` + } + + vals := url.Values{} + vals.Set("symbol", symbol) + vals.Set("states", states) + + if types != "" { + vals.Set("types", types) + } + + if start != "" { + vals.Set("start-date", start) + } + + if end != "" { + vals.Set("end-date", end) + } + + if from != "" { + vals.Set("from", from) + } + + if direct != "" { + vals.Set("direct", direct) + } + + if size != "" { + vals.Set("size", size) + } + + var result response + err := h.SendAuthenticatedHTTPRequest("GET", huobiGetOrders, vals, &result) + + if result.ErrorMessage != "" { + return nil, errors.New(result.ErrorMessage) + } + return result.Orders, err +} + +// GetOrdersMatch returns a list of matched orders +func (h *HUOBI) GetOrdersMatch(symbol, types, start, end, from, direct, size string) ([]OrderMatchInfo, error) { + type response struct { + Response + Orders []OrderMatchInfo `json:"data"` + } + + vals := url.Values{} + vals.Set("symbol", symbol) + + if types != "" { + vals.Set("types", types) + } + + if start != "" { + vals.Set("start-date", start) + } + + if end != "" { + vals.Set("end-date", end) + } + + if from != "" { + vals.Set("from", from) + } + + if direct != "" { + vals.Set("direct", direct) + } + + if size != "" { + vals.Set("size", size) + } + + var result response + err := h.SendAuthenticatedHTTPRequest("GET", huobiGetOrdersMatch, vals, &result) + + if result.ErrorMessage != "" { + return nil, errors.New(result.ErrorMessage) + } + return result.Orders, err +} + +// MarginTransfer transfers assets into or out of the margin account +func (h *HUOBI) MarginTransfer(symbol, currency string, amount float64, in bool) (int64, error) { + vals := url.Values{} + vals.Set("symbol", symbol) + vals.Set("currency", currency) + vals.Set("amount", strconv.FormatFloat(amount, 'f', -1, 64)) + + path := huobiMarginTransferIn + if !in { + path = huobiMarginTransferOut + } + + type response struct { + Response + TransferID int64 `json:"data"` + } + + var result response + err := h.SendAuthenticatedHTTPRequest("POST", path, vals, &result) + + if result.ErrorMessage != "" { + return 0, errors.New(result.ErrorMessage) + } + return result.TransferID, err +} + +// MarginOrder submits a margin order application +func (h *HUOBI) MarginOrder(symbol, currency string, amount float64) (int64, error) { + vals := url.Values{} + vals.Set("symbol", symbol) + vals.Set("currency", currency) + vals.Set("amount", strconv.FormatFloat(amount, 'f', -1, 64)) + + type response struct { + Response + MarginOrderID int64 `json:"data"` + } + + var result response + err := h.SendAuthenticatedHTTPRequest("POST", huobiMarginOrders, vals, &result) + + if result.ErrorMessage != "" { + return 0, errors.New(result.ErrorMessage) + } + return result.MarginOrderID, err +} + +// MarginRepayment repays a margin amount for a margin ID +func (h *HUOBI) MarginRepayment(orderID int64, amount float64) (int64, error) { + vals := url.Values{} + vals.Set("order-id", strconv.FormatInt(orderID, 10)) + vals.Set("amount", strconv.FormatFloat(amount, 'f', -1, 64)) + + type response struct { + Response + MarginOrderID int64 `json:"data"` + } + + var result response + endpoint := fmt.Sprintf(huobiMarginRepay, strconv.FormatInt(orderID, 10)) + err := h.SendAuthenticatedHTTPRequest("POST", endpoint, vals, &result) + + if result.ErrorMessage != "" { + return 0, errors.New(result.ErrorMessage) + } + return result.MarginOrderID, err +} + +// GetMarginLoanOrders returns the margin loan orders +func (h *HUOBI) GetMarginLoanOrders(symbol, currency, start, end, states, from, direct, size string) ([]MarginOrder, error) { + vals := url.Values{} + vals.Set("symbol", symbol) + vals.Set("currency", currency) + + if start != "" { + vals.Set("start-date", start) + } + + if end != "" { + vals.Set("end-date", end) + } + + if states != "" { + vals.Set("states", states) + } + + if from != "" { + vals.Set("from", from) + } + + if direct != "" { + vals.Set("direct", direct) + } + + if size != "" { + vals.Set("size", size) + } + + type response struct { + Response + MarginLoanOrders []MarginOrder `json:"data"` + } + + var result response + err := h.SendAuthenticatedHTTPRequest("GET", huobiMarginLoanOrders, vals, &result) + + if result.ErrorMessage != "" { + return nil, errors.New(result.ErrorMessage) + } + return result.MarginLoanOrders, err +} + +// GetMarginAccountBalance returns the margin account balances +func (h *HUOBI) GetMarginAccountBalance(symbol string) ([]MarginAccountBalance, error) { + type response struct { + Response + Balances []MarginAccountBalance `json:"data"` + } + + vals := url.Values{} + if symbol != "" { + vals.Set("symbol", symbol) + } + + var result response + err := h.SendAuthenticatedHTTPRequest("GET", huobiMarginAccountBalance, vals, &result) + + if result.ErrorMessage != "" { + return nil, errors.New(result.ErrorMessage) + } + return result.Balances, err +} + +// Withdraw withdraws the desired amount and currency +func (h *HUOBI) Withdraw(address, currency, addrTag string, amount, fee float64) (int64, error) { + type response struct { + Response + WithdrawID int64 `json:"data"` + } + + vals := url.Values{} + vals.Set("address", address) + vals.Set("currency", currency) + vals.Set("amount", strconv.FormatFloat(amount, 'f', -1, 64)) + + if fee != 0 { + vals.Set("fee", strconv.FormatFloat(fee, 'f', -1, 64)) + } + + if currency == "XRP" { + vals.Set("addr-tag", addrTag) + } + + var result response + err := h.SendAuthenticatedHTTPRequest("POST", huobiWithdrawCreate, vals, &result) + + if result.ErrorMessage != "" { + return 0, errors.New(result.ErrorMessage) + } + return result.WithdrawID, err +} + +// CancelWithdraw cancels a withdraw request +func (h *HUOBI) CancelWithdraw(withdrawID int64) (int64, error) { + type response struct { + Response + WithdrawID int64 `json:"data"` + } + + vals := url.Values{} + vals.Set("withdraw-id", strconv.FormatInt(withdrawID, 10)) + + var result response + endpoint := fmt.Sprintf(huobiWithdrawCancel, strconv.FormatInt(withdrawID, 10)) + err := h.SendAuthenticatedHTTPRequest("POST", endpoint, vals, &result) + + if result.ErrorMessage != "" { + return 0, errors.New(result.ErrorMessage) + } + return result.WithdrawID, err +} + +// SendAuthenticatedHTTPRequest sends authenticated requests to the HUOBI API +func (h *HUOBI) SendAuthenticatedHTTPRequest(method, endpoint string, values url.Values, result interface{}) error { if !h.AuthenticatedAPISupport { return fmt.Errorf(exchange.WarningAuthenticatedRequestWithoutCredentialsSet, h.Name) } - v.Set("access_key", h.APIKey) - v.Set("created", strconv.FormatInt(time.Now().Unix(), 10)) - v.Set("method", method) - hash := common.GetMD5([]byte(v.Encode() + "&secret_key=" + h.APISecret)) - v.Set("sign", common.StringToLower(common.HexEncodeToString(hash))) - encoded := v.Encode() + values.Set("AccessKeyId", h.APIKey) + values.Set("SignatureMethod", "HmacSHA256") + values.Set("SignatureVersion", "2") + values.Set("Timestamp", time.Now().UTC().Format("2006-01-02T15:04:05")) - if h.Verbose { - log.Printf("Sending POST request to %s with params %s\n", huobiAPIURL, encoded) - } + endpoint = fmt.Sprintf("/v%s/%s", huobiAPIVersion, endpoint) + payload := fmt.Sprintf("%s\napi.huobi.pro\n%s\n%s", + method, endpoint, values.Encode()) headers := make(map[string]string) headers["Content-Type"] = "application/x-www-form-urlencoded" - resp, err := common.SendHTTPRequest("POST", huobiAPIURL, headers, strings.NewReader(encoded)) + hmac := common.GetHMAC(common.HashSHA256, []byte(payload), []byte(h.APISecret)) + values.Set("Signature", common.Base64Encode(hmac)) + + url := fmt.Sprintf("%s%s", huobiAPIURL, endpoint) + url = common.EncodeURLValues(url, values) + resp, err := common.SendHTTPRequest(method, url, headers, bytes.NewBufferString("")) if err != nil { return err } - if h.Verbose { - log.Printf("Received raw: %s\n", resp) + err = common.JSONDecode([]byte(resp), &result) + if err != nil { + return errors.New("unable to JSON Unmarshal response") } return nil diff --git a/exchanges/huobi/huobi_test.go b/exchanges/huobi/huobi_test.go index 4f2d3c93..46f9458e 100644 --- a/exchanges/huobi/huobi_test.go +++ b/exchanges/huobi/huobi_test.go @@ -1,6 +1,7 @@ package huobi import ( + "strconv" "testing" "github.com/thrasher-/gocryptotrader/config" @@ -37,14 +38,216 @@ func TestSetup(t *testing.T) { func TestGetFee(t *testing.T) { t.Parallel() if h.GetFee() != 0 { - t.Error("test failed - Huobi GetFee() error") + t.Errorf("test failed - Huobi GetFee() error") } } -func TestGetTicker(t *testing.T) { +func TestGetKline(t *testing.T) { t.Parallel() - _, err := h.GetTicker("btcusd") - if err == nil { - t.Error("test failed - Huobi GetTicker() error", err) + _, err := h.GetKline("btcusdt", "1week", "") + if err != nil { + t.Errorf("Test failed - Huobi TestGetKline: %s", err) + } +} + +func TestGetMarketDetailMerged(t *testing.T) { + t.Parallel() + _, err := h.GetMarketDetailMerged("btcusdt") + if err != nil { + t.Errorf("Test failed - Huobi TestGetMarketDetailMerged: %s", err) + } +} + +func TestGetDepth(t *testing.T) { + t.Parallel() + _, err := h.GetDepth("btcusdt", "step1") + if err != nil { + t.Errorf("Test failed - Huobi TestGetDepth: %s", err) + } +} + +func TestGetTrades(t *testing.T) { + t.Parallel() + _, err := h.GetTrades("btcusdt") + if err != nil { + t.Errorf("Test failed - Huobi TestGetTrades: %s", err) + } +} + +func TestGetTradeHistory(t *testing.T) { + t.Parallel() + _, err := h.GetTradeHistory("btcusdt", "50") + if err != nil { + t.Errorf("Test failed - Huobi TestGetTradeHistory: %s", err) + } +} + +func TestGetMarketDetail(t *testing.T) { + t.Parallel() + _, err := h.GetMarketDetail("btcusdt") + if err != nil { + t.Errorf("Test failed - Huobi TestGetTradeHistory: %s", err) + } +} + +func TestGetSymbols(t *testing.T) { + t.Parallel() + _, err := h.GetSymbols() + if err != nil { + t.Errorf("Test failed - Huobi TestGetSymbols: %s", err) + } +} + +func TestGetCurrencies(t *testing.T) { + t.Parallel() + _, err := h.GetCurrencies() + if err != nil { + t.Errorf("Test failed - Huobi TestGetCurrencies: %s", err) + } +} + +func TestGetTimestamp(t *testing.T) { + t.Parallel() + _, err := h.GetTimestamp() + if err != nil { + t.Errorf("Test failed - Huobi TestGetTimestamp: %s", err) + } +} + +func TestGetAccounts(t *testing.T) { + t.Parallel() + if apiKey == "" && apiSecret == "" { + t.Skip() + } + + h.APIKey = apiKey + h.APISecret = apiSecret + h.AuthenticatedAPISupport = true + + _, err := h.GetAccounts() + if err != nil { + t.Errorf("Test failed - Huobi GetAccounts: %s", err) + } +} + +func TestGetAccountBalance(t *testing.T) { + t.Parallel() + if apiKey == "" && apiSecret == "" { + t.Skip() + } + + h.APIKey = apiKey + h.APISecret = apiSecret + h.AuthenticatedAPISupport = true + + result, err := h.GetAccounts() + if err != nil { + t.Errorf("Test failed - Huobi GetAccounts: %s", err) + } + + userID := strconv.FormatInt(result[0].ID, 10) + _, err = h.GetAccountBalance(userID) + if err != nil { + t.Errorf("Test failed - Huobi GetAccountBalance: %s", err) + } +} + +func TestPlaceOrder(t *testing.T) { + t.Parallel() + if apiKey == "" && apiSecret == "" { + t.Skip() + } + + h.APIKey = apiKey + h.APISecret = apiSecret + h.AuthenticatedAPISupport = true + + _, err := h.GetAccounts() + if err != nil { + t.Errorf("Test failed - Huobi GetAccounts: %s", err) + } + + /* + userID := strconv.FormatInt(result[0].ID, 10) + _, err = h.PlaceOrder("ethusdt", "api", userID, "buy-limit", 10.1, 100.1) + if err != nil { + t.Errorf("Test failed - Huobi TestPlaceOrder: %s", err) + } + */ +} + +func TestCancelOrder(t *testing.T) { + t.Parallel() + if apiKey == "" && apiSecret == "" { + t.Skip() + } + + h.APIKey = apiKey + h.APISecret = apiSecret + h.AuthenticatedAPISupport = true + + _, err := h.CancelOrder(1337) + if err == nil { + t.Error("Test failed - Huobi TestCancelOrder: Invalid orderID returned true") + } +} + +func TestGetOrder(t *testing.T) { + t.Parallel() + if apiKey == "" && apiSecret == "" { + t.Skip() + } + + h.APIKey = apiKey + h.APISecret = apiSecret + h.AuthenticatedAPISupport = true + _, err := h.GetOrder(1337) + if err == nil { + t.Error("Test failed - Huobi TestCancelOrder: Invalid orderID returned true") + } +} + +func TestGetMarginLoanOrders(t *testing.T) { + t.Parallel() + if apiKey == "" && apiSecret == "" { + t.Skip() + } + + h.APIKey = apiKey + h.APISecret = apiSecret + h.AuthenticatedAPISupport = true + _, err := h.GetMarginLoanOrders("btcusdt", "", "", "", "", "", "", "") + if err != nil { + t.Errorf("Test failed - Huobi TestGetMarginLoanOrders: %s", err) + } +} + +func TestGetMarginAccountBalance(t *testing.T) { + t.Parallel() + if apiKey == "" && apiSecret == "" { + t.Skip() + } + + h.APIKey = apiKey + h.APISecret = apiSecret + h.AuthenticatedAPISupport = true + _, err := h.GetMarginAccountBalance("btcusdt") + if err != nil { + t.Errorf("Test failed - Huobi TestGetMarginAccountBalance: %s", err) + } +} + +func TestCancelWithdraw(t *testing.T) { + t.Parallel() + if apiKey == "" && apiSecret == "" { + t.Skip() + } + + h.APIKey = apiKey + h.APISecret = apiSecret + h.AuthenticatedAPISupport = true + _, err := h.CancelWithdraw(1337) + if err == nil { + t.Error("Test failed - Huobi TestCancelWithdraw: Invalid withdraw-ID was valid") } } diff --git a/exchanges/huobi/huobi_types.go b/exchanges/huobi/huobi_types.go index 5cd8c7f6..858a7c40 100644 --- a/exchanges/huobi/huobi_types.go +++ b/exchanges/huobi/huobi_types.go @@ -1,26 +1,171 @@ package huobi -// Ticker holds ticker information -type Ticker struct { - High float64 - Low float64 - Last float64 - Vol float64 - Buy float64 - Sell float64 +// Response stores the Huobi response information +type Response struct { + Status string `json:"status"` + Channel string `json:"ch"` + Timestamp int64 `json:"ts"` + ErrorCode string `json:"err-code"` + ErrorMessage string `json:"err-msg"` } -// TickerResponse holds the initial response type -type TickerResponse struct { - Time string - Ticker Ticker +// KlineItem stores a kline item +type KlineItem struct { + ID int `json:"id"` + Open float64 `json:"open"` + Close float64 `json:"close"` + Low float64 `json:"low"` + High float64 `json:"high"` + Amount float64 `json:"amount"` + Vol float64 `json:"vol"` + Count int `json:"count"` } -// Orderbook holds the order book information +// Klines stores tan array of kline items +type Klines struct { + Klines []KlineItem `json:"data"` +} + +// DetailMerged stores the ticker detail merged data +type DetailMerged struct { + Detail + Version int `json:"version"` + Ask []float64 `json:"ask"` + Bid []float64 `json:"bid"` +} + +// Orderbook stores the orderbook data type Orderbook struct { - ID float64 - TS float64 - Bids [][]float64 `json:"bids"` - Asks [][]float64 `json:"asks"` - Symbol string `json:"string"` + ID int64 `json:"id"` + Timetstamp int64 `json:"ts"` + Bids [][]float64 `json:"bids"` + Asks [][]float64 `json:"asks"` +} + +// Trade stores the trade data +type Trade struct { + ID float64 `json:"id"` + Price float64 `json:"price"` + Amount float64 `json:"amount"` + Direction string `json:"direction"` + Timestamp int64 `json:"ts"` +} + +// TradeHistory stores the the trade history data +type TradeHistory struct { + ID int64 `json:"id"` + Timestamp int64 `json:"ts"` + Trades []Trade `json:"data"` +} + +// Detail stores the ticker detail data +type Detail struct { + Amount float64 `json:"amount"` + Open float64 `json:"open"` + Close float64 `json:"close"` + High float64 `json:"high"` + Timestamp int64 `json:"id"` + ID int `json:"id"` + Count int `json:"count"` + Low float64 `json:"low"` + Volume float64 `json:"vol"` +} + +// Symbol stores the symbol data +type Symbol struct { + BaseCurrency string `json:"base-currency"` + QuoteCurrency string `json:"quote-currency"` + PricePrecision int `json:"price-precision"` + AmountPrecision int `json:"amount-precision"` + SymbolPartition string `json:"symbol-partition"` +} + +// Account stores the account data +type Account struct { + ID int64 `json:"id"` + Type string `json:"type"` + State string `json:"working"` + UserID int64 `json:"user-id"` +} + +// AccountBalance stores the user account balance +type AccountBalance struct { + Currency string `json:"currency"` + Type string `json:"type"` + Balance float64 `json:"balance,string"` +} + +// CancelOrderBatch stores the cancel order batch data +type CancelOrderBatch struct { + Success []string `json:"success"` + Failed []struct { + OrderID int64 `json:"order-id,string"` + ErrorCode string `json:"err-code"` + ErrorMessage string `json:"err-msg"` + } `json:"failed"` +} + +// OrderInfo stores the order info +type OrderInfo struct { + ID int `json:"id"` + Symbol string `json:"symbol"` + AccountID int `json:"account-id"` + Amount string `json:"amount"` + Price string `json:"price"` + CreatedAt int64 `json:"created-at"` + Type string `json:"type"` + FieldAmount string `json:"field-amount"` + FieldCashAmount string `json:"field-cash-amount"` + FieldFees string `json:"field-fees"` + FinishedAt int64 `json:"finished-at"` + UserID int `json:"user-id"` + Source string `json:"source"` + State string `json:"state"` + CanceledAt int `json:"canceled-at"` + Exchange string `json:"exchange"` + Batch string `json:"batch"` +} + +// OrderMatchInfo stores the order match info +type OrderMatchInfo struct { + ID int `json:"id"` + OrderID int `json:"order-id"` + MatchID int `json:"match-id"` + Symbol string `json:"symbol"` + Type string `json:"type"` + Source string `json:"source"` + Price string `json:"price"` + FilledAmount string `json:"filled-amount"` + FilledFees string `json:"filled-fees"` + CreatedAt int64 `json:"created-at"` +} + +// MarginOrder stores the margin order info +type MarginOrder struct { + Currency string `json:"currency"` + Symbol string `json:"symbol"` + AccruedAt int64 `json:"accrued-at"` + LoanAmount string `json:"loan-amount"` + LoanBalance string `json:"loan-balance"` + InterestBalance string `json:"interest-balance"` + CreatedAt int64 `json:"created-at"` + InterestAmount string `json:"interest-amount"` + InterestRate string `json:"interest-rate"` + AccountID int `json:"account-id"` + UserID int `json:"user-id"` + UpdatedAt int64 `json:"updated-at"` + ID int `json:"id"` + State string `json:"state"` +} + +// MarginAccountBalance stores the margin account balance info +type MarginAccountBalance struct { + ID int `json:"id"` + Type string `json:"type"` + State string `json:"state"` + Symbol string `json:"symbol"` + FlPrice string `json:"fl-price"` + FlType string `json:"fl-type"` + RiskRate string `json:"risk-rate"` + List []AccountBalance `json:"list"` } diff --git a/exchanges/huobi/huobi_wrapper.go b/exchanges/huobi/huobi_wrapper.go index 6981d22c..2783a928 100644 --- a/exchanges/huobi/huobi_wrapper.go +++ b/exchanges/huobi/huobi_wrapper.go @@ -4,6 +4,7 @@ import ( "log" "github.com/thrasher-/gocryptotrader/common" + "github.com/thrasher-/gocryptotrader/config" "github.com/thrasher-/gocryptotrader/currency/pair" "github.com/thrasher-/gocryptotrader/exchanges" "github.com/thrasher-/gocryptotrader/exchanges/orderbook" @@ -26,22 +27,70 @@ func (h *HUOBI) Run() { if h.Websocket { go h.WebsocketClient() } + + exchangeProducts, err := h.GetSymbols() + if err != nil { + log.Printf("%s Failed to get available symbols.\n", h.GetName()) + } else { + forceUpgrade := false + if common.DataContains(h.EnabledPairs, "CNY") || common.DataContains(h.AvailablePairs, "CNY") { + forceUpgrade = true + } + + if common.DataContains(h.BaseCurrencies, "CNY") { + cfg := config.GetConfig() + exchCfg, err := cfg.GetExchangeConfig(h.Name) + if err != nil { + log.Printf("%s failed to get exchange config. %s\n", h.Name, err) + return + } + exchCfg.BaseCurrencies = "USD" + h.BaseCurrencies = []string{"USD"} + + err = cfg.UpdateExchangeConfig(exchCfg) + if err != nil { + log.Printf("%s failed to update config. %s\n", h.Name, err) + return + } + } + + var currencies []string + for x := range exchangeProducts { + newCurrency := exchangeProducts[x].BaseCurrency + "-" + exchangeProducts[x].QuoteCurrency + currencies = append(currencies, newCurrency) + } + + if forceUpgrade { + enabledPairs := []string{"btc-usdt"} + log.Println("WARNING: Available and enabled pairs for Huobi reset due to config upgrade, please enable the ones you would like again") + + err = h.UpdateEnabledCurrencies(enabledPairs, true) + if err != nil { + log.Printf("%s Failed to update enabled currencies.\n", h.GetName()) + } + } + err = h.UpdateAvailableCurrencies(currencies, forceUpgrade) + if err != nil { + log.Printf("%s Failed to update available currencies.\n", h.GetName()) + } + } } // UpdateTicker updates and returns the ticker for a currency pair func (h *HUOBI) UpdateTicker(p pair.CurrencyPair, assetType string) (ticker.Price, error) { var tickerPrice ticker.Price - tick, err := h.GetTicker(p.GetFirstCurrency().Lower().String()) + tick, err := h.GetMarketDetailMerged(exchange.FormatExchangeCurrency(h.Name, p).String()) if err != nil { return tickerPrice, err } + tickerPrice.Pair = p - tickerPrice.Ask = tick.Sell - tickerPrice.Bid = tick.Buy tickerPrice.Low = tick.Low - tickerPrice.Last = tick.Last - tickerPrice.Volume = tick.Vol + tickerPrice.Last = tick.Close + tickerPrice.Volume = tick.Volume tickerPrice.High = tick.High + tickerPrice.Ask = tick.Ask[0] + tickerPrice.Bid = tick.Bid[0] ticker.ProcessTicker(h.GetName(), p, tickerPrice, assetType) return ticker.GetTicker(h.Name, p, assetType) } @@ -67,7 +116,7 @@ func (h *HUOBI) GetOrderbookEx(p pair.CurrencyPair, assetType string) (orderbook // UpdateOrderbook updates and returns the orderbook for a currency pair func (h *HUOBI) UpdateOrderbook(p pair.CurrencyPair, assetType string) (orderbook.Base, error) { var orderBook orderbook.Base - orderbookNew, err := h.GetOrderBook(p.GetFirstCurrency().Lower().String()) + orderbookNew, err := h.GetDepth(exchange.FormatExchangeCurrency(h.Name, p).String(), "step1") if err != nil { return orderBook, err } diff --git a/testdata/configtest.json b/testdata/configtest.json index 5844b97e..835d7ef8 100644 --- a/testdata/configtest.json +++ b/testdata/configtest.json @@ -19,7 +19,7 @@ { "Address": "3Nxwenay9Z8Lc9JBiywExpnEFiLp6Afp8v", "CoinType": "BTC", - "Balance": 78348.33579495, + "Balance": 83348.33579495, "Description": "" }, { @@ -31,7 +31,7 @@ { "Address": "0xb794f5ea0ba39494ce839613fffba74279579268", "CoinType": "ETH", - "Balance": 2075000.2917679, + "Balance": 2000000.289943, "Description": "" } ] @@ -90,7 +90,7 @@ "AuthenticatedAPISupport": false, "APIKey": "Key", "APISecret": "Secret", - "AvailablePairs": "BTCUSD,LTCUSD,LTCBTC,ETHUSD,ETHBTC,ETCBTC,ETCUSD,RRTUSD,RRTBTC,ZECUSD,ZECBTC,XMRUSD,XMRBTC,DSHUSD,DSHBTC,BTCEUR,XRPUSD,XRPBTC,IOTUSD,IOTBTC,IOTETH,EOSUSD,EOSBTC,EOSETH,SANUSD,SANBTC,SANETH,OMGUSD,OMGBTC,OMGETH,BCHUSD,BCHBTC,BCHETH,NEOUSD,NEOBTC,NEOETH,ETPUSD,ETPBTC,ETPETH,QTMUSD,QTMBTC,QTMETH,AVTUSD,AVTBTC,AVTETH,EDOUSD,EDOBTC,EDOETH,BTGUSD,BTGBTC,DATUSD,DATBTC,DATETH,QSHUSD,QSHBTC,QSHETH,YYWUSD,YYWBTC,YYWETH,GNTUSD,GNTBTC,GNTETH,SNTUSD,SNTBTC,SNTETH,IOTEUR,BATUSD,BATBTC,BATETH,MNAUSD,MNABTC,MNAETH,FUNUSD,FUNBTC,FUNETH,ZRXUSD,ZRXBTC,ZRXETH,TNBUSD,TNBBTC,TNBETH,SPKUSD,SPKBTC,SPKETH", + "AvailablePairs": "BTCUSD,LTCUSD,LTCBTC,ETHUSD,ETHBTC,ETCBTC,ETCUSD,RRTUSD,RRTBTC,ZECUSD,ZECBTC,XMRUSD,XMRBTC,DSHUSD,DSHBTC,BTCEUR,XRPUSD,XRPBTC,IOTUSD,IOTBTC,IOTETH,EOSUSD,EOSBTC,EOSETH,SANUSD,SANBTC,SANETH,OMGUSD,OMGBTC,OMGETH,BCHUSD,BCHBTC,BCHETH,NEOUSD,NEOBTC,NEOETH,ETPUSD,ETPBTC,ETPETH,QTMUSD,QTMBTC,QTMETH,AVTUSD,AVTBTC,AVTETH,EDOUSD,EDOBTC,EDOETH,BTGUSD,BTGBTC,DATUSD,DATBTC,DATETH,QSHUSD,QSHBTC,QSHETH,YYWUSD,YYWBTC,YYWETH,GNTUSD,GNTBTC,GNTETH,SNTUSD,SNTBTC,SNTETH,IOTEUR,BATUSD,BATBTC,BATETH,MNAUSD,MNABTC,MNAETH,FUNUSD,FUNBTC,FUNETH,ZRXUSD,ZRXBTC,ZRXETH,TNBUSD,TNBBTC,TNBETH,SPKUSD,SPKBTC,SPKETH,TRXUSD,TRXBTC,TRXETH,RCNUSD,RCNBTC,RCNETH,RLCUSD,RLCBTC,RLCETH,AIDUSD,AIDBTC,AIDETH,SNGUSD,SNGBTC,SNGETH,REPUSD,REPBTC,REPETH,ELFUSD,ELFBTC,ELFETH", "EnabledPairs": "BTCUSD,LTCUSD,LTCBTC,ETHUSD,ETHBTC", "BaseCurrencies": "USD", "AssetTypes": "SPOT", @@ -133,7 +133,7 @@ "AuthenticatedAPISupport": false, "APIKey": "Key", "APISecret": "Secret", - "AvailablePairs": "BTC-LTC,BTC-DOGE,BTC-VTC,BTC-PPC,BTC-FTC,BTC-RDD,BTC-NXT,BTC-DASH,BTC-POT,BTC-BLK,BTC-EMC2,BTC-XMY,BTC-AUR,BTC-EFL,BTC-GLD,BTC-SLR,BTC-PTC,BTC-GRS,BTC-NLG,BTC-RBY,BTC-XWC,BTC-MONA,BTC-THC,BTC-ENRG,BTC-ERC,BTC-VRC,BTC-CURE,BTC-XMR,BTC-CLOAK,BTC-START,BTC-KORE,BTC-XDN,BTC-TRUST,BTC-NAV,BTC-XST,BTC-BTCD,BTC-VIA,BTC-PINK,BTC-IOC,BTC-CANN,BTC-SYS,BTC-NEOS,BTC-DGB,BTC-BURST,BTC-EXCL,BTC-DOPE,BTC-BLOCK,BTC-ABY,BTC-BYC,BTC-XMG,BTC-BLITZ,BTC-BAY,BTC-FAIR,BTC-SPR,BTC-VTR,BTC-XRP,BTC-GAME,BTC-COVAL,BTC-NXS,BTC-XCP,BTC-BITB,BTC-GEO,BTC-FLDC,BTC-GRC,BTC-FLO,BTC-NBT,BTC-MUE,BTC-XEM,BTC-CLAM,BTC-DMD,BTC-GAM,BTC-SPHR,BTC-OK,BTC-SNRG,BTC-PKB,BTC-CPC,BTC-AEON,BTC-ETH,BTC-GCR,BTC-TX,BTC-BCY,BTC-EXP,BTC-INFX,BTC-OMNI,BTC-AMP,BTC-AGRS,BTC-XLM,USDT-BTC,BTC-CLUB,BTC-VOX,BTC-EMC,BTC-FCT,BTC-MAID,BTC-EGC,BTC-SLS,BTC-RADS,BTC-DCR,BTC-BSD,BTC-XVG,BTC-PIVX,BTC-XVC,BTC-MEME,BTC-STEEM,BTC-2GIVE,BTC-LSK,BTC-PDC,BTC-BRK,BTC-WAVES,BTC-RISE,BTC-LBC,BTC-SBD,BTC-BRX,BTC-ETC,ETH-ETC,BTC-STRAT,BTC-UNB,BTC-SYNX,BTC-EBST,BTC-VRM,BTC-SEQ,BTC-REP,BTC-SHIFT,BTC-ARDR,BTC-XZC,BTC-NEO,BTC-ZEC,BTC-ZCL,BTC-IOP,BTC-GOLOS,BTC-UBQ,BTC-KMD,BTC-GBG,BTC-SIB,BTC-ION,BTC-LMC,BTC-QWARK,BTC-CRW,BTC-SWT,BTC-MLN,BTC-ARK,BTC-DYN,BTC-TKS,BTC-MUSIC,BTC-DTB,BTC-INCNT,BTC-GBYTE,BTC-GNT,BTC-NXC,BTC-EDG,BTC-LGD,BTC-TRST,ETH-GNT,ETH-REP,USDT-ETH,ETH-WINGS,BTC-WINGS,BTC-RLC,BTC-GNO,BTC-GUP,BTC-LUN,ETH-GUP,ETH-RLC,ETH-LUN,ETH-GNO,BTC-APX,BTC-HMQ,ETH-HMQ,BTC-ANT,ETH-TRST,ETH-ANT,BTC-SC,ETH-BAT,BTC-BAT,BTC-ZEN,BTC-1ST,BTC-QRL,ETH-1ST,ETH-QRL,BTC-CRB,ETH-CRB,ETH-LGD,BTC-PTOY,ETH-PTOY,BTC-MYST,ETH-MYST,BTC-CFI,ETH-CFI,BTC-BNT,ETH-BNT,BTC-NMR,ETH-NMR,ETH-LTC,ETH-XRP,BTC-SNT,ETH-SNT,BTC-DCT,BTC-XEL,BTC-MCO,ETH-MCO,BTC-ADT,ETH-ADT,BTC-FUN,ETH-FUN,BTC-PAY,ETH-PAY,BTC-STORJ,ETH-STORJ,BTC-ADX,ETH-ADX,ETH-DASH,ETH-SC,ETH-ZEC,USDT-ZEC,USDT-LTC,USDT-ETC,USDT-XRP,BTC-OMG,ETH-OMG,BTC-CVC,ETH-CVC,BTC-PART,BTC-QTUM,ETH-QTUM,ETH-XMR,ETH-XEM,ETH-XLM,ETH-NEO,USDT-XMR,USDT-DASH,ETH-BCC,USDT-BCC,BTC-BCC,BTC-DNT,ETH-DNT,USDT-NEO,ETH-WAVES,ETH-STRAT,ETH-DGB,ETH-FCT,USDT-OMG,BTC-ADA,BTC-MANA,ETH-MANA,BTC-SALT,ETH-SALT,BTC-TIX,ETH-TIX,BTC-RCN,ETH-RCN,BTC-VIB,ETH-VIB,BTC-MER,BTC-POWR,ETH-POWR,BTC-BTG,ETH-BTG,USDT-BTG,ETH-ADA,BTC-ENG,ETH-ENG,USDT-ADA,USDT-XVG,USDT-NXT,BTC-UKG,ETH-UKG", + "AvailablePairs": "BTC-LTC,BTC-DOGE,BTC-VTC,BTC-PPC,BTC-FTC,BTC-RDD,BTC-NXT,BTC-DASH,BTC-POT,BTC-BLK,BTC-EMC2,BTC-XMY,BTC-AUR,BTC-EFL,BTC-GLD,BTC-SLR,BTC-PTC,BTC-GRS,BTC-NLG,BTC-RBY,BTC-XWC,BTC-MONA,BTC-THC,BTC-ENRG,BTC-ERC,BTC-VRC,BTC-CURE,BTC-XMR,BTC-CLOAK,BTC-START,BTC-KORE,BTC-XDN,BTC-TRUST,BTC-NAV,BTC-XST,BTC-VIA,BTC-PINK,BTC-IOC,BTC-CANN,BTC-SYS,BTC-NEOS,BTC-DGB,BTC-BURST,BTC-EXCL,BTC-DOPE,BTC-BLOCK,BTC-ABY,BTC-BYC,BTC-XMG,BTC-BLITZ,BTC-BAY,BTC-FAIR,BTC-SPR,BTC-VTR,BTC-XRP,BTC-GAME,BTC-COVAL,BTC-NXS,BTC-XCP,BTC-BITB,BTC-FLDC,BTC-GRC,BTC-FLO,BTC-NBT,BTC-MUE,BTC-XEM,BTC-CLAM,BTC-DMD,BTC-GAM,BTC-SPHR,BTC-OK,BTC-SNRG,BTC-PKB,BTC-CPC,BTC-AEON,BTC-ETH,BTC-GCR,BTC-TX,BTC-BCY,BTC-EXP,BTC-INFX,BTC-OMNI,BTC-AMP,BTC-AGRS,BTC-XLM,USDT-BTC,BTC-CLUB,BTC-VOX,BTC-EMC,BTC-FCT,BTC-MAID,BTC-EGC,BTC-SLS,BTC-RADS,BTC-DCR,BTC-BSD,BTC-XVG,BTC-PIVX,BTC-XVC,BTC-MEME,BTC-STEEM,BTC-2GIVE,BTC-LSK,BTC-PDC,BTC-BRK,BTC-WAVES,BTC-RISE,BTC-LBC,BTC-SBD,BTC-BRX,BTC-ETC,ETH-ETC,BTC-STRAT,BTC-UNB,BTC-SYNX,BTC-EBST,BTC-VRM,BTC-SEQ,BTC-REP,BTC-SHIFT,BTC-ARDR,BTC-XZC,BTC-NEO,BTC-ZEC,BTC-ZCL,BTC-IOP,BTC-GOLOS,BTC-UBQ,BTC-KMD,BTC-GBG,BTC-SIB,BTC-ION,BTC-LMC,BTC-QWARK,BTC-CRW,BTC-SWT,BTC-MLN,BTC-ARK,BTC-DYN,BTC-TKS,BTC-MUSIC,BTC-DTB,BTC-INCNT,BTC-GBYTE,BTC-GNT,BTC-NXC,BTC-EDG,BTC-LGD,BTC-TRST,ETH-GNT,ETH-REP,USDT-ETH,ETH-WINGS,BTC-WINGS,BTC-RLC,BTC-GNO,BTC-GUP,BTC-LUN,ETH-GUP,ETH-RLC,ETH-LUN,ETH-GNO,BTC-HMQ,ETH-HMQ,BTC-ANT,ETH-TRST,ETH-ANT,BTC-SC,ETH-BAT,BTC-BAT,BTC-ZEN,BTC-1ST,BTC-QRL,ETH-1ST,ETH-QRL,BTC-CRB,ETH-CRB,ETH-LGD,BTC-PTOY,ETH-PTOY,BTC-CFI,ETH-CFI,BTC-BNT,ETH-BNT,BTC-NMR,ETH-NMR,ETH-LTC,ETH-XRP,BTC-SNT,ETH-SNT,BTC-DCT,BTC-XEL,BTC-MCO,ETH-MCO,BTC-ADT,ETH-ADT,BTC-FUN,ETH-FUN,BTC-PAY,ETH-PAY,BTC-STORJ,ETH-STORJ,BTC-ADX,ETH-ADX,ETH-DASH,ETH-SC,ETH-ZEC,USDT-ZEC,USDT-LTC,USDT-ETC,USDT-XRP,BTC-OMG,ETH-OMG,BTC-CVC,ETH-CVC,BTC-PART,BTC-QTUM,ETH-QTUM,ETH-XMR,ETH-XEM,ETH-XLM,ETH-NEO,USDT-XMR,USDT-DASH,ETH-BCC,USDT-BCC,BTC-BCC,BTC-DNT,ETH-DNT,USDT-NEO,ETH-WAVES,ETH-STRAT,ETH-DGB,ETH-FCT,USDT-OMG,BTC-ADA,BTC-MANA,ETH-MANA,BTC-SALT,ETH-SALT,BTC-TIX,ETH-TIX,BTC-RCN,ETH-RCN,BTC-VIB,ETH-VIB,BTC-MER,BTC-POWR,ETH-POWR,BTC-BTG,ETH-BTG,USDT-BTG,ETH-ADA,BTC-ENG,ETH-ENG,USDT-ADA,USDT-XVG,USDT-NXT,BTC-UKG,ETH-UKG", "EnabledPairs": "USDT-BTC", "BaseCurrencies": "USD", "AssetTypes": "SPOT", @@ -244,7 +244,7 @@ "APIKey": "Key", "APISecret": "Secret", "ClientID": "ClientID", - "AvailablePairs": "BCHBTC,BCHUSD,BTCEUR,BTCGBP,BTCUSD,ETHBTC,ETHEUR,ETHUSD,LTCBTC,LTCEUR,LTCUSD", + "AvailablePairs": "BCHBTC,BCHUSD,BTCEUR,BTCGBP,BTCUSD,ETHBTC,ETHEUR,ETHUSD,LTCBTC,LTCEUR,LTCUSD,BCHEUR", "EnabledPairs": "BTCUSD,BTCGBP,BTCEUR", "BaseCurrencies": "USD,GBP,EUR", "AssetTypes": "SPOT", @@ -287,12 +287,13 @@ "AuthenticatedAPISupport": false, "APIKey": "Key", "APISecret": "Secret", - "AvailablePairs": "BTCCNY,LTCCNY", - "EnabledPairs": "BTCCNY,LTCCNY", - "BaseCurrencies": "CNY", + "AvailablePairs": "OMG-USDT,LINK-BTC,NAS-ETH,EOS-ETH,SWFTC-BTC,XEM-USDT,ZEC-USDT,DASH-BTC,PAY-BTC,EVX-BTC,MDS-ETH,TNT-BTC,QASH-ETH,SMT-ETH,RUFF-ETH,BCH-BTC,IOST-ETH,TNB-BTC,GNX-ETH,THETA-BTC,SNT-USDT,DAT-BTC,SOC-ETH,EOS-USDT,CHAT-ETH,MANA-BTC,SMT-USDT,XRP-BTC,LTC-USDT,QTUM-USDT,LET-BTC,BCD-BTC,SNT-BTC,CVC-USDT,ELF-ETH,GNT-ETH,UTK-BTC,SBTC-BTC,NEO-USDT,MCO-BTC,OST-ETH,RCN-BTC,BT2-BTC,QUN-BTC,HSR-ETH,TOPC-ETH,SALT-ETH,AIDOC-ETH,WAX-BTC,CVC-ETH,DTA-ETH,BTC-USDT,MEE-ETH,POWR-ETH,GAS-ETH,ADX-ETH,NEO-BTC,SALT-BTC,BTM-BTC,EKO-ETH,BAT-ETH,EKO-BTC,APPC-BTC,CMT-BTC,VEN-ETH,QTUM-ETH,REQ-BTC,BIFI-BTC,BTM-ETH,ICX-BTC,ZEC-BTC,ACT-BTC,DGD-ETH,DAT-ETH,ETC-USDT,OST-BTC,IOST-USDT,MCO-ETH,STORJ-BTC,HSR-BTC,QUN-ETH,SOC-BTC,ELF-BTC,CMT-ETH,VEN-BTC,GNT-BTC,DBC-BTC,STORJ-USDT,WAX-ETH,POWR-BTC,DTA-BTC,ZIL-BTC,MEE-BTC,NAS-BTC,TNB-ETH,SWFTC-ETH,LTC-BTC,EOS-BTC,LINK-ETH,IOST-BTC,YEE-BTC,RUFF-BTC,RDN-BTC,GNX-BTC,LET-ETH,EVX-ETH,AST-BTC,ACT-ETH,BCH-USDT,DASH-USDT,ICX-ETH,BCX-BTC,PROPY-ETH,DGD-BTC,XRP-USDT,ZIL-ETH,ZRX-BTC,THETA-ETH,ETH-BTC,DBC-ETH,REQ-ETH,WICC-ETH,SMT-BTC,RPX-BTC,TNT-ETH,ETH-USDT,ITC-BTC,OMG-BTC,PAY-ETH,VEN-USDT,MDS-BTC,ADX-BTC,ETC-BTC,AIDOC-BTC,KNC-BTC,HSR-USDT,QTUM-BTC,CVC-BTC,QSP-BTC,QSP-ETH,BTG-BTC,BAT-BTC,QASH-BTC,ITC-ETH,XEM-BTC,MANA-ETH,GAS-BTC,CHAT-BTC,BT1-BTC,OMG-ETH,RCN-ETH,UTK-ETH,TOPC-BTC,MTL-BTC,GNT-USDT,APPC-ETH,PROPY-BTC,WICC-BTC,RDN-ETH,ELF-USDT,YEE-ETH", + "EnabledPairs": "BTC-USDT", + "BaseCurrencies": "USD", "AssetTypes": "SPOT", "ConfigCurrencyPairFormat": { - "Uppercase": true + "Uppercase": true, + "Delimiter": "-" }, "RequestCurrencyPairFormat": { "Uppercase": false @@ -374,7 +375,7 @@ "AuthenticatedAPISupport": false, "APIKey": "Key", "APISecret": "Secret", - "AvailablePairs": "ICN_BTC,SALT_BTC,QRL_BTC,TIME_BTC,STORJ_BTC,PAY_USDT,AE_BTC,KNC_ETH,ANT_ETH,IND_ETH,SRN_USDT,BTC_USDT,SNM_USDT,MCO_USDT,TRX_ETH,ETH_USDT,MGO_BTC,MYST_BTC,SNGLS_BTC,STORJ_ETH,CVC_BTC,DGD_USDT,BCC_BTC,AE_ETH,GNO_BTC,GUP_ETH,ANT_BTC,BAT_USDT,AE_USDT,BNT_ETH,ADX_ETH,SAN_ETH,TKN_ETH,CFI_USDT,ADX_BTC,PRO_USDT,TRX_BTC,TKN_BTC,MCO_BTC,OMG_BTC,DNT_USDT,EDG_USDT,MYST_USDT,OMG_ETH,SAN_BTC,OAX_USDT,MANA_USDT,SALT_USDT,GUP_USDT,MGO_ETH,SALT_ETH,WINGS_USDT,OAX_ETH,KNC_USDT,REQ_USDT,TKN_USDT,BAT_ETH,CVC_USDT,STX_BTC,GNO_ETH,SNT_BTC,EOS_ETH,VEN_ETH,LTC_ETH,REP_ETH,PTOY_USDT,PTOY_BTC,NET_USDT,TNT_BTC,PAY_BTC,PRO_ETH,SRN_ETH,PRO_BTC,MCO_ETH,BMC_ETH,TNT_USDT,ENG_ETH,NEU_USDT,IND_BTC,REQ_BTC,LTC_USDT,WINGS_ETH,DNT_ETH,ETH_BTC,ANT_USDT,DGD_ETH,GNT_ETH,ENG_USDT,BAT_BTC,QRL_ETH,QRL_USDT,SNGLS_ETH,SNM_ETH,WINGS_BTC,WAVES_ETH,SNGLS_USDT,MANA_BTC,BNT_BTC,OMG_USDT,GNT_USDT,WAVES_USDT,SNT_ETH,XID_USDT,ICN_USDT,TAAS_BTC,MLN_BTC,TIME_USDT,WAVES_BTC,DASH_USDT,REP_BTC,NEU_BTC,STORJ_USDT,STX_USDT,VEN_BTC,MLN_USDT,KNC_BTC,REQ_ETH,SAN_USDT,BCC_USDT,TNT_ETH,EOS_USDT,XID_ETH,DGD_BTC,ZRX_BTC,TRST_USDT,REP_USDT,PAY_ETH,TIME_ETH,BNT_USDT,NET_BTC,DASH_ETH,ICN_ETH,TRST_BTC,BCC_ETH,STX_ETH,RLC_ETH,SRN_BTC,NET_ETH,MANA_ETH,RLC_USDT,CFI_BTC,TRX_USDT,AST_BTC,AST_USDT,RLC_BTC,DNT_BTC,VEN_USDT,BMC_BTC,EDG_BTC,OAX_BTC,IND_USDT,EDG_ETH,NEU_ETH,BMC_USDT,GNT_BTC,PTOY_ETH,SNT_USDT,ZRX_USDT,MLN_ETH,MGO_USDT,CFI_ETH,GUP_BTC,ZRX_ETH,MYST_ETH,ENG_BTC,DASH_BTC,EOS_BTC,CVC_ETH,AST_ETH,LTC_BTC,GNO_USDT,TAAS_ETH,XID_BTC,TRST_ETH,TAAS_USDT,SNM_BTC,ADX_USDT", + "AvailablePairs": "WAVES_USDT,EOS_USDT,VEN_USDT,SNGLS_ETH,DNT_ETH,GNO_ETH,GUP_USDT,DGD_ETH,PRO_USDT,ENG_BTC,DGD_USDT,MLN_ETH,GUP_BTC,SNT_USDT,CFI_BTC,MCO_USDT,STORJ_BTC,RLC_BTC,SNM_ETH,AE_USDT,ENG_ETH,ICN_BTC,MGO_ETH,AE_BTC,IND_ETH,STORJ_ETH,MYST_USDT,ETH_USDT,TKN_ETH,PAY_BTC,OMG_ETH,ZRX_USDT,REQ_ETH,DNT_BTC,SRN_ETH,GNT_ETH,WAVES_ETH,BAT_BTC,EOS_ETH,AST_BTC,TRST_ETH,CVC_BTC,NEU_ETH,GNT_USDT,XID_BTC,KNC_ETH,BTC_USDT,BAT_USDT,MLN_BTC,ICN_ETH,SAN_ETH,SALT_BTC,SALT_USDT,REP_ETH,GNO_USDT,RLC_ETH,ANT_BTC,STORJ_USDT,AST_ETH,LTC_USDT,TRST_USDT,GUP_ETH,CVC_USDT,SNM_USDT,BCC_ETH,REQ_USDT,LTC_BTC,TAAS_BTC,SAN_USDT,BMC_USDT,ETH_BTC,TKN_BTC,MGO_BTC,SNM_BTC,STX_ETH,PTOY_ETH,LTC_ETH,REP_BTC,MANA_BTC,DGD_BTC,PRO_BTC,AION_USDT,REQ_BTC,VEN_BTC,TRX_ETH,EOS_BTC,AION_BTC,VEN_ETH,ENG_USDT,SRN_BTC,INS_BTC,BNT_BTC,ADX_USDT,NET_ETH,INS_ETH,XID_ETH,SALT_ETH,EDG_ETH,WINGS_ETH,BNT_ETH,BCC_USDT,TNT_ETH,MANA_USDT,MYST_ETH,CFI_ETH,SNT_ETH,XID_USDT,DNT_USDT,INS_USDT,EDG_BTC,EDG_USDT,WAVES_BTC,WINGS_USDT,TKN_USDT,QRL_BTC,TNT_USDT,TRX_BTC,NEU_USDT,GNT_BTC,TIME_USDT,BAT_ETH,ADX_BTC,STX_USDT,SRN_USDT,AE_ETH,BMC_ETH,KNC_USDT,RLC_USDT,IND_BTC,DASH_BTC,TRX_USDT,OAX_ETH,NEU_BTC,BMC_BTC,MYST_BTC,PTOY_BTC,DASH_ETH,QRL_USDT,BNT_USDT,MGO_USDT,ANT_ETH,PTOY_USDT,SAN_BTC,NET_USDT,OMG_USDT,AION_ETH,TAAS_ETH,ADX_ETH,SNGLS_USDT,WINGS_BTC,REP_USDT,OAX_USDT,GNO_BTC,SNGLS_BTC,PAY_USDT,KNC_BTC,MCO_ETH,STX_BTC,AST_USDT,CFI_USDT,ZRX_BTC,QRL_ETH,PAY_ETH,BCC_BTC,IND_USDT,SNT_BTC,MCO_BTC,DASH_USDT,OMG_BTC,CVC_ETH,TIME_BTC,MLN_USDT,TIME_ETH,NET_BTC,TRST_BTC,ZRX_ETH,PRO_ETH,TAAS_USDT,MANA_ETH,TNT_BTC,ICN_USDT,ANT_USDT,OAX_BTC", "EnabledPairs": "ETH_BTC,LTC_BTC,DASH_BTC", "BaseCurrencies": "USD", "AssetTypes": "SPOT", @@ -500,4 +501,4 @@ } } ] -} +} \ No newline at end of file