├── .gitattributes
├── .gitignore
├── .npmignore
├── .travis.yml
├── CHANGELOG.md
├── CONTRIBUTING.md
├── ISSUE_TEMPLATE.md
├── LICENSE.txt
├── README.md
├── appveyor.yml
├── build
└── ccxt.browser.js
├── ccxt.browser.js
├── ccxt.d.ts
├── ccxt.js
├── ccxt.php
├── composer.json
├── composer.lock
├── convert-md-2-rst
├── countries.js
├── doc
├── .gitignore
├── FAQ.rst
├── Makefile
├── README.rst
├── _static
│ └── css
│ │ └── index.css
├── _templates
│ └── layout.html
├── conf.py
├── exchanges-by-country.rst
├── exchanges.rst
├── index.rst
├── install.rst
├── make.bat
└── manual.rst
├── examples
├── README.md
├── html
│ ├── basic-cors-proxy.html
│ ├── basic-inheritance.html
│ ├── basic-rate-limiting.html
│ └── basic.html
├── js
│ ├── README.md
│ ├── arbitrage-pairs.js
│ ├── balances.js
│ ├── basic-chart.js
│ ├── bcc-vs-bch.js
│ ├── binance-fetch-ohlcv.js
│ ├── binance-server-time.js
│ ├── bitfinex-fetch-trades.js
│ ├── bitfinex2-fetch-trades.js
│ ├── bittrex-balance.js
│ ├── bittrex-fetch-closed-orders-history.js
│ ├── builtin-rate-limiting-rest-poller.js
│ ├── bypass-cloudflare.js
│ ├── cli.js
│ ├── cors-proxy.js
│ ├── create-order-handle-errors.js
│ ├── credentials.json
│ ├── cryptopia-fetch-order-books.js
│ ├── custom-proxy-url.js
│ ├── exchange-capabilities.js
│ ├── exchanges.js
│ ├── fetch-create-deposit-address.js
│ ├── fetch-from-many-exchanges-simultaneously.js
│ ├── fetch-ohlcv-cex.js
│ ├── fetch-okex-futures.js
│ ├── fetch-orders.js
│ ├── fetch-ticker-from-multiple-exchanges.js
│ ├── fetch-ticker-where-available.js
│ ├── hitbtc2-withdraw.js
│ ├── instantiate-all-at-once.js
│ ├── instantiate-all-from-json.js
│ ├── live-orderbook.js
│ ├── live-ticker.js
│ ├── live-tickers.js
│ ├── load-all-symbols-at-once.js
│ ├── load-all-tickers-at-once.js
│ ├── market-status-and-currency-status.js
│ ├── okex-fetch-ohlcv-since-limit.js
│ ├── order-book-extra-level-depth-param.js
│ ├── poloniex-limits-amount-min.js
│ ├── proxy-round-robin.js
│ ├── search-all-exchanges.js
│ ├── symbols.js
│ └── tickers.js
├── php
│ ├── README.md
│ ├── arbitrage-pairs.php
│ ├── basic-error-handling.php
│ ├── binance-cancel-order.php
│ ├── binance-fetch-ticker.php
│ ├── binance-fetch-tickers.php
│ ├── bitfinex2-fetch-ohlcv-since-limit.php
│ ├── bitfinex2-fetch-ohlcv.php
│ ├── bitfinex2-fetch-trades-since.php
│ ├── bitmex-create-order.php
│ ├── built-in-rate-limiting-poller.php
│ ├── cli.php
│ ├── error-handling-message.php
│ ├── huobi-fetch-balance.php
│ ├── indodax-fetch-balance-create-order-cancel-order.php
│ ├── kraken-query-ledgers.php
│ ├── load-all-at-once.php
│ ├── order-book-level-depth-extra-param.php
│ ├── react-eventloop-with-rate-limiting.php
│ ├── symbols.php
│ ├── trading-view.php
│ └── vaultoro-fetch-balance.php
└── py
│ ├── README.md
│ ├── arbitrage-pairs.py
│ ├── asciichart.py
│ ├── async-balance-gdax.py
│ ├── async-balance.py
│ ├── async-balances.py
│ ├── async-basic-rate-limiter.py
│ ├── async-basic.py
│ ├── async-bitfinex-private-post-account-infos.py
│ ├── async-bitstamp-create-limit-buy-order.py
│ ├── async-bittrex-orderbook.py
│ ├── async-fetch-ticker.py
│ ├── async-gdax-fetch-order-book-continuously.py
│ ├── async-gdax-fetch-ticker-continuously.py
│ ├── async-generator-basic.py
│ ├── async-generator-multiple-tickers.py
│ ├── async-generator-ticker-poller.py
│ ├── async-instantiate-all-at-once.py
│ ├── async-orderbooks-from-multiple-exchanges-at-once.py
│ ├── async-theocean-orderbook.py
│ ├── async-theocean-tickers.py
│ ├── async-tickers-from-many-exchanges-at-once.py
│ ├── async-tickers.py
│ ├── async.py
│ ├── balance-gdax.py
│ ├── balance-kraken.py
│ ├── balances.py
│ ├── basic-chart.py
│ ├── basic-rate-limiting.py
│ ├── binance-fetch-ohlcv.py
│ ├── binance-test-order.py
│ ├── bitfinex-rate-limiting.py
│ ├── bitmex-create-order.py
│ ├── bitmex-fetch-ohlcv-with-extra-params.py
│ ├── bitmex-ohlcv-convert-5m-to-15m.py
│ ├── builtin-rate-limiting-long-poller.py
│ ├── bypass-cloudflare-with-aiocfscrape.py
│ ├── bypass-cloudflare-with-cookies.py
│ ├── bypass-cloudflare.py
│ ├── cli.py
│ ├── cryptopia-fetch-order-books.py
│ ├── exchanges.py
│ ├── fetch-bitfinex-ohlcv-history.py
│ ├── fetch-create-deposit-address.py
│ ├── fetch-gdax-ohlcv-sequentially.py
│ ├── fetch-ohlcv-cex.py
│ ├── fetch-ohlcv-kraken.py
│ ├── fetch-ohlcv-sequentially.py
│ ├── fetch-okex-futures.py
│ ├── fetch-orders.py
│ ├── filter-words.py
│ ├── gdax-fetch-my-trades-pagination.py
│ ├── hitbtc2-withdraw.py
│ ├── instantiate-all-at-once.py
│ ├── manual-rate-limiting-long-poller.py
│ ├── margin-leverage-order-kraken.py
│ ├── minimal-2-lines.py
│ ├── normalize-sparse-candle-timestamps.py
│ ├── order-book-extra-level-depth-param.py
│ ├── proxy-asyncio-aiohttp-python-3.py
│ ├── proxy-sync-python-requests-2-and-3.py
│ ├── record-future-history.py
│ ├── study-trade.py
│ ├── study1.py
│ ├── symbols.py
│ ├── test-server.py
│ ├── tickers.py
│ ├── triangle-trade-async.py
│ ├── triangle-trade.py
│ └── triangle.py
├── exchanges.cfg
├── export-exchanges.js
├── js
├── .eslintrc
├── _1broker.js
├── _1btcxe.js
├── acx.js
├── allcoin.js
├── anxpro.js
├── anybits.js
├── base
│ ├── .eslintrc.js
│ ├── Exchange.js
│ ├── Market.js
│ ├── errors.js
│ ├── functions.js
│ ├── functions
│ │ ├── crypto.js
│ │ ├── encode.js
│ │ ├── generic.js
│ │ ├── misc.js
│ │ ├── number.js
│ │ ├── orders.js
│ │ ├── platform.js
│ │ ├── string.js
│ │ ├── throttle.js
│ │ ├── time.js
│ │ └── type.js
│ └── journal.js
├── bcex.js
├── bibox.js
├── bigone.js
├── binance.js
├── bit2c.js
├── bitbank.js
├── bitbay.js
├── bitfinex.js
├── bitfinex2.js
├── bitflyer.js
├── bitforex.js
├── bithumb.js
├── bitkk.js
├── bitlish.js
├── bitmarket.js
├── bitmex.js
├── bitsane.js
├── bitso.js
├── bitstamp.js
├── bitstamp1.js
├── bittrex.js
├── bitz.js
├── bl3p.js
├── bleutrade.js
├── braziliex.js
├── btcalpha.js
├── btcbox.js
├── btcchina.js
├── btcexchange.js
├── btcmarkets.js
├── btctradeim.js
├── btctradeua.js
├── btcturk.js
├── btcx.js
├── bxinth.js
├── ccex.js
├── cex.js
├── chbtc.js
├── chilebit.js
├── cobinhood.js
├── coinbase.js
├── coinbaseprime.js
├── coinbasepro.js
├── coincheck.js
├── coinegg.js
├── coinex.js
├── coinexchange.js
├── coinfalcon.js
├── coinfloor.js
├── coingi.js
├── coinmarketcap.js
├── coinmate.js
├── coinnest.js
├── coinone.js
├── coinsecure.js
├── coinspot.js
├── cointiger.js
├── coolcoin.js
├── crypton.js
├── cryptopia.js
├── deribit.js
├── dsx.js
├── ethfinex.js
├── exmo.js
├── exx.js
├── fcoin.js
├── flowbtc.js
├── foxbit.js
├── fybse.js
├── fybsg.js
├── gatecoin.js
├── gateio.js
├── gdax.js
├── gemini.js
├── getbtc.js
├── hadax.js
├── hitbtc.js
├── hitbtc2.js
├── huobi.js
├── huobicny.js
├── huobipro.js
├── ice3x.js
├── independentreserve.js
├── indodax.js
├── itbit.js
├── jubi.js
├── kraken.js
├── kucoin.js
├── kuna.js
├── lakebtc.js
├── lbank.js
├── liqui.js
├── liquid.js
├── livecoin.js
├── luno.js
├── lykke.js
├── mercado.js
├── mixcoins.js
├── negociecoins.js
├── nova.js
├── okcoincny.js
├── okcoinusd.js
├── okex.js
├── paymium.js
├── poloniex.js
├── qryptos.js
├── quadrigacx.js
├── quoinex.js
├── rightbtc.js
├── southxchange.js
├── surbitcoin.js
├── test
│ ├── .eslintrc.js
│ ├── Exchange
│ │ ├── test.currency.js
│ │ ├── test.fetchBalance.js
│ │ ├── test.fetchClosedOrders.js
│ │ ├── test.fetchCurrencies.js
│ │ ├── test.fetchFundingFees.js
│ │ ├── test.fetchL2OrderBook.js
│ │ ├── test.fetchMarkets.js
│ │ ├── test.fetchMyTrades.js
│ │ ├── test.fetchOHLCV.js
│ │ ├── test.fetchOpenOrders.js
│ │ ├── test.fetchOrderBook.js
│ │ ├── test.fetchOrderBooks.js
│ │ ├── test.fetchOrders.js
│ │ ├── test.fetchTicker.js
│ │ ├── test.fetchTickers.js
│ │ ├── test.fetchTrades.js
│ │ ├── test.fetchTradingFees.js
│ │ ├── test.market.js
│ │ ├── test.order.js
│ │ ├── test.orderbook.js
│ │ ├── test.ticker.js
│ │ ├── test.trade.js
│ │ └── tmp.test.fetchOHLCV.js
│ ├── base
│ │ ├── .eslintrc
│ │ ├── functions
│ │ │ ├── test.datetime.js
│ │ │ ├── test.generic.js
│ │ │ ├── test.number.js
│ │ │ ├── test.time.js
│ │ │ └── test.type.js
│ │ └── test.base.js
│ ├── errors
│ │ ├── test.InsufficientFunds.js
│ │ ├── test.InvalidNonce.js
│ │ ├── test.InvalidOrder.js
│ │ └── test.OrderNotFound.js
│ ├── test.js
│ └── test.timeout_hang.js
├── theocean.js
├── therock.js
├── tidebit.js
├── tidex.js
├── uex.js
├── urdubit.js
├── vaultoro.js
├── vbtc.js
├── virwox.js
├── wex.js
├── xbtce.js
├── yobit.js
├── yunbi.js
├── zaif.js
└── zb.js
├── keys.json
├── package.json
├── php
├── AccountSuspended.php
├── AddressPending.php
├── ArgumentsRequired.php
├── AuthenticationError.php
├── BadRequest.php
├── BadResponse.php
├── BaseError.php
├── CancelPending.php
├── DDoSProtection.php
├── Exchange.php
├── ExchangeError.php
├── ExchangeNotAvailable.php
├── InsufficientFunds.php
├── InvalidAddress.php
├── InvalidNonce.php
├── InvalidOrder.php
├── NetworkError.php
├── NotSupported.php
├── NullResponse.php
├── OrderImmediatelyFillable.php
├── OrderNotCached.php
├── OrderNotFillable.php
├── OrderNotFound.php
├── PermissionDenied.php
├── RequestTimeout.php
├── _1broker.php
├── _1btcxe.php
├── acx.php
├── allcoin.php
├── anxpro.php
├── anybits.php
├── bcex.php
├── bibox.php
├── bigone.php
├── binance.php
├── bit2c.php
├── bitbank.php
├── bitbay.php
├── bitfinex.php
├── bitfinex2.php
├── bitflyer.php
├── bitforex.php
├── bithumb.php
├── bitkk.php
├── bitlish.php
├── bitmarket.php
├── bitmex.php
├── bitsane.php
├── bitso.php
├── bitstamp.php
├── bitstamp1.php
├── bittrex.php
├── bitz.php
├── bl3p.php
├── bleutrade.php
├── braziliex.php
├── btcalpha.php
├── btcbox.php
├── btcchina.php
├── btcexchange.php
├── btcmarkets.php
├── btctradeim.php
├── btctradeua.php
├── btcturk.php
├── btcx.php
├── bxinth.php
├── ccex.php
├── cex.php
├── chbtc.php
├── chilebit.php
├── cobinhood.php
├── coinbase.php
├── coinbaseprime.php
├── coinbasepro.php
├── coincheck.php
├── coinegg.php
├── coinex.php
├── coinexchange.php
├── coinfalcon.php
├── coinfloor.php
├── coingi.php
├── coinmarketcap.php
├── coinmate.php
├── coinnest.php
├── coinone.php
├── coinsecure.php
├── coinspot.php
├── cointiger.php
├── coolcoin.php
├── crypton.php
├── cryptopia.php
├── deribit.php
├── dsx.php
├── ethfinex.php
├── exmo.php
├── exx.php
├── fcoin.php
├── flowbtc.php
├── foxbit.php
├── fybse.php
├── fybsg.php
├── gatecoin.php
├── gateio.php
├── gdax.php
├── gemini.php
├── getbtc.php
├── hadax.php
├── hitbtc.php
├── hitbtc2.php
├── huobi.php
├── huobicny.php
├── huobipro.php
├── ice3x.php
├── independentreserve.php
├── indodax.php
├── itbit.php
├── jubi.php
├── kraken.php
├── kucoin.php
├── kuna.php
├── lakebtc.php
├── lbank.php
├── liqui.php
├── liquid.php
├── livecoin.php
├── luno.php
├── lykke.php
├── mercado.php
├── mixcoins.php
├── negociecoins.php
├── nova.php
├── okcoincny.php
├── okcoinusd.php
├── okex.php
├── paymium.php
├── poloniex.php
├── qryptos.php
├── quadrigacx.php
├── quoinex.php
├── rightbtc.php
├── southxchange.php
├── surbitcoin.php
├── test
│ ├── ExchangeTest.php
│ ├── bootstrap.php
│ ├── decimal_to_precision.php
│ ├── syntax.php
│ ├── test.php
│ └── test_exchange_datetime_functions.php
├── theocean.php
├── therock.php
├── tidebit.php
├── tidex.php
├── uex.php
├── urdubit.php
├── vaultoro.php
├── vbtc.php
├── virwox.php
├── wex.php
├── xbtce.php
├── yobit.php
├── yunbi.php
├── zaif.php
└── zb.php
├── phpunit.xml.dist
├── postinstall.js
├── push-wiki.sh
├── push.sh
├── python
├── MANIFEST.in
├── README.rst
├── ccxt
│ ├── _1broker.py
│ ├── _1btcxe.py
│ ├── __init__.py
│ ├── acx.py
│ ├── allcoin.py
│ ├── anxpro.py
│ ├── anybits.py
│ ├── async_support
│ │ ├── _1broker.py
│ │ ├── _1btcxe.py
│ │ ├── __init__.py
│ │ ├── acx.py
│ │ ├── allcoin.py
│ │ ├── anxpro.py
│ │ ├── anybits.py
│ │ ├── base
│ │ │ ├── __init__.py
│ │ │ ├── exchange.py
│ │ │ └── throttle.py
│ │ ├── bcex.py
│ │ ├── bibox.py
│ │ ├── bigone.py
│ │ ├── binance.py
│ │ ├── bit2c.py
│ │ ├── bitbank.py
│ │ ├── bitbay.py
│ │ ├── bitfinex.py
│ │ ├── bitfinex2.py
│ │ ├── bitflyer.py
│ │ ├── bitforex.py
│ │ ├── bithumb.py
│ │ ├── bitkk.py
│ │ ├── bitlish.py
│ │ ├── bitmarket.py
│ │ ├── bitmex.py
│ │ ├── bitsane.py
│ │ ├── bitso.py
│ │ ├── bitstamp.py
│ │ ├── bitstamp1.py
│ │ ├── bittrex.py
│ │ ├── bitz.py
│ │ ├── bl3p.py
│ │ ├── bleutrade.py
│ │ ├── braziliex.py
│ │ ├── btcalpha.py
│ │ ├── btcbox.py
│ │ ├── btcchina.py
│ │ ├── btcexchange.py
│ │ ├── btcmarkets.py
│ │ ├── btctradeim.py
│ │ ├── btctradeua.py
│ │ ├── btcturk.py
│ │ ├── btcx.py
│ │ ├── bxinth.py
│ │ ├── ccex.py
│ │ ├── cex.py
│ │ ├── chbtc.py
│ │ ├── chilebit.py
│ │ ├── cobinhood.py
│ │ ├── coinbase.py
│ │ ├── coinbaseprime.py
│ │ ├── coinbasepro.py
│ │ ├── coincheck.py
│ │ ├── coinegg.py
│ │ ├── coinex.py
│ │ ├── coinexchange.py
│ │ ├── coinfalcon.py
│ │ ├── coinfloor.py
│ │ ├── coingi.py
│ │ ├── coinmarketcap.py
│ │ ├── coinmate.py
│ │ ├── coinnest.py
│ │ ├── coinone.py
│ │ ├── coinsecure.py
│ │ ├── coinspot.py
│ │ ├── cointiger.py
│ │ ├── coolcoin.py
│ │ ├── crypton.py
│ │ ├── cryptopia.py
│ │ ├── deribit.py
│ │ ├── dsx.py
│ │ ├── ethfinex.py
│ │ ├── exmo.py
│ │ ├── exx.py
│ │ ├── fcoin.py
│ │ ├── flowbtc.py
│ │ ├── foxbit.py
│ │ ├── fybse.py
│ │ ├── fybsg.py
│ │ ├── gatecoin.py
│ │ ├── gateio.py
│ │ ├── gdax.py
│ │ ├── gemini.py
│ │ ├── getbtc.py
│ │ ├── hadax.py
│ │ ├── hitbtc.py
│ │ ├── hitbtc2.py
│ │ ├── huobi.py
│ │ ├── huobicny.py
│ │ ├── huobipro.py
│ │ ├── ice3x.py
│ │ ├── independentreserve.py
│ │ ├── indodax.py
│ │ ├── itbit.py
│ │ ├── jubi.py
│ │ ├── kraken.py
│ │ ├── kucoin.py
│ │ ├── kuna.py
│ │ ├── lakebtc.py
│ │ ├── lbank.py
│ │ ├── liqui.py
│ │ ├── liquid.py
│ │ ├── livecoin.py
│ │ ├── luno.py
│ │ ├── lykke.py
│ │ ├── mercado.py
│ │ ├── mixcoins.py
│ │ ├── negociecoins.py
│ │ ├── nova.py
│ │ ├── okcoincny.py
│ │ ├── okcoinusd.py
│ │ ├── okex.py
│ │ ├── paymium.py
│ │ ├── poloniex.py
│ │ ├── qryptos.py
│ │ ├── quadrigacx.py
│ │ ├── quoinex.py
│ │ ├── rightbtc.py
│ │ ├── southxchange.py
│ │ ├── surbitcoin.py
│ │ ├── theocean.py
│ │ ├── therock.py
│ │ ├── tidebit.py
│ │ ├── tidex.py
│ │ ├── uex.py
│ │ ├── urdubit.py
│ │ ├── vaultoro.py
│ │ ├── vbtc.py
│ │ ├── virwox.py
│ │ ├── wex.py
│ │ ├── xbtce.py
│ │ ├── yobit.py
│ │ ├── yunbi.py
│ │ ├── zaif.py
│ │ └── zb.py
│ ├── base
│ │ ├── __init__.py
│ │ ├── decimal_to_precision.py
│ │ ├── errors.py
│ │ └── exchange.py
│ ├── bcex.py
│ ├── bibox.py
│ ├── bigone.py
│ ├── binance.py
│ ├── bit2c.py
│ ├── bitbank.py
│ ├── bitbay.py
│ ├── bitfinex.py
│ ├── bitfinex2.py
│ ├── bitflyer.py
│ ├── bitforex.py
│ ├── bithumb.py
│ ├── bitkk.py
│ ├── bitlish.py
│ ├── bitmarket.py
│ ├── bitmex.py
│ ├── bitsane.py
│ ├── bitso.py
│ ├── bitstamp.py
│ ├── bitstamp1.py
│ ├── bittrex.py
│ ├── bitz.py
│ ├── bl3p.py
│ ├── bleutrade.py
│ ├── braziliex.py
│ ├── btcalpha.py
│ ├── btcbox.py
│ ├── btcchina.py
│ ├── btcexchange.py
│ ├── btcmarkets.py
│ ├── btctradeim.py
│ ├── btctradeua.py
│ ├── btcturk.py
│ ├── btcx.py
│ ├── bxinth.py
│ ├── ccex.py
│ ├── cex.py
│ ├── chbtc.py
│ ├── chilebit.py
│ ├── cobinhood.py
│ ├── coinbase.py
│ ├── coinbaseprime.py
│ ├── coinbasepro.py
│ ├── coincheck.py
│ ├── coinegg.py
│ ├── coinex.py
│ ├── coinexchange.py
│ ├── coinfalcon.py
│ ├── coinfloor.py
│ ├── coingi.py
│ ├── coinmarketcap.py
│ ├── coinmate.py
│ ├── coinnest.py
│ ├── coinone.py
│ ├── coinsecure.py
│ ├── coinspot.py
│ ├── cointiger.py
│ ├── coolcoin.py
│ ├── crypton.py
│ ├── cryptopia.py
│ ├── deribit.py
│ ├── dsx.py
│ ├── ethfinex.py
│ ├── exmo.py
│ ├── exx.py
│ ├── fcoin.py
│ ├── flowbtc.py
│ ├── foxbit.py
│ ├── fybse.py
│ ├── fybsg.py
│ ├── gatecoin.py
│ ├── gateio.py
│ ├── gdax.py
│ ├── gemini.py
│ ├── getbtc.py
│ ├── hadax.py
│ ├── hitbtc.py
│ ├── hitbtc2.py
│ ├── huobi.py
│ ├── huobicny.py
│ ├── huobipro.py
│ ├── ice3x.py
│ ├── independentreserve.py
│ ├── indodax.py
│ ├── itbit.py
│ ├── jubi.py
│ ├── kraken.py
│ ├── kucoin.py
│ ├── kuna.py
│ ├── lakebtc.py
│ ├── lbank.py
│ ├── liqui.py
│ ├── liquid.py
│ ├── livecoin.py
│ ├── luno.py
│ ├── lykke.py
│ ├── mercado.py
│ ├── mixcoins.py
│ ├── negociecoins.py
│ ├── nova.py
│ ├── okcoincny.py
│ ├── okcoinusd.py
│ ├── okex.py
│ ├── paymium.py
│ ├── poloniex.py
│ ├── qryptos.py
│ ├── quadrigacx.py
│ ├── quoinex.py
│ ├── rightbtc.py
│ ├── southxchange.py
│ ├── surbitcoin.py
│ ├── theocean.py
│ ├── therock.py
│ ├── tidebit.py
│ ├── tidex.py
│ ├── uex.py
│ ├── urdubit.py
│ ├── vaultoro.py
│ ├── vbtc.py
│ ├── virwox.py
│ ├── wex.py
│ ├── xbtce.py
│ ├── yobit.py
│ ├── yunbi.py
│ ├── zaif.py
│ └── zb.py
├── deploy.sh
├── setup.cfg
├── setup.py
├── test
│ ├── test.py
│ ├── test_async.py
│ ├── test_calculate_fee.py
│ ├── test_decimal_to_precision.py
│ ├── test_deep_extend.py
│ └── test_exchange_datetime_functions.py
└── tox.ini
├── run-tests.js
├── setup.cfg
├── transpile.js
├── update-badges.js
├── vss.js
└── wiki
├── Certification.md
├── Exchange-Markets-By-Country.md
├── Exchange-Markets.md
├── FAQ.md
├── Install.md
├── Manual.md
└── README.md
/.gitattributes:
--------------------------------------------------------------------------------
1 | *.* text eol=lf
2 | ccxt/exchanges.py linguis-generated=true
3 | ccxt/async/exchanges.py linguist-generated=true
4 | ccxt/async/__init__.py linguist-generated=false
5 | ccxt/async/exchange.py linguist-generated=false
6 | ccxt/__init__.py linguist-generated=false
7 | ccxt/errors.py linguist-generated=false
8 | ccxt/exchange.py linguist-generated=false
9 | ccxt/version.py linguist-generated=false
10 | ccxt.js linguist-generated=false
11 | ccxt.php linguist-generated=false
12 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | # You shouldn't edit these files, as they're generated automatically from ccxt.js by build scripts.
3 | # Please read https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#multilanguage-support for details.
4 | #
5 | .vscode
6 | build/*
7 | node_modules/
8 | npm-debug.log
9 | .DS_Store
10 | config.js
11 | config.py
12 | config.php
13 | dist/
14 | ccxt.egg-info/
15 | tmp/
16 | *.pyc
17 | .tox/
18 | coverage
19 | .nyc_output
20 | travis-keys.sh
21 | ccxt.wiki/
22 | package-lock.json
23 | exchanges.json
24 | ccxt.sublime-workspace
25 | .idea
26 | yarn.lock
27 | keys.local.json
28 | nbproject/
29 | vendor/
30 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | ccxt.egg-info/
2 | ccxt.wiki/
3 | dist/
4 | examples/php/
5 | examples/py/
6 | node_modules/
7 | python/
8 | php/
9 | tmp/
10 | .tox/
11 | .DS_Store
12 | .nyc_output
13 | *.php
14 | *.py
15 | *.pyc
16 | ccxt.sublime-workspace
17 | composer.*
18 | config.js
19 | convert-md-2-rst
20 | coverage
21 | exchanges.json
22 | ISSUE_TEMPLATE.md
23 | keys.local.json
24 | npm-debug.log
25 | package-lock.json
26 | travis-keys.sh
27 |
--------------------------------------------------------------------------------
/ISSUE_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | ATTENTION!!!
2 |
3 | MUST READ THIS BEFORE SUBMITTING ISSUES:
4 |
5 | https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-submit-an-issue
6 |
7 | - OS:
8 | - Programming Language version:
9 | - CCXT version:
10 | - Exchange:
11 | - Method:
12 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Igor Kroitor
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/ccxt.browser.js:
--------------------------------------------------------------------------------
1 | /* A entry point for the browser bundle version. This gets compiled by:
2 |
3 | browserify --debug ./ccxt.browser.js > ./build/ccxt.browser.js
4 | */
5 |
6 | window.ccxt = require ('./ccxt')
--------------------------------------------------------------------------------
/ccxt.php:
--------------------------------------------------------------------------------
1 | NUL 2>NUL
17 | if errorlevel 9009 (
18 | echo.
19 | echo.The Sphinx module was not found. Make sure you have Sphinx installed,
20 | echo.then set the SPHINXBUILD environment variable to point to the full
21 | echo.path of the 'sphinx-build' executable. Alternatively you may add the
22 | echo.Sphinx directory to PATH.
23 | echo.
24 | echo.If you don't have Sphinx installed, grab it from
25 | echo.http://sphinx-doc.org/
26 | exit /b 1
27 | )
28 |
29 | %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS%
30 | goto end
31 |
32 | :help
33 | %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS%
34 |
35 | :end
36 | popd
37 |
--------------------------------------------------------------------------------
/examples/html/basic-cors-proxy.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | CCXT Basic example for the browser
5 |
6 |
29 |
30 |
31 | Hello, CCXT!
32 |
33 |
34 |
--------------------------------------------------------------------------------
/examples/html/basic-inheritance.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | CCXT Basic example for the browser
5 |
6 |
10 |
42 |
43 |
44 | Hello, CCXT!
45 |
46 |
47 |
--------------------------------------------------------------------------------
/examples/html/basic-rate-limiting.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | CCXT Basic example for the browser
5 |
6 |
44 |
45 |
46 | Hello, CCXT!
47 |
48 |
49 |
--------------------------------------------------------------------------------
/examples/html/basic.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | CCXT Basic example for the browser
5 |
6 |
38 |
39 |
40 | Hello, CCXT!
41 |
42 |
43 |
--------------------------------------------------------------------------------
/examples/js/README.md:
--------------------------------------------------------------------------------
1 | # CCXT JavaScript Examples
2 |
3 | These examples might require the following super-useful high-quality Node.js modules by [xpl](https://github.com/xpl):
4 |
5 | - [ansicolor](https://github.com/xpl/ansicolor): A quality JavaScript library for the ANSI color/style management ([ansicolor @ npm](https://npmjs.com/package/ansicolor))
6 | - [as-table](https://github.com/xpl/as-table): A simple function that prints objects as ASCII tables ([as-table @ npm](https://npmjs.com/package/as-table))
7 | - [ololog](https://github.com/xpl/ololog): Platform-agnostic logging with blackjack and hookers ([ololog @ npm](https://npmjs.com/package/ololog))
8 |
9 | All of the modules above are installed with the ccxt library devDependencies by npm automatically.
10 |
11 | To run the ccxt JavaScript examples from any folder type in console:
12 |
13 | ```shell
14 | node path/to/example.js # substitute for actual filename here
15 | ```
16 |
--------------------------------------------------------------------------------
/examples/js/basic-chart.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | const ccxt = require ('../../ccxt.js')
4 | const asciichart = require ('asciichart')
5 | const asTable = require ('as-table')
6 | const log = require ('ololog').configure ({ locate: false })
7 |
8 | require ('ansicolor').nice
9 |
10 | //-----------------------------------------------------------------------------
11 |
12 | ;(async function main () {
13 |
14 | // experimental, not yet implemented for all exchanges
15 | // your contributions are welcome ;)
16 |
17 | const index = 4 // [ timestamp, open, high, low, close, volume ]
18 | const ohlcv = await new ccxt.okcoinusd ().fetchOHLCV ('BTC/USD', '15m')
19 | const lastPrice = ohlcv[ohlcv.length - 1][index] // closing price
20 | const series = ohlcv.map (x => x[index]) // closing price
21 | const bitcoinRate = ('₿ = $' + lastPrice).green
22 | const chart = asciichart.plot (series, { height: 15, padding: ' ' })
23 | log.yellow ("\n" + chart, bitcoinRate, "\n")
24 | process.exit ()
25 |
26 | }) ()
--------------------------------------------------------------------------------
/examples/js/binance-fetch-ohlcv.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | const ccxt = require ('../../ccxt.js')
4 | const asciichart = require ('asciichart')
5 | const asTable = require ('as-table')
6 | const log = require ('ololog').configure ({ locate: false })
7 |
8 | require ('ansicolor').nice
9 |
10 | //-----------------------------------------------------------------------------
11 |
12 | ;(async function main () {
13 |
14 | const index = 4 // [ timestamp, open, high, low, close, volume ]
15 |
16 |
17 | const ohlcv = await new ccxt.binance ().fetchOHLCV ('BTC/USDT', '1h')
18 |
19 |
20 | const lastPrice = ohlcv[ohlcv.length - 1][index] // closing price
21 | const series = ohlcv.slice (-80).map (x => x[index]) // closing price
22 | const bitcoinRate = ('₿ = $' + lastPrice).green
23 | const chart = asciichart.plot (series, { height: 15, padding: ' ' })
24 | log.yellow ("\n" + chart, bitcoinRate, "\n")
25 | process.exit ()
26 |
27 | }) ()
--------------------------------------------------------------------------------
/examples/js/binance-server-time.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const log = require ('ololog').configure ({ locate: false })
4 | const ccxt = require('../../ccxt')
5 |
6 | const binance = new ccxt['binance'] ()
7 | const recvWindow = binance.security.recvWindow
8 | const aheadWindow = 1000
9 |
10 | async function test () {
11 | const localStartTime = Date.now ()
12 | const { serverTime } = await binance.publicGetTime ()
13 | const localFinishTime = Date.now ()
14 | const estimatedLandingTime = (localFinishTime + localStartTime) / 2
15 |
16 | const diff = serverTime - estimatedLandingTime
17 |
18 | log (`request departure time: ${binance.iso8601 (localStartTime)}`)
19 | log (`response arrival time: ${binance.iso8601 (localFinishTime)}`)
20 | log (`server time: ${binance.iso8601 (serverTime)}`)
21 | log (`request landing time (est): ${binance.iso8601 (estimatedLandingTime)}, ${Math.abs (diff)} ms ${Math.sign (diff) > 0 ? 'behind' : 'ahead of'} server`)
22 | log ('\n')
23 |
24 | if (diff < -aheadWindow) {
25 | log.error.red (`your request will likely be rejected if local time is ahead of the server's time for more than ${aheadWindow} ms \n`)
26 | }
27 |
28 | if (diff > recvWindow) {
29 | log.error.red (`your request will likely be rejected if local time is behind server time for more than ${recvWindow} ms\n`)
30 | }
31 | }
32 |
33 | test ();
34 |
--------------------------------------------------------------------------------
/examples/js/bitfinex-fetch-trades.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | // ----------------------------------------------------------------------------
4 |
5 | const ccxt = require ('../../ccxt.js')
6 | , log = require ('ololog')
7 | , asTable = require ('as-table').configure ({ delimiter: ' | ' })
8 |
9 | // ----------------------------------------------------------------------------
10 |
11 | ;(async () => {
12 |
13 | const exchange = new ccxt.bitfinex ({
14 | 'verbose': process.argv.includes ('--verbose'),
15 | 'timeout': 60000,
16 | })
17 |
18 | try {
19 |
20 | const response = await exchange.fetchTrades ('ETH/BTC', 1518983548636 - 2 * 24 * 60 * 60 * 1000)
21 | log (asTable (response))
22 | log (response.length.toString (), 'trades')
23 | log.green ('Succeeded.')
24 |
25 | } catch (e) {
26 |
27 | log.dim ('--------------------------------------------------------')
28 | log (e.constructor.name, e.message)
29 | log.dim ('--------------------------------------------------------')
30 | log.dim (exchange.last_http_response)
31 | log.error ('Failed.')
32 | }
33 |
34 | }) ()
--------------------------------------------------------------------------------
/examples/js/bitfinex2-fetch-trades.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | // ----------------------------------------------------------------------------
4 |
5 | const ccxt = require ('../../ccxt.js')
6 | , log = require ('ololog')
7 | , asTable = require ('as-table').configure ({ delimiter: ' | ' })
8 |
9 | // ----------------------------------------------------------------------------
10 |
11 | ;(async () => {
12 |
13 | const exchange = new ccxt.bitfinex2 ({
14 | 'verbose': process.argv.includes ('--verbose'),
15 | 'timeout': 60000,
16 | })
17 |
18 | try {
19 |
20 | const response = await exchange.fetchTrades ('ETH/BTC', 1518983548636 - 2 * 24 * 60 * 60 * 1000)
21 | log (asTable (response))
22 | log (response.length.toString (), 'trades')
23 | log.green ('Succeeded.')
24 |
25 | } catch (e) {
26 |
27 | log.dim ('--------------------------------------------------------')
28 | log (e.constructor.name, e.message)
29 | log.dim ('--------------------------------------------------------')
30 | log.dim (exchange.last_http_response)
31 | log.error ('Failed.')
32 | }
33 |
34 | }) ()
--------------------------------------------------------------------------------
/examples/js/bittrex-balance.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | const ccxt = require ('../../ccxt.js')
4 | const asTable = require ('as-table')
5 | const log = require ('ololog').configure ({ locate: false })
6 |
7 | require ('ansicolor').nice
8 |
9 | let sleep = (ms) => new Promise (resolve => setTimeout (resolve, ms))
10 |
11 | ;(async () => {
12 |
13 | // instantiate the exchange
14 | let exchange = new ccxt.bittrex ({
15 | "apiKey": "471b47a06c384e81b24072e9a8739064",
16 | "secret": "694025686e9445589787e8ca212b4cff",
17 | })
18 |
19 |
20 | try {
21 |
22 | // fetch account balance from the exchange
23 | let balance = await exchange.fetchBalance ()
24 |
25 | // output the result
26 | log (exchange.name.green, 'balance', balance)
27 |
28 | } catch (e) {
29 |
30 | if (e instanceof ccxt.DDoSProtection || e.message.includes ('ECONNRESET')) {
31 | log.bright.yellow ('[DDoS Protection] ' + e.message)
32 | } else if (e instanceof ccxt.RequestTimeout) {
33 | log.bright.yellow ('[Request Timeout] ' + e.message)
34 | } else if (e instanceof ccxt.AuthenticationError) {
35 | log.bright.yellow ('[Authentication Error] ' + e.message)
36 | } else if (e instanceof ccxt.ExchangeNotAvailable) {
37 | log.bright.yellow ('[Exchange Not Available Error] ' + e.message)
38 | } else if (e instanceof ccxt.ExchangeError) {
39 | log.bright.yellow ('[Exchange Error] ' + e.message)
40 | } else if (e instanceof ccxt.NetworkError) {
41 | log.bright.yellow ('[Network Error] ' + e.message)
42 | } else {
43 | throw e;
44 | }
45 | }
46 |
47 | }) ()
--------------------------------------------------------------------------------
/examples/js/builtin-rate-limiting-rest-poller.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | const ccxt = require ('../../ccxt.js')
4 | const log = require ('ololog')
5 | const ansi = require ('ansicolor').nice
6 | const asTable = require ('as-table')
7 |
8 | const exchange = new ccxt.gdax ({ enableRateLimit: true })
9 | const repeat = 100
10 |
11 | async function test (symbol) {
12 |
13 | for (let i = 0; i < repeat; i++) {
14 | let ticker = await exchange.fetchTicker (symbol)
15 | log (exchange.id.green, exchange.iso8601 (exchange.milliseconds ()), ticker['datetime'], symbol.green, ticker['last'])
16 | }
17 | }
18 |
19 | const concurrent = [
20 | test ('BTC/USD'),
21 | test ('ETH/BTC'),
22 | test ('ETH/USD')
23 | ]
24 |
25 | Promise.all (concurrent)
--------------------------------------------------------------------------------
/examples/js/bypass-cloudflare.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | // ----------------------------------------------------------------------------
4 |
5 | const cloudscraper = require ('cloudscraper')
6 | , ccxt = require ('../../ccxt.js')
7 |
8 | // ----------------------------------------------------------------------------
9 |
10 | const scrapeCloudflareHttpHeaderCookie = (url) =>
11 |
12 | (new Promise ((resolve, reject) =>
13 |
14 | (cloudscraper.get (url, function (error, response, body) {
15 |
16 | if (error) {
17 |
18 | reject (error)
19 |
20 | } else {
21 |
22 | resolve (response.request.headers)
23 | }
24 | }))
25 | ))
26 |
27 | // ----------------------------------------------------------------------------
28 |
29 | ;(async () => {
30 |
31 | const exchange = new ccxt.braziliex ({
32 | 'verbose': process.argv.includes ('--verbose'),
33 | 'timeout': 60000,
34 | })
35 |
36 | exchange.headers = await scrapeCloudflareHttpHeaderCookie (exchange.urls.www)
37 |
38 | // console.log (exchange.headers)
39 |
40 | try {
41 |
42 | const response = await exchange.loadMarkets ()
43 | console.log (response);
44 | console.log ('Succeeded.')
45 |
46 | } catch (e) {
47 |
48 | console.log ('--------------------------------------------------------')
49 | console.log (e.constructor.name, e.message)
50 | console.log ('--------------------------------------------------------')
51 | console.log (exchange.last_http_response)
52 | console.log ('Failed.')
53 | }
54 |
55 | }) ()
--------------------------------------------------------------------------------
/examples/js/cors-proxy.js:
--------------------------------------------------------------------------------
1 | // JavaScript CORS Proxy
2 | // Save this in a file like cors.js and run with `node cors [port]`
3 | // It will listen for your requests on the port you pass in command line or port 8080 by default
4 | let port = (process.argv.length > 2) ? parseInt (process.argv[2]) : 4080 // default
5 | require ('cors-anywhere').createServer ().listen (port, 'localhost')
6 |
--------------------------------------------------------------------------------
/examples/js/create-order-handle-errors.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | // ----------------------------------------------------------------------------
4 |
5 | const ccxt = require ('../../ccxt.js')
6 |
7 | // ----------------------------------------------------------------------------
8 |
9 | ;(async () => {
10 |
11 | const exchange = new ccxt.bittrex ({
12 | 'apiKey': 'YOUR_API_KEY',
13 | 'secret': 'YOUR_SECRET_KEY',
14 | 'verbose': false, // set to true to see more debugging output
15 | 'timeout': 60000,
16 | 'enableRateLimit': true, // add this
17 | })
18 |
19 | // try to load markets first, retry on request timeouts until it succeeds:
20 |
21 | while (true) {
22 |
23 | try {
24 |
25 | await exchange.loadMarkets ();
26 | break;
27 |
28 | } catch (e) {
29 |
30 | if (e instanceof ccxt.RequestTimeout)
31 | console.log (exchange.iso8601 (Date.now ()), e.constructor.name, e.message)
32 | }
33 | }
34 |
35 | const symbol = 'ETH/BTC'
36 | const orderType = 'limit'
37 | const side = 'sell'
38 | const amount = 0.321;
39 | const price = 0.123;
40 |
41 | // try just one attempt to create an order
42 |
43 | try {
44 |
45 | const response = await exchange.createOrder (symbol, orderType, side, amount, price);
46 | console.log (response);
47 | console.log ('Succeeded');
48 |
49 | } catch (e) {
50 |
51 | console.log (exchange.iso8601 (Date.now ()), e.constructor.name, e.message)
52 | console.log ('Failed');
53 |
54 | }
55 |
56 | }) ()
57 |
--------------------------------------------------------------------------------
/examples/js/credentials.json:
--------------------------------------------------------------------------------
1 | {
2 | "hitbtc": { "apiKey": "b6aad581670b30fb25d1c91cdbe8ca5c", "secret": "fa394ced37a488f9b5826a2d9ce39ae3" },
3 | "bitso": { "apiKey": "xZnHRmdlgJ", "secret": "e156bb7f7ab3a831afbc7a80f7866b9e" },
4 | "coincheck": { "apiKey": "dCyzY2T6w0DFhaco", "secret": "JpI0eMmxfa0tEpk3X-dNwyclSASJkl-S" }
5 | }
6 |
--------------------------------------------------------------------------------
/examples/js/cryptopia-fetch-order-books.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | // ----------------------------------------------------------------------------
4 |
5 | const cloudscraper = require ('cloudscraper')
6 | , ccxt = require ('../../ccxt.js')
7 |
8 | // ----------------------------------------------------------------------------
9 |
10 | ;(async () => {
11 |
12 | const exchange = new ccxt.cryptopia ({
13 | 'verbose': process.argv.includes ('--verbose'),
14 | 'timeout': 60000,
15 | })
16 |
17 | try {
18 |
19 | const response = await exchange.fetchOrderBooks ([
20 | 'ETH/BTC',
21 | 'LTC/BTC',
22 | 'OMG/BTC',
23 | ])
24 | console.log (response);
25 | console.log ('Succeeded.')
26 |
27 | } catch (e) {
28 |
29 | console.log ('--------------------------------------------------------')
30 | console.log (e.constructor.name, e.message)
31 | console.log ('--------------------------------------------------------')
32 | console.log (exchange.last_http_response)
33 | console.log ('Failed.')
34 | }
35 |
36 | }) ()
--------------------------------------------------------------------------------
/examples/js/custom-proxy-url.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | const ccxt = require ('../../ccxt.js')
4 |
5 | ;(async function main () {
6 |
7 | const kraken1 = new ccxt.kraken ({
8 | proxy: function (url) {
9 | return 'https://example.com/?url=' + encodeURIComponent (url)
10 | },
11 | })
12 |
13 | console.log (await kraken1.loadMarkets ())
14 |
15 | const kraken2 = new ccxt.kraken ({
16 | proxy: function (url) {
17 | return 'https://cors-anywhere.herokuapp.com/' + url
18 | },
19 | })
20 |
21 | console.log (await kraken2.loadMarkets ())
22 |
23 | }) ()
--------------------------------------------------------------------------------
/examples/js/exchanges.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | const ccxt = require ('../../ccxt.js')
4 | const countries = require ('../../countries.js')
5 | const asTable = require ('as-table')
6 | const util = require ('util')
7 | const log = require ('ololog').configure ({ locate: false })
8 |
9 | require ('ansicolor').nice
10 |
11 | process.on ('uncaughtException', e => { log.bright.red.error (e); process.exit (1) })
12 | process.on ('unhandledRejection', e => { log.bright.red.error (e); process.exit (1) })
13 |
14 | let exchanges = {}
15 |
16 | ccxt.exchanges.forEach (id => { exchanges[id] = new (ccxt)[id] () })
17 |
18 | log ('The ccxt library supports', (ccxt.exchanges.length.toString ()).green, 'exchanges:')
19 |
20 | var countryName = function (code) {
21 | return ((countries[code] !== undefined) ? countries[code] : code)
22 | }
23 |
24 | log (asTable.configure ({ delimiter: ' | ' }) (Object.values (exchanges).map (exchange => {
25 |
26 | let countries = Array.isArray (exchange.countries) ?
27 | exchange.countries.map (countryName).join (', ') :
28 | countryName (exchange.countries)
29 |
30 | let website = Array.isArray (exchange.urls.www) ? exchange.urls.www[0] : exchange.urls.www
31 |
32 | return {
33 | id: exchange.id,
34 | name: exchange.name,
35 | url: website,
36 | countries: countries,
37 | }
38 |
39 | })))
40 |
--------------------------------------------------------------------------------
/examples/js/fetch-from-many-exchanges-simultaneously.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | const ccxt = require ('../../ccxt.js')
4 | const log = require ('ololog')
5 |
6 | const symbol = 'ETH/BTC'
7 | const exchanges = [ 'gdax', 'hitbtc2', 'poloniex' ]
8 |
9 | ;(async () => {
10 |
11 | const result = await Promise.all (exchanges.map (async id => {
12 |
13 | const exchange = new ccxt[id] ({ 'enableRateLimit': true })
14 | const ticker = await exchange.fetchTicker (symbol)
15 | return exchange.extend ({ 'exchange': id }, ticker)
16 |
17 | }))
18 |
19 | log (result);
20 |
21 | }) ()
--------------------------------------------------------------------------------
/examples/js/fetch-ohlcv-cex.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | const ccxt = require ('../../ccxt.js')
4 | const asciichart = require ('asciichart')
5 | const asTable = require ('as-table')
6 | const log = require ('ololog').configure ({ locate: false })
7 |
8 | require ('ansicolor').nice
9 |
10 | //-----------------------------------------------------------------------------
11 |
12 | ;(async function main () {
13 |
14 | // experimental, not yet implemented for all exchanges
15 | // your contributions are welcome ;)
16 |
17 | const index = 4 // [ timestamp, open, high, low, close, volume ]
18 | const ohlcv = await new ccxt.cex ().fetchOHLCV ('BTC/USD', '1m')
19 | const lastPrice = ohlcv[ohlcv.length - 1][index] // closing price
20 | const series = ohlcv.slice (-80).map (x => x[index]) // closing price
21 | const bitcoinRate = ('₿ = $' + lastPrice).green
22 | const chart = asciichart.plot (series, { height: 15, padding: ' ' })
23 | log.yellow ("\n" + chart, bitcoinRate, "\n")
24 | process.exit ()
25 |
26 | }) ()
--------------------------------------------------------------------------------
/examples/js/fetch-okex-futures.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | const ccxt = require ('../../ccxt')
4 |
5 | async function test () {
6 |
7 | const exchange = new ccxt.okex ()
8 | await exchange.loadMarkets ()
9 |
10 | for (let symbol in exchange.markets) {
11 |
12 | const market = exchange.markets[symbol]
13 |
14 | if (market['future']) {
15 | console.log ('----------------------------------------------------')
16 | console.log (symbol, await exchange.fetchTicker (symbol))
17 | await ccxt.sleep (exchange.rateLimit)
18 | }
19 | }
20 | }
21 |
22 | test ()
23 |
--------------------------------------------------------------------------------
/examples/js/fetch-orders.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | const ccxt = require ('../../ccxt')
4 | const asTable = require ('as-table')
5 | const log = require ('ololog')
6 |
7 | require ('ansicolor').nice
8 |
9 | const exchange = new ccxt.bittrex ({
10 | apiKey: "471b47a06c384e81b24072e9a8739064",
11 | secret: "694025686e9445589787e8ca212b4cff",
12 | enableRateLimit: true,
13 | })
14 |
15 | async function test () {
16 |
17 | const orders = await exchange.fetchOrders ()
18 |
19 | log (asTable (orders.map (order => ccxt.omit (order, [ 'timestamp', 'info' ]))))
20 |
21 | const order = await exchange.fetchOrder (orders[0]['id'])
22 |
23 | log (order)
24 | }
25 |
26 | test ()
--------------------------------------------------------------------------------
/examples/js/fetch-ticker-from-multiple-exchanges.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | const ccxt = require ('../../ccxt.js')
4 |
5 | ;(async () => {
6 |
7 | const exchanges = [
8 | 'bittrex',
9 | 'poloniex',
10 | ]
11 |
12 | const symbol = 'BTC/USDT'
13 | const tickers = {}
14 |
15 | await Promise.all (exchanges.map (exchangeId =>
16 |
17 | new Promise (async (resolve, reject) => {
18 |
19 | const exchange = new ccxt[exchangeId] ({ enableRateLimit: true })
20 |
21 | while (true) {
22 |
23 | const ticker = await exchange.fetchTicker (symbol)
24 | tickers[exchangeId] = ticker
25 |
26 | Object.keys (tickers).map (exchangeId => {
27 | const ticker = tickers[exchangeId]
28 | console.log (ticker['datetime'], exchangeId, ticker['bid'], ticker['ask'])
29 | })
30 | }
31 |
32 | })
33 |
34 | ))
35 |
36 | }) ()
--------------------------------------------------------------------------------
/examples/js/instantiate-all-at-once.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | const ccxt = require ('../../ccxt')
4 |
5 | async function test () {
6 |
7 | let exchanges = {
8 | "bittrex": {
9 | "apiKey": "60f38a5818934fc08308778f94d3d8c4",
10 | "secret": "9d294ddb5b944403b58e5298653720c1",
11 | },
12 | "bitfinex": {
13 | "apiKey": "02YsRDRAFwqt9JXfFKPIEw82mgmNbZtfpwvt8q5WK5a",
14 | "secret": "IummLrCfcZ9d9NPEtMg6chCpO8hugCvsDIscNm1F3pE"
15 | },
16 | }
17 |
18 | let ids = ccxt.exchanges.filter (id => id in exchanges)
19 |
20 | await Promise.all (ids.map (async id => {
21 |
22 | console.log (exchanges[id])
23 |
24 | // // instantiate the exchange
25 | let exchange = new ccxt[id] (exchanges[id])
26 | console.log (exchange.id, exchange.apiKey)
27 | exchanges[id] = exchange
28 |
29 | // load markets
30 | await exchange.loadMarkets ()
31 | console.log (exchange.id, 'loaded')
32 |
33 | // check the balance
34 | if (exchange.apiKey) {
35 | let balance = await exchange.fetchBalance ()
36 | console.log (exchange.id, balance)
37 | }
38 |
39 | return exchange
40 | }))
41 |
42 | // when all of them are ready, do your other things
43 | console.log ('Loaded exchanges:', ids.join (', '))
44 | }
45 |
46 | test ()
47 |
--------------------------------------------------------------------------------
/examples/js/instantiate-all-from-json.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | const ccxt = require ('../../ccxt')
4 | , settings = require ('./credentials.json')
5 |
6 | const enableRateLimit = true
7 |
8 | async function test () {
9 |
10 | const ids = ccxt.exchanges.filter (id => id in settings)
11 |
12 | const exchanges = ccxt.indexBy (await Promise.all (ids.map (async id => {
13 |
14 | // instantiate the exchange
15 | let exchange = new ccxt[id] (ccxt.extend ({ enableRateLimit }, settings[id]))
16 |
17 | // load markets
18 | await exchange.loadMarkets ()
19 |
20 | // check the balance
21 | if (exchange.apiKey) {
22 | let balance = await exchange.fetchBalance ()
23 | console.log (exchange.id, balance['free'])
24 | }
25 |
26 | return exchange
27 | })), 'id')
28 |
29 | // when all of them are ready, do your other things
30 | console.log ('Loaded exchanges:', Object.keys (exchanges).join (', '))
31 | }
32 |
33 | test ()
34 |
--------------------------------------------------------------------------------
/examples/js/market-status-and-currency-status.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | const ccxt = require ('../../ccxt')
4 | , log = require ('ololog')
5 | , asTable = require ('as-table')
6 |
7 | ;(async function main () {
8 |
9 | let kraken = new ccxt.kraken ({ enableRateLimit: true })
10 | await kraken.loadMarkets ()
11 |
12 | const markets = Object.values (kraken.markets).map (market => ({
13 | symbol: market.symbol,
14 | active: market.active,
15 | }))
16 |
17 | log.bright.green.noLocate ('Markets:')
18 | log.green.noLocate (asTable (markets), '\n')
19 |
20 | const currencies = Object.values (kraken.currencies).map (currency => ({
21 | code: currency.code,
22 | active: currency.active,
23 | status: currency.status,
24 | }))
25 |
26 | log.bright.yellow.noLocate ('Currencies:')
27 | log.yellow.noLocate (asTable (currencies))
28 |
29 | }) ()
30 |
--------------------------------------------------------------------------------
/examples/js/okex-fetch-ohlcv-since-limit.js:
--------------------------------------------------------------------------------
1 | const ccxt = require ('../../ccxt.js')
2 | , log = require ('ololog')
3 | , ansi = require ('ansicolor').nice
4 |
5 | ;(async () => {
6 |
7 | const exchange = new ccxt['okex']()
8 | exchange.enableRateLimit = true
9 |
10 | let limit = undefined
11 | let symbol = 'BTC/USDT'
12 | let interval = '15m'
13 |
14 | // enable either of the following two lines
15 | exchange.options['warnOnFetchOHLCVLimitArgument'] = false
16 | // limit = 3
17 |
18 | const dates = [
19 | '2014-01-01T00:00:00', // okex did not exist then
20 | '2016-02-01T00:00:00',
21 | '2018-02-15T00:00:00',
22 | '2018-02-25T00:00:00',
23 | '2018-02-27T00:00:00',
24 | ]
25 |
26 | const results = await Promise.all (dates.map (async date => {
27 | since = exchange.parse8601 (date)
28 | const ohlcv = await exchange.fetchOHLCV (symbol, interval, since, limit)
29 | const fetchingFrom = date.green
30 | const firstCandleDate = ohlcv.length ? exchange.iso8601 (ohlcv[0][0]).yellow : undefined
31 | const lastCandleDate = ohlcv.length ? exchange.iso8601 (ohlcv[ohlcv.length - 1][0]).yellow : undefined
32 | const count = ohlcv.length.toString ().red
33 | return { fetchingFrom, firstCandleDate, lastCandleDate, count, ohlcv }
34 | }))
35 |
36 | log (results)
37 |
38 | }) ()
39 |
--------------------------------------------------------------------------------
/examples/js/order-book-extra-level-depth-param.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | const ccxt = require ('../../ccxt')
4 | const asTable = require ('as-table')
5 | const log = require ('ololog')
6 |
7 | require ('ansicolor').nice
8 |
9 | ;(async function test () {
10 |
11 | const exchange = new ccxt.bitfinex ()
12 | const limit = 5
13 | const orders = await exchange.fetchOrderBook ('BTC/USD', limit, {
14 | // this parameter is exchange-specific, all extra params have unique names per exchange
15 | 'group': 1, // 1 = orders are grouped by price, 0 = orders are separate
16 | })
17 |
18 | log (orders)
19 | }) ()
--------------------------------------------------------------------------------
/examples/php/README.md:
--------------------------------------------------------------------------------
1 | # CCXT PHP Examples
2 |
3 | To run PHP examples from any folder type in console:
4 |
5 | ```shell
6 | php -f path/to/example.php # substitute for actual filename here
7 | ```
--------------------------------------------------------------------------------
/examples/php/basic-error-handling.php:
--------------------------------------------------------------------------------
1 | fetch_ticker ('NONEXISTENT_SYMBOL');
16 | var_dump ($result);
17 |
18 | } catch (Exception $e) {
19 |
20 | // print it
21 | echo $e->getMessage () . "\n";
22 |
23 | // save to $message (for whatever needs)
24 | $message = $e->getMessage ();
25 | }
26 |
27 | ?>
28 |
--------------------------------------------------------------------------------
/examples/php/binance-cancel-order.php:
--------------------------------------------------------------------------------
1 | 'YOUR_API_KEY', // ←------------ replace with your keys
11 | 'secret' => 'YOUR_SECRET',
12 | 'verbose' => true,
13 | ));
14 |
15 | try {
16 |
17 | $orderId = 'xxxxxxxx'; // ←--------- replace with your order id
18 | $symbol = 'XRP/BTC'; // ←--------- replace with your symbol
19 |
20 | $exchange->cancelOrder ($orderId, $symbol);
21 |
22 | } catch (\ccxt\NetworkError $e) {
23 | echo '[Network Error] ' . $e->getMessage () . "\n";
24 | } catch (\ccxt\ExchangeError $e) {
25 | echo '[Exchange Error] ' . $e->getMessage () . "\n";
26 | } catch (Exception $e) {
27 | echo '[Error] ' . $e->getMessage () . "\n";
28 | }
29 |
30 | ?>
--------------------------------------------------------------------------------
/examples/php/binance-fetch-ticker.php:
--------------------------------------------------------------------------------
1 | true,
11 | 'timeout' => 30000,
12 | ));
13 |
14 | try {
15 |
16 | $symbol = 'ETH/BTC';
17 | $result = $exchange->fetch_ticker ($symbol);
18 |
19 | var_dump ($result);
20 |
21 | } catch (\ccxt\NetworkError $e) {
22 | echo '[Network Error] ' . $e->getMessage () . "\n";
23 | } catch (\ccxt\ExchangeError $e) {
24 | echo '[Exchange Error] ' . $e->getMessage () . "\n";
25 | } catch (Exception $e) {
26 | echo '[Error] ' . $e->getMessage () . "\n";
27 | }
28 |
29 | ?>
--------------------------------------------------------------------------------
/examples/php/binance-fetch-tickers.php:
--------------------------------------------------------------------------------
1 | true, // for debugging
11 | 'timeout' => 30000,
12 | ));
13 |
14 | try {
15 |
16 | // WARNING !!!
17 |
18 | // DO NOT CALL THIS MORE THAN ONCE IN 2 MINUTES OR YOU WILL GET BANNED BY BINANCE!
19 |
20 | // https://github.com/binance-exchange/binance-official-api-docs/blob/master/rest-api.md#limits
21 |
22 | $result = $exchange->fetch_tickers ();
23 |
24 | print_r ($result);
25 |
26 | } catch (\ccxt\NetworkError $e) {
27 | echo '[Network Error] ' . $e->getMessage () . "\n";
28 | } catch (\ccxt\ExchangeError $e) {
29 | echo '[Exchange Error] ' . $e->getMessage () . "\n";
30 | } catch (Exception $e) {
31 | echo '[Error] ' . $e->getMessage () . "\n";
32 | }
33 |
34 | ?>
--------------------------------------------------------------------------------
/examples/php/bitfinex2-fetch-ohlcv-since-limit.php:
--------------------------------------------------------------------------------
1 | true));
12 |
13 | // load all markets from the exchange
14 | $markets = $exchange->load_markets ();
15 |
16 | function run ($exchange, $symbol, $timeframe, $since, $limit) {
17 | $ohlcvs = $exchange->fetchOHLCV ($symbol, $timeframe, $since, $limit);
18 | foreach ($ohlcvs as $v) {
19 | printf ("%s O:%.8f H:%.8f L:%.8f C:%.8f V:%.8f\n", $exchange->iso8601 ($v[0]), $v[1], $v[2], $v[3], $v[4], $v[5]);
20 | }
21 | }
22 |
23 | printf ("--------------------------------------------------------------\n");
24 | run ($exchange, 'ETH/BTC', '1m', 1518842513569, 5);
25 | printf ("--------------------------------------------------------------\n");
26 | run ($exchange, 'ETH/BTC', '1m', 1518842513569, 10);
27 | printf ("--------------------------------------------------------------\n");
28 |
29 | ?>
--------------------------------------------------------------------------------
/examples/php/bitfinex2-fetch-ohlcv.php:
--------------------------------------------------------------------------------
1 | true,
12 | 'rateLimit' => 12000,
13 | ));
14 |
15 | // bitfinex2 breaks occasionally
16 |
17 | for ($i = 0; $i < 1000; $i++) {
18 | $ohlcv = $exchange->fetch_ohlcv ('BTC/USD', '1m');
19 | print_r ($exchange->iso8601 ($ohlcv[0][0]) . "\t" . count($ohlcv) . "\n");
20 | }
21 |
22 | ?>
--------------------------------------------------------------------------------
/examples/php/bitfinex2-fetch-trades-since.php:
--------------------------------------------------------------------------------
1 | fetch_trades ('ETH/BTC', 1518983548636 - 2 * 24 * 60 * 60 * 1000);
17 |
18 | foreach ($trades as $trade) {
19 | echo $trade['datetime'] . "\n";
20 | }
21 | echo count ($trades) . " trades\n";
22 |
23 | ?>
--------------------------------------------------------------------------------
/examples/php/bitmex-create-order.php:
--------------------------------------------------------------------------------
1 | 'YOUR_API_KEY', // ←------------ replace with your keys
11 | 'secret' => 'YOUR_SECRET',
12 | 'enableRateLimit' => true,
13 | ));
14 |
15 | $symbol = 'XBTM18'; // bitcoin contract according to bitmex futures coding
16 | $type = 'StopLimit'; // # or 'market', or 'Stop' or 'StopLimit'
17 | $side = 'sell'; // or 'buy'
18 | $amount = 1.0;
19 | $price = 6500.0; // or None
20 |
21 | // extra params and overrides
22 | $params = array (
23 | 'stopPx' => 6000.0, // if needed
24 | );
25 |
26 | $order = $exchange->create_order ($symbol, $type, $side, $amount, $price, $params);
27 |
28 | print_r ($order);
29 |
--------------------------------------------------------------------------------
/examples/php/built-in-rate-limiting-poller.php:
--------------------------------------------------------------------------------
1 | true,
12 | ));
13 |
14 | $symbol = 'DOGE/BTC';
15 |
16 | while (true) {
17 | $order_book = $exchange->fetch_order_book ($symbol);
18 | echo "----------------------------------------------------------------\n";
19 | echo date ('c') . "\n";
20 | echo count ($order_book['bids']) . " bids and " . count ($order_book['asks']) . " asks\n";
21 | echo sprintf ("bid: %.8f ask: %.8f", $order_book['bids'][0][0], $order_book['asks'][0][0]) . "\n";
22 | }
23 |
--------------------------------------------------------------------------------
/examples/php/error-handling-message.php:
--------------------------------------------------------------------------------
1 | 'foo',
11 | 'secret' => 'bar',
12 | ));
13 |
14 | $message = null;
15 |
16 | try {
17 |
18 | $result = $exchange->fetch_balance ();
19 | var_dump ($result);
20 |
21 | // these catch-clauses are showing the proper way of handling the errors
22 |
23 | } catch (\ccxt\AuthenticationError $e) {
24 |
25 | // handle authentication error here
26 |
27 | } catch (\ccxt\NetworkError $e) {
28 |
29 | // your code to handle the network code and retries here
30 |
31 | } catch (\ccxt\ExchangeError $e) {
32 |
33 | // your code to handle an exchange error
34 |
35 | } catch (Exception $e) {
36 |
37 | // This is an example of how NOT TO DO error handling
38 | // One should not rely on the message string contained in the exception
39 | // If you want to access it, that might indicate a design error in your code.
40 | // See: https://github.com/ccxt/ccxt/issues/3053
41 |
42 | $message = $e->getMessage ();
43 |
44 | if (preg_match ('/[a-z]+\s+(\{.+\})$/iu', $e->getMessage (), $matches)) {
45 | $message = $matches[1];
46 | }
47 |
48 | echo print_r ($message, true) . "\n";
49 |
50 | }
51 |
52 | ?>
53 |
--------------------------------------------------------------------------------
/examples/php/huobi-fetch-balance.php:
--------------------------------------------------------------------------------
1 | 'YOUR_API_KEY', // ←------------ replace with your keys
11 | 'secret' => 'YOUR_SECRET',
12 | // 'verbose' => true, // uncomment if debug output is needed
13 | ));
14 |
15 | try {
16 |
17 | $balance = $exchange->fetch_balance ();
18 | var_dump ($balance);
19 |
20 | } catch (\ccxt\NetworkError $e) {
21 | echo '[Network Error] ' . $e->getMessage () . "\n";
22 | } catch (\ccxt\ExchangeError $e) {
23 | echo '[Exchange Error] ' . $e->getMessage () . "\n";
24 | } catch (Exception $e) {
25 | echo '[Error] ' . $e->getMessage () . "\n";
26 | }
27 |
28 | ?>
29 |
--------------------------------------------------------------------------------
/examples/php/kraken-query-ledgers.php:
--------------------------------------------------------------------------------
1 | 'YOUR_API_KEY',
15 | 'secret' => 'YOUR_SECRET_KEY',
16 | ));
17 |
18 | // get ledgers
19 | $ledgers = $exchange->privatePostLedgers ();
20 |
21 | // get ledger ids
22 | $ids = array_keys ($ledgers['result']['ledger']);
23 |
24 | // get ledger entries for ledger id
25 | $ledger_entries = $exchange->privatePostQueryLedgers (array (
26 | 'id' => $ids[0],
27 | ));
28 |
29 | var_dump ($ledger_entries);
30 |
31 | ?>
--------------------------------------------------------------------------------
/examples/php/load-all-at-once.php:
--------------------------------------------------------------------------------
1 | id . "\n";
16 |
17 | try {
18 | $markets = $exchange->load_markets ();
19 | echo count (array_values ($exchange->markets)) . " markets: " .
20 | implode (', ', array_slice ($exchange->symbols, 0, 5)) . "...\n";
21 | } catch (\ccxt\RequestTimeout $e) {
22 | echo '[Timeout Error] ' . $e->getMessage () . ' (ignoring)' . "\n";
23 | } catch (\ccxt\DDoSProtection $e) {
24 | echo '[DDoS Protection Error] ' . $e->getMessage () . ' (ignoring)' . "\n";
25 | } catch (\ccxt\AuthenticationError $e) {
26 | echo '[Authentication Error] ' . $e->getMessage () . ' (ignoring)' . "\n";
27 | } catch (\ccxt\ExchangeNotAvailable $e) {
28 | echo '[Exchange Not Available] ' . $e->getMessage () . ' (ignoring)' . "\n";
29 | } catch (\ccxt\NotSupported $e) {
30 | echo '[Not Supported] ' . $e->getMessage () . ' (ignoring)' . "\n";
31 | } catch (\ccxt\NetworkError $e) {
32 | echo '[Network Error] ' . $e->getMessage () . ' (ignoring)' . "\n";
33 | } catch (\ccxt\ExchangeError $e) {
34 | echo '[Exchange Error] ' . $e->getMessage () . ' (ignoring)' . "\n";
35 | } catch (Exception $e) {
36 | echo '[Error] ' . $e->getMessage () . "\n";
37 | }
38 | echo "\n";
39 | }
40 |
41 |
42 | ?>
--------------------------------------------------------------------------------
/examples/php/order-book-level-depth-extra-param.php:
--------------------------------------------------------------------------------
1 | fetch_order_book ('BTC/USD', $limit));
14 |
15 |
16 | ?>
--------------------------------------------------------------------------------
/examples/php/react-eventloop-with-rate-limiting.php:
--------------------------------------------------------------------------------
1 | fetch_order_book ($symbol);
20 | echo "----------------------------------------------------------------\n";
21 | echo date ('c') . "\n";
22 | echo count ($order_book['bids']) . " bids and " . count ($order_book['asks']) . " asks\n";
23 | echo sprintf ("bid: %.8f ask: %.8f", $order_book['bids'][0][0], $order_book['asks'][0][0]) . "\n";
24 |
25 | $loop->futureTick ($tick_function);
26 | };
27 |
28 | $loop->futureTick ($tick_function);
29 | $loop->run ();
--------------------------------------------------------------------------------
/examples/php/trading-view.php:
--------------------------------------------------------------------------------
1 | true,
19 | ));
20 |
21 | // OHLCV format by default
22 | $ohlcv = $exchange->fetch_ohlcv ($symbol);
23 |
24 | // convert OHLCV → TradingView
25 | $trading_view = $exchange->convert_ohlcv_to_trading_view ($ohlcv);
26 |
27 | // convert TradingView → OHCLV
28 | $restored_ohlcvs = $exchange->convert_trading_view_to_ohlcv ($trading_view);
29 |
30 | print_r ($restored_ohlcvs);
31 |
32 | ?>
--------------------------------------------------------------------------------
/examples/php/vaultoro-fetch-balance.php:
--------------------------------------------------------------------------------
1 | true, // for debugging
11 | // 'timeout' => 30000,
12 | "apiKey" => "CEwxqNb3GzixcrhzrPkn47JkdsDpff6z",
13 | "secret" => "ZXRBWURDN3NSVFNJSmFIRHlOWUVfd1d6UjZwSFdiTGI=",
14 | ));
15 |
16 | try {
17 |
18 | $result = $exchange->fetch_balance ();
19 |
20 | print_r ($result);
21 |
22 | } catch (\ccxt\NetworkError $e) {
23 | echo '[Network Error] ' . $e->getMessage () . "\n";
24 | } catch (\ccxt\ExchangeError $e) {
25 | echo '[Exchange Error] ' . $e->getMessage () . "\n";
26 | } catch (Exception $e) {
27 | echo '[Error] ' . $e->getMessage () . "\n";
28 | }
29 |
30 | ?>
--------------------------------------------------------------------------------
/examples/py/README.md:
--------------------------------------------------------------------------------
1 | # CCXT Python Examples
2 |
3 | To run Python examples from any folder, type in console:
4 |
5 | ```shell
6 | python path/to/example.py # substitute for actual filename here
7 | ```
8 |
9 | Example files starting with `async-` require Python 3.6 with `async`/`await` and async generators support.
10 |
11 | 
12 |
13 | ## See Also
14 |
15 | [co3k-crypto-currency-note](https://github.com/co3k/co3k-crypto-currency-note/blob/master/Untitled.ipynb) – an example of using ccxt to fetch OHLCV candles from Kraken and charting them with matplotlib in a Jupyter Notebook, made by [co3k](https://github.com/co3k).
16 |
--------------------------------------------------------------------------------
/examples/py/async-balance-gdax.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | import asyncio
4 | import os
5 | import sys
6 |
7 | root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
8 | sys.path.append(root + '/python')
9 |
10 | import ccxt.async_support as ccxt # noqa: E402
11 |
12 |
13 | async def test():
14 | gdax = ccxt.gdax({
15 | 'apiKey': "a43edfe629bc5991acc83a536ac6358e",
16 | 'secret': "xOvq+iH8NT07TheFB/fmY3GcnMZMwP7Xct9zwWtAZxsCbJh8rxeEe/0BGxfbV2em7P9iqQD7/TJGqmsDO8B/kw==",
17 | 'password': 'zdmj8o7byla',
18 | 'verbose': True, # switch it to False if you don't want the HTTP log
19 | })
20 | # move gdax to sandbox
21 | gdax.urls['api'] = 'https://api-public.sandbox.gdax.com'
22 | print(await gdax.fetch_balance())
23 |
24 |
25 | asyncio.get_event_loop().run_until_complete(test())
26 |
--------------------------------------------------------------------------------
/examples/py/async-balance.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | import asyncio
4 | import os
5 | import sys
6 |
7 | root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
8 | sys.path.append(root + '/python')
9 |
10 | import ccxt.async_support as ccxt # noqa: E402
11 |
12 |
13 | async def test():
14 | bittrex = ccxt.bittrex({
15 | 'apiKey': "c5af1d0ceeaa4729ad87da1b05d9dfc3",
16 | 'secret': "d055d8e47fdf4c3bbd0ec6c289ea8ffd",
17 | 'verbose': True, # switch it to False if you don't want the HTTP log
18 | })
19 | print(await bittrex.fetch_balance())
20 |
21 |
22 | asyncio.get_event_loop().run_until_complete(test())
23 |
--------------------------------------------------------------------------------
/examples/py/async-balances.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | import asyncio
4 | import os
5 | import sys
6 |
7 | root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
8 | sys.path.append(root + '/python')
9 |
10 | import ccxt.async_support as ccxt # noqa: E402
11 |
12 |
13 | async def test(exchange):
14 | print(await exchange.fetch_balance())
15 |
16 |
17 | kraken = ccxt.kraken({
18 | 'apiKey': "hEvQNMDIeoCJbr7W/ZBb5CGOrx3G0lWF5B3zqa1JBxdZlEaL8EK+D0Mw",
19 | 'secret': "JaE9wI6Nwgh5oRxiHcVxurwzwBxwc05W/qv/k1srGg4s3EYuXPpNkLLM5NYbbWpM8rCyijIeDavRuqWbU0ZV9A==",
20 | 'verbose': True, # switch it to False if you don't want the HTTP log
21 | })
22 | bitfinex = ccxt.bitfinex({
23 | 'apiKey': "4FlEDtxDl35gdEiobnfZ72vJeZteE4Bb7JdvqzjIjHq",
24 | 'secret': "D4DXM8DZdHuAq9YptUsb42aWT1XBnGlIJgLi8a7tzFH",
25 | 'verbose': True, # switch it to False if you don't want the HTTP log
26 | })
27 |
28 | [asyncio.ensure_future(test(exchange)) for exchange in [kraken, bitfinex]]
29 | pending = asyncio.Task.all_tasks()
30 | loop = asyncio.get_event_loop()
31 | loop.run_until_complete(asyncio.gather(*pending))
32 |
--------------------------------------------------------------------------------
/examples/py/async-basic-rate-limiter.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | import asyncio
4 | import os
5 | import sys
6 |
7 | root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
8 | sys.path.append(root + '/python')
9 |
10 | import ccxt.async_support as ccxt # noqa: E402
11 |
12 |
13 | async def main(exchange):
14 | for i in range(0, 10):
15 | # this can be any call instead of fetch_ticker, really
16 | print(await exchange.fetch_ticker('BTC/USD'))
17 |
18 |
19 | # you can set enableRateLimit = True to enable the built-in rate limiter
20 | # this way you request rate will never hit the limit of an exchange
21 | # the library will throttle your requests to avoid that
22 |
23 | exchange = ccxt.bitfinex({
24 | 'enableRateLimit': True, # this option enables the built-in rate limiter
25 | })
26 |
27 | asyncio.get_event_loop().run_until_complete(main(exchange))
28 |
--------------------------------------------------------------------------------
/examples/py/async-basic.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | import asyncio
4 | import os
5 | import sys
6 |
7 | root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
8 | sys.path.append(root + '/python')
9 |
10 | import ccxt.async_support as ccxt # noqa: E402
11 |
12 |
13 | async def test_gdax():
14 | gdax = ccxt.gdax()
15 | markets = await gdax.load_markets()
16 | await gdax.close()
17 | return markets
18 |
19 | if __name__ == '__main__':
20 | print(asyncio.get_event_loop().run_until_complete(test_gdax()))
21 |
--------------------------------------------------------------------------------
/examples/py/async-bitfinex-private-post-account-infos.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | import asyncio
4 | import os
5 | import sys
6 |
7 | root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
8 | sys.path.append(root + '/python')
9 |
10 | import ccxt.async_support as ccxt # noqa: E402
11 |
12 |
13 | async def test(exchange):
14 | print(await exchange.private_post_account_infos())
15 |
16 |
17 | bitfinex = ccxt.bitfinex({
18 | 'apiKey': "4FlEDtxDl35gdEiobnfZ72vJeZteE4Bb7JdvqzjIjHq",
19 | 'secret': "D4DXM8DZdHuAq9YptUsb42aWT1XBnGlIJgLi8a7tzFH",
20 | 'verbose': True, # switch it to False if you don't want the HTTP log
21 | })
22 |
23 | [asyncio.ensure_future(test(exchange)) for exchange in [bitfinex]]
24 | pending = asyncio.Task.all_tasks()
25 | loop = asyncio.get_event_loop()
26 | loop.run_until_complete(asyncio.gather(*pending))
27 |
--------------------------------------------------------------------------------
/examples/py/async-bitstamp-create-limit-buy-order.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | import asyncio
4 | import os
5 | import sys
6 |
7 | root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
8 | sys.path.append(root + '/python')
9 |
10 | import ccxt.async_support as ccxt # noqa: E402
11 |
12 |
13 | async def test():
14 |
15 | exchange = ccxt.bitstamp({
16 | 'apiKey': 'YOUR_API_KEY',
17 | 'secret': 'YOUR_SECRET',
18 | 'enableRateLimit': True, # this is required, as documented in the Manual!
19 | })
20 |
21 | response = None
22 |
23 | try:
24 |
25 | await exchange.load_markets() # force-preload markets first
26 |
27 | exchange.verbose = True # this is for debugging
28 |
29 | symbol = 'BTC/USD' # change for your symbol
30 | amount = 1.0 # change the amount
31 | price = 6000.00 # change the price
32 |
33 | try:
34 |
35 | response = await exchange.create_limit_buy_order(symbol, amount, price)
36 |
37 | except Exception as e:
38 | print('Failed to create order with', exchange.id, type(e).__name__, str(e))
39 |
40 | except Exception as e:
41 | print('Failed to load markets from', exchange.id, type(e).__name__, str(e))
42 |
43 | await exchange.close()
44 | return response
45 |
46 | if __name__ == '__main__':
47 | print(asyncio.get_event_loop().run_until_complete(test()))
48 |
--------------------------------------------------------------------------------
/examples/py/async-bittrex-orderbook.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | import asyncio
4 | import os
5 | import sys
6 |
7 | if not sys.version >= '3.6':
8 | print('This script requires Python 3.6+')
9 | sys.exit()
10 |
11 | root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
12 | sys.path.append(root + '/python')
13 |
14 | import ccxt.async_support as ccxt # noqa: E402
15 |
16 | exchange = ccxt.bittrex()
17 |
18 |
19 | async def poll():
20 | while True:
21 | yield await exchange.fetch_order_book('BTC/USDT')
22 | await asyncio.sleep(exchange.rateLimit / 1000)
23 |
24 |
25 | async def main():
26 | async for orderbook in poll():
27 | print(orderbook['bids'][0], orderbook['asks'][0])
28 |
29 |
30 | asyncio.get_event_loop().run_until_complete(main())
31 |
--------------------------------------------------------------------------------
/examples/py/async-fetch-ticker.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | import asyncio
4 | import os
5 | import sys
6 |
7 | root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
8 | sys.path.append(root + '/python')
9 |
10 | import ccxt.async_support as ccxt # noqa: E402
11 |
12 | print(asyncio.get_event_loop().run_until_complete(ccxt.liqui().fetch_ticker('ETH/BTC')))
13 |
--------------------------------------------------------------------------------
/examples/py/async-gdax-fetch-order-book-continuously.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | import asyncio
4 | import os
5 | import sys
6 |
7 | root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
8 | sys.path.append(root + '/python')
9 |
10 | import ccxt.async_support as ccxt # noqa: E402
11 |
12 |
13 | async def main(exchange, symbol):
14 | while True:
15 | print('--------------------------------------------------------------')
16 | print(exchange.iso8601(exchange.milliseconds()), 'fetching', symbol, 'ticker from', exchange.name)
17 | # this can be any call really
18 | ticker = await exchange.fetch_order_book(symbol)
19 | print(exchange.iso8601(exchange.milliseconds()), 'fetched', symbol, 'ticker from', exchange.name)
20 | print(ticker)
21 |
22 |
23 | # you can set enableRateLimit = True to enable the built-in rate limiter
24 | # this way you request rate will never hit the limit of an exchange
25 | # the library will throttle your requests to avoid that
26 |
27 | exchange = ccxt.gdax({
28 | 'enableRateLimit': True, # this option enables the built-in rate limiter
29 | })
30 |
31 | asyncio.get_event_loop().run_until_complete(main(exchange, 'LTC/USD'))
32 |
--------------------------------------------------------------------------------
/examples/py/async-generator-basic.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | import asyncio
4 | import os
5 | import sys
6 |
7 | root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
8 | sys.path.append(root + '/python')
9 |
10 | import ccxt.async_support as ccxt # noqa: E402
11 |
12 | exchange = ccxt.poloniex({
13 | 'enableRateLimit': True, # don't remove this line or they might ban you: https://github.com/ccxt/ccxt/wiki/Manual#rate-limit
14 | })
15 |
16 |
17 | async def poll():
18 | while True:
19 | yield await exchange.fetch_ticker('ETH/BTC')
20 |
21 |
22 | async def main():
23 | async for ticker in poll():
24 | print(ticker)
25 |
26 |
27 | asyncio.get_event_loop().run_until_complete(main())
28 |
--------------------------------------------------------------------------------
/examples/py/async-generator-multiple-tickers.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | import asyncio
4 | import ccxt.async_support as ccxt
5 |
6 |
7 | async def poll(tickers):
8 | i = 0
9 | kraken = ccxt.kraken()
10 | while True:
11 | symbol = tickers[i % len(tickers)]
12 | yield (symbol, await kraken.fetch_ticker(symbol))
13 | i += 1
14 | await asyncio.sleep(kraken.rateLimit / 1000)
15 |
16 |
17 | async def main():
18 | async for (symbol, ticker) in poll(['BTC/USD', 'ETH/BTC', 'BTC/EUR']):
19 | print(symbol, ticker)
20 |
21 |
22 | asyncio.get_event_loop().run_until_complete(main())
23 |
--------------------------------------------------------------------------------
/examples/py/async-generator-ticker-poller.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | import asyncio
4 | import os
5 | import sys
6 |
7 | root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
8 | sys.path.append(root + '/python')
9 |
10 | import ccxt.async_support as ccxt # noqa: E402
11 |
12 | kraken = ccxt.kraken({
13 | 'apiKey': "hEvQNMDIeoCJbr7W/ZBb5CGOrx3G0lWF5B3zqa1JBxdZlEaL8EK+D0Mw",
14 | 'secret': "JaE9wI6Nwgh5oRxiHcVxurwzwBxwc05W/qv/k1srGg4s3EYuXPpNkLLM5NYbbWpM8rCyijIeDavRuqWbU0ZV9A==",
15 | # 'verbose': True, # switch it to False if you don't want the HTTP log
16 | })
17 |
18 |
19 | async def poll():
20 | while True:
21 | yield await kraken.fetch_ticker('BTC/USD')
22 | await asyncio.sleep(kraken.rateLimit / 1000)
23 |
24 |
25 | async def main():
26 | async for ticker in poll():
27 | print(ticker)
28 |
29 |
30 | asyncio.get_event_loop().run_until_complete(main())
31 |
--------------------------------------------------------------------------------
/examples/py/async-instantiate-all-at-once.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | import os
4 | import sys
5 | import asyncio
6 |
7 | root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
8 | sys.path.append(root + '/python')
9 |
10 | import ccxt.async_support as ccxt # noqa: E402
11 |
12 | exchanges = {} # a placeholder for your instances
13 |
14 | for id in ccxt.exchanges:
15 | exchange = getattr(ccxt, id)
16 | exchanges[id] = exchange()
17 |
18 | # now exchanges dictionary contains all exchange instances...
19 | asyncio.get_event_loop().run_until_complete(exchanges['bittrex'].fetch_order_book('ETH/BTC'))
20 |
--------------------------------------------------------------------------------
/examples/py/async-theocean-orderbook.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | import asyncio
4 | import os
5 | import sys
6 |
7 | if not sys.version >= '3.6':
8 | print('This script requires Python 3.6+')
9 | sys.exit()
10 |
11 | root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
12 | sys.path.append(root + '/python')
13 |
14 | import ccxt.async_support as ccxt # noqa: E402
15 |
16 | exchange = ccxt.theocean()
17 |
18 |
19 | async def poll():
20 | while True:
21 | yield await exchange.fetch_order_book('WETH/TUSD')
22 | await asyncio.sleep(exchange.rateLimit / 1000)
23 |
24 |
25 | async def main():
26 | async for orderbook in poll():
27 | print(orderbook['bids'][0], orderbook['asks'][0])
28 |
29 |
30 | asyncio.get_event_loop().run_until_complete(main())
31 |
--------------------------------------------------------------------------------
/examples/py/async-theocean-tickers.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | import asyncio
4 | import os
5 | import sys
6 |
7 | root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
8 | sys.path.append(root + '/python')
9 |
10 | import ccxt.async_support as ccxt # noqa: E402
11 |
12 |
13 | def get_active_symbols(exchange):
14 | return [symbol for symbol in exchange.symbols if is_active_symbol(exchange, symbol)]
15 |
16 |
17 | def is_active_symbol(exchange, symbol):
18 | return ('.' not in symbol) and (('active' not in exchange.markets[symbol]) or (exchange.markets[symbol]['active']))
19 |
20 |
21 | async def fetch_ticker(exchange, symbol):
22 | ticker = await exchange.fetchTicker(symbol)
23 | print(exchange.id, symbol, ticker)
24 | return ticker
25 |
26 |
27 | async def fetch_tickers(exchange):
28 | await exchange.load_markets()
29 | print(exchange.id, 'fetching all tickers by simultaneous multiple concurrent requests')
30 | symbols_to_load = get_active_symbols(exchange)
31 | input_coroutines = [fetch_ticker(exchange, symbol) for symbol in symbols_to_load]
32 | tickers = await asyncio.gather(*input_coroutines, return_exceptions=True)
33 | for ticker, symbol in zip(tickers, symbols_to_load):
34 | if not isinstance(ticker, dict):
35 | print(exchange.id, symbol, 'error')
36 | else:
37 | print(exchange.id, symbol, 'ok')
38 | print(exchange.id, 'fetched', len(list(tickers)), 'tickers')
39 | await exchange.close()
40 |
41 |
42 | asyncio.get_event_loop().run_until_complete(fetch_tickers(ccxt.theocean({
43 | 'enableRateLimit': True, # this option enables the built-in rate limiter
44 | })))
45 |
--------------------------------------------------------------------------------
/examples/py/async-tickers-from-many-exchanges-at-once.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | import asyncio
4 | import ccxt
5 | import ccxt.async_support as ccxta # noqa: E402
6 | import time
7 | import os
8 | import sys
9 |
10 | root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
11 | sys.path.append(root + '/python')
12 |
13 |
14 | def sync_client(exchange):
15 | client = getattr(ccxt, exchange)()
16 | tickers = client.fetch_tickers()
17 | return tickers
18 |
19 |
20 | async def async_client(exchange):
21 | client = getattr(ccxta, exchange)()
22 | tickers = await client.fetch_tickers()
23 | await client.close()
24 | return tickers
25 |
26 |
27 | async def multi_tickers(exchanges):
28 | input_coroutines = [async_client(exchange) for exchange in exchanges]
29 | tickers = await asyncio.gather(*input_coroutines, return_exceptions=True)
30 | return tickers
31 |
32 |
33 | if __name__ == '__main__':
34 |
35 | # Consider review request rate limit in the methods you call
36 | exchanges = ["coinex", "bittrex", "bitfinex", "poloniex", "hitbtc"]
37 |
38 | tic = time.time()
39 | a = asyncio.get_event_loop().run_until_complete(multi_tickers(exchanges))
40 | print("async call spend:", time.time() - tic)
41 |
42 | time.sleep(1)
43 |
44 | tic = time.time()
45 | a = [sync_client(exchange) for exchange in exchanges]
46 | print("sync call spend:", time.time() - tic)
47 |
--------------------------------------------------------------------------------
/examples/py/async-tickers.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | import asyncio
4 | import os
5 | import sys
6 |
7 | root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
8 | sys.path.append(root + '/python')
9 |
10 | import ccxt.async_support as ccxt # noqa: E402
11 |
12 |
13 | def get_active_symbols(exchange):
14 | return [symbol for symbol in exchange.symbols if is_active_symbol(exchange, symbol)]
15 |
16 |
17 | def is_active_symbol(exchange, symbol):
18 | return ('.' not in symbol) and (('active' not in exchange.markets[symbol]) or (exchange.markets[symbol]['active']))
19 |
20 |
21 | async def fetch_ticker(exchange, symbol):
22 | ticker = await exchange.fetchTicker(symbol)
23 | print(exchange.id, symbol, ticker)
24 | return ticker
25 |
26 |
27 | async def fetch_tickers(exchange):
28 | await exchange.load_markets()
29 | print(exchange.id, 'fetching all tickers by simultaneous multiple concurrent requests')
30 | symbols_to_load = get_active_symbols(exchange)
31 | input_coroutines = [fetch_ticker(exchange, symbol) for symbol in symbols_to_load]
32 | tickers = await asyncio.gather(*input_coroutines, return_exceptions=True)
33 | for ticker, symbol in zip(tickers, symbols_to_load):
34 | if not isinstance(ticker, dict):
35 | print(exchange.id, symbol, 'error')
36 | else:
37 | print(exchange.id, symbol, 'ok')
38 | print(exchange.id, 'fetched', len(list(tickers)), 'tickers')
39 |
40 |
41 | asyncio.get_event_loop().run_until_complete(fetch_tickers(ccxt.bitfinex({
42 | 'enableRateLimit': True, # this option enables the built-in rate limiter
43 | })))
44 |
--------------------------------------------------------------------------------
/examples/py/async.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | import asyncio
4 | import functools
5 | import os
6 | import sys
7 |
8 | root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
9 | sys.path.append(root + '/python')
10 |
11 | import ccxt.async_support as ccxt # noqa: E402
12 |
13 |
14 | async def print_ticker(symbol, id):
15 | # verbose mode will show the order of execution to verify concurrency
16 | exchange = getattr(ccxt, id)({'verbose': True})
17 | print(await exchange.fetch_ticker(symbol))
18 |
19 |
20 | if __name__ == '__main__':
21 |
22 | symbol = 'ETH/BTC'
23 | print_ethbtc_ticker = functools.partial(print_ticker, symbol)
24 | [asyncio.ensure_future(print_ethbtc_ticker(id)) for id in [
25 | 'bitfinex',
26 | 'poloniex',
27 | 'kraken',
28 | 'gdax',
29 | 'bittrex',
30 | 'hitbtc',
31 | ]]
32 | pending = asyncio.Task.all_tasks()
33 | loop = asyncio.get_event_loop()
34 | loop.run_until_complete(asyncio.gather(*pending))
35 |
--------------------------------------------------------------------------------
/examples/py/balance-gdax.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | import os
4 | import sys
5 |
6 | root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
7 | sys.path.append(root + '/python')
8 |
9 | import ccxt # noqa: E402
10 |
11 | gdax = ccxt.gdax({
12 | 'apiKey': "a43edfe629bc5991acc83a536ac6358e",
13 | 'secret': "xOvq+iH8NT07TheFB/fmY3GcnMZMwP7Xct9zwWtAZxsCbJh8rxeEe/0BGxfbV2em7P9iqQD7/TJGqmsDO8B/kw==",
14 | 'password': 'zdmj8o7byla',
15 | 'verbose': True, # switch it to False if you don't want the HTTP log
16 | })
17 |
18 | # move gdax to sandbox
19 | gdax.urls['api'] = 'https://api-public.sandbox.gdax.com'
20 |
21 | print(gdax.fetch_balance())
22 |
--------------------------------------------------------------------------------
/examples/py/balance-kraken.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | import os
4 | import sys
5 |
6 | root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
7 | sys.path.append(root + '/python')
8 |
9 | import ccxt # noqa: E402
10 |
11 | kraken = ccxt.kraken({
12 | 'apiKey': "hEvQNMDIeoCJbr7W/ZBb5CGOrx3G0lWF5B3zqa1JBxdZlEaL8EK+D0Mw",
13 | 'secret': "JaE9wI6Nwgh5oRxiHcVxurwzwBxwc05W/qv/k1srGg4s3EYuXPpNkLLM5NYbbWpM8rCyijIeDavRuqWbU0ZV9A==",
14 | 'verbose': True, # switch it to False if you don't want the HTTP log
15 | })
16 |
17 | print(kraken.fetch_balance())
18 |
--------------------------------------------------------------------------------
/examples/py/basic-chart.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | import os
4 | import sys
5 | import asciichart
6 |
7 | # -----------------------------------------------------------------------------
8 |
9 | this_folder = os.path.dirname(os.path.abspath(__file__))
10 | root_folder = os.path.dirname(os.path.dirname(this_folder))
11 | sys.path.append(root_folder + '/python')
12 | sys.path.append(this_folder)
13 |
14 | # -----------------------------------------------------------------------------
15 |
16 | import ccxt # noqa: E402
17 |
18 | # -----------------------------------------------------------------------------
19 |
20 | kraken = ccxt.kraken()
21 | gdax = ccxt.gdax()
22 |
23 | symbol = 'BTC/USD'
24 |
25 | # each ohlcv candle is a list of [ timestamp, open, high, low, close, volume ]
26 | index = 4 # use close price from each ohlcv candle
27 |
28 |
29 | def print_chart(exchange, symbol, timeframe):
30 |
31 | print("\n" + exchange.name + ' ' + symbol + ' ' + timeframe + ' chart:')
32 |
33 | # get a list of ohlcv candles
34 | ohlcv = exchange.fetch_ohlcv(symbol, timeframe)
35 |
36 | # get the ohlCv (closing price, index == 4)
37 | series = [x[index] for x in ohlcv]
38 |
39 | # print the chart
40 | print("\n" + asciichart.plot(series[-120:], {'height': 20})) # print the chart
41 |
42 | last = ohlcv[len(ohlcv) - 1][index] # last closing price
43 | return last
44 |
45 |
46 | last = print_chart(kraken, 'BTC/USD', '1h')
47 | print("\n" + kraken.name + " ₿ = $" + str(last) + "\n") # print last closing price
48 |
49 | last = print_chart(gdax, 'BTC/USD', '1h')
50 | print("\n" + gdax.name + " ₿ = $" + str(last) + "\n") # print last closing price
51 |
--------------------------------------------------------------------------------
/examples/py/basic-rate-limiting.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | from pprint import pprint
4 |
5 | import os
6 | import sys
7 |
8 | root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
9 | sys.path.append(root + '/python')
10 |
11 | import ccxt # noqa: E402
12 |
13 |
14 | symbol = 'ETH/BTC'
15 |
16 | exchange = ccxt.poloniex({
17 | 'enableRateLimit': True, # or .enableRateLimit = True later
18 | })
19 |
20 | # print 10 times with appropriate delay
21 | for i in range(0, 10):
22 | print('--------------------------------------------------------------------')
23 | ticker = exchange.fetch_ticker(symbol)
24 | ticker = exchange.omit(ticker, 'info')
25 | pprint(ticker)
26 |
--------------------------------------------------------------------------------
/examples/py/binance-fetch-ohlcv.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | import os
4 | import sys
5 | import asciichart
6 |
7 | # -----------------------------------------------------------------------------
8 |
9 | this_folder = os.path.dirname(os.path.abspath(__file__))
10 | root_folder = os.path.dirname(os.path.dirname(this_folder))
11 | sys.path.append(root_folder + '/python')
12 | sys.path.append(this_folder)
13 |
14 | # -----------------------------------------------------------------------------
15 |
16 | import ccxt # noqa: E402
17 |
18 | # -----------------------------------------------------------------------------
19 |
20 | binance = ccxt.binance()
21 | symbol = 'BTC/USDT'
22 | timeframe = '1h'
23 |
24 | # each ohlcv candle is a list of [ timestamp, open, high, low, close, volume ]
25 | index = 4 # use close price from each ohlcv candle
26 |
27 | height = 15
28 | length = 80
29 |
30 |
31 | def print_chart(exchange, symbol, timeframe):
32 |
33 | print("\n" + exchange.name + ' ' + symbol + ' ' + timeframe + ' chart:')
34 |
35 | # get a list of ohlcv candles
36 | ohlcv = exchange.fetch_ohlcv(symbol, timeframe)
37 |
38 | # get the ohlCv (closing price, index == 4)
39 | series = [x[index] for x in ohlcv]
40 |
41 | # print the chart
42 | print("\n" + asciichart.plot(series[-length:], {'height': height})) # print the chart
43 |
44 | last = ohlcv[len(ohlcv) - 1][index] # last closing price
45 | return last
46 |
47 |
48 | last = print_chart(binance, symbol, timeframe)
49 | print("\n" + binance.name + " ₿ = $" + str(last) + "\n") # print last closing price
50 |
--------------------------------------------------------------------------------
/examples/py/binance-test-order.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | import os
4 | import sys
5 |
6 | root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
7 | sys.path.append(root + '/python')
8 |
9 | import ccxt # noqa: E402
10 |
11 |
12 | exchange = ccxt.binance({
13 | 'apiKey': 'YOUR_API_KEY',
14 | 'secret': 'YOUR_SECRET',
15 | 'enableRateLimit': True,
16 | })
17 |
18 | symbol = 'ETH/BTC'
19 | type = 'limit' # or 'market'
20 | side = 'sell' # or 'buy'
21 | amount = 1.0
22 | price = 0.060154 # or None
23 |
24 | # extra params and overrides if needed
25 | params = {
26 | 'test': True, # test if it's valid, but don't actually place it
27 | }
28 |
29 | order = exchange.create_order(symbol, type, side, amount, price, params)
30 |
31 | print(order)
32 |
--------------------------------------------------------------------------------
/examples/py/bitfinex-rate-limiting.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | import os
4 | import sys
5 |
6 | root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
7 | sys.path.append(root + '/python')
8 |
9 | import ccxt # noqa: E402
10 |
11 |
12 | symbol = 'ETH/BTC'
13 |
14 | exchange = ccxt.bitfinex({
15 |
16 | 'enableRateLimit': True, # or .enableRateLimit = True later
17 |
18 | # BITFINEX RATELIMITS DON'T CORRESPOND TO THEIR DOCUMENTATION!
19 |
20 | # their actual rate limit is significantly more strict than documented!
21 | 'rateLimit': 3000, # once every 3 seconds, 20 times per minute – will work
22 |
23 | # this is their documented ratelimit according to this page:
24 | # https://docs.bitfinex.com/v1/reference#rest-public-orderbook
25 | # 'rateLimit': 1000, # once every second, 60 times per minute – won't work, will throw DDoSProtection
26 | })
27 |
28 | for i in range(0, 100):
29 | print('--------------------------------------------------------------------')
30 | print(i)
31 | print('sent:', exchange.iso8601(exchange.milliseconds()))
32 | orderbook = exchange.fetch_order_book(symbol)
33 | print('received:', exchange.iso8601(exchange.milliseconds()), 'bid:', orderbook['bids'][0], 'ask:', orderbook['asks'][0])
34 |
--------------------------------------------------------------------------------
/examples/py/bitmex-create-order.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | import os
4 | import sys
5 |
6 | root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
7 | sys.path.append(root + '/python')
8 |
9 | import ccxt # noqa: E402
10 |
11 |
12 | exchange = ccxt.bitmex({
13 | 'apiKey': 'YOUR_API_KEY',
14 | 'secret': 'YOUR_SECRET',
15 | 'enableRateLimit': True,
16 | })
17 |
18 | symbol = 'XBTM18' # bitcoin contract according to bitmex futures coding
19 | type = 'StopLimit' # or 'market', or 'Stop' or 'StopLimit'
20 | side = 'sell' # or 'buy'
21 | amount = 1.0
22 | price = 6500.0 # or None
23 |
24 | # extra params and overrides
25 | params = {
26 | 'stopPx': 6000.0, # if needed
27 | }
28 |
29 | order = exchange.create_order(symbol, type, side, amount, price, params)
30 | print(order)
31 |
--------------------------------------------------------------------------------
/examples/py/bitmex-fetch-ohlcv-with-extra-params.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | import os
4 | import sys
5 | import time
6 |
7 | root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
8 | sys.path.append(root + '/python')
9 |
10 | import ccxt # noqa: E402
11 |
12 | bitmex = ccxt.bitmex()
13 |
14 | # params:
15 | symbol = 'BTC/USD'
16 | timeframe = '1m'
17 | limit = 100
18 | params = {'partial': False} # ←-------- no reversal
19 |
20 | while True:
21 |
22 | # pay attention to since with respect to limit if you're doing it in a loop
23 | since = bitmex.milliseconds() - limit * 60 * 1000
24 |
25 | candles = bitmex.fetch_ohlcv(symbol, timeframe, since, limit, params)
26 | num_candles = len(candles)
27 | print('{}: O: {} H: {} L:{} C:{}'.format(
28 | bitmex.iso8601(candles[num_candles - 1][0]),
29 | candles[num_candles - 1][1],
30 | candles[num_candles - 1][2],
31 | candles[num_candles - 1][3],
32 | candles[num_candles - 1][4]))
33 | # * 5 to make distinct delay and to avoid too much load
34 | # / 1000 to convert milliseconds to fractional seconds
35 | time.sleep(bitmex.rateLimit * 5 / 1000)
36 |
--------------------------------------------------------------------------------
/examples/py/bitmex-ohlcv-convert-5m-to-15m.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | import os
4 | import sys
5 | from pprint import pprint
6 |
7 | root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
8 | sys.path.append(root + '/python')
9 |
10 | import ccxt # noqa: E402
11 |
12 |
13 | bitmex = ccxt.bitmex({
14 | 'enableRateLimit': True,
15 | # 'verbose': True,
16 | })
17 |
18 | # fetch 5m OHLCV
19 |
20 | symbol = 'BTC/USD'
21 |
22 | ohlcv5 = bitmex.fetch_ohlcv(symbol, '5m')
23 | ohlcv15 = []
24 |
25 | # OHLCV key indexes
26 |
27 | timestamp = 0
28 | open = 1
29 | high = 2
30 | low = 3
31 | close = 4
32 | volume = 5
33 |
34 | # convert 5m → 15m
35 |
36 | if len(ohlcv5) > 2:
37 | for i in range(0, len(ohlcv5) - 2, 3):
38 | highs = [ohlcv5[i + j][high] for j in range(0, 3) if ohlcv5[i + j][high]]
39 | lows = [ohlcv5[i + j][low] for j in range(0, 3) if ohlcv5[i + j][low]]
40 | volumes = [ohlcv5[i + j][volume] for j in range(0, 3) if ohlcv5[i + j][volume]]
41 | candle = [
42 | ohlcv5[i + 0][timestamp],
43 | ohlcv5[i + 0][open],
44 | max(highs) if len(highs) else None,
45 | min(lows) if len(lows) else None,
46 | ohlcv5[i + 2][close],
47 | sum(volumes) if len(volumes) else None,
48 | ]
49 | ohlcv15.append(candle)
50 | else:
51 | raise Exception('Too few 5m candles')
52 |
53 | # do whatever you want with your 15m candles here...
54 |
55 | pprint(ohlcv15)
56 |
--------------------------------------------------------------------------------
/examples/py/builtin-rate-limiting-long-poller.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | import os
4 | import sys
5 |
6 | root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
7 | sys.path.append(root + '/python')
8 |
9 | import ccxt # noqa: E402
10 |
11 | # if you imported the ccxt library with `import ccxt` you can
12 | # set enableRateLimit = True to enable the rate limit in synchronous version of ccxt
13 | # this way you request rate will never hit the limit of an exchange
14 | # the library will throttle your requests to avoid that
15 |
16 | exchange = ccxt.bitfinex({
17 | 'enableRateLimit': True, # this option enables the built-in rate limiter
18 | })
19 |
20 | for i in range(0, 10):
21 | # this can be any call instead of fetch_ticker, really
22 | print(exchange.fetch_ticker('BTC/USD'))
23 |
--------------------------------------------------------------------------------
/examples/py/bypass-cloudflare.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | import cfscrape
4 | import os
5 | import sys
6 |
7 | root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
8 | sys.path.append(root + '/python')
9 |
10 | import ccxt # noqa: E402
11 |
12 |
13 | def print_supported_exchanges():
14 | print('Supported exchanges:')
15 | print(', '.join(ccxt.exchanges))
16 |
17 |
18 | try:
19 |
20 | id = sys.argv[1] # get exchange id from command line arguments
21 |
22 | # check if the exchange is supported by ccxt
23 | exchange_found = id in ccxt.exchanges
24 |
25 | if exchange_found:
26 |
27 | print('Instantiating ' + id + ' exchange')
28 |
29 | # instantiate the exchange by id
30 | exchange = getattr(ccxt, id)({
31 | 'timeout': 20000,
32 | 'session': cfscrape.create_scraper(),
33 | })
34 |
35 | try:
36 |
37 | # load all markets from the exchange
38 | markets = exchange.load_markets()
39 |
40 | # output a list of all market symbols
41 | print(id + ' has ' + str(len(exchange.symbols)) + ' symbols: ' + ', '.join(exchange.symbols))
42 | print('Succeeded.')
43 |
44 | except ccxt.BaseError as e:
45 |
46 | print(type(e).__name__, str(e))
47 | print('Failed.')
48 |
49 | else:
50 |
51 | print('Exchange ' + id + ' not found')
52 | print_supported_exchanges()
53 |
54 | except Exception as e:
55 | print('[' + type(e).__name__ + ']', str(e))
56 | print('Usage: python ' + sys.argv[0] + ' id')
57 | print_supported_exchanges()
58 |
--------------------------------------------------------------------------------
/examples/py/cryptopia-fetch-order-books.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | import os
4 | import sys
5 | from pprint import pprint
6 |
7 | root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
8 | sys.path.append(root + '/python')
9 |
10 | import ccxt # noqa: E402
11 |
12 | id = 'cryptopia'
13 |
14 | # instantiate the exchange by id
15 | exchange = getattr(ccxt, id)({
16 | # 'proxy':'https://cors-anywhere.herokuapp.com/',
17 | })
18 |
19 | # load all markets from the exchange
20 | markets = exchange.load_markets()
21 |
22 | # this will work (a limited number of symbols)
23 | result = exchange.fetch_order_books(['ETH/BTC', 'LTC/BTC'])
24 | pprint(result)
25 |
26 | # this will also work (a limited number of symbols)
27 | result = exchange.fetch_order_books(exchange.symbols[0:10])
28 | pprint(result)
29 |
30 | # this will not work (too many symbols)
31 | result = exchange.fetch_order_books(exchange.symbols)
32 | pprint(result)
33 |
--------------------------------------------------------------------------------
/examples/py/exchanges.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | import os
4 | import sys
5 | root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
6 | sys.path.append(root + '/python')
7 |
8 | import ccxt # noqa: E402
9 |
10 |
11 | def style(s, style):
12 | return style + s + '\033[0m'
13 |
14 |
15 | def green(s):
16 | return style(s, '\033[92m')
17 |
18 |
19 | def blue(s):
20 | return style(s, '\033[94m')
21 |
22 |
23 | def yellow(s):
24 | return style(s, '\033[93m')
25 |
26 |
27 | def red(s):
28 | return style(s, '\033[91m')
29 |
30 |
31 | def pink(s):
32 | return style(s, '\033[95m')
33 |
34 |
35 | def bold(s):
36 | return style(s, '\033[1m')
37 |
38 |
39 | def underline(s):
40 | return style(s, '\033[4m')
41 |
42 |
43 | def log(*args):
44 | print(' '.join([str(arg) for arg in args]))
45 |
46 |
47 | exchanges = {}
48 |
49 | for id in ccxt.exchanges:
50 | exchange = getattr(ccxt, id)
51 | exchanges[id] = exchange()
52 |
53 | log('The ccxt library supports', green(str(len(ccxt.exchanges))), 'exchanges:')
54 |
55 | # output a table of all exchanges
56 | log(pink('{:<15} {:<15} {:<15}'.format('id', 'name', 'URL')))
57 | tuples = list(ccxt.Exchange.keysort(exchanges).items())
58 | for (id, params) in tuples:
59 | exchange = exchanges[id]
60 | website = exchange.urls['www'][0] if type(exchange.urls['www']) is list else exchange.urls['www']
61 | log('{:<15} {:<15} {:<15}'.format(exchange.id, exchange.name, website))
62 |
--------------------------------------------------------------------------------
/examples/py/fetch-gdax-ohlcv-sequentially.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | import os
4 | import sys
5 | import time
6 |
7 | root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
8 | sys.path.append(root + '/python')
9 |
10 | import ccxt # noqa: E402
11 |
12 | # -----------------------------------------------------------------------------
13 | # common constants
14 |
15 | msec = 1000
16 | minute = 60 * msec
17 | hold = 30
18 |
19 | # -----------------------------------------------------------------------------
20 |
21 | exchange = ccxt.gdax({
22 | 'rateLimit': 3000,
23 | 'enableRateLimit': True,
24 | # 'verbose': True,
25 | })
26 |
27 | # -----------------------------------------------------------------------------
28 |
29 | from_datetime = '2017-09-01 00:00:00'
30 | from_timestamp = exchange.parse8601(from_datetime)
31 |
32 | # -----------------------------------------------------------------------------
33 |
34 | now = exchange.milliseconds()
35 |
36 | # -----------------------------------------------------------------------------
37 |
38 | data = []
39 |
40 | while from_timestamp < now:
41 |
42 | try:
43 |
44 | print(exchange.milliseconds(), 'Fetching candles starting from', exchange.iso8601(from_timestamp))
45 | ohlcvs = exchange.fetch_ohlcv('BTC/USD', '1m', from_timestamp)
46 | print(exchange.milliseconds(), 'Fetched', len(ohlcvs), 'candles')
47 | from_timestamp = ohlcvs[-1][0]
48 | data += ohlcvs
49 |
50 | except (ccxt.ExchangeError, ccxt.AuthenticationError, ccxt.ExchangeNotAvailable, ccxt.RequestTimeout) as error:
51 |
52 | print('Got an error', type(error).__name__, error.args, ', retrying in', hold, 'seconds...')
53 | time.sleep(hold)
54 |
--------------------------------------------------------------------------------
/examples/py/fetch-ohlcv-cex.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | import os
4 | import sys
5 | import asciichart
6 |
7 | # -----------------------------------------------------------------------------
8 |
9 | this_folder = os.path.dirname(os.path.abspath(__file__))
10 | root_folder = os.path.dirname(os.path.dirname(this_folder))
11 | sys.path.append(root_folder + '/python')
12 | sys.path.append(this_folder)
13 |
14 | # -----------------------------------------------------------------------------
15 |
16 | import ccxt # noqa: E402
17 |
18 | # -----------------------------------------------------------------------------
19 |
20 | exchange = ccxt.cex()
21 | symbol = 'BTC/USD'
22 |
23 | # each ohlcv candle is a list of [ timestamp, open, high, low, close, volume ]
24 | index = 4 # use close price from each ohlcv candle
25 |
26 | length = 80
27 | height = 15
28 |
29 |
30 | def print_chart(exchange, symbol, timeframe):
31 |
32 | print("\n" + exchange.name + ' ' + symbol + ' ' + timeframe + ' chart:')
33 |
34 | # get a list of ohlcv candles
35 | ohlcv = exchange.fetch_ohlcv(symbol, timeframe)
36 |
37 | # get the ohlCv (closing price, index == 4)
38 | series = [x[index] for x in ohlcv]
39 |
40 | # print the chart
41 | print("\n" + asciichart.plot(series[-length:], {'height': height})) # print the chart
42 |
43 | last = ohlcv[len(ohlcv) - 1][index] # last closing price
44 | return last
45 |
46 |
47 | last = print_chart(exchange, symbol, '1m')
48 | print("\n" + exchange.name + " ₿ = $" + str(last) + "\n") # print last closing price
49 |
--------------------------------------------------------------------------------
/examples/py/fetch-ohlcv-kraken.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | import os
4 | import sys
5 | import asciichart
6 |
7 | # -----------------------------------------------------------------------------
8 |
9 | this_folder = os.path.dirname(os.path.abspath(__file__))
10 | root_folder = os.path.dirname(os.path.dirname(this_folder))
11 | sys.path.append(root_folder + '/python')
12 | sys.path.append(this_folder)
13 |
14 | # -----------------------------------------------------------------------------
15 |
16 | import ccxt # noqa: E402
17 |
18 | # -----------------------------------------------------------------------------
19 |
20 | exchange = ccxt.kraken()
21 | symbol = 'LTC/EUR'
22 |
23 | # each ohlcv candle is a list of [ timestamp, open, high, low, close, volume ]
24 | index = 4 # use close price from each ohlcv candle
25 |
26 | length = 80
27 | height = 15
28 |
29 |
30 | def print_chart(exchange, symbol, timeframe):
31 |
32 | # get a list of ohlcv candles
33 | ohlcv = exchange.fetch_ohlcv(symbol, timeframe)
34 |
35 | # get the ohlCv (closing price, index == 4)
36 | series = [x[index] for x in ohlcv]
37 |
38 | # print datetime and other values
39 | for x in ohlcv:
40 | print(exchange.iso8601(x[0]), x)
41 |
42 | print("\n" + exchange.name + ' ' + symbol + ' ' + timeframe + ' chart:')
43 |
44 | # print the chart
45 | print("\n" + asciichart.plot(series[-length:], {'height': height})) # print the chart
46 |
47 | last = ohlcv[len(ohlcv) - 1][index] # last closing price
48 | return last
49 |
50 |
51 | last = print_chart(exchange, symbol, '1m')
52 | print("\n" + exchange.name + ' last price: ' + str(last) + "\n") # print last closing price
53 |
--------------------------------------------------------------------------------
/examples/py/fetch-okex-futures.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | import os
4 | import sys
5 | import time
6 |
7 | # ------------------------------------------------------------------------------
8 |
9 | root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
10 | sys.path.append(root + '/python')
11 |
12 | # ------------------------------------------------------------------------------
13 |
14 | import ccxt # noqa: E402
15 |
16 | # ------------------------------------------------------------------------------
17 |
18 | exchange = ccxt.okex()
19 | exchange.load_markets()
20 | for symbol in exchange.markets:
21 | market = exchange.markets[symbol]
22 | if market['future']:
23 | print('----------------------------------------------------')
24 | print(symbol, exchange.fetchTicker(symbol))
25 | time.sleep(exchange.rateLimit / 1000)
26 |
--------------------------------------------------------------------------------
/examples/py/fetch-orders.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | import os
4 | import sys
5 |
6 | root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
7 | sys.path.append(root + '/python')
8 |
9 | import ccxt # noqa: E402
10 |
11 | exchange = ccxt.bittrex({
12 | "apiKey": "471b47a06c384e81b24072e9a8739064",
13 | "secret": "694025686e9445589787e8ca212b4cff",
14 | "enableRateLimit": True,
15 | })
16 |
17 | orders = exchange.fetch_orders()
18 | print(orders)
19 |
20 | order = exchange.fetch_order(orders[0]['id'])
21 | print(order)
22 |
--------------------------------------------------------------------------------
/examples/py/gdax-fetch-my-trades-pagination.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | import os
4 | import sys
5 | root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
6 | sys.path.append(root + '/python')
7 |
8 | import ccxt # noqa: E402
9 |
10 | '''
11 | Example snippet to traverse GDAX / CoinBase Pro pagination.
12 | Useful for reaching back more than 100 myTrades, the same works
13 | for fetchClosedOrders
14 | '''
15 |
16 | exchange = ccxt.gdax({
17 | "apiKey": "123456",
18 | "secret": "/abcdefghijklmnop/w==",
19 | "password": "987654321",
20 | "enableRateLimit": True
21 | })
22 |
23 | param_key = ''
24 | param_value = ''
25 | allMyTrades = []
26 |
27 | while True:
28 | myTrades = exchange.fetch_my_trades(symbol='BTC/USD', params={param_key: param_value})
29 |
30 | # Handle gdax with pagination ...
31 | if exchange.last_response_headers._store.get('cb-after'):
32 | param_key = 'after'
33 | param_value = exchange.last_response_headers._store['cb-after'][1]
34 |
35 | allMyTrades.extend(myTrades)
36 |
37 | else:
38 | allMyTrades.extend(myTrades)
39 | break
40 |
41 | for trade in allMyTrades:
42 | print(trade)
43 |
--------------------------------------------------------------------------------
/examples/py/hitbtc2-withdraw.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | from pprint import pprint
4 |
5 | import os
6 | import sys
7 |
8 | root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
9 | sys.path.append(root + '/python')
10 |
11 | import ccxt # noqa: E402
12 |
13 |
14 | def get_positive_accounts(balance):
15 | result = {}
16 | currencies = list(balance.keys())
17 | for currency in currencies:
18 | if balance[currency] and balance[currency] > 0:
19 | result[currency] = balance[currency]
20 | return result
21 |
22 |
23 | exchange = ccxt.hitbtc2({
24 | "apiKey": "a34ca826b430bdfcca969241b0f7bd2d",
25 | "secret": "7b28d6b17aea18ae39903add0dae048a",
26 | "enableRateLimit": True,
27 | })
28 |
29 |
30 | trading_balance = exchange.fetch_balance()
31 | account_balance = exchange.fetch_balance({'type': 'account'})
32 |
33 | pprint('Trading balance:')
34 | pprint(get_positive_accounts(trading_balance['total']))
35 | pprint('Account balance:')
36 | pprint(get_positive_accounts(account_balance['total']))
37 |
38 |
39 | withdraw = exchange.withdraw('ETH', 0.01, '0x811DCfeb6dC0b9ed825808B6B060Ca469b83fB81')
40 |
41 |
42 | pprint('Withdraw:')
43 | pprint(withdraw)
44 |
--------------------------------------------------------------------------------
/examples/py/instantiate-all-at-once.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | import os
4 | import sys
5 |
6 | root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
7 | sys.path.append(root + '/python')
8 |
9 | import ccxt # noqa: E402
10 |
11 | exchanges = {} # a placeholder for your instances
12 |
13 | for id in ccxt.exchanges:
14 | exchange = getattr(ccxt, id)
15 | exchanges[id] = exchange()
16 |
17 | # now exchanges dictionary contains all exchange instances...
18 | exchanges['bittrex'].fetch_order_book('ETH/BTC')
19 |
--------------------------------------------------------------------------------
/examples/py/manual-rate-limiting-long-poller.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | import os
4 | import sys
5 | import time
6 |
7 | root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
8 | sys.path.append(root + '/python')
9 |
10 | import ccxt # noqa: E402
11 |
12 | # if you imported the ccxt library with `import ccxt` you can
13 | # throttle your requests manually, by using the rateLimit property of an exchange
14 | # to delay each request by waiting for some time to stay below request rate limits
15 |
16 | exchange = ccxt.bitfinex()
17 |
18 | # the rateLimit is in milliseconds → divide it by a thousand to get seconds
19 | delay = exchange.rateLimit / 1000
20 |
21 | for i in range(0, 10):
22 | # this can be any call instead of fetch_ticker, really
23 | print(exchange.fetch_ticker('BTC/USD'))
24 | time.sleep(delay) # sleep a little before sending each next request
25 |
--------------------------------------------------------------------------------
/examples/py/margin-leverage-order-kraken.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | import os
4 | import sys
5 |
6 | root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
7 | sys.path.append(root + '/python')
8 |
9 | import ccxt # noqa: E402
10 |
11 |
12 | kraken = ccxt.kraken({
13 | 'apiKey': 'YOUR_API_KEY',
14 | 'secret': 'YOUR_SECRET',
15 | })
16 |
17 | kraken.load_markets()
18 |
19 | for symbol in kraken.symbols:
20 | print(
21 | symbol,
22 | 'Available leverage levels',
23 | 'Buy:', kraken.markets[symbol]['info']['leverage_buy'],
24 | 'Sell:', kraken.markets[symbol]['info']['leverage_sell']
25 | )
26 |
27 | # THIS IS A KRAKEN-SPECIFIC EXAMPLE.
28 | # THE LEVERAGE WILL NOT WORK WITH OTHER EXCHANGES THE SAME WAY.
29 | # USE IMPLICIT METHODS FOR MARGIN/LEVERAGED ORDERS WITH OTHER EXCHANGES:
30 | # https://github.com/ccxt/ccxt/wiki/Manual#implicit-api-methods
31 |
32 | # with create_order all params (including the price=None) are needed!
33 | # the extra param should be "leverage", not "leverage_sell" nor "leverage-sell"
34 | kraken.create_order('BTC/USD', 'market', 'sell', 0.01, None, {'leverage': 3})
35 |
36 | # or use a shorthand create_market_sell_order (no "price" param)
37 | kraken.create_market_sell_order('BTC/USD', 0.01, {'leverage': 3})
38 |
--------------------------------------------------------------------------------
/examples/py/minimal-2-lines.py:
--------------------------------------------------------------------------------
1 | import ccxt
2 | print(ccxt.bitfinex().fetch_ticker('BTC/USD'))
3 |
--------------------------------------------------------------------------------
/examples/py/normalize-sparse-candle-timestamps.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | import os
4 | import sys
5 | from pprint import pprint
6 |
7 | root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
8 | sys.path.append(root + '/python')
9 |
10 | import ccxt # noqa: E402
11 |
12 | exchange = ccxt.cryptopia({'enableRateLimit': True})
13 |
14 | symbol = 'ETH/BTC'
15 | timeframe = '1h'
16 |
17 | candles = exchange.fetch_ohlcv(symbol, timeframe)
18 |
19 | # timeframe duration in seconds
20 | duration = exchange.parse_timeframe(timeframe)
21 |
22 | # timeframe duration in milliseconds
23 | duration *= 1000
24 |
25 | pprint([[
26 | exchange.iso8601(int(round(candle[0] / duration)) * duration),
27 | candle[1], # o
28 | candle[2], # h
29 | candle[3], # l
30 | candle[4], # c
31 | candle[5] # v
32 | ] for candle in candles])
33 |
--------------------------------------------------------------------------------
/examples/py/order-book-extra-level-depth-param.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | import os
4 | import sys
5 |
6 | root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
7 | sys.path.append(root + '/python')
8 |
9 | import ccxt # noqa: E402
10 |
11 | # return up to ten bidasks on each side of the order book stack
12 | limit = 10
13 | print(ccxt.cex().fetch_order_book('BTC/USD', limit))
14 |
--------------------------------------------------------------------------------
/examples/py/proxy-sync-python-requests-2-and-3.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | import os
4 | import sys
5 |
6 | from pprint import pprint
7 |
8 | root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
9 | sys.path.append(root + '/python')
10 |
11 | import ccxt # noqa: E402
12 |
13 | exchange = ccxt.poloniex({
14 | #
15 | # ↓ The "proxy" property setting below is for CORS-proxying only!
16 | # Do not use it if you don't know what a CORS proxy is.
17 | # https://github.com/ccxt/ccxt/wiki/Install#cors-access-control-allow-origin
18 | # You should only use the "proxy" setting if you're having a problem with Access-Control-Allow-Origin
19 | # In Python you rarely need to use it, if ever at all.
20 | #
21 | # 'proxy': 'https://cors-anywhere.herokuapp.com/',
22 | #
23 | # ↓ On the other hand, the "proxies" setting is for HTTP(S)-proxying (SOCKS, etc...)
24 | # It is a standard method of sending your requests through your proxies
25 | # This gets passed to the `python-requests` implementation directly
26 | # You can also enable this with environment variables, as described here:
27 | # http://docs.python-requests.org/en/master/user/advanced/#proxies
28 | # The environment variables should be set before importing ccxt (!)
29 | # This is the setting you should be using with synchronous version of ccxt in Python 2 and 3
30 | #
31 | 'proxies': {
32 | 'http': 'http://10.10.1.10:3128',
33 | 'https': 'http://10.10.1.10:1080',
34 | },
35 | })
36 |
37 | # your code goes here...
38 |
39 | pprint(exchange.fetch_ticker('ETH/BTC'))
40 |
--------------------------------------------------------------------------------
/exchanges.cfg:
--------------------------------------------------------------------------------
1 | # -------------------------------------------------------------------------------
2 | # You can create a custom bundle of CCXT including only the exchanges you need.
3 | # Add or uncomment ids below and launch `npm run build`.
4 | # Leaving this config empty will build all exchanges.
5 | # -------------------------------------------------------------------------------
6 |
7 | # binance
8 | # huobi
9 | # kraken
10 |
--------------------------------------------------------------------------------
/js/base/.eslintrc.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = {
4 | "env": {
5 | "node": true,
6 | "es6": true,
7 | "browser": true,
8 | },
9 | "parserOptions": {
10 | "ecmaVersion": 2017,
11 | "sourceType": "script",
12 | },
13 | "rules": {
14 | "semi": "off",
15 | "no-unused-vars": ["off"],
16 | "quotes": ["off", "single"],
17 | "quote-props": "off",
18 | "func-call-spacing": ["error", "always"],
19 | "one-var": "off",
20 | "indent": ["warn", 4, { "ignoredNodes": ["ObjectPattern"] }],
21 | "comma-style": "off",
22 | "no-multi-spaces": "off",
23 | "comma-dangle": "off",
24 | "spaced-comment": "off",
25 | "camelcase": "off",
26 | "padded-blocks": "off",
27 | "multiline-comment-style": "off",
28 | "curly": "off",
29 | "rest-spread-spacing": "off",
30 | "no-multiple-empty-lines": "off",
31 | "no-undef-init": "off",
32 | "no-useless-return": "off",
33 | "no-console": "off",
34 | "operator-linebreak": "off",
35 | "key-spacing": "off",
36 | "brace-style": "off",
37 | "padding-line-between-statements": ["off",
38 | {"blankLine": "never", "prev":"*", "next": "*" },
39 | {"blankLine": "always", "prev":"directive", "next": "*" },
40 | {"blankLine": "always", "prev":"*", "next": "cjs-export" },
41 | ],
42 | },
43 | }
44 |
--------------------------------------------------------------------------------
/js/base/Market.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | module.exports = class Market {
4 |
5 | constructor (exchange, symbol) {
6 | this.exchange = exchange;
7 | this.symbol = symbol;
8 | this.market = exchange.markets[symbol];
9 | }
10 |
11 | amountToPrecision (amount) {
12 | return this.exchange.amountToPrecision (this.symbol, amount)
13 | }
14 |
15 | createLimitBuyOrder(amount, price) {
16 | return this.exchange.createLimitBuyOrder (this.symbol, amount, price)
17 | }
18 |
19 | createLimitSellOrder(amount, price) {
20 | return this.exchange.createLimitSellOrder (this.symbol, amount, price)
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/js/base/functions.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /* ------------------------------------------------------------------------ */
4 |
5 | const { unCamelCase } = require ('./functions/string')
6 |
7 | const unCamelCasePropertyNames = x => {
8 | for (const k in x) x[unCamelCase (k)] = x[k] // camel_case_method = camelCaseMethod
9 | return x
10 | }
11 |
12 | /* ------------------------------------------------------------------------ */
13 |
14 | module.exports = unCamelCasePropertyNames (Object.assign ({}
15 |
16 | , require ('./functions/platform')
17 | , require ('./functions/generic')
18 | , require ('./functions/string')
19 | , require ('./functions/type')
20 | , require ('./functions/number')
21 | , require ('./functions/encode')
22 | , require ('./functions/crypto')
23 | , require ('./functions/time')
24 | , require ('./functions/throttle')
25 | , require ('./functions/misc')
26 | ))
27 |
28 | /* ------------------------------------------------------------------------ */
29 |
--------------------------------------------------------------------------------
/js/base/functions/platform.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | // ----------------------------------------------------------------------------
4 | // There's been a lot of messing with this code...
5 | // The problem is to satisfy the following requirements:
6 | // - properly detect isNode == true on server side and isNode == false in the browser (on client side)
7 | // - make sure create-react-app, react-starter-kit and other react frameworks work
8 | // - make sure it does not break the browserified version (when linked into a html from a cdn)
9 | // - make sure it does not break the webpacking and babel-transpiled scripts
10 | // - make sure it works in Electron
11 | // - make sure it works with Angular.js
12 | // - make sure it does not break other possible usage scenarios
13 |
14 | const isBrowser = typeof window !== 'undefined'
15 |
16 | const isElectron = typeof process !== 'undefined' &&
17 | typeof process.versions !== 'undefined' &&
18 | typeof process.versions.electron !== 'undefined'
19 |
20 | const isWebWorker = typeof WorkerGlobalScope !== 'undefined' && (self instanceof WorkerGlobalScope)
21 |
22 | const isWindows = typeof process !== 'undefined' && process.platform === "win32"
23 |
24 | const isNode = !(isBrowser || isWebWorker)
25 |
26 | // ----------------------------------------------------------------------------
27 |
28 | module.exports = {
29 |
30 | isBrowser,
31 | isElectron,
32 | isWebWorker,
33 | isNode,
34 | isWindows,
35 | }
--------------------------------------------------------------------------------
/js/base/functions/string.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | /* ------------------------------------------------------------------------ */
4 |
5 | const uuid = a => a ? (a ^ Math.random () * 16 >> a / 4).toString (16)
6 | : ([1e7]+-1e3+-4e3+-8e3+-1e11).replace (/[018]/g, uuid)
7 |
8 | module.exports =
9 |
10 | { uuid
11 |
12 | // hasFetchOHLCV → has_fetch_ohlcv; parseHTTPResponse → parse_http_response
13 | , unCamelCase: s => s.match (/^[A-Z0-9_]+$/) ? s : (s.replace (/[a-z0-9][A-Z]/g, x => x[0] + '_' + x[1]).replace(/[A-Z0-9][A-Z0-9][a-z]/g, x => x[0] + '_' + x[1] + x[2]).toLowerCase ())
14 |
15 | , capitalize: s => s.length
16 | ? (s.charAt (0).toUpperCase () + s.slice (1))
17 | : s
18 | }
19 |
20 | /* ------------------------------------------------------------------------ */
21 |
--------------------------------------------------------------------------------
/js/bitkk.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | // ---------------------------------------------------------------------------
4 |
5 | const zb = require ('./zb.js');
6 |
7 | // ---------------------------------------------------------------------------
8 |
9 | module.exports = class bitkk extends zb {
10 | describe () {
11 | return this.deepExtend (super.describe (), {
12 | 'id': 'bitkk',
13 | 'name': 'bitkk',
14 | 'comment': 'a Chinese ZB clone',
15 | 'urls': {
16 | 'api': {
17 | 'public': 'http://api.bitkk.com/data', // no https for public API
18 | 'private': 'https://trade.bitkk.com/api',
19 | },
20 | 'www': 'https://www.bitkk.com',
21 | 'doc': 'https://www.bitkk.com/i/developer',
22 | 'fees': 'https://www.bitkk.com/i/rate',
23 | },
24 | });
25 | }
26 | };
27 |
--------------------------------------------------------------------------------
/js/btcexchange.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | // ---------------------------------------------------------------------------
4 |
5 | const btcturk = require ('./btcturk.js');
6 |
7 | // ---------------------------------------------------------------------------
8 |
9 | module.exports = class btcexchange extends btcturk {
10 | describe () {
11 | return this.deepExtend (super.describe (), {
12 | 'id': 'btcexchange',
13 | 'name': 'BTCExchange',
14 | 'countries': [ 'PH' ], // Philippines
15 | 'rateLimit': 1500,
16 | 'has': {
17 | 'CORS': false,
18 | },
19 | 'urls': {
20 | 'logo': 'https://user-images.githubusercontent.com/1294454/27993052-4c92911a-64aa-11e7-96d8-ec6ac3435757.jpg',
21 | 'api': 'https://www.btcexchange.ph/api',
22 | 'www': 'https://www.btcexchange.ph',
23 | 'doc': 'https://github.com/BTCTrader/broker-api-docs',
24 | },
25 | 'markets': {
26 | 'BTC/PHP': { 'id': 'BTC/PHP', 'symbol': 'BTC/PHP', 'base': 'BTC', 'quote': 'PHP' },
27 | },
28 | });
29 | }
30 | };
31 |
--------------------------------------------------------------------------------
/js/chilebit.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | // ---------------------------------------------------------------------------
4 |
5 | const foxbit = require ('./foxbit.js');
6 |
7 | // ---------------------------------------------------------------------------
8 |
9 | module.exports = class chilebit extends foxbit {
10 | describe () {
11 | return this.deepExtend (super.describe (), {
12 | 'id': 'chilebit',
13 | 'name': 'ChileBit',
14 | 'countries': [ 'CL' ],
15 | 'has': {
16 | 'CORS': false,
17 | },
18 | 'urls': {
19 | 'logo': 'https://user-images.githubusercontent.com/1294454/27991414-1298f0d8-647f-11e7-9c40-d56409266336.jpg',
20 | 'api': {
21 | 'public': 'https://api.blinktrade.com/api',
22 | 'private': 'https://api.blinktrade.com/tapi',
23 | },
24 | 'www': 'https://chilebit.net',
25 | 'doc': 'https://blinktrade.com/docs',
26 | },
27 | 'options': {
28 | 'brokerId': '9', // https://blinktrade.com/docs/#brokers
29 | },
30 | });
31 | }
32 | };
33 |
--------------------------------------------------------------------------------
/js/coinbaseprime.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | // ---------------------------------------------------------------------------
4 |
5 | const gdax = require ('./gdax.js');
6 |
7 | // ---------------------------------------------------------------------------
8 |
9 | module.exports = class coinbaseprime extends gdax {
10 | describe () {
11 | return this.deepExtend (super.describe (), {
12 | 'id': 'coinbaseprime',
13 | 'name': 'Coinbase Prime',
14 | 'urls': {
15 | 'test': 'https://api-public.sandbox.prime.coinbase.com',
16 | 'logo': 'https://user-images.githubusercontent.com/1294454/44539184-29f26e00-a70c-11e8-868f-e907fc236a7c.jpg',
17 | 'api': 'https://api.prime.coinbase.com',
18 | 'www': 'https://prime.coinbase.com',
19 | 'doc': 'https://docs.prime.coinbase.com',
20 | 'fees': 'https://support.prime.coinbase.com/customer/en/portal/articles/2945629-fees?b_id=17475',
21 | },
22 | });
23 | }
24 | };
25 |
--------------------------------------------------------------------------------
/js/coinbasepro.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | // ---------------------------------------------------------------------------
4 |
5 | const gdax = require ('./gdax.js');
6 |
7 | // ---------------------------------------------------------------------------
8 |
9 | module.exports = class coinbasepro extends gdax {
10 | describe () {
11 | return this.deepExtend (super.describe (), {
12 | 'id': 'coinbasepro',
13 | 'name': 'Coinbase Pro',
14 | 'urls': {
15 | 'test': 'https://api-public.sandbox.pro.coinbase.com',
16 | 'logo': 'https://user-images.githubusercontent.com/1294454/41764625-63b7ffde-760a-11e8-996d-a6328fa9347a.jpg',
17 | 'api': 'https://api.pro.coinbase.com',
18 | 'www': 'https://pro.coinbase.com/',
19 | 'doc': 'https://docs.pro.coinbase.com/',
20 | 'fees': [
21 | 'https://docs.pro.coinbase.com/#fees',
22 | 'https://support.pro.coinbase.com/customer/en/portal/articles/2945310-fees',
23 | ],
24 | },
25 | });
26 | }
27 | };
28 |
--------------------------------------------------------------------------------
/js/fybsg.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | // ---------------------------------------------------------------------------
4 |
5 | const fybse = require ('./fybse.js');
6 |
7 | // ---------------------------------------------------------------------------
8 |
9 | module.exports = class fybsg extends fybse {
10 | describe () {
11 | return this.deepExtend (super.describe (), {
12 | 'id': 'fybsg',
13 | 'name': 'FYB-SG',
14 | 'countries': [ 'SG' ], // Singapore
15 | 'has': {
16 | 'CORS': false,
17 | },
18 | 'urls': {
19 | 'logo': 'https://user-images.githubusercontent.com/1294454/27766513-3364d56a-5edb-11e7-9e6b-d5898bb89c81.jpg',
20 | 'api': 'https://www.fybsg.com/api/SGD',
21 | 'www': 'https://www.fybsg.com',
22 | 'doc': 'http://docs.fyb.apiary.io',
23 | },
24 | 'markets': {
25 | 'BTC/SGD': { 'id': 'SGD', 'symbol': 'BTC/SGD', 'base': 'BTC', 'quote': 'SGD' },
26 | },
27 | });
28 | }
29 | };
30 |
--------------------------------------------------------------------------------
/js/huobicny.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | // ---------------------------------------------------------------------------
4 |
5 | const huobipro = require ('./huobipro.js');
6 |
7 | // ---------------------------------------------------------------------------
8 |
9 | module.exports = class huobicny extends huobipro {
10 | describe () {
11 | return this.deepExtend (super.describe (), {
12 | 'id': 'huobicny',
13 | 'name': 'Huobi CNY',
14 | 'hostname': 'be.huobi.com',
15 | 'has': {
16 | 'CORS': false,
17 | },
18 | 'urls': {
19 | 'logo': 'https://user-images.githubusercontent.com/1294454/27766569-15aa7b9a-5edd-11e7-9e7f-44791f4ee49c.jpg',
20 | 'api': {
21 | 'public': 'https://be.huobi.com',
22 | 'private': 'https://be.huobi.com',
23 | 'market': 'https://be.huobi.com',
24 | },
25 | 'www': 'https://www.huobi.com',
26 | 'doc': 'https://github.com/huobiapi/API_Docs/wiki/REST_api_reference',
27 | },
28 | });
29 | }
30 | };
31 |
--------------------------------------------------------------------------------
/js/qryptos.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | // ---------------------------------------------------------------------------
4 |
5 | const liquid = require ('./liquid');
6 |
7 | // ---------------------------------------------------------------------------
8 |
9 | module.exports = class qryptos extends liquid {
10 | describe () {
11 | return this.deepExtend (super.describe (), {
12 | 'id': 'qryptos',
13 | 'name': 'QRYPTOS',
14 | });
15 | }
16 | };
17 |
--------------------------------------------------------------------------------
/js/quoinex.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | // ---------------------------------------------------------------------------
4 |
5 | const liquid = require ('./liquid');
6 |
7 | // ---------------------------------------------------------------------------
8 |
9 | module.exports = class quoinex extends liquid {
10 | describe () {
11 | return this.deepExtend (super.describe (), {
12 | 'id': 'quoinex',
13 | 'name': 'QUOINEX',
14 | });
15 | }
16 | };
17 |
--------------------------------------------------------------------------------
/js/surbitcoin.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | // ---------------------------------------------------------------------------
4 |
5 | const foxbit = require ('./foxbit.js');
6 |
7 | // ---------------------------------------------------------------------------
8 |
9 | module.exports = class surbitcoin extends foxbit {
10 | describe () {
11 | return this.deepExtend (super.describe (), {
12 | 'id': 'surbitcoin',
13 | 'name': 'SurBitcoin',
14 | 'countries': [ 'VE' ],
15 | 'has': {
16 | 'CORS': false,
17 | },
18 | 'urls': {
19 | 'logo': 'https://user-images.githubusercontent.com/1294454/27991511-f0a50194-6481-11e7-99b5-8f02932424cc.jpg',
20 | 'api': {
21 | 'public': 'https://api.blinktrade.com/api',
22 | 'private': 'https://api.blinktrade.com/tapi',
23 | },
24 | 'www': 'https://surbitcoin.com',
25 | 'doc': 'https://blinktrade.com/docs',
26 | },
27 | 'options': {
28 | 'brokerId': '1', // https://blinktrade.com/docs/#brokers
29 | },
30 | });
31 | }
32 | };
33 |
--------------------------------------------------------------------------------
/js/test/.eslintrc.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = {
4 | "env": {
5 | "node": true,
6 | "mocha": true
7 | },
8 | "parserOptions": {
9 | "ecmaVersion": 2017,
10 | "sourceType": "script",
11 | },
12 | "extends": ["eslint:recommended"],
13 | "rules": {
14 | "semi": ["error", "never"],
15 | "no-unused-vars": ["off"],
16 | "quotes": ["off", "single"],
17 | "func-call-spacing": ["error", "always"],
18 | "one-var": "off",
19 | "indent": ["error", 4],
20 | "comma-style": "off",
21 | "no-multi-spaces": "off",
22 | "comma-dangle": "off",
23 | "spaced-comment": "off",
24 | "camelcase": "off",
25 | "padded-blocks": "off",
26 | "multiline-comment-style": "off",
27 | "curly": "off",
28 | "rest-spread-spacing": "off",
29 | "no-multiple-empty-lines": "off",
30 | "no-undef-init": "off",
31 | "no-useless-return": "off",
32 | "no-console": "off",
33 | "operator-linebreak": "off",
34 | "key-spacing": "off",
35 | "brace-style": "off",
36 | "padding-line-between-statements": ["off",
37 | { "blankLine": "always", "prev":"function", "next": "*" },
38 | { "blankLine": "always", "prev":"directive", "next": "*" },
39 | { "blankLine": "always", "prev":"*", "next": "cjs-export" },
40 | ],
41 | "import/no-extraneous-dependencies": ["error", { "devDependencies": true }],
42 | },
43 | }
44 |
--------------------------------------------------------------------------------
/js/test/Exchange/test.fetchClosedOrders.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | // ----------------------------------------------------------------------------
4 |
5 | const log = require ('ololog')
6 | , ansi = require ('ansicolor').nice
7 | , chai = require ('chai')
8 | , expect = chai.expect
9 | , assert = chai.assert
10 | , testOrder = require ('./test.order.js')
11 |
12 | /* ------------------------------------------------------------------------ */
13 |
14 | module.exports = async (exchange, symbol) => {
15 |
16 | if (exchange.has.fetchClosedOrders) {
17 |
18 | // log ('fetching closed orders...')
19 |
20 | let orders = await exchange.fetchClosedOrders (symbol)
21 |
22 | log ('fetched', orders.length.toString ().green, 'closed orders, testing each')
23 |
24 | assert (orders instanceof Array)
25 |
26 | let now = Date.now ()
27 |
28 | for (let i = 0; i < orders.length; i++) {
29 | let order = orders[i]
30 | testOrder (exchange, order, symbol, now)
31 | assert (order.status === 'closed')
32 | }
33 |
34 | // log (asTable (orders))
35 |
36 | } else {
37 |
38 | log ('fetching closed orders not supported')
39 | }
40 | }
--------------------------------------------------------------------------------
/js/test/Exchange/test.fetchCurrencies.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | // ----------------------------------------------------------------------------
4 |
5 | const log = require ('ololog')
6 | , ansi = require ('ansicolor').nice
7 | , chai = require ('chai')
8 | , expect = chai.expect
9 | , assert = chai.assert
10 | , testCurrency = require ('./test.currency.js')
11 |
12 | /* ------------------------------------------------------------------------ */
13 |
14 | module.exports = async (exchange) => {
15 |
16 | const skippedExchanges = [
17 | ]
18 |
19 | if (skippedExchanges.includes (exchange.id)) {
20 | log (exchange.id, 'found in ignored exchanges, skipping fetchCurrencies...')
21 | return
22 | }
23 |
24 | if (exchange.has.fetchCurrencies) {
25 |
26 | // log ('fetching currencies...')
27 |
28 | const method = 'fetchCurrencies'
29 | const currencies = await exchange[method] ()
30 | Object.values (currencies).forEach (currency => testCurrency (exchange, currency, method))
31 | return currencies
32 |
33 | } else {
34 |
35 | log ('fetching currencies not supported')
36 | }
37 | }
38 |
39 |
--------------------------------------------------------------------------------
/js/test/Exchange/test.fetchFundingFees.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | // ----------------------------------------------------------------------------
4 |
5 | const log = require ('ololog')
6 | , ansi = require ('ansicolor').nice
7 | , chai = require ('chai')
8 | , expect = chai.expect
9 | , assert = chai.assert
10 |
11 | /* ------------------------------------------------------------------------ */
12 |
13 | module.exports = async (exchange) => {
14 |
15 | const skippedExchanges = [
16 | ]
17 |
18 | if (skippedExchanges.includes (exchange.id)) {
19 | log (exchange.id, 'found in ignored exchanges, skipping fetchFundingFees...')
20 | return
21 | }
22 |
23 | if (exchange.has.fetchFundingFees) {
24 |
25 | // log ('fetching funding fees...')
26 |
27 | const method = 'fetchFundingFees'
28 | const fees = await exchange[method] ()
29 | log.green (fees)
30 | return fees
31 |
32 | } else {
33 |
34 | log ('fetching funding fees not supported')
35 | }
36 | }
37 |
38 |
--------------------------------------------------------------------------------
/js/test/Exchange/test.fetchL2OrderBook.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | // ----------------------------------------------------------------------------
4 |
5 | const log = require ('ololog')
6 | , ansi = require ('ansicolor').nice
7 | , chai = require ('chai')
8 | , expect = chai.expect
9 | , assert = chai.assert
10 | , testOrderBook = require ('./test.orderbook.js')
11 |
12 | /* ------------------------------------------------------------------------ */
13 |
14 | module.exports = async (exchange, symbol) => {
15 |
16 | // log (symbol.green, 'fetching order book...')
17 |
18 | const method = 'fetchL2OrderBook'
19 |
20 | if (exchange.has[method]) {
21 |
22 | let orderbook = await exchange[method] (symbol)
23 | testOrderBook (exchange, orderbook, method, symbol)
24 | return orderbook
25 |
26 | } else {
27 |
28 | log (method + '() not supported')
29 | }
30 |
31 | }
--------------------------------------------------------------------------------
/js/test/Exchange/test.fetchMarkets.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | // ----------------------------------------------------------------------------
4 |
5 | const log = require ('ololog')
6 | , ansi = require ('ansicolor').nice
7 | , chai = require ('chai')
8 | , expect = chai.expect
9 | , assert = chai.assert
10 | , testMarket = require ('./test.market.js')
11 |
12 | /* ------------------------------------------------------------------------ */
13 |
14 | module.exports = async (exchange) => {
15 |
16 | const skippedExchanges = [
17 | 'bitforex',
18 | ]
19 |
20 | if (skippedExchanges.includes (exchange.id)) {
21 | log (exchange.id, 'found in ignored exchanges, skipping fetchMarkets...')
22 | return
23 | }
24 |
25 | if (exchange.has.fetchMarkets) {
26 |
27 | // log ('fetching markets...')
28 |
29 | const method = 'fetchMarkets'
30 | const markets = await exchange[method] ()
31 | Object.values (markets).forEach (market => testMarket (exchange, market, method))
32 | return markets
33 |
34 | } else {
35 |
36 | log ('fetching markets not supported')
37 | }
38 | }
39 |
40 |
--------------------------------------------------------------------------------
/js/test/Exchange/test.fetchMyTrades.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | // ----------------------------------------------------------------------------
4 |
5 | const log = require ('ololog')
6 | , ansi = require ('ansicolor').nice
7 | , chai = require ('chai')
8 | , expect = chai.expect
9 | , assert = chai.assert
10 | , testTrade = require ('./test.trade.js')
11 |
12 | /* ------------------------------------------------------------------------ */
13 |
14 | module.exports = async (exchange, symbol) => {
15 |
16 | if (exchange.has.fetchMyTrades) {
17 |
18 | // log ('fetching my trades...')
19 |
20 | let trades = await exchange.fetchMyTrades (symbol, 0)
21 |
22 | assert (trades instanceof Array)
23 |
24 | log ('fetched', trades.length.toString ().green, 'trades')
25 |
26 | let now = Date.now ()
27 |
28 | for (let i = 0; i < trades.length; i++) {
29 | testTrade (exchange, trades[i], symbol, now)
30 | if (i > 0)
31 | assert (trades[i].timestamp >= trades[i - 1].timestamp)
32 | }
33 |
34 | // trades.forEach (trade => log.dim ('-'.repeat (80), "\n", trade))
35 | // log (asTable (trades))
36 |
37 | } else {
38 |
39 | log ('fetching my trades not supported')
40 | }
41 | }
--------------------------------------------------------------------------------
/js/test/Exchange/test.fetchOHLCV.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | // ----------------------------------------------------------------------------
4 |
5 | const log = require ('ololog')
6 | , ansi = require ('ansicolor').nice
7 | , chai = require ('chai')
8 | , expect = chai.expect
9 | , assert = chai.assert
10 |
11 | /* ------------------------------------------------------------------------ */
12 |
13 | module.exports = async (exchange, symbol) => {
14 |
15 | if (exchange.has.fetchOHLCV) {
16 |
17 | // log (symbol.green, 'fetching OHLCV...')
18 |
19 | let ohlcv = await exchange.fetchOHLCV (symbol)
20 |
21 | log (symbol.green, 'fetched', Object.keys (ohlcv).length.toString ().green, 'OHLCVs')
22 |
23 | return ohlcv
24 |
25 | } else {
26 |
27 | log ('fetching OHLCV not supported')
28 | }
29 | }
--------------------------------------------------------------------------------
/js/test/Exchange/test.fetchOpenOrders.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | // ----------------------------------------------------------------------------
4 |
5 | const log = require ('ololog')
6 | , ansi = require ('ansicolor').nice
7 | , chai = require ('chai')
8 | , expect = chai.expect
9 | , assert = chai.assert
10 | , testOrder = require ('./test.order.js')
11 |
12 | /* ------------------------------------------------------------------------ */
13 |
14 | module.exports = async (exchange, symbol) => {
15 |
16 | if (exchange.has.fetchOpenOrders) {
17 |
18 | // log ('fetching open orders...')
19 |
20 | let orders = await exchange.fetchOpenOrders (symbol)
21 |
22 | assert (orders instanceof Array)
23 |
24 | log ('fetched', orders.length.toString ().green, 'open orders')
25 |
26 | let now = Date.now ()
27 |
28 | for (let i = 0; i < orders.length; i++) {
29 | let order = orders[i]
30 | testOrder (exchange, order, symbol, now)
31 | assert (order.status === 'open')
32 | }
33 |
34 | // log (asTable (orders))
35 |
36 | } else {
37 |
38 | log ('fetching open orders not supported')
39 | }
40 | }
--------------------------------------------------------------------------------
/js/test/Exchange/test.fetchOrderBook.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | // ----------------------------------------------------------------------------
4 |
5 | const log = require ('ololog')
6 | , ansi = require ('ansicolor').nice
7 | , chai = require ('chai')
8 | , expect = chai.expect
9 | , assert = chai.assert
10 | , testOrderBook = require ('./test.orderbook.js')
11 |
12 | /* ------------------------------------------------------------------------ */
13 |
14 | module.exports = async (exchange, symbol) => {
15 |
16 | // log (symbol.green, 'fetching order book...')
17 |
18 | const method = 'fetchOrderBook'
19 |
20 | if (exchange.has[method]) {
21 |
22 | let orderbook = await exchange[method] (symbol)
23 |
24 | testOrderBook (exchange, orderbook, method, symbol)
25 |
26 | return orderbook
27 |
28 | } else {
29 |
30 | log (method + '() not supported')
31 | }
32 | }
--------------------------------------------------------------------------------
/js/test/Exchange/test.fetchOrderBooks.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | // ----------------------------------------------------------------------------
4 |
5 | const log = require ('ololog')
6 | , ansi = require ('ansicolor').nice
7 | , chai = require ('chai')
8 | , expect = chai.expect
9 | , assert = chai.assert
10 | , testOrderBook = require ('./test.orderbook.js')
11 |
12 | /* ------------------------------------------------------------------------ */
13 |
14 | module.exports = async (exchange) => {
15 |
16 | const randomSymbols = exchange.symbols.sort (() => 0.5 - Math.random ()).slice (0, 2)
17 | const customExchangeParams = ([
18 | 'yobit',
19 | 'tidex',
20 | 'cryptopia',
21 | 'ccex',
22 | 'liqui',
23 | ]).reduce ((params, id) => ({ ...params, [id]: [randomSymbols], }), {})
24 |
25 | const args = (exchange.id in customExchangeParams) ? customExchangeParams[exchange.id] : []
26 | const method = 'fetchOrderBooks'
27 |
28 | if (exchange.has[method]) {
29 |
30 | // log ('fetching order books...')
31 |
32 | let orderbooks = await exchange[method] (...args)
33 |
34 | // log.green (orderbooks)
35 |
36 | Object.entries (orderbooks).forEach (([symbol, orderbook]) => {
37 | testOrderBook (exchange, orderbook, method, symbol)
38 | })
39 |
40 | // return orderbooks
41 |
42 | } else {
43 |
44 | log (method + '() not supported')
45 | }
46 | }
--------------------------------------------------------------------------------
/js/test/Exchange/test.fetchOrders.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | // ----------------------------------------------------------------------------
4 |
5 | const log = require ('ololog')
6 | , ansi = require ('ansicolor').nice
7 | , chai = require ('chai')
8 | , expect = chai.expect
9 | , assert = chai.assert
10 | , testOrder = require ('./test.order.js')
11 |
12 | /* ------------------------------------------------------------------------ */
13 |
14 | module.exports = async (exchange, symbol) => {
15 |
16 | if (exchange.has.fetchOrders) {
17 |
18 | // log ('fetching orders...')
19 |
20 | let orders = await exchange.fetchOrders (symbol)
21 |
22 | log ('fetched', orders.length.toString ().green, 'orders, asserting each...')
23 |
24 | assert (orders instanceof Array)
25 |
26 | let now = Date.now ()
27 |
28 | for (let i = 0; i < orders.length; i++) {
29 | let order = orders[i]
30 | testOrder (exchange, order, symbol, now)
31 | }
32 |
33 | // log (asTable (orders))
34 |
35 | } else {
36 |
37 | log ('fetching orders not supported')
38 | }
39 | }
--------------------------------------------------------------------------------
/js/test/Exchange/test.fetchTicker.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | // ----------------------------------------------------------------------------
4 |
5 | const log = require ('ololog')
6 | , ansi = require ('ansicolor').nice
7 | , chai = require ('chai')
8 | , expect = chai.expect
9 | , assert = chai.assert
10 | , testTicker = require ('./test.ticker.js')
11 |
12 | /* ------------------------------------------------------------------------ */
13 |
14 | module.exports = async (exchange, symbol) => {
15 |
16 | const method = 'fetchTicker'
17 |
18 | if (exchange.has[method]) {
19 |
20 | // log (symbol.green, 'fetching ticker...')
21 |
22 | let ticker = await exchange.fetchTicker (symbol)
23 |
24 | testTicker (exchange, ticker, method, symbol)
25 |
26 | return ticker
27 |
28 | } else {
29 |
30 | log (symbol.green, 'fetchTicker () not supported')
31 | }
32 | }
33 |
34 |
--------------------------------------------------------------------------------
/js/test/Exchange/test.fetchTickers.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | // ----------------------------------------------------------------------------
4 |
5 | const log = require ('ololog')
6 | , ansi = require ('ansicolor').nice
7 | , chai = require ('chai')
8 | , expect = chai.expect
9 | , assert = chai.assert
10 | , testTicker = require ('./test.ticker.js')
11 |
12 | /* ------------------------------------------------------------------------ */
13 |
14 | module.exports = async (exchange, symbol) => {
15 |
16 | const skippedExchanges = [
17 | 'binance',
18 | ]
19 |
20 | if (skippedExchanges.includes (exchange.id)) {
21 | log (exchange.id, 'found in ignored exchanges, skipping fetch all tickers...')
22 | return
23 | }
24 |
25 | if (exchange.has.fetchTickers) {
26 |
27 | // log ('fetching all tickers at once...')
28 |
29 | const method = 'fetchTickers'
30 | let tickers = undefined
31 |
32 | try {
33 |
34 | tickers = await exchange[method] ()
35 | log ('fetched all', Object.keys (tickers).length.toString ().green, 'tickers')
36 |
37 | } catch (e) {
38 |
39 | log ('failed to fetch all tickers, fetching multiple tickers at once...')
40 | tickers = await exchange[method] ([ symbol ])
41 | log ('fetched', Object.keys (tickers).length.toString ().green, 'tickers')
42 | }
43 |
44 | Object.values (tickers).forEach (ticker => testTicker (exchange, ticker, method, symbol))
45 | return tickers
46 |
47 | } else {
48 |
49 | log ('fetching all tickers at once not supported')
50 | }
51 | }
52 |
53 |
--------------------------------------------------------------------------------
/js/test/Exchange/test.fetchTrades.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | // ----------------------------------------------------------------------------
4 |
5 | const log = require ('ololog')
6 | , ansi = require ('ansicolor').nice
7 | , chai = require ('chai')
8 | , expect = chai.expect
9 | , assert = chai.assert
10 | , testTrade = require ('./test.trade.js')
11 |
12 | /* ------------------------------------------------------------------------ */
13 |
14 | module.exports = async (exchange, symbol) => {
15 |
16 | if (exchange.has.fetchTrades) {
17 |
18 | // log (symbol.green, 'fetching trades...')
19 |
20 | let trades = await exchange.fetchTrades (symbol)
21 | assert (trades instanceof Array)
22 | log (symbol.green, 'fetched', Object.values (trades).length.toString ().green, 'trades')
23 | let now = Date.now ()
24 | for (let i = 0; i < trades.length; i++) {
25 | testTrade (exchange, trades[i], symbol, now)
26 | if (i > 0)
27 | assert (trades[i].timestamp >= trades[i - 1].timestamp)
28 | }
29 | // log (asTable (trades))
30 |
31 | } else {
32 |
33 | log (symbol.green, 'fetchTrades () not supported'.yellow)
34 | }
35 | }
--------------------------------------------------------------------------------
/js/test/Exchange/test.fetchTradingFees.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | // ----------------------------------------------------------------------------
4 |
5 | const log = require ('ololog')
6 | , ansi = require ('ansicolor').nice
7 | , chai = require ('chai')
8 | , expect = chai.expect
9 | , assert = chai.assert
10 |
11 | /* ------------------------------------------------------------------------ */
12 |
13 | module.exports = async (exchange) => {
14 |
15 | const skippedExchanges = [
16 | ]
17 |
18 | if (skippedExchanges.includes (exchange.id)) {
19 | log (exchange.id, 'found in ignored exchanges, skipping fetchTradingFees...')
20 | return
21 | }
22 |
23 | if (exchange.has.fetchTradingFees) {
24 |
25 | // log ('fetching trading fees...')
26 |
27 | const method = 'fetchTradingFees'
28 | const fees = await exchange[method] ()
29 | log.green (fees)
30 | return fees
31 |
32 | } else {
33 |
34 | log ('fetching trading fees not supported')
35 | }
36 | }
37 |
38 |
--------------------------------------------------------------------------------
/js/test/Exchange/tmp.test.fetchOHLCV.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | // ----------------------------------------------------------------------------
4 |
5 | const log = require ('ololog')
6 | , ansi = require ('ansicolor').nice
7 | , chai = require ('chai')
8 | , expect = chai.expect
9 | , assert = chai.assert
10 |
11 | /* ------------------------------------------------------------------------ */
12 |
13 | module.exports = async (exchange, symbol) => {
14 |
15 | if (exchange.has.fetchOHLCV) {
16 |
17 | // log (symbol.green, 'fetching OHLCV...')
18 |
19 | let ohlcvs = await exchange.fetchOHLCV (symbol)
20 |
21 | log (symbol.green, 'fetched', Object.keys (ohlcvs).length.toString ().green, 'OHLCVs')
22 |
23 | // let now = Date.now ()
24 | for (let i = 1; i < ohlcvs.length; i++) {
25 | // testOHLCV (exchange, ohlcvs[i], symbol, now)
26 | assert (ohlcvs[i][0] >= ohlcvs[i - 1][0], 'OHLCV timestamps out of order: ' + ohlcvs[i][0] + ' < ' + ohlcvs[i - 1][0])
27 | }
28 |
29 | return ohlcvs
30 |
31 | } else {
32 |
33 | log ('fetching OHLCV not supported')
34 | }
35 | }
--------------------------------------------------------------------------------
/js/test/base/.eslintrc:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = {
4 | "env": {
5 | "node": true,
6 | "mocha": true
7 | },
8 | "parserOptions": {
9 | "ecmaVersion": 2017,
10 | "sourceType": "script",
11 | },
12 | "rules": {
13 | "semi": ["error", "never"],
14 | "no-unused-vars": ["off"],
15 | "quotes": ["off", "single"],
16 | "func-call-spacing": ["error", "always"],
17 | "one-var": "off",
18 | "indent": ["warn", 4, { "ignoredNodes": ["ObjectPattern"] }],
19 | "comma-style": "off",
20 | "no-multi-spaces": "off",
21 | "comma-dangle": "off",
22 | "spaced-comment": "off",
23 | "camelcase": "off",
24 | "padded-blocks": "off",
25 | "multiline-comment-style": "off",
26 | "curly": "off",
27 | "rest-spread-spacing": "off",
28 | "no-multiple-empty-lines": "off",
29 | "no-undef-init": "off",
30 | "no-useless-return": "off",
31 | "no-console": "off",
32 | "operator-linebreak": "off",
33 | "key-spacing": "off",
34 | "brace-style": "off",
35 | "padding-line-between-statements": ["off",
36 | {"blankLine": "always", "prev":"function", "next": "*" },
37 | {"blankLine": "always", "prev":"directive", "next": "*" },
38 | {"blankLine": "always", "prev":"*", "next": "cjs-export" },
39 | ],
40 | },
41 | }
42 |
--------------------------------------------------------------------------------
/js/test/errors/test.InvalidOrder.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | // ----------------------------------------------------------------------------
4 |
5 | const log = require ('ololog')
6 | , ansi = require ('ansicolor').nice
7 | , chai = require ('chai')
8 | , ccxt = require ('../../../ccxt.js')
9 | , expect = chai.expect
10 | , assert = chai.assert
11 |
12 | /* ------------------------------------------------------------------------ */
13 |
14 | module.exports = async (exchange, symbol) => {
15 |
16 | if (!exchange.has.createOrder) {
17 | log ('createOrder not supported')
18 | return
19 | }
20 |
21 | try {
22 |
23 | await exchange.createLimitBuyOrder (symbol, 0, 0)
24 | assert.fail ()
25 |
26 | } catch (e) {
27 |
28 | if (e instanceof ccxt.InvalidOrder) {
29 |
30 | log ('InvalidOrder thrown as expected')
31 | return
32 |
33 | } else {
34 |
35 | log ('InvalidOrder failed, exception follows:')
36 | throw e
37 | }
38 | }
39 | }
--------------------------------------------------------------------------------
/js/test/errors/test.OrderNotFound.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | // ----------------------------------------------------------------------------
4 |
5 | const log = require ('ololog')
6 | , ansi = require ('ansicolor').nice
7 | , chai = require ('chai')
8 | , ccxt = require ('../../../ccxt.js')
9 | , expect = chai.expect
10 | , assert = chai.assert
11 |
12 | /* ------------------------------------------------------------------------ */
13 |
14 | module.exports = async (exchange, symbol) => {
15 |
16 | if (!exchange.has.createOrder) {
17 | log ('createOrder not supported -> test skipped')
18 | return
19 | }
20 |
21 | let id = 1
22 |
23 | try {
24 |
25 | await exchange.cancelOrder (id, symbol)
26 |
27 | log ('test failed')
28 |
29 | assert.fail ()
30 |
31 | } catch (e) {
32 |
33 | if (e instanceof ccxt.OrderNotFound) {
34 |
35 | log ('OrderNotFound thrown as expected')
36 |
37 | } else {
38 |
39 | log ('OrderNotFound test failed')
40 | throw e
41 | }
42 | }
43 | }
--------------------------------------------------------------------------------
/js/test/test.timeout_hang.js:
--------------------------------------------------------------------------------
1 | // run with `node test_timeout_hang`
2 | // TODO: integrate with CI tests somehow...
3 |
4 | const { timeout } = require ('../base/functions')
5 |
6 | ;(async function () {
7 |
8 | await timeout (10000, Promise.resolve ('foo'))
9 |
10 | console.log ('Look ma, no hangs!') // should terminate the process immediately..
11 |
12 | }) ()
--------------------------------------------------------------------------------
/js/urdubit.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | // ---------------------------------------------------------------------------
4 |
5 | const foxbit = require ('./foxbit.js');
6 |
7 | // ---------------------------------------------------------------------------
8 |
9 | module.exports = class urdubit extends foxbit {
10 | describe () {
11 | return this.deepExtend (super.describe (), {
12 | 'id': 'urdubit',
13 | 'name': 'UrduBit',
14 | 'countries': [ 'PK' ],
15 | 'has': {
16 | 'CORS': false,
17 | },
18 | 'urls': {
19 | 'logo': 'https://user-images.githubusercontent.com/1294454/27991453-156bf3ae-6480-11e7-82eb-7295fe1b5bb4.jpg',
20 | 'api': {
21 | 'public': 'https://api.blinktrade.com/api',
22 | 'private': 'https://api.blinktrade.com/tapi',
23 | },
24 | 'www': 'https://urdubit.com',
25 | 'doc': 'https://blinktrade.com/docs',
26 | },
27 | 'options': {
28 | 'brokerId': '8', // https://blinktrade.com/docs/#brokers
29 | },
30 | });
31 | }
32 | };
33 |
--------------------------------------------------------------------------------
/js/vbtc.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | // ---------------------------------------------------------------------------
4 |
5 | const foxbit = require ('./foxbit.js');
6 |
7 | // ---------------------------------------------------------------------------
8 |
9 | module.exports = class vbtc extends foxbit {
10 | describe () {
11 | return this.deepExtend (super.describe (), {
12 | 'id': 'vbtc',
13 | 'name': 'VBTC',
14 | 'countries': [ 'VN' ],
15 | 'has': {
16 | 'CORS': false,
17 | },
18 | 'urls': {
19 | 'logo': 'https://user-images.githubusercontent.com/1294454/27991481-1f53d1d8-6481-11e7-884e-21d17e7939db.jpg',
20 | 'api': {
21 | 'public': 'https://api.blinktrade.com/api',
22 | 'private': 'https://api.blinktrade.com/tapi',
23 | },
24 | 'www': 'https://vbtc.exchange',
25 | 'doc': 'https://blinktrade.com/docs',
26 | },
27 | 'options': {
28 | 'brokerId': '3', // https://blinktrade.com/docs/#brokers
29 | },
30 | });
31 | }
32 | };
33 |
--------------------------------------------------------------------------------
/php/AccountSuspended.php:
--------------------------------------------------------------------------------
1 | 'bitkk',
15 | 'name' => 'bitkk',
16 | 'comment' => 'a Chinese ZB clone',
17 | 'urls' => array (
18 | 'api' => array (
19 | 'public' => 'http://api.bitkk.com/data', // no https for public API
20 | 'private' => 'https://trade.bitkk.com/api',
21 | ),
22 | 'www' => 'https://www.bitkk.com',
23 | 'doc' => 'https://www.bitkk.com/i/developer',
24 | 'fees' => 'https://www.bitkk.com/i/rate',
25 | ),
26 | ));
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/php/btcexchange.php:
--------------------------------------------------------------------------------
1 | 'btcexchange',
15 | 'name' => 'BTCExchange',
16 | 'countries' => array ( 'PH' ), // Philippines
17 | 'rateLimit' => 1500,
18 | 'has' => array (
19 | 'CORS' => false,
20 | ),
21 | 'urls' => array (
22 | 'logo' => 'https://user-images.githubusercontent.com/1294454/27993052-4c92911a-64aa-11e7-96d8-ec6ac3435757.jpg',
23 | 'api' => 'https://www.btcexchange.ph/api',
24 | 'www' => 'https://www.btcexchange.ph',
25 | 'doc' => 'https://github.com/BTCTrader/broker-api-docs',
26 | ),
27 | 'markets' => array (
28 | 'BTC/PHP' => array ( 'id' => 'BTC/PHP', 'symbol' => 'BTC/PHP', 'base' => 'BTC', 'quote' => 'PHP' ),
29 | ),
30 | ));
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/php/chilebit.php:
--------------------------------------------------------------------------------
1 | 'chilebit',
15 | 'name' => 'ChileBit',
16 | 'countries' => array ( 'CL' ),
17 | 'has' => array (
18 | 'CORS' => false,
19 | ),
20 | 'urls' => array (
21 | 'logo' => 'https://user-images.githubusercontent.com/1294454/27991414-1298f0d8-647f-11e7-9c40-d56409266336.jpg',
22 | 'api' => array (
23 | 'public' => 'https://api.blinktrade.com/api',
24 | 'private' => 'https://api.blinktrade.com/tapi',
25 | ),
26 | 'www' => 'https://chilebit.net',
27 | 'doc' => 'https://blinktrade.com/docs',
28 | ),
29 | 'options' => array (
30 | 'brokerId' => '9', // https://blinktrade.com/docs/#brokers
31 | ),
32 | ));
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/php/coinbaseprime.php:
--------------------------------------------------------------------------------
1 | 'coinbaseprime',
15 | 'name' => 'Coinbase Prime',
16 | 'urls' => array (
17 | 'test' => 'https://api-public.sandbox.prime.coinbase.com',
18 | 'logo' => 'https://user-images.githubusercontent.com/1294454/44539184-29f26e00-a70c-11e8-868f-e907fc236a7c.jpg',
19 | 'api' => 'https://api.prime.coinbase.com',
20 | 'www' => 'https://prime.coinbase.com',
21 | 'doc' => 'https://docs.prime.coinbase.com',
22 | 'fees' => 'https://support.prime.coinbase.com/customer/en/portal/articles/2945629-fees?b_id=17475',
23 | ),
24 | ));
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/php/coinbasepro.php:
--------------------------------------------------------------------------------
1 | 'coinbasepro',
15 | 'name' => 'Coinbase Pro',
16 | 'urls' => array (
17 | 'test' => 'https://api-public.sandbox.pro.coinbase.com',
18 | 'logo' => 'https://user-images.githubusercontent.com/1294454/41764625-63b7ffde-760a-11e8-996d-a6328fa9347a.jpg',
19 | 'api' => 'https://api.pro.coinbase.com',
20 | 'www' => 'https://pro.coinbase.com/',
21 | 'doc' => 'https://docs.pro.coinbase.com/',
22 | 'fees' => array (
23 | 'https://docs.pro.coinbase.com/#fees',
24 | 'https://support.pro.coinbase.com/customer/en/portal/articles/2945310-fees',
25 | ),
26 | ),
27 | ));
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/php/fybsg.php:
--------------------------------------------------------------------------------
1 | 'fybsg',
15 | 'name' => 'FYB-SG',
16 | 'countries' => array ( 'SG' ), // Singapore
17 | 'has' => array (
18 | 'CORS' => false,
19 | ),
20 | 'urls' => array (
21 | 'logo' => 'https://user-images.githubusercontent.com/1294454/27766513-3364d56a-5edb-11e7-9e6b-d5898bb89c81.jpg',
22 | 'api' => 'https://www.fybsg.com/api/SGD',
23 | 'www' => 'https://www.fybsg.com',
24 | 'doc' => 'http://docs.fyb.apiary.io',
25 | ),
26 | 'markets' => array (
27 | 'BTC/SGD' => array ( 'id' => 'SGD', 'symbol' => 'BTC/SGD', 'base' => 'BTC', 'quote' => 'SGD' ),
28 | ),
29 | ));
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/php/huobicny.php:
--------------------------------------------------------------------------------
1 | 'huobicny',
15 | 'name' => 'Huobi CNY',
16 | 'hostname' => 'be.huobi.com',
17 | 'has' => array (
18 | 'CORS' => false,
19 | ),
20 | 'urls' => array (
21 | 'logo' => 'https://user-images.githubusercontent.com/1294454/27766569-15aa7b9a-5edd-11e7-9e7f-44791f4ee49c.jpg',
22 | 'api' => array (
23 | 'public' => 'https://be.huobi.com',
24 | 'private' => 'https://be.huobi.com',
25 | 'market' => 'https://be.huobi.com',
26 | ),
27 | 'www' => 'https://www.huobi.com',
28 | 'doc' => 'https://github.com/huobiapi/API_Docs/wiki/REST_api_reference',
29 | ),
30 | ));
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/php/qryptos.php:
--------------------------------------------------------------------------------
1 | 'qryptos',
15 | 'name' => 'QRYPTOS',
16 | ));
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/php/quoinex.php:
--------------------------------------------------------------------------------
1 | 'quoinex',
15 | 'name' => 'QUOINEX',
16 | ));
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/php/surbitcoin.php:
--------------------------------------------------------------------------------
1 | 'surbitcoin',
15 | 'name' => 'SurBitcoin',
16 | 'countries' => array ( 'VE' ),
17 | 'has' => array (
18 | 'CORS' => false,
19 | ),
20 | 'urls' => array (
21 | 'logo' => 'https://user-images.githubusercontent.com/1294454/27991511-f0a50194-6481-11e7-99b5-8f02932424cc.jpg',
22 | 'api' => array (
23 | 'public' => 'https://api.blinktrade.com/api',
24 | 'private' => 'https://api.blinktrade.com/tapi',
25 | ),
26 | 'www' => 'https://surbitcoin.com',
27 | 'doc' => 'https://blinktrade.com/docs',
28 | ),
29 | 'options' => array (
30 | 'brokerId' => '1', // https://blinktrade.com/docs/#brokers
31 | ),
32 | ));
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/php/test/bootstrap.php:
--------------------------------------------------------------------------------
1 | false));
22 | }
23 |
--------------------------------------------------------------------------------
/php/urdubit.php:
--------------------------------------------------------------------------------
1 | 'urdubit',
15 | 'name' => 'UrduBit',
16 | 'countries' => array ( 'PK' ),
17 | 'has' => array (
18 | 'CORS' => false,
19 | ),
20 | 'urls' => array (
21 | 'logo' => 'https://user-images.githubusercontent.com/1294454/27991453-156bf3ae-6480-11e7-82eb-7295fe1b5bb4.jpg',
22 | 'api' => array (
23 | 'public' => 'https://api.blinktrade.com/api',
24 | 'private' => 'https://api.blinktrade.com/tapi',
25 | ),
26 | 'www' => 'https://urdubit.com',
27 | 'doc' => 'https://blinktrade.com/docs',
28 | ),
29 | 'options' => array (
30 | 'brokerId' => '8', // https://blinktrade.com/docs/#brokers
31 | ),
32 | ));
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/php/vbtc.php:
--------------------------------------------------------------------------------
1 | 'vbtc',
15 | 'name' => 'VBTC',
16 | 'countries' => array ( 'VN' ),
17 | 'has' => array (
18 | 'CORS' => false,
19 | ),
20 | 'urls' => array (
21 | 'logo' => 'https://user-images.githubusercontent.com/1294454/27991481-1f53d1d8-6481-11e7-884e-21d17e7939db.jpg',
22 | 'api' => array (
23 | 'public' => 'https://api.blinktrade.com/api',
24 | 'private' => 'https://api.blinktrade.com/tapi',
25 | ),
26 | 'www' => 'https://vbtc.exchange',
27 | 'doc' => 'https://blinktrade.com/docs',
28 | ),
29 | 'options' => array (
30 | 'brokerId' => '3', // https://blinktrade.com/docs/#brokers
31 | ),
32 | ));
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/phpunit.xml.dist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
13 |
14 |
15 |
16 | php/test
17 |
18 |
19 |
20 |
21 |
22 | php
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/postinstall.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | console.log (' ')
4 | console.log (' ---------------------------------------------------')
5 | console.log (' ')
6 | console.log (' You can contribute in crypto directly: ')
7 | console.log (' ')
8 | console.log (' ETH 0xa7c2b18b7c8b86984560cad3b1bc3224b388ded0 ')
9 | console.log (' BTC 33RmVRfhK2WZVQR1R83h2e9yXoqRNDvJva ')
10 | console.log (' BCH 1GN9p233TvNcNQFthCgfiHUnj5JRKEc2Ze ')
11 | console.log (' LTC LbT8mkAqQBphc4yxLXEDgYDfEax74et3bP ')
12 | console.log (' ')
13 | console.log (' ---------------------------------------------------')
14 | console.log (' ')
15 | console.log (' Thank you! ')
16 | console.log (' ')
--------------------------------------------------------------------------------
/push-wiki.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | cd ccxt.wiki
4 | cp ../wiki/FAQ.md .
5 | cp ../wiki/Certification.md .
6 | cp ../wiki/Manual.md .
7 | cp ../wiki/README.md ./Home.md
8 | cp ../wiki/Exchange-Markets.md .
9 | cp ../wiki/Exchange-Markets-By-Country.md .
10 | cp ../wiki/Install.md .
11 | git config --global user.email "travis@travis-ci.org"
12 | git config --global user.name "Travis CI"
13 | git commit -a -m ${COMMIT_MESSAGE}
14 | git remote remove origin
15 | git remote add origin https://${GITHUB_TOKEN}@github.com/ccxt/ccxt.wiki.git
16 | git push origin HEAD:master
17 |
--------------------------------------------------------------------------------
/push.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | LAST_COMMIT_MESSAGE="$(git log --no-merges -1 --pretty=%B)"
4 | git config --global user.email "travis@travis-ci.org"
5 | git config --global user.name "Travis CI"
6 | git add --force build/ccxt.browser.js
7 | git commit -a -m "${COMMIT_MESSAGE}" -m '[ci skip]'
8 | git tag -a "${COMMIT_MESSAGE}" -m "${LAST_COMMIT_MESSAGE}" -m "" -m "[ci skip]"
9 | git remote remove origin
10 | git remote add origin https://${GITHUB_TOKEN}@github.com/ccxt/ccxt.git
11 | git push origin --tags HEAD:master
12 |
--------------------------------------------------------------------------------
/python/MANIFEST.in:
--------------------------------------------------------------------------------
1 | # Include the license file
2 | include LICENSE.txt
3 |
4 | # Include the package.json file
5 | include package.json
--------------------------------------------------------------------------------
/python/ccxt/async_support/base/throttle.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | from asyncio import Queue, sleep, Future, ensure_future, get_event_loop
4 | from time import time
5 |
6 | __all__ = [
7 | 'throttle',
8 | ]
9 |
10 |
11 | def throttle(config=None):
12 |
13 | cfg = {
14 | 'lastTimestamp': time(),
15 | 'numTokens': 0,
16 | 'running': False,
17 | 'queue': Queue(),
18 | 'loop': get_event_loop(),
19 | 'delay': 0.001,
20 | 'refillRate': 0.001,
21 | 'defaultCost': 1.000,
22 | 'capacity': 1.000,
23 | }
24 |
25 | cfg.update(config)
26 |
27 | async def run():
28 | if not cfg['running']:
29 | cfg['running'] = True
30 | while not cfg['queue'].empty():
31 | now = time()
32 | elapsed = (now - cfg['lastTimestamp'])
33 | cfg['lastTimestamp'] = now
34 | cfg['numTokens'] = min(cfg['capacity'], cfg['numTokens'] + elapsed * cfg['refillRate'] * 1000)
35 | if cfg['numTokens'] > 0:
36 | if not cfg['queue'].empty():
37 | cost, future = cfg['queue'].get_nowait()
38 | cfg['numTokens'] -= (cost if cost else cfg['defaultCost'])
39 | if not future.done():
40 | future.set_result(None)
41 | await sleep(cfg['delay'])
42 | cfg['running'] = False
43 |
44 | def throttle(cost=None):
45 | future = Future()
46 | cfg['queue'].put_nowait((cost, future))
47 | ensure_future(run())
48 | return future
49 |
50 | return throttle
51 |
--------------------------------------------------------------------------------
/python/ccxt/async_support/bitkk.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | # PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
4 | # https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
5 |
6 | from ccxt.async_support.zb import zb
7 |
8 |
9 | class bitkk (zb):
10 |
11 | def describe(self):
12 | return self.deep_extend(super(bitkk, self).describe(), {
13 | 'id': 'bitkk',
14 | 'name': 'bitkk',
15 | 'comment': 'a Chinese ZB clone',
16 | 'urls': {
17 | 'api': {
18 | 'public': 'http://api.bitkk.com/data', # no https for public API
19 | 'private': 'https://trade.bitkk.com/api',
20 | },
21 | 'www': 'https://www.bitkk.com',
22 | 'doc': 'https://www.bitkk.com/i/developer',
23 | 'fees': 'https://www.bitkk.com/i/rate',
24 | },
25 | })
26 |
--------------------------------------------------------------------------------
/python/ccxt/async_support/btcexchange.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | # PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
4 | # https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
5 |
6 | from ccxt.async_support.btcturk import btcturk
7 |
8 |
9 | class btcexchange (btcturk):
10 |
11 | def describe(self):
12 | return self.deep_extend(super(btcexchange, self).describe(), {
13 | 'id': 'btcexchange',
14 | 'name': 'BTCExchange',
15 | 'countries': ['PH'], # Philippines
16 | 'rateLimit': 1500,
17 | 'has': {
18 | 'CORS': False,
19 | },
20 | 'urls': {
21 | 'logo': 'https://user-images.githubusercontent.com/1294454/27993052-4c92911a-64aa-11e7-96d8-ec6ac3435757.jpg',
22 | 'api': 'https://www.btcexchange.ph/api',
23 | 'www': 'https://www.btcexchange.ph',
24 | 'doc': 'https://github.com/BTCTrader/broker-api-docs',
25 | },
26 | 'markets': {
27 | 'BTC/PHP': {'id': 'BTC/PHP', 'symbol': 'BTC/PHP', 'base': 'BTC', 'quote': 'PHP'},
28 | },
29 | })
30 |
--------------------------------------------------------------------------------
/python/ccxt/async_support/chilebit.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | # PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
4 | # https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
5 |
6 | from ccxt.async_support.foxbit import foxbit
7 |
8 |
9 | class chilebit (foxbit):
10 |
11 | def describe(self):
12 | return self.deep_extend(super(chilebit, self).describe(), {
13 | 'id': 'chilebit',
14 | 'name': 'ChileBit',
15 | 'countries': ['CL'],
16 | 'has': {
17 | 'CORS': False,
18 | },
19 | 'urls': {
20 | 'logo': 'https://user-images.githubusercontent.com/1294454/27991414-1298f0d8-647f-11e7-9c40-d56409266336.jpg',
21 | 'api': {
22 | 'public': 'https://api.blinktrade.com/api',
23 | 'private': 'https://api.blinktrade.com/tapi',
24 | },
25 | 'www': 'https://chilebit.net',
26 | 'doc': 'https://blinktrade.com/docs',
27 | },
28 | 'options': {
29 | 'brokerId': '9', # https://blinktrade.com/docs/#brokers
30 | },
31 | })
32 |
--------------------------------------------------------------------------------
/python/ccxt/async_support/coinbaseprime.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | # PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
4 | # https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
5 |
6 | from ccxt.async_support.gdax import gdax
7 |
8 |
9 | class coinbaseprime (gdax):
10 |
11 | def describe(self):
12 | return self.deep_extend(super(coinbaseprime, self).describe(), {
13 | 'id': 'coinbaseprime',
14 | 'name': 'Coinbase Prime',
15 | 'urls': {
16 | 'test': 'https://api-public.sandbox.prime.coinbase.com',
17 | 'logo': 'https://user-images.githubusercontent.com/1294454/44539184-29f26e00-a70c-11e8-868f-e907fc236a7c.jpg',
18 | 'api': 'https://api.prime.coinbase.com',
19 | 'www': 'https://prime.coinbase.com',
20 | 'doc': 'https://docs.prime.coinbase.com',
21 | 'fees': 'https://support.prime.coinbase.com/customer/en/portal/articles/2945629-fees?b_id=17475',
22 | },
23 | })
24 |
--------------------------------------------------------------------------------
/python/ccxt/async_support/coinbasepro.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | # PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
4 | # https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
5 |
6 | from ccxt.async_support.gdax import gdax
7 |
8 |
9 | class coinbasepro (gdax):
10 |
11 | def describe(self):
12 | return self.deep_extend(super(coinbasepro, self).describe(), {
13 | 'id': 'coinbasepro',
14 | 'name': 'Coinbase Pro',
15 | 'urls': {
16 | 'test': 'https://api-public.sandbox.pro.coinbase.com',
17 | 'logo': 'https://user-images.githubusercontent.com/1294454/41764625-63b7ffde-760a-11e8-996d-a6328fa9347a.jpg',
18 | 'api': 'https://api.pro.coinbase.com',
19 | 'www': 'https://pro.coinbase.com/',
20 | 'doc': 'https://docs.pro.coinbase.com/',
21 | 'fees': [
22 | 'https://docs.pro.coinbase.com/#fees',
23 | 'https://support.pro.coinbase.com/customer/en/portal/articles/2945310-fees',
24 | ],
25 | },
26 | })
27 |
--------------------------------------------------------------------------------
/python/ccxt/async_support/fybsg.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | # PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
4 | # https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
5 |
6 | from ccxt.async_support.fybse import fybse
7 |
8 |
9 | class fybsg (fybse):
10 |
11 | def describe(self):
12 | return self.deep_extend(super(fybsg, self).describe(), {
13 | 'id': 'fybsg',
14 | 'name': 'FYB-SG',
15 | 'countries': ['SG'], # Singapore
16 | 'has': {
17 | 'CORS': False,
18 | },
19 | 'urls': {
20 | 'logo': 'https://user-images.githubusercontent.com/1294454/27766513-3364d56a-5edb-11e7-9e6b-d5898bb89c81.jpg',
21 | 'api': 'https://www.fybsg.com/api/SGD',
22 | 'www': 'https://www.fybsg.com',
23 | 'doc': 'http://docs.fyb.apiary.io',
24 | },
25 | 'markets': {
26 | 'BTC/SGD': {'id': 'SGD', 'symbol': 'BTC/SGD', 'base': 'BTC', 'quote': 'SGD'},
27 | },
28 | })
29 |
--------------------------------------------------------------------------------
/python/ccxt/async_support/huobicny.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | # PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
4 | # https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
5 |
6 | from ccxt.async_support.huobipro import huobipro
7 |
8 |
9 | class huobicny (huobipro):
10 |
11 | def describe(self):
12 | return self.deep_extend(super(huobicny, self).describe(), {
13 | 'id': 'huobicny',
14 | 'name': 'Huobi CNY',
15 | 'hostname': 'be.huobi.com',
16 | 'has': {
17 | 'CORS': False,
18 | },
19 | 'urls': {
20 | 'logo': 'https://user-images.githubusercontent.com/1294454/27766569-15aa7b9a-5edd-11e7-9e7f-44791f4ee49c.jpg',
21 | 'api': {
22 | 'public': 'https://be.huobi.com',
23 | 'private': 'https://be.huobi.com',
24 | 'market': 'https://be.huobi.com',
25 | },
26 | 'www': 'https://www.huobi.com',
27 | 'doc': 'https://github.com/huobiapi/API_Docs/wiki/REST_api_reference',
28 | },
29 | })
30 |
--------------------------------------------------------------------------------
/python/ccxt/async_support/jubi.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | # PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
4 | # https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
5 |
6 | from ccxt.async_support.btcbox import btcbox
7 |
8 |
9 | class jubi (btcbox):
10 |
11 | def describe(self):
12 | return self.deep_extend(super(jubi, self).describe(), {
13 | 'id': 'jubi',
14 | 'name': 'jubi.com',
15 | 'countries': ['CN'],
16 | 'rateLimit': 1500,
17 | 'version': 'v1',
18 | 'has': {
19 | 'CORS': False,
20 | 'fetchTickers': True,
21 | },
22 | 'urls': {
23 | 'logo': 'https://user-images.githubusercontent.com/1294454/27766581-9d397d9a-5edd-11e7-8fb9-5d8236c0e692.jpg',
24 | 'api': 'https://www.jubi.com/api',
25 | 'www': 'https://www.jubi.com',
26 | 'doc': 'https://www.jubi.com/help/api.html',
27 | },
28 | })
29 |
30 | async def fetch_markets(self):
31 | markets = await self.publicGetAllticker()
32 | keys = list(markets.keys())
33 | result = []
34 | for p in range(0, len(keys)):
35 | id = keys[p]
36 | base = id.upper()
37 | quote = 'CNY' # todo
38 | symbol = base + '/' + quote
39 | base = self.common_currency_code(base)
40 | quote = self.common_currency_code(quote)
41 | result.append({
42 | 'id': id,
43 | 'symbol': symbol,
44 | 'base': base,
45 | 'quote': quote,
46 | 'info': id,
47 | })
48 | return result
49 |
--------------------------------------------------------------------------------
/python/ccxt/async_support/qryptos.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | # PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
4 | # https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
5 |
6 | from ccxt.async_support.liquid import liquid
7 |
8 |
9 | class qryptos (liquid):
10 |
11 | def describe(self):
12 | return self.deep_extend(super(qryptos, self).describe(), {
13 | 'id': 'qryptos',
14 | 'name': 'QRYPTOS',
15 | })
16 |
--------------------------------------------------------------------------------
/python/ccxt/async_support/quoinex.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | # PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
4 | # https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
5 |
6 | from ccxt.async_support.liquid import liquid
7 |
8 |
9 | class quoinex (liquid):
10 |
11 | def describe(self):
12 | return self.deep_extend(super(quoinex, self).describe(), {
13 | 'id': 'quoinex',
14 | 'name': 'QUOINEX',
15 | })
16 |
--------------------------------------------------------------------------------
/python/ccxt/async_support/surbitcoin.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | # PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
4 | # https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
5 |
6 | from ccxt.async_support.foxbit import foxbit
7 |
8 |
9 | class surbitcoin (foxbit):
10 |
11 | def describe(self):
12 | return self.deep_extend(super(surbitcoin, self).describe(), {
13 | 'id': 'surbitcoin',
14 | 'name': 'SurBitcoin',
15 | 'countries': ['VE'],
16 | 'has': {
17 | 'CORS': False,
18 | },
19 | 'urls': {
20 | 'logo': 'https://user-images.githubusercontent.com/1294454/27991511-f0a50194-6481-11e7-99b5-8f02932424cc.jpg',
21 | 'api': {
22 | 'public': 'https://api.blinktrade.com/api',
23 | 'private': 'https://api.blinktrade.com/tapi',
24 | },
25 | 'www': 'https://surbitcoin.com',
26 | 'doc': 'https://blinktrade.com/docs',
27 | },
28 | 'options': {
29 | 'brokerId': '1', # https://blinktrade.com/docs/#brokers
30 | },
31 | })
32 |
--------------------------------------------------------------------------------
/python/ccxt/async_support/urdubit.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | # PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
4 | # https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
5 |
6 | from ccxt.async_support.foxbit import foxbit
7 |
8 |
9 | class urdubit (foxbit):
10 |
11 | def describe(self):
12 | return self.deep_extend(super(urdubit, self).describe(), {
13 | 'id': 'urdubit',
14 | 'name': 'UrduBit',
15 | 'countries': ['PK'],
16 | 'has': {
17 | 'CORS': False,
18 | },
19 | 'urls': {
20 | 'logo': 'https://user-images.githubusercontent.com/1294454/27991453-156bf3ae-6480-11e7-82eb-7295fe1b5bb4.jpg',
21 | 'api': {
22 | 'public': 'https://api.blinktrade.com/api',
23 | 'private': 'https://api.blinktrade.com/tapi',
24 | },
25 | 'www': 'https://urdubit.com',
26 | 'doc': 'https://blinktrade.com/docs',
27 | },
28 | 'options': {
29 | 'brokerId': '8', # https://blinktrade.com/docs/#brokers
30 | },
31 | })
32 |
--------------------------------------------------------------------------------
/python/ccxt/async_support/vbtc.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | # PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
4 | # https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
5 |
6 | from ccxt.async_support.foxbit import foxbit
7 |
8 |
9 | class vbtc (foxbit):
10 |
11 | def describe(self):
12 | return self.deep_extend(super(vbtc, self).describe(), {
13 | 'id': 'vbtc',
14 | 'name': 'VBTC',
15 | 'countries': ['VN'],
16 | 'has': {
17 | 'CORS': False,
18 | },
19 | 'urls': {
20 | 'logo': 'https://user-images.githubusercontent.com/1294454/27991481-1f53d1d8-6481-11e7-884e-21d17e7939db.jpg',
21 | 'api': {
22 | 'public': 'https://api.blinktrade.com/api',
23 | 'private': 'https://api.blinktrade.com/tapi',
24 | },
25 | 'www': 'https://vbtc.exchange',
26 | 'doc': 'https://blinktrade.com/docs',
27 | },
28 | 'options': {
29 | 'brokerId': '3', # https://blinktrade.com/docs/#brokers
30 | },
31 | })
32 |
--------------------------------------------------------------------------------
/python/ccxt/bitkk.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | # PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
4 | # https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
5 |
6 | from ccxt.zb import zb
7 |
8 |
9 | class bitkk (zb):
10 |
11 | def describe(self):
12 | return self.deep_extend(super(bitkk, self).describe(), {
13 | 'id': 'bitkk',
14 | 'name': 'bitkk',
15 | 'comment': 'a Chinese ZB clone',
16 | 'urls': {
17 | 'api': {
18 | 'public': 'http://api.bitkk.com/data', # no https for public API
19 | 'private': 'https://trade.bitkk.com/api',
20 | },
21 | 'www': 'https://www.bitkk.com',
22 | 'doc': 'https://www.bitkk.com/i/developer',
23 | 'fees': 'https://www.bitkk.com/i/rate',
24 | },
25 | })
26 |
--------------------------------------------------------------------------------
/python/ccxt/btcexchange.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | # PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
4 | # https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
5 |
6 | from ccxt.btcturk import btcturk
7 |
8 |
9 | class btcexchange (btcturk):
10 |
11 | def describe(self):
12 | return self.deep_extend(super(btcexchange, self).describe(), {
13 | 'id': 'btcexchange',
14 | 'name': 'BTCExchange',
15 | 'countries': ['PH'], # Philippines
16 | 'rateLimit': 1500,
17 | 'has': {
18 | 'CORS': False,
19 | },
20 | 'urls': {
21 | 'logo': 'https://user-images.githubusercontent.com/1294454/27993052-4c92911a-64aa-11e7-96d8-ec6ac3435757.jpg',
22 | 'api': 'https://www.btcexchange.ph/api',
23 | 'www': 'https://www.btcexchange.ph',
24 | 'doc': 'https://github.com/BTCTrader/broker-api-docs',
25 | },
26 | 'markets': {
27 | 'BTC/PHP': {'id': 'BTC/PHP', 'symbol': 'BTC/PHP', 'base': 'BTC', 'quote': 'PHP'},
28 | },
29 | })
30 |
--------------------------------------------------------------------------------
/python/ccxt/chilebit.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | # PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
4 | # https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
5 |
6 | from ccxt.foxbit import foxbit
7 |
8 |
9 | class chilebit (foxbit):
10 |
11 | def describe(self):
12 | return self.deep_extend(super(chilebit, self).describe(), {
13 | 'id': 'chilebit',
14 | 'name': 'ChileBit',
15 | 'countries': ['CL'],
16 | 'has': {
17 | 'CORS': False,
18 | },
19 | 'urls': {
20 | 'logo': 'https://user-images.githubusercontent.com/1294454/27991414-1298f0d8-647f-11e7-9c40-d56409266336.jpg',
21 | 'api': {
22 | 'public': 'https://api.blinktrade.com/api',
23 | 'private': 'https://api.blinktrade.com/tapi',
24 | },
25 | 'www': 'https://chilebit.net',
26 | 'doc': 'https://blinktrade.com/docs',
27 | },
28 | 'options': {
29 | 'brokerId': '9', # https://blinktrade.com/docs/#brokers
30 | },
31 | })
32 |
--------------------------------------------------------------------------------
/python/ccxt/coinbaseprime.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | # PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
4 | # https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
5 |
6 | from ccxt.gdax import gdax
7 |
8 |
9 | class coinbaseprime (gdax):
10 |
11 | def describe(self):
12 | return self.deep_extend(super(coinbaseprime, self).describe(), {
13 | 'id': 'coinbaseprime',
14 | 'name': 'Coinbase Prime',
15 | 'urls': {
16 | 'test': 'https://api-public.sandbox.prime.coinbase.com',
17 | 'logo': 'https://user-images.githubusercontent.com/1294454/44539184-29f26e00-a70c-11e8-868f-e907fc236a7c.jpg',
18 | 'api': 'https://api.prime.coinbase.com',
19 | 'www': 'https://prime.coinbase.com',
20 | 'doc': 'https://docs.prime.coinbase.com',
21 | 'fees': 'https://support.prime.coinbase.com/customer/en/portal/articles/2945629-fees?b_id=17475',
22 | },
23 | })
24 |
--------------------------------------------------------------------------------
/python/ccxt/coinbasepro.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | # PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
4 | # https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
5 |
6 | from ccxt.gdax import gdax
7 |
8 |
9 | class coinbasepro (gdax):
10 |
11 | def describe(self):
12 | return self.deep_extend(super(coinbasepro, self).describe(), {
13 | 'id': 'coinbasepro',
14 | 'name': 'Coinbase Pro',
15 | 'urls': {
16 | 'test': 'https://api-public.sandbox.pro.coinbase.com',
17 | 'logo': 'https://user-images.githubusercontent.com/1294454/41764625-63b7ffde-760a-11e8-996d-a6328fa9347a.jpg',
18 | 'api': 'https://api.pro.coinbase.com',
19 | 'www': 'https://pro.coinbase.com/',
20 | 'doc': 'https://docs.pro.coinbase.com/',
21 | 'fees': [
22 | 'https://docs.pro.coinbase.com/#fees',
23 | 'https://support.pro.coinbase.com/customer/en/portal/articles/2945310-fees',
24 | ],
25 | },
26 | })
27 |
--------------------------------------------------------------------------------
/python/ccxt/fybsg.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | # PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
4 | # https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
5 |
6 | from ccxt.fybse import fybse
7 |
8 |
9 | class fybsg (fybse):
10 |
11 | def describe(self):
12 | return self.deep_extend(super(fybsg, self).describe(), {
13 | 'id': 'fybsg',
14 | 'name': 'FYB-SG',
15 | 'countries': ['SG'], # Singapore
16 | 'has': {
17 | 'CORS': False,
18 | },
19 | 'urls': {
20 | 'logo': 'https://user-images.githubusercontent.com/1294454/27766513-3364d56a-5edb-11e7-9e6b-d5898bb89c81.jpg',
21 | 'api': 'https://www.fybsg.com/api/SGD',
22 | 'www': 'https://www.fybsg.com',
23 | 'doc': 'http://docs.fyb.apiary.io',
24 | },
25 | 'markets': {
26 | 'BTC/SGD': {'id': 'SGD', 'symbol': 'BTC/SGD', 'base': 'BTC', 'quote': 'SGD'},
27 | },
28 | })
29 |
--------------------------------------------------------------------------------
/python/ccxt/huobicny.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | # PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
4 | # https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
5 |
6 | from ccxt.huobipro import huobipro
7 |
8 |
9 | class huobicny (huobipro):
10 |
11 | def describe(self):
12 | return self.deep_extend(super(huobicny, self).describe(), {
13 | 'id': 'huobicny',
14 | 'name': 'Huobi CNY',
15 | 'hostname': 'be.huobi.com',
16 | 'has': {
17 | 'CORS': False,
18 | },
19 | 'urls': {
20 | 'logo': 'https://user-images.githubusercontent.com/1294454/27766569-15aa7b9a-5edd-11e7-9e7f-44791f4ee49c.jpg',
21 | 'api': {
22 | 'public': 'https://be.huobi.com',
23 | 'private': 'https://be.huobi.com',
24 | 'market': 'https://be.huobi.com',
25 | },
26 | 'www': 'https://www.huobi.com',
27 | 'doc': 'https://github.com/huobiapi/API_Docs/wiki/REST_api_reference',
28 | },
29 | })
30 |
--------------------------------------------------------------------------------
/python/ccxt/jubi.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | # PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
4 | # https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
5 |
6 | from ccxt.btcbox import btcbox
7 |
8 |
9 | class jubi (btcbox):
10 |
11 | def describe(self):
12 | return self.deep_extend(super(jubi, self).describe(), {
13 | 'id': 'jubi',
14 | 'name': 'jubi.com',
15 | 'countries': ['CN'],
16 | 'rateLimit': 1500,
17 | 'version': 'v1',
18 | 'has': {
19 | 'CORS': False,
20 | 'fetchTickers': True,
21 | },
22 | 'urls': {
23 | 'logo': 'https://user-images.githubusercontent.com/1294454/27766581-9d397d9a-5edd-11e7-8fb9-5d8236c0e692.jpg',
24 | 'api': 'https://www.jubi.com/api',
25 | 'www': 'https://www.jubi.com',
26 | 'doc': 'https://www.jubi.com/help/api.html',
27 | },
28 | })
29 |
30 | def fetch_markets(self):
31 | markets = self.publicGetAllticker()
32 | keys = list(markets.keys())
33 | result = []
34 | for p in range(0, len(keys)):
35 | id = keys[p]
36 | base = id.upper()
37 | quote = 'CNY' # todo
38 | symbol = base + '/' + quote
39 | base = self.common_currency_code(base)
40 | quote = self.common_currency_code(quote)
41 | result.append({
42 | 'id': id,
43 | 'symbol': symbol,
44 | 'base': base,
45 | 'quote': quote,
46 | 'info': id,
47 | })
48 | return result
49 |
--------------------------------------------------------------------------------
/python/ccxt/qryptos.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | # PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
4 | # https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
5 |
6 | from ccxt.liquid import liquid
7 |
8 |
9 | class qryptos (liquid):
10 |
11 | def describe(self):
12 | return self.deep_extend(super(qryptos, self).describe(), {
13 | 'id': 'qryptos',
14 | 'name': 'QRYPTOS',
15 | })
16 |
--------------------------------------------------------------------------------
/python/ccxt/quoinex.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | # PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
4 | # https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
5 |
6 | from ccxt.liquid import liquid
7 |
8 |
9 | class quoinex (liquid):
10 |
11 | def describe(self):
12 | return self.deep_extend(super(quoinex, self).describe(), {
13 | 'id': 'quoinex',
14 | 'name': 'QUOINEX',
15 | })
16 |
--------------------------------------------------------------------------------
/python/ccxt/surbitcoin.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | # PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
4 | # https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
5 |
6 | from ccxt.foxbit import foxbit
7 |
8 |
9 | class surbitcoin (foxbit):
10 |
11 | def describe(self):
12 | return self.deep_extend(super(surbitcoin, self).describe(), {
13 | 'id': 'surbitcoin',
14 | 'name': 'SurBitcoin',
15 | 'countries': ['VE'],
16 | 'has': {
17 | 'CORS': False,
18 | },
19 | 'urls': {
20 | 'logo': 'https://user-images.githubusercontent.com/1294454/27991511-f0a50194-6481-11e7-99b5-8f02932424cc.jpg',
21 | 'api': {
22 | 'public': 'https://api.blinktrade.com/api',
23 | 'private': 'https://api.blinktrade.com/tapi',
24 | },
25 | 'www': 'https://surbitcoin.com',
26 | 'doc': 'https://blinktrade.com/docs',
27 | },
28 | 'options': {
29 | 'brokerId': '1', # https://blinktrade.com/docs/#brokers
30 | },
31 | })
32 |
--------------------------------------------------------------------------------
/python/ccxt/urdubit.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | # PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
4 | # https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
5 |
6 | from ccxt.foxbit import foxbit
7 |
8 |
9 | class urdubit (foxbit):
10 |
11 | def describe(self):
12 | return self.deep_extend(super(urdubit, self).describe(), {
13 | 'id': 'urdubit',
14 | 'name': 'UrduBit',
15 | 'countries': ['PK'],
16 | 'has': {
17 | 'CORS': False,
18 | },
19 | 'urls': {
20 | 'logo': 'https://user-images.githubusercontent.com/1294454/27991453-156bf3ae-6480-11e7-82eb-7295fe1b5bb4.jpg',
21 | 'api': {
22 | 'public': 'https://api.blinktrade.com/api',
23 | 'private': 'https://api.blinktrade.com/tapi',
24 | },
25 | 'www': 'https://urdubit.com',
26 | 'doc': 'https://blinktrade.com/docs',
27 | },
28 | 'options': {
29 | 'brokerId': '8', # https://blinktrade.com/docs/#brokers
30 | },
31 | })
32 |
--------------------------------------------------------------------------------
/python/ccxt/vbtc.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | # PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
4 | # https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
5 |
6 | from ccxt.foxbit import foxbit
7 |
8 |
9 | class vbtc (foxbit):
10 |
11 | def describe(self):
12 | return self.deep_extend(super(vbtc, self).describe(), {
13 | 'id': 'vbtc',
14 | 'name': 'VBTC',
15 | 'countries': ['VN'],
16 | 'has': {
17 | 'CORS': False,
18 | },
19 | 'urls': {
20 | 'logo': 'https://user-images.githubusercontent.com/1294454/27991481-1f53d1d8-6481-11e7-884e-21d17e7939db.jpg',
21 | 'api': {
22 | 'public': 'https://api.blinktrade.com/api',
23 | 'private': 'https://api.blinktrade.com/tapi',
24 | },
25 | 'www': 'https://vbtc.exchange',
26 | 'doc': 'https://blinktrade.com/docs',
27 | },
28 | 'options': {
29 | 'brokerId': '3', # https://blinktrade.com/docs/#brokers
30 | },
31 | })
32 |
--------------------------------------------------------------------------------
/python/deploy.sh:
--------------------------------------------------------------------------------
1 | python setup.py sdist bdist_wheel
2 | twine upload dist/* -u x84 -p ${PYPI_PASSWORD}
--------------------------------------------------------------------------------
/python/setup.cfg:
--------------------------------------------------------------------------------
1 | [bdist_wheel]
2 | # This flag says that the code is written to work on both Python 2 and Python
3 | # 3. If at all possible, it is good practice to do this. If you cannot, you
4 | # will need to generate wheels for each Python version that you support.
5 | universal=1
6 |
7 | [flake8]
8 | ignore = E501
9 | exclude =
10 | .ropeproject,
11 | .tox,
12 | .eggs,
13 | # No need to traverse our git directory
14 | .git,
15 | # There's no value in checking cache directories
16 | __pycache__,
17 | # Other special cases
18 | node_modules,
19 | .nyc_output,
20 | build,
21 | tmp,
22 | # No need to check the basecode
23 | ccxt.py
24 |
--------------------------------------------------------------------------------
/python/test/test_calculate_fee.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | # THIS IS A MOCKUP FILE IN PROGRESS
4 |
5 | # import argparse
6 | import os
7 | import sys
8 | # import json
9 | # import time
10 |
11 | # ------------------------------------------------------------------------------
12 |
13 | root = os.path.dirname(os.path.abspath(__file__))
14 | sys.path.append(root)
15 |
16 | # ------------------------------------------------------------------------------
17 |
18 | import ccxt # noqa: E402
19 |
20 | # ------------------------------------------------------------------------------
21 |
22 | taker = 0.0025
23 | maker = 0.0010
24 | price = 100.00
25 | amount = 10.00
26 |
27 | market = {
28 | 'id': 'foobar',
29 | 'symbol': 'FOO/BAR',
30 | 'base': 'FOO',
31 | 'quote': 'BAR',
32 | 'taker': taker,
33 | 'maker': maker,
34 | }
35 |
36 | exchange = ccxt.Exchange({
37 | 'id': 'mock',
38 | 'markets': {'FOO/BAR': market},
39 | })
40 |
41 | exchange.calculate_fee(market['symbol'], 'limit', 'sell', amount, price, 'taker', {})
42 |
43 | # {'rate': {'quote': 0.0025, 'base': 0.0}, 'cost': {'quote': 2.5, 'base': 0.0}}
44 |
45 | exchange.calculate_fee(market['symbol'], 'limit', 'sell', amount, price, 'maker', {})
46 |
47 | # {'rate': {'quote': 0.001, 'base': 0.0}, 'cost': {'quote': 1.0, 'base': 0.0}}
48 |
--------------------------------------------------------------------------------
/python/test/test_deep_extend.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | # THIS IS A MOCKUP FILE IN PROGRESS
4 |
5 | # import argparse
6 | import os
7 | import sys
8 | from pprint import pprint
9 | # import json
10 | # import time
11 |
12 | # ------------------------------------------------------------------------------
13 |
14 | root = os.path.dirname(os.path.abspath(__file__))
15 | sys.path.append(root)
16 |
17 | # ------------------------------------------------------------------------------
18 |
19 | import ccxt # noqa: E402
20 |
21 | # ------------------------------------------------------------------------------
22 |
23 | values = [
24 | {
25 | 'a': 1,
26 | 'b': 2,
27 | 'd': {
28 | 'a': 1,
29 | 'b': [],
30 | 'c': {'test1': 123, 'test2': 321}},
31 | 'f': 5,
32 | 'g': 123,
33 | 'i': 321,
34 | 'j': [1, 2],
35 | },
36 | {
37 | 'b': 3,
38 | 'c': 5,
39 | 'd': {
40 | 'b': {'first': 'one', 'second': 'two'},
41 | 'c': {'test2': 222}},
42 | 'e': {'one': 1, 'two': 2},
43 | 'f': [{'foo': 'bar'}],
44 | 'g': None,
45 | 'h': r'abc',
46 | 'i': None,
47 | 'j': [3, 4]
48 | }
49 | ]
50 |
51 | pprint(ccxt.Exchange.deep_extend(*values))
52 |
53 | # assert.deepEqual ({
54 | # a: 1,
55 | # b: 3,
56 | # d: {
57 | # a: 1,
58 | # b: {first: 'one', second: 'two'},
59 | # c: {test1: 123, test2: 222}
60 | # },
61 | # f: [{'foo': 'bar'}],
62 | # g: undefined,
63 | # c: 5,
64 | # e: {one: 1, two: 2},
65 | # h: /abc/g,
66 | # i: null,
67 | # j: [3, 4]
68 | # }, extended)
69 |
--------------------------------------------------------------------------------
/python/tox.ini:
--------------------------------------------------------------------------------
1 | [tox]
2 | envlist = py{27,35,36},qa
3 | skipsdist = True
4 | skip_missing_interpreters = True
5 |
6 | [testenv]
7 | setenv =
8 | PYTHONPATH = {toxinidir}:{toxinidir}
9 | commands =
10 | python test.py
11 |
12 | [testenv:qa]
13 | basepython = python3
14 | changedir=..
15 | commands = flake8
16 | deps = .[qa]
17 |
18 | [testenv:doc]
19 | changedir=../doc
20 | deps = .[doc]
21 | commands=
22 | sphinx-build -W -b html -d {envtmpdir}/doctrees . {envtmpdir}/html
23 |
--------------------------------------------------------------------------------
/setup.cfg:
--------------------------------------------------------------------------------
1 | [flake8]
2 | ignore = E501
3 | exclude =
4 | .ropeproject,
5 | .tox,
6 | .eggs,
7 | # No need to traverse our git directory
8 | .git,
9 | # There's no value in checking cache directories
10 | __pycache__,
11 | # Other special cases
12 | node_modules,
13 | .nyc_output,
14 | build,
15 | tmp,
16 | # No need to check the basecode
17 | ccxt.py
18 |
--------------------------------------------------------------------------------
/wiki/Certification.md:
--------------------------------------------------------------------------------
1 | # CCXT Certification Program · 
2 |
3 | The structure of CCXT defines a good, portable and cross-compatible standard for exchanges' API interfaces, that is implemented in the CCXT Unified API. Exchanges are welcome to apply for our certification program. Certification is technically supervised and quality-assured by members of the CCXT Dev Team. That implies that an exchange having a "certified" badge is properly implemented and tested by the authors of CCXT. Certification means less bugs, more functionality, priority support and a much more stable and efficient implementation in general.
4 |
5 | ## Contact Us
6 |
7 | For inquiries on getting your exchange integrated, listed and certified: info@ccxt.trade
8 |
--------------------------------------------------------------------------------