mirror of
https://github.com/discountry/ritmex-bot.git
synced 2026-09-10 08:48:07 +00:00
commit
This commit is contained in:
@@ -0,0 +1,303 @@
|
||||
<style>ul { margin-bottom: -10px; }</style>
|
||||
|
||||
# [<-](Examples?id=javascript)
|
||||
|
||||
# CCXT JavaScript Examples
|
||||
|
||||
These examples might require the following super-useful high-quality Node.js modules by [xpl](https://github.com/xpl):
|
||||
|
||||
- [ansicolor](https://github.com/xpl/ansicolor): A quality JavaScript library for the ANSI color/style management ([ansicolor @ npm](https://npmjs.com/package/ansicolor))
|
||||
- [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))
|
||||
- [ololog](https://github.com/xpl/ololog): Platform-agnostic logging with blackjack and hookers ([ololog @ npm](https://npmjs.com/package/ololog))
|
||||
|
||||
All of the modules above are installed with the ccxt library devDependencies by npm automatically.
|
||||
|
||||
To run the ccxt JavaScript examples from any folder type in console:
|
||||
|
||||
```shell
|
||||
node path/to/example.js # substitute for actual filename here
|
||||
```
|
||||
|
||||
|
||||
- [Advanced Error Handling](./examples/js/advanced-error-handling.md)
|
||||
|
||||
- [Aggregate Orderbook](./examples/js/aggregate-orderbook.md)
|
||||
|
||||
- [Apex Example](./examples/js/apex-example.md)
|
||||
|
||||
- [Arbitrage Pairs](./examples/js/arbitrage-pairs.md)
|
||||
|
||||
- [Basic Chart](./examples/js/basic-chart.md)
|
||||
|
||||
- [Basic Orderbook Polling](./examples/js/basic-orderbook-polling.md)
|
||||
|
||||
- [Bcc Vs Bch](./examples/js/bcc-vs-bch.md)
|
||||
|
||||
- [Benchmark](./examples/js/benchmark.md)
|
||||
|
||||
- [Binance Fetch All Deposits](./examples/js/binance-fetch-all-deposits.md)
|
||||
|
||||
- [Binance Fetch Ohlcv Many Symbols Async Await](./examples/js/binance-fetch-ohlcv-many-symbols-async-await.md)
|
||||
|
||||
- [Binance Fetch Ohlcv Many Symbols Promise Then Callbacks](./examples/js/binance-fetch-ohlcv-many-symbols-promise-then-callbacks.md)
|
||||
|
||||
- [Binance Fetchticker Delivery Vs Future](./examples/js/binance-fetchTicker-delivery-vs-future.md)
|
||||
|
||||
- [Binance Futures Transfer From Sub Account To Master](./examples/js/binance-futures-transfer-from-sub-account-to-master.md)
|
||||
|
||||
- [Binance Margin Stop Order](./examples/js/binance-margin-stop-order.md)
|
||||
|
||||
- [Binance Server Time](./examples/js/binance-server-time.md)
|
||||
|
||||
- [Binance Universal Transfer](./examples/js/binance-universal-transfer.md)
|
||||
|
||||
- [Bitfinex Fetch Trades](./examples/js/bitfinex-fetch-trades.md)
|
||||
|
||||
- [Bitfinex2 Fetch Trades](./examples/js/bitfinex2-fetch-trades.md)
|
||||
|
||||
- [Bitmex Browser Cors Proxy](./examples/js/bitmex-browser-cors-proxy.md)
|
||||
|
||||
- [Bitpanda Fetchmytrades Reduce](./examples/js/bitpanda-fetchMyTrades-reduce.md)
|
||||
|
||||
- [Bitrue Fetch Balance](./examples/js/bitrue-fetch-balance.md)
|
||||
|
||||
- [Bitstamp Private Api](./examples/js/bitstamp-private-api.md)
|
||||
|
||||
- [Bitstamp Public Api](./examples/js/bitstamp-public-api.md)
|
||||
|
||||
- [Bittrex Balance](./examples/js/bittrex-balance.md)
|
||||
|
||||
- [Bittrex Fetch Closed Orders History](./examples/js/bittrex-fetch-closed-orders-history.md)
|
||||
|
||||
- [Blockchaincom Withdrawal](./examples/js/blockchaincom-withdrawal.md)
|
||||
|
||||
- [Build Ohlcv Bars](./examples/js/build-ohlcv-bars.md)
|
||||
|
||||
- [Builtin Rate Limiting Rest Poller](./examples/js/builtin-rate-limiting-rest-poller.md)
|
||||
|
||||
- [Bybit Trailing](./examples/js/bybit-trailing.md)
|
||||
|
||||
- [Bybit Updated](./examples/js/bybit-updated.md)
|
||||
|
||||
- [Coinbase Fetch All Balances](./examples/js/coinbase-fetch-all-balances.md)
|
||||
|
||||
- [Coinex Fetch All Deposit Addresses Using Fetchdepositaddress](./examples/js/coinex-fetch-all-deposit-addresses-using-fetchDepositAddress.md)
|
||||
|
||||
- [Coinex Futures](./examples/js/coinex-futures.md)
|
||||
|
||||
- [Coinone Fetch Tickers](./examples/js/coinone-fetch-tickers.md)
|
||||
|
||||
- [Coinone Markets](./examples/js/coinone-markets.md)
|
||||
|
||||
- [Compare Two Exchanges Capabilities](./examples/js/compare-two-exchanges-capabilities.md)
|
||||
|
||||
- [Cors Proxy](./examples/js/cors-proxy.md)
|
||||
|
||||
- [Create Order Handle Errors](./examples/js/create-order-handle-errors.md)
|
||||
|
||||
- [Create Order Position With Takeprofit Stoploss](./examples/js/create-order-position-with-takeprofit-stoploss.md)
|
||||
|
||||
- [Create Order With Retry](./examples/js/create-order-with-retry.md)
|
||||
|
||||
- [Create Order Ws Example](./examples/js/create-order-ws-example.md)
|
||||
|
||||
- [Create Orders Example](./examples/js/create-orders-example.md)
|
||||
|
||||
- [Create Trailing Amount Order](./examples/js/create-trailing-amount-order.md)
|
||||
|
||||
- [Create Trailing Percent Order](./examples/js/create-trailing-percent-order.md)
|
||||
|
||||
- [Credentials](./examples/js/credentials.md)
|
||||
|
||||
- [Custom Proxy Agent For Js](./examples/js/custom-proxy-agent-for-js.md)
|
||||
|
||||
- [Custom Proxy Url](./examples/js/custom-proxy-url.md)
|
||||
|
||||
- [Delta Maintenance Margin Rate Max Leverage](./examples/js/delta-maintenance-margin-rate-max-leverage.md)
|
||||
|
||||
- [Env Variables](./examples/js/env-variables.md)
|
||||
|
||||
- [Error Handling](./examples/js/error-handling.md)
|
||||
|
||||
- [Exchange Capabilities](./examples/js/exchange-capabilities.md)
|
||||
|
||||
- [Exchanges By Volume](./examples/js/exchanges-by-volume.md)
|
||||
|
||||
- [Exchanges](./examples/js/exchanges.md)
|
||||
|
||||
- [Fetch All Balances](./examples/js/fetch-all-balances.md)
|
||||
|
||||
- [Fetch All Tickers To Files 2](./examples/js/fetch-all-tickers-to-files-2.md)
|
||||
|
||||
- [Fetch All Tickers To Files](./examples/js/fetch-all-tickers-to-files.md)
|
||||
|
||||
- [Fetch Balance](./examples/js/fetch-balance.md)
|
||||
|
||||
- [Fetch Create Deposit Address](./examples/js/fetch-create-deposit-address.md)
|
||||
|
||||
- [Fetch First Ohlcv Timestamp](./examples/js/fetch-first-ohlcv-timestamp.md)
|
||||
|
||||
- [Fetch From Many Exchanges Simultaneously](./examples/js/fetch-from-many-exchanges-simultaneously.md)
|
||||
|
||||
- [Fetch Funding Rate History](./examples/js/fetch-funding-rate-history.md)
|
||||
|
||||
- [📂 Fetch Futures](https://github.com/ccxt/ccxt/tree/master/./examples/js/fetch-futures)
|
||||
|
||||
- [Fetch Ohlcv From To Mark Index Premium](./examples/js/fetch-ohlcv-from-to-mark-index-premium.md)
|
||||
|
||||
- [Fetch Ohlcv Many Exchanges Continuosly](./examples/js/fetch-ohlcv-many-exchanges-continuosly.md)
|
||||
|
||||
- [Fetch Ohlcv](./examples/js/fetch-ohlcv.md)
|
||||
|
||||
- [Fetch Okex Futures](./examples/js/fetch-okex-futures.md)
|
||||
|
||||
- [Fetch Orders](./examples/js/fetch-orders.md)
|
||||
|
||||
- [Fetch Ticker From Multiple Exchanges](./examples/js/fetch-ticker-from-multiple-exchanges.md)
|
||||
|
||||
- [Fetch Ticker Where Available](./examples/js/fetch-ticker-where-available.md)
|
||||
|
||||
- [📂 Fetch Tickers](https://github.com/ccxt/ccxt/tree/master/./examples/js/fetch-tickers)
|
||||
|
||||
- [Gateio Create Batch Order](./examples/js/gateio-create-batch-order.md)
|
||||
|
||||
- [Gateio Futures](./examples/js/gateio-futures.md)
|
||||
|
||||
- [Gateio Open Close Contract](./examples/js/gateio-open-close-contract.md)
|
||||
|
||||
- [Gateio Swaps](./examples/js/gateio-swaps.md)
|
||||
|
||||
- [Gdax Fetch Trades Pagination](./examples/js/gdax-fetch-trades-pagination.md)
|
||||
|
||||
- [Hibachi Example](./examples/js/hibachi-example.md)
|
||||
|
||||
- [Hitbtc2 Withdraw](./examples/js/hitbtc2-withdraw.md)
|
||||
|
||||
- [How To Import One Exchange Esm](./examples/js/how-to-import-one-exchange-esm.md)
|
||||
|
||||
- [Huobi Futures](./examples/js/huobi-futures.md)
|
||||
|
||||
- [Huobi Open Close Contract](./examples/js/huobi-open-close-contract.md)
|
||||
|
||||
- [Huobi Swaps](./examples/js/huobi-swaps.md)
|
||||
|
||||
- [Huobipro Market Buy Sell Fetch Trading Limits](./examples/js/huobipro-market-buy-sell-fetch-trading-limits.md)
|
||||
|
||||
- [Hybridcjsexample](./examples/js/hybridCJSExample.md)
|
||||
|
||||
- [Hybridesmexample](./examples/js/hybridESMExample.md)
|
||||
|
||||
- [Idex Fetch Balance](./examples/js/idex-fetch-balance.md)
|
||||
|
||||
- [Instantiate All At Once](./examples/js/instantiate-all-at-once.md)
|
||||
|
||||
- [Instantiate All From Json](./examples/js/instantiate-all-from-json.md)
|
||||
|
||||
- [Kraken Create And Close Position](./examples/js/kraken-create-and-close-position.md)
|
||||
|
||||
- [Kraken Fetch Order Trades](./examples/js/kraken-fetch-order-trades.md)
|
||||
|
||||
- [Kraken Margin Trading](./examples/js/kraken-margin-trading.md)
|
||||
|
||||
- [Kucoin Rate Limit](./examples/js/kucoin-rate-limit.md)
|
||||
|
||||
- [Latoken Example](./examples/js/latoken-example.md)
|
||||
|
||||
- [Live Orderbook](./examples/js/live-orderbook.md)
|
||||
|
||||
- [Live Ticker](./examples/js/live-ticker.md)
|
||||
|
||||
- [Live Tickers](./examples/js/live-tickers.md)
|
||||
|
||||
- [Load All Contracts](./examples/js/load-all-contracts.md)
|
||||
|
||||
- [Load All Symbols At Once](./examples/js/load-all-symbols-at-once.md)
|
||||
|
||||
- [Load All Tickers At Once](./examples/js/load-all-tickers-at-once.md)
|
||||
|
||||
- [Load Markets To Files](./examples/js/load-markets-to-files.md)
|
||||
|
||||
- [Looping Over All Symbols Of Specific Exchanges](./examples/js/looping-over-all-symbols-of-specific-exchanges.md)
|
||||
|
||||
- [Looping Over Specific Symbols Of All Exchanges](./examples/js/looping-over-specific-symbols-of-all-exchanges.md)
|
||||
|
||||
- [Margin Loan Borrow Buy Sell Repay](./examples/js/margin-loan-borrow-buy-sell-repay.md)
|
||||
|
||||
- [Market Status And Currency Status](./examples/js/market-status-and-currency-status.md)
|
||||
|
||||
- [Ohlcv Console Chart](./examples/js/ohlcv-console-chart.md)
|
||||
|
||||
- [Okex Fetch Closed Orders Archive](./examples/js/okex-fetch-closed-orders-archive.md)
|
||||
|
||||
- [Okex Transfer](./examples/js/okex-transfer.md)
|
||||
|
||||
- [Okx Poll Fetch My Trades](./examples/js/okx-poll-fetch-my-trades.md)
|
||||
|
||||
- [Okx Poll Rate Limit](./examples/js/okx-poll-rate-limit.md)
|
||||
|
||||
- [Order Book Extra Level Depth Param](./examples/js/order-book-extra-level-depth-param.md)
|
||||
|
||||
- [Phemex Create Order Position With Takeprofit Stoploss](./examples/js/phemex-create-order-position-with-takeprofit-stoploss.md)
|
||||
|
||||
- [Poll Ohlcv](./examples/js/poll-ohlcv.md)
|
||||
|
||||
- [Poloniex Fetch Order Books](./examples/js/poloniex-fetch-order-books.md)
|
||||
|
||||
- [Poloniex Limits Amount Min](./examples/js/poloniex-limits-amount-min.md)
|
||||
|
||||
- [Proxy Round Robin](./examples/js/proxy-round-robin.md)
|
||||
|
||||
- [Proxy Usage](./examples/js/proxy-usage.md)
|
||||
|
||||
- [Sample Local Proxy Server With Cors](./examples/js/sample-local-proxy-server-with-cors.md)
|
||||
|
||||
- [Search All Exchanges](./examples/js/search-all-exchanges.md)
|
||||
|
||||
- [Shared Load Markets](./examples/js/shared-load-markets.md)
|
||||
|
||||
- [Sort Swap Markets By Hourly Price Change](./examples/js/sort-swap-markets-by-hourly-price-change.md)
|
||||
|
||||
- [Symbols](./examples/js/symbols.md)
|
||||
|
||||
- [Theocean](./examples/js/theocean.md)
|
||||
|
||||
- [Tickers](./examples/js/tickers.md)
|
||||
|
||||
- [Validate Paginated Data](./examples/js/validate-paginated-data.md)
|
||||
|
||||
- [Watch Ohlcv For Symbols](./examples/js/watch-OHLCV-For-Symbols.md)
|
||||
|
||||
- [Watch Ohlcv](./examples/js/watch-OHLCV.md)
|
||||
|
||||
- [Watch Orderbook For Symbols](./examples/js/watch-OrderBook-For-Symbols.md)
|
||||
|
||||
- [Watch Trades For Symbols](./examples/js/watch-Trades-For-Symbols.md)
|
||||
|
||||
- [Watch Tickers](./examples/js/watch-tickers.md)
|
||||
|
||||
- [Watchohlcvforsymbols](./examples/js/watchOHLCVForSymbols.md)
|
||||
|
||||
- [Watchorderbookforsymbols](./examples/js/watchOrderBookForSymbols.md)
|
||||
|
||||
- [Watchpositions Many Exchanges Continuosly.d](./examples/js/watchPositions-many-exchanges-continuosly.d.md)
|
||||
|
||||
- [Watchpositions Many Exchanges Continuosly.d.ts](./examples/js/watchPositions-many-exchanges-continuosly.d.ts.md)
|
||||
|
||||
- [Watchpositions Many Exchanges Continuosly](./examples/js/watchPositions-many-exchanges-continuosly.md)
|
||||
|
||||
- [Watchpositions.d](./examples/js/watchPositions.d.md)
|
||||
|
||||
- [Watchpositions.d.ts](./examples/js/watchPositions.d.ts.md)
|
||||
|
||||
- [Watchpositions](./examples/js/watchPositions.md)
|
||||
|
||||
- [Watchpositionsforsymbols.d](./examples/js/watchPositionsForSymbols.d.md)
|
||||
|
||||
- [Watchpositionsforsymbols.d.ts](./examples/js/watchPositionsForSymbols.d.ts.md)
|
||||
|
||||
- [Watchpositionsforsymbols](./examples/js/watchPositionsForSymbols.md)
|
||||
|
||||
- [Watchtradesforsymbols](./examples/js/watchTradesForSymbols.md)
|
||||
|
||||
- [Withdraw From One Exchange To Another](./examples/js/withdraw-from-one-exchange-to-another.md)
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
- [Advanced Error Handling](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
"use strict";
|
||||
|
||||
const ccxt = require ('../../ccxt.js');
|
||||
|
||||
// instantiate the exchange
|
||||
let exchange = new ccxt.coinbasepro ({
|
||||
'apiKey': 'XXXXXXXXXXXXXX',
|
||||
'secret': 'YYYYYYYYYYYYYY',
|
||||
});
|
||||
|
||||
async function checkOrders(){
|
||||
try {
|
||||
// fetch orders
|
||||
let orders = await exchange.fetchOrders ('BTC/USDT');
|
||||
// output the result
|
||||
console.log (exchange.id, 'fetched orders', orders);
|
||||
} catch (e) {
|
||||
if (e instanceof ccxt.DDoSProtection || e.message.includes ('ECONNRESET')) {
|
||||
console.log ('[DDoS Protection] ' + e.message);
|
||||
} else if (e instanceof ccxt.RequestTimeout) {
|
||||
console.log ('[Request Timeout] ' + e.message);
|
||||
} else if (e instanceof ccxt.AuthenticationError) {
|
||||
console.log ('[Authentication Error] ' + e.message);
|
||||
} else if (e instanceof ccxt.ExchangeNotAvailable) {
|
||||
console.log ('[Exchange Not Available Error] ' + e.message);
|
||||
} else if (e instanceof ccxt.ExchangeError) {
|
||||
console.log ('[Exchange Error] ' + e.message);
|
||||
} else if (e instanceof ccxt.NetworkError) {
|
||||
console.log ('[Network Error] ' + e.message);
|
||||
} else {
|
||||
// you can throw it if you want to stop the execution
|
||||
// console.log ('[Exception ' + e.constructor.name + '] ' + e.message);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// for demonstrational purposes, we use 1000 ms interval
|
||||
setInterval(checkOrders, 1000);
|
||||
|
||||
```
|
||||
@@ -0,0 +1,59 @@
|
||||
- [Aggregate Orderbook](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
|
||||
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
|
||||
const aggregateOrderBookSide = function (orderbookSide, precision = undefined) {
|
||||
const result = []
|
||||
const amounts = {}
|
||||
for (let i = 0; i < orderbookSide.length; i++) {
|
||||
const ask = orderbookSide[i]
|
||||
let price = ask[0]
|
||||
if (precision !== undefined) {
|
||||
price = ccxt.decimalToPrecision (price, ccxt.ROUND, precision, ccxt.TICK_SIZE)
|
||||
}
|
||||
amounts[price] = (amounts[price] || 0) + ask[1]
|
||||
}
|
||||
Object.keys (amounts).forEach (price => {
|
||||
result.push ([
|
||||
parseFloat (price),
|
||||
amounts[price]
|
||||
])
|
||||
})
|
||||
return result
|
||||
}
|
||||
|
||||
const aggregateOrderBook = function (orderbook, precision = undefined) {
|
||||
let asks = aggregateOrderBookSide(orderbook['asks'], precision)
|
||||
let bids = aggregateOrderBookSide(orderbook['bids'], precision)
|
||||
return {
|
||||
'asks': ccxt.sortBy (asks, 0),
|
||||
'bids': ccxt.sortBy (bids, 0, true),
|
||||
'timestamp': orderbook['timestamp'],
|
||||
'datetime': orderbook['datetime'],
|
||||
'nonce': orderbook['nonce'],
|
||||
};
|
||||
}
|
||||
|
||||
;(async () => {
|
||||
|
||||
const exchange = new ccxt.coinbasepro()
|
||||
|
||||
await exchange.loadMarkets ()
|
||||
|
||||
// exchange.verbose = true // uncomment for verbose debug output
|
||||
|
||||
// level 2 (default)
|
||||
const orderbook = await exchange.fetchOrderBook('BTC/USD')
|
||||
|
||||
// or level 3
|
||||
// const orderbook = await exchange.fetchOrderBook('BTC/USD', undefined, { 'level': 3 })
|
||||
|
||||
const step = 0.5 // 0.01, 0.1, 0.5, 1.0, 2.5, 5.0, 10.0
|
||||
console.log (aggregateOrderBook (orderbook, step))
|
||||
|
||||
})();
|
||||
```
|
||||
@@ -0,0 +1,103 @@
|
||||
- [Apex Example](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
// AUTO-TRANSPILE //
|
||||
async function example() {
|
||||
const exchange = new ccxt.apex({
|
||||
'apiKey': 'your api Key',
|
||||
'secret': 'your api secret',
|
||||
'walletAddress': 'your eth address',
|
||||
'options': {
|
||||
'accountId': 'your account id',
|
||||
'passphrase': 'your api passphrase',
|
||||
'seeds': 'your zklink omni seed',
|
||||
'brokerId': '',
|
||||
},
|
||||
});
|
||||
exchange.setSandboxMode (true)
|
||||
const fetchTime = await exchange.fetchTime();
|
||||
console.log(fetchTime);
|
||||
//const transfer = await exchange.transfer('USDT', 1.1);
|
||||
//console.log(transfer);
|
||||
//const transferFromContract = await exchange.transfer('USDT', 1.2, 'contract', 'spot');
|
||||
//console.log(transferFromContract);
|
||||
//const fetchCurrencies = await exchange.fetchCurrencies();
|
||||
//console.log(fetchCurrencies);
|
||||
//const fetchBalance = await exchange.fetchBalance();
|
||||
//console.log(fetchBalance);
|
||||
//const fetchMarkets = await exchange.fetchMarkets();
|
||||
//console.log(fetchMarkets);
|
||||
//const fetchTicker = await exchange.fetchTicker('BTC-USDT');
|
||||
//console.log(fetchTicker);
|
||||
//const fetchTickers = await exchange.fetchTickers();
|
||||
//console.log(fetchTickers);
|
||||
//const fetchTrades = await exchange.fetchTrades('BTC-USDT');
|
||||
//console.log(fetchTrades);
|
||||
//const fetchOHLCV = await exchange.fetchOHLCV('BTC-USDT','1m', undefined, 200);
|
||||
//console.log(fetchOHLCV);
|
||||
//const fechOrderBook = await exchange.fetchOrderBook('BTC-USDT');
|
||||
//console.log(fechOrderBook);
|
||||
//const fetchOpenInterest = await exchange.fetchOpenInterest('BTC-USDT');
|
||||
//console.log(fetchOpenInterest);
|
||||
|
||||
//const fetchTransfers = await exchange.fetchTransfers();
|
||||
//console.log(fetchTransfers);
|
||||
//const fetchTransfer = await exchange.fetchTransfer();
|
||||
//console.log(fetchTransfer);
|
||||
|
||||
//const createOrderRes1 = await exchange.createOrder('BTC-USDT', 'LIMIT', 'SELL', 0.001, 100000, {'reduceOnly':true});
|
||||
//console.log(createOrderRes1);
|
||||
const createOrderRes1 = await exchange.createOrder('BTC-USDT', 'STOP_LIMIT', 'BUY', 0.001, 100000, {'triggerPriceType':'INDEX', 'triggerPrice':'10100'});
|
||||
console.log(createOrderRes1);
|
||||
|
||||
const fetchOpenOrders = await exchange.fetchOpenOrders();
|
||||
console.log(fetchOpenOrders);
|
||||
//const fetchOpenOrder = await exchange.fetchOrder(undefined,undefined,{"clientOrderId":'apexomni-615910568987983964-1741322302826-253839'});
|
||||
//console.log(fetchOpenOrder);
|
||||
//const cancelOrder = await exchange.cancelOrder('685707935650677596');
|
||||
//console.log(cancelOrder);
|
||||
//const cancelOrder1 = await exchange.cancelOrder(undefined,undefined,{"clientOrderId":'apexomni-615910568987983964-1741324574601-908656'});
|
||||
//console.log(cancelOrder1);
|
||||
//const cancelAllOrders = await exchange.cancelAllOrders();
|
||||
//console.log(cancelAllOrders);
|
||||
|
||||
//const setLeverage = await exchange.setLeverage(5,'BTC-USDT');
|
||||
//console.log(setLeverage);
|
||||
|
||||
//const fetchPositions = await exchange.fetchPositions();
|
||||
//console.log(fetchPositions);
|
||||
|
||||
//const fetchOrder = await exchange.fetchOrder('685781264227107164');
|
||||
//console.log(fetchOrder);
|
||||
|
||||
//const fetchOrderTrades = await exchange.fetchOrderTrades('685781264227107164'); //{"clientOrderId":'apexomni-615910568987983964-1741339789276-640091'}
|
||||
//console.log(fetchOrderTrades);
|
||||
|
||||
|
||||
let since = exchange.milliseconds () - 86400000*1; // -1 day from now
|
||||
let allTrades = [];
|
||||
let page = 0;
|
||||
while (since < exchange.milliseconds ()) {
|
||||
const params = {
|
||||
'page': page, // exchange-specific non-unified parameter name
|
||||
}
|
||||
const trades = await exchange.fetchFundingHistory ('BTC-USDT', since, 20, params)
|
||||
if (trades.length) {
|
||||
allTrades = allTrades.concat (trades)
|
||||
page++
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
allTrades = exchange.sortBy(allTrades, 'timestamp');
|
||||
|
||||
|
||||
const createOrderRes = await exchange.createOrder('BTC-USDT', 'LIMIT', 'BUY', 0.001, 70000, {'reduceOnly':true,'postOnly':true});
|
||||
console.log(createOrderRes);
|
||||
console.log('end');
|
||||
}
|
||||
await example();
|
||||
|
||||
```
|
||||
@@ -0,0 +1,135 @@
|
||||
- [Arbitrage Pairs](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
|
||||
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
import asTable from 'as-table';
|
||||
import fs from 'fs';
|
||||
import ansicolor from 'ansicolor';
|
||||
import ololog from 'ololog';
|
||||
|
||||
const log = ololog.configure ({ locate: false }), verbose = process.argv.includes ('--verbose'), keysGlobal = 'keys.json', keysLocal = 'keys.local.json', keysFile = fs.existsSync (keysLocal) ? keysLocal : (fs.existsSync (keysGlobal) ? keysGlobal : false), config = keysFile ? require ('../../' + keysFile) : {};
|
||||
|
||||
let printSupportedExchanges = function () {
|
||||
log ('Supported exchanges:', ccxt.exchanges.join (', ').green)
|
||||
}
|
||||
|
||||
let printUsage = function () {
|
||||
log ('Usage: node', process.argv[1], 'id1'.green, 'id2'.yellow, 'id3'.blue, '...')
|
||||
printSupportedExchanges ()
|
||||
}
|
||||
|
||||
let printExchangeSymbolsAndMarkets = function (exchange) {
|
||||
log (getExchangeSymbols (exchange))
|
||||
log (getExchangeMarketsTable (exchange))
|
||||
}
|
||||
|
||||
let getExchangeMarketsTable = (exchange) => {
|
||||
return asTable.configure ({ delimiter: ' | ' }) (Object.values (markets))
|
||||
}
|
||||
|
||||
let sleep = (ms) => new Promise (resolve => setTimeout (resolve, ms));
|
||||
|
||||
let proxies = [
|
||||
'', // no proxy by default
|
||||
'https://crossorigin.me/',
|
||||
'https://cors-anywhere.herokuapp.com/',
|
||||
]
|
||||
|
||||
;(async function main () {
|
||||
|
||||
if (process.argv.length > 3) {
|
||||
|
||||
let ids = process.argv.slice (2)
|
||||
let exchanges = {}
|
||||
|
||||
log (ids.join (', ').yellow)
|
||||
|
||||
// load all markets from all exchanges
|
||||
for (let id of ids) {
|
||||
|
||||
let settings = config[id] || {}
|
||||
|
||||
// instantiate the exchange by id
|
||||
let exchange = new ccxt[id] (ccxt.extend ({
|
||||
// verbose,
|
||||
// 'proxy': 'https://cors-anywhere.herokuapp.com/',
|
||||
}, settings))
|
||||
|
||||
// save it in a dictionary under its id for future use
|
||||
exchanges[id] = exchange
|
||||
|
||||
// load all markets from the exchange
|
||||
let markets = await exchange.loadMarkets ()
|
||||
|
||||
// basic round-robin proxy scheduler
|
||||
let currentProxy = 0
|
||||
let maxRetries = proxies.length
|
||||
|
||||
for (let numRetries = 0; numRetries < maxRetries; numRetries++) {
|
||||
|
||||
try { // try to load exchange markets using current proxy
|
||||
|
||||
exchange.proxy = proxies[currentProxy]
|
||||
await exchange.loadMarkets ()
|
||||
|
||||
} catch (e) { // rotate proxies in case of connectivity errors, catch all other exceptions
|
||||
|
||||
// swallow connectivity exceptions only
|
||||
if (e instanceof ccxt.DDoSProtection || e.message.includes ('ECONNRESET')) {
|
||||
log.bright.yellow ('[DDoS Protection Error] ' + e.message)
|
||||
} else if (e instanceof ccxt.RequestTimeout) {
|
||||
log.bright.yellow ('[Timeout Error] ' + e.message)
|
||||
} else if (e instanceof ccxt.AuthenticationError) {
|
||||
log.bright.yellow ('[Authentication Error] ' + e.message)
|
||||
} else if (e instanceof ccxt.ExchangeNotAvailable) {
|
||||
log.bright.yellow ('[Exchange Not Available Error] ' + e.message)
|
||||
} else if (e instanceof ccxt.ExchangeError) {
|
||||
log.bright.yellow ('[Exchange Error] ' + e.message)
|
||||
} else {
|
||||
throw e; // rethrow all other exceptions
|
||||
}
|
||||
|
||||
// retry next proxy in round-robin fashion in case of error
|
||||
currentProxy = ++currentProxy % proxies.length
|
||||
}
|
||||
}
|
||||
|
||||
log (id.green, 'loaded', exchange.symbols.length.toString ().green, 'markets')
|
||||
}
|
||||
|
||||
log ('Loaded all markets'.green)
|
||||
|
||||
// get all unique symbols
|
||||
let uniqueSymbols = ccxt.unique (ccxt.flatten (ids.map (id => exchanges[id].symbols)))
|
||||
|
||||
// filter out symbols that are not present on at least two exchanges
|
||||
let arbitrableSymbols = uniqueSymbols
|
||||
.filter (symbol =>
|
||||
ids.filter (id =>
|
||||
(exchanges[id].symbols.indexOf (symbol) >= 0)).length > 1)
|
||||
.sort ((id1, id2) => (id1 > id2) ? 1 : ((id2 > id1) ? -1 : 0))
|
||||
|
||||
// print a table of arbitrable symbols
|
||||
let table = arbitrableSymbols.map (symbol => {
|
||||
let row = { symbol }
|
||||
for (let id of ids)
|
||||
if (exchanges[id].symbols.indexOf (symbol) >= 0)
|
||||
row[id] = id
|
||||
return row
|
||||
})
|
||||
|
||||
log (asTable.configure ({ delimiter: ' | ' }) (table))
|
||||
|
||||
} else {
|
||||
|
||||
printUsage ()
|
||||
|
||||
}
|
||||
|
||||
process.exit ()
|
||||
|
||||
}) ()
|
||||
```
|
||||
@@ -0,0 +1,34 @@
|
||||
- [Basic Chart](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
|
||||
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
import asciichart from 'asciichart';
|
||||
import asTable from 'as-table';
|
||||
import ololog from 'ololog'
|
||||
import ansicolor from 'ansicolor';
|
||||
|
||||
const log = ololog.configure ({ locate: false })
|
||||
|
||||
ansicolor.nice
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
;(async function main () {
|
||||
|
||||
// experimental, not yet implemented for all exchanges
|
||||
// your contributions are welcome ;)
|
||||
|
||||
const index = 4 // [ timestamp, open, high, low, close, volume ]
|
||||
const ohlcv = await new ccxt.okcoin ().fetchOHLCV ('BTC/USD', '15m')
|
||||
const lastPrice = ohlcv[ohlcv.length - 1][index] // closing price
|
||||
const series = ohlcv.map (x => x[index]) // closing price
|
||||
const bitcoinRate = ('₿ = $' + lastPrice).green
|
||||
const chart = asciichart.plot (series, { height: 15, padding: ' ' })
|
||||
log.yellow ("\n" + chart, bitcoinRate, "\n")
|
||||
process.exit ()
|
||||
|
||||
}) ()
|
||||
```
|
||||
@@ -0,0 +1,18 @@
|
||||
- [Basic Orderbook Polling](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
|
||||
const id = 'huobipro', exchange = new ccxt[id] ({ enableRateLimit: true }), symbol = 'ETH/BTC';(async function main () {
|
||||
|
||||
await exchange.loadMarkets ()
|
||||
|
||||
for (let i = 0; i < 2000; i++) {
|
||||
|
||||
const orderbook = await exchange.fetchOrderBook (symbol)
|
||||
console.log (new Date (), i, symbol, orderbook.asks[0], orderbook.bids[0])
|
||||
}
|
||||
|
||||
}) ()
|
||||
```
|
||||
@@ -0,0 +1,121 @@
|
||||
- [Bcc Vs Bch](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
|
||||
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
import asTable from 'as-table';
|
||||
import ololog from 'ololog'
|
||||
import config from '../../keys.json';
|
||||
import ansicolor from 'ansicolor';
|
||||
|
||||
const log = ololog.configure ({ locate: false })
|
||||
|
||||
ansicolor.nice
|
||||
|
||||
let sleep = (ms) => new Promise (resolve => setTimeout (resolve, ms))
|
||||
|
||||
let proxies = [
|
||||
'', // no proxy by default
|
||||
'https://crossorigin.me/',
|
||||
'https://cors-anywhere.herokuapp.com/',
|
||||
]
|
||||
|
||||
;(async function main () {
|
||||
|
||||
let ids = ccxt.exchanges
|
||||
let exchanges = {}
|
||||
|
||||
// instantiate all exchanges
|
||||
ccxt.exchanges.forEach (id => {
|
||||
if (id in ccxt)
|
||||
exchanges[id] = new (ccxt)[id] ({
|
||||
verbose: false,
|
||||
substituteCommonCurrencyCodes: true,
|
||||
})
|
||||
})
|
||||
|
||||
// set up api keys appropriately
|
||||
for (let id in config) {
|
||||
if (id in exchanges)
|
||||
for (let key in config[id])
|
||||
exchanges[id][key] = config[id][key]
|
||||
}
|
||||
|
||||
log (ids.join (', ').yellow)
|
||||
|
||||
// load all markets from all exchanges
|
||||
|
||||
await Promise.all (ids.map (async id => {
|
||||
|
||||
let exchange = exchanges[id]
|
||||
|
||||
// basic round-robin proxy scheduler
|
||||
let currentProxy = 0
|
||||
let maxRetries = proxies.length
|
||||
|
||||
for (let numRetries = 0; numRetries < maxRetries; numRetries++) {
|
||||
|
||||
try { // try to load exchange markets using current proxy
|
||||
|
||||
exchange.proxy = proxies[currentProxy]
|
||||
await exchange.loadMarkets ()
|
||||
|
||||
} catch (e) { // rotate proxies in case of connectivity errors, catch all other exceptions
|
||||
|
||||
// swallow connectivity exceptions only
|
||||
if ((e instanceof ccxt.DDoSProtection) || e.message.includes ('ECONNRESET')) {
|
||||
log.bright.yellow (exchange.id + ' [DDoS Protection]')
|
||||
} else if (e instanceof ccxt.RequestTimeout) {
|
||||
log.bright.yellow (exchange.id + ' [Request Timeout] ' + e.message)
|
||||
} else if (e instanceof ccxt.AuthenticationError) {
|
||||
log.bright.yellow (exchange.id + ' [Authentication Error] ' + e.message)
|
||||
} else if (e instanceof ccxt.ExchangeNotAvailable) {
|
||||
log.bright.yellow (exchange.id + ' [Exchange Not Available] ' + e.message)
|
||||
} else if (e instanceof ccxt.ExchangeError) {
|
||||
log.bright.yellow (exchange.id + ' [Exchange Error] ' + e.message)
|
||||
} else {
|
||||
throw e; // rethrow all other exceptions
|
||||
}
|
||||
|
||||
// retry next proxy in round-robin fashion in case of error
|
||||
currentProxy = ++currentProxy % proxies.length
|
||||
}
|
||||
}
|
||||
|
||||
if (exchange.symbols)
|
||||
log (id.green, 'loaded', exchange.symbols.length.toString ().green, 'markets')
|
||||
|
||||
}))
|
||||
|
||||
log ('Loaded all markets'.green)
|
||||
|
||||
let table = ccxt.exchanges.map (id => {
|
||||
console.log (id)
|
||||
let exchange = exchanges[id]
|
||||
if (exchange.currencies) {
|
||||
let hasBCC = exchange.currencies.includes ('BCC')
|
||||
let hasBCH = exchange.currencies.includes ('BCH')
|
||||
let hasBoth = (hasBCC && hasBCH)
|
||||
return {
|
||||
id,
|
||||
'BCC': hasBoth ? id.green : (hasBCC ? id.yellow : ''),
|
||||
'BCH': hasBCH ? id.green : '',
|
||||
}
|
||||
} else {
|
||||
return {
|
||||
'id': id.red,
|
||||
'BCC': '',
|
||||
'BCH': '',
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
log (asTable.configure ({ delimiter: ' | ' }) (table))
|
||||
|
||||
process.exit ()
|
||||
|
||||
}) ()
|
||||
|
||||
```
|
||||
@@ -0,0 +1,110 @@
|
||||
- [Benchmark](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
import { spawn } from 'child_process';
|
||||
import asTable from 'as-table';
|
||||
import ccxt, { version } from '../../js/ccxt.js';
|
||||
const stats = (times) => {
|
||||
// calculate statistics
|
||||
const sum = times.reduce((a, b) => a + b, 0);
|
||||
const avg = Math.round(sum / times.length);
|
||||
const min = Math.min(...times);
|
||||
const max = Math.max(...times);
|
||||
times.sort((a, b) => a - b);
|
||||
const median = times.length % 2 === 0 ? (times[times.length / 2 - 1] + times[times.length / 2]) / 2 : times[Math.floor(times.length / 2)];
|
||||
return { min, 'average': avg, max, median, 'iterations': times.length };
|
||||
};
|
||||
async function benchmark(exchangeId, method, args, verbose = false, minIterations = 10, argsv = '') {
|
||||
const exchange = new ccxt.pro[exchangeId]({});
|
||||
const languages = ['js', 'py', 'php', 'cs'];
|
||||
const commands = languages.map((language) => ({
|
||||
'language': language,
|
||||
'method': method,
|
||||
'command': `npm run cli.${language} ${exchangeId} ${method} ${args.join(' ')} -- ${argsv} --poll`,
|
||||
}));
|
||||
const wsMethod = method + 'Ws';
|
||||
if (exchange.has[wsMethod]) {
|
||||
const wsCommands = languages.map((language) => ({
|
||||
'language': language,
|
||||
'method': wsMethod,
|
||||
'command': `npm run cli.${language} ${exchangeId} ${wsMethod} ${args.join(' ')} -- ${argsv} --poll`,
|
||||
}));
|
||||
commands.push(...wsCommands);
|
||||
}
|
||||
const regex = /iteration (\d+) passed in (\d+) ms/g;
|
||||
async function runCommand(command) {
|
||||
if (verbose) {
|
||||
console.log(exchange.iso8601(new Date().getTime()), ' running command:', command);
|
||||
}
|
||||
return new Promise((resolve, reject) => {
|
||||
const [cmd, ...args] = command.split(' ');
|
||||
const child = spawn(cmd, args);
|
||||
const matches = [];
|
||||
const language = command.slice(8, 15);
|
||||
child.stdout.on('data', (data) => {
|
||||
const message = data.toString();
|
||||
matches.push(...Array.from(message.matchAll(regex)));
|
||||
const match = matches[matches.length - 1];
|
||||
if (match && match[1] && match[2]) {
|
||||
const iteration = parseInt(match[1]);
|
||||
const time = parseInt(match[2]);
|
||||
if (iteration <= minIterations) {
|
||||
if (verbose) {
|
||||
console.log(exchange.iso8601(new Date().getTime()), `${language} iteration ${iteration} passed in ${time} ms`);
|
||||
}
|
||||
}
|
||||
else {
|
||||
const times = matches.map((m) => parseInt(m[2]));
|
||||
child.kill();
|
||||
if (verbose) {
|
||||
console.log(exchange.iso8601(new Date().getTime()), `killed process - ${language} iteration ${iteration} passed in ${time} ms`);
|
||||
}
|
||||
resolve({ times });
|
||||
}
|
||||
}
|
||||
});
|
||||
child.stderr.on('data', (data) => {
|
||||
const message = data.toString();
|
||||
console.error(exchange.iso8601(new Date().getTime()), `command ${command} failed. stderr: ${message}`);
|
||||
const times = matches.map((m) => parseInt(m[2]));
|
||||
resolve({ times });
|
||||
});
|
||||
child.on('close', (code) => {
|
||||
const times = matches.map((m) => parseInt(m[2]));
|
||||
resolve({ times });
|
||||
console.log(exchange.iso8601(new Date().getTime()), `${language} child process exited with code ${code}`);
|
||||
});
|
||||
child.on('error', (err) => {
|
||||
console.error(exchange.iso8601(new Date().getTime()), `command ${command} failed. error: ${err}`);
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
}
|
||||
const benchmarks = [];
|
||||
const results = await Promise.all(commands.map((c) => runCommand(c.command)));
|
||||
for (let i = 0; i < results.length; i++) {
|
||||
const result = results[i];
|
||||
benchmarks.push({ 'language': commands[i].language, 'method': commands[i].method, ...stats(result.times) });
|
||||
}
|
||||
if (verbose) {
|
||||
const rawResults = results.map((r, i) => ({ 'language': commands[i].language, 'method': commands[i].method, ...stats(r.times), 'times': r.times }));
|
||||
console.log(rawResults);
|
||||
}
|
||||
console.log(asTable(benchmarks));
|
||||
}
|
||||
const [_, , exchangeId, methodName, ...params] = process.argv.filter((x) => !x.startsWith('--'));
|
||||
const verbose = process.argv.includes('--verbose');
|
||||
const minIterationsString = process.argv.find((x) => x.startsWith('--min-iterations='))?.slice(18);
|
||||
const minIterations = minIterationsString ? parseInt(minIterationsString) : 10;
|
||||
const argsv = process.argv.filter((x) => x.startsWith('--') && !x.startsWith('--min-iterations')).join(' ');
|
||||
console.log((new Date()).toISOString());
|
||||
console.log('Node.js:', process.version);
|
||||
console.log('CCXT v' + version);
|
||||
const start = new Date().getTime();
|
||||
await benchmark(exchangeId, methodName, params, verbose, minIterations, argsv);
|
||||
const end = new Date().getTime();
|
||||
console.log((new Date().toISOString()), 'Total time:', end - start, 'ms');
|
||||
process.exit(0);
|
||||
|
||||
```
|
||||
@@ -0,0 +1,50 @@
|
||||
- [Binance Fetch All Deposits](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
|
||||
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
|
||||
(async function main () {
|
||||
|
||||
const exchange = new ccxt.binance ({
|
||||
'apiKey': 'YOUR_API_KEY',
|
||||
'secret': 'YOUR_SECRET',
|
||||
})
|
||||
|
||||
await exchange.loadMarkets ()
|
||||
|
||||
// exchange.verbose = true // uncomment for debugging
|
||||
|
||||
const ninetyDays = 90 * 24 * 60 * 60 * 1000;
|
||||
let startTime = exchange.parse8601 ('2018-01-01T00:00:00')
|
||||
const now = exchange.milliseconds ()
|
||||
const currencyCode = undefined // any currency
|
||||
|
||||
let allTransactions = []
|
||||
|
||||
while (startTime < now) {
|
||||
|
||||
const endTime = startTime + ninetyDays
|
||||
|
||||
const transactions = await exchange.fetchDeposits (currencyCode, startTime, undefined, {
|
||||
'endTime': endTime,
|
||||
})
|
||||
if (transactions.length) {
|
||||
const lastTransaction = transactions[transactions.length - 1]
|
||||
startTime = lastTransaction['timestamp'] + 1
|
||||
allTransactions = allTransactions.concat (transactions)
|
||||
} else {
|
||||
startTime = endTime;
|
||||
}
|
||||
}
|
||||
|
||||
console.log ('Fetched', allTransactions.length, 'transactions')
|
||||
for (let i = 0; i < allTransactions.length; i++) {
|
||||
const transaction = allTransactions[i]
|
||||
console.log (i, transaction['datetime'], transaction['txid'], transaction['currency'], transaction['amount'])
|
||||
}
|
||||
|
||||
}) ()
|
||||
```
|
||||
@@ -0,0 +1,39 @@
|
||||
- [Binance Fetch Ohlcv Many Symbols Async Await](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
'use strict';
|
||||
|
||||
const ccxt = require ('../../js/ccxt.js')
|
||||
|
||||
console.log('CCXT Version:', ccxt.version)
|
||||
|
||||
async function symbolLoop (exchange, symbol, timeframe) {
|
||||
while (true) {
|
||||
try {
|
||||
const ohlcvs = await exchange.fetchOHLCV (symbol, timeframe)
|
||||
console.log (exchange.iso8601 (exchange.milliseconds ()), exchange.id, symbol, ohlcvs.length, 'OHLCV candles received')
|
||||
// await exchange.sleep (60 * 1000) // sleep if necessary, though not required
|
||||
} catch (e) {
|
||||
console.log (exchange.iso8601 (exchange.milliseconds ()), exchange.id, symbol, e.constructor.name, e.message)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function main () {
|
||||
const exchange = new ccxt.binance ()
|
||||
await exchange.loadMarkets ()
|
||||
// exchange.verbose = true // uncomment for debugging purposes if necessary
|
||||
const symbols = [
|
||||
'BTC/USDT', // unified symbols used here as opposed to exchange-specific market ids
|
||||
'ETH/USDT', // more about unified symbols vs exchange-specific ids here:
|
||||
'ADA/USDT', // https://github.com/ccxt/ccxt/wiki/Manual#markets
|
||||
]
|
||||
const timeframe = '1m'
|
||||
const loops = symbols.map (symbol => symbolLoop (exchange, symbol, timeframe))
|
||||
await Promise.all (loops)
|
||||
}
|
||||
|
||||
|
||||
main ()
|
||||
```
|
||||
@@ -0,0 +1,38 @@
|
||||
- [Binance Fetch Ohlcv Many Symbols Promise Then Callbacks](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
'use strict';
|
||||
|
||||
const ccxt = require ('../../js/ccxt.js')
|
||||
|
||||
console.log('CCXT Version:', ccxt.version)
|
||||
|
||||
function symbolLoop (exchange, symbol, timeframe) {
|
||||
exchange.fetchOHLCV (symbol, timeframe).then (ohlcvs => {
|
||||
console.log (exchange.iso8601 (exchange.milliseconds ()), exchange.id, symbol, ohlcvs.length, 'OHLCV candles received')
|
||||
setTimeout (() => symbolLoop (exchange, symbol, timeframe), 0)
|
||||
}).catch (e => {
|
||||
console.log (exchange.iso8601 (exchange.milliseconds ()), exchange.id, symbol, e.constructor.name, e.message)
|
||||
setTimeout (() => symbolLoop (exchange, symbol, timeframe), 0)
|
||||
})
|
||||
}
|
||||
|
||||
function main () {
|
||||
const exchange = new ccxt.binance ()
|
||||
// exchange.verbose = true // uncomment for debugging purposes if necessary
|
||||
const symbols = [
|
||||
'BTC/USDT', // unified symbols used here as opposed to exchange-specific market ids
|
||||
'ETH/USDT', // more about unified symbols vs exchange-specific ids here:
|
||||
'ADA/USDT', // https://github.com/ccxt/ccxt/wiki/Manual#markets
|
||||
]
|
||||
const timeframe = '1m'
|
||||
exchange.loadMarkets ().then (markets => {
|
||||
for (const symbol of symbols) {
|
||||
setTimeout (() => symbolLoop (exchange, symbol, timeframe), 0)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
main ()
|
||||
```
|
||||
@@ -0,0 +1,36 @@
|
||||
- [Binance Fetchticker Delivery Vs Future](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
|
||||
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
|
||||
async function fetchTickers (exchange) {
|
||||
let tickers = undefined
|
||||
try {
|
||||
// await exchange.loadMarkets () // optional
|
||||
tickers = await exchange.fetchTickers ()
|
||||
} catch (e) {
|
||||
console.error (e.constructor.name, e.message)
|
||||
}
|
||||
return tickers
|
||||
}
|
||||
|
||||
(async () => {
|
||||
|
||||
const future = new ccxt.binance ({ options: { defaultType: 'future' }})
|
||||
const delivery = new ccxt.binance ({ options: { defaultType: 'delivery' }})
|
||||
|
||||
// ...
|
||||
|
||||
const futureTickers = await fetchTickers (future);
|
||||
console.log (futureTickers)
|
||||
|
||||
console.log ('-------------------------------------------')
|
||||
|
||||
const deliveryTickers = await fetchTickers (delivery);
|
||||
console.log (deliveryTickers)
|
||||
|
||||
}) ()
|
||||
```
|
||||
@@ -0,0 +1,47 @@
|
||||
- [Binance Futures Transfer From Sub Account To Master](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
|
||||
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
|
||||
console.log ('CCXT Version:', ccxt.version)
|
||||
|
||||
// https://github.com/ccxt/ccxt/issues/10181
|
||||
|
||||
async function main () {
|
||||
|
||||
const exchange = new ccxt.binance ({
|
||||
'apiKey': 'YOUR_API_KEY',
|
||||
'secret': 'YOUR_SECRET',
|
||||
})
|
||||
|
||||
const markets = await exchange.loadMarkets ()
|
||||
|
||||
// exchange.verbose = true // uncomment for debugging purposes
|
||||
|
||||
const fromEmail = 'sender@example.com' // edit for your values
|
||||
, toEmail = 'receiver@example.com' // edit for your values
|
||||
, code = 'USDT' // edit for your values
|
||||
, amount = 100 // edit for your values
|
||||
, futuresType = 1 // 1 for USDT-margined futures,2 for coin-margined futures
|
||||
|
||||
const currency = exchange.currency (code);
|
||||
|
||||
const response = await exchange.sapiPostSubAccountFuturesInternalTransfer ({
|
||||
'fromEmail': fromEmail, // sender email
|
||||
'toEmail': toEmail, // recipient email
|
||||
'futuresType': futuresType, // 1 for USDT-margined futures,2 for coin-margined futures
|
||||
'asset': currency['id'],
|
||||
'amount': exchange.currencyToPrecision (code, amount),
|
||||
})
|
||||
|
||||
console.log (response)
|
||||
|
||||
}
|
||||
|
||||
main ()
|
||||
|
||||
|
||||
```
|
||||
@@ -0,0 +1,45 @@
|
||||
- [Binance Margin Stop Order](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
|
||||
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
|
||||
console.log ('CCXT Version:', ccxt.version)
|
||||
|
||||
async function main () {
|
||||
|
||||
const exchange = new ccxt.binance({
|
||||
'apiKey': 'YOUR_API_KEY',
|
||||
'secret': 'YOUR_API_SECRET',
|
||||
'options': {
|
||||
'defaultType': 'margin',
|
||||
},
|
||||
})
|
||||
|
||||
const markets = await exchange.loadMarkets ()
|
||||
|
||||
exchange.verbose = true // uncomment for debugging purposes if necessary
|
||||
|
||||
const symbol = 'BTC/USDT'
|
||||
const type = 'STOP_LOSS_LIMIT'
|
||||
const side = 'buy'
|
||||
const amount = YOUR_AMOUNT_HERE
|
||||
const price = YOUR_PRICE_HERE
|
||||
const params = {
|
||||
'stopPrice': YOUR_STOP_PRICE_HERE,
|
||||
'timeInForce': 'GTC',
|
||||
}
|
||||
|
||||
try {
|
||||
const order = await exchange.createOrder (symbol, type, side, amount, price, params)
|
||||
console.log (order)
|
||||
} catch (e) {
|
||||
console.log (e.constructor.name, e.message)
|
||||
}
|
||||
}
|
||||
|
||||
main ()
|
||||
|
||||
```
|
||||
@@ -0,0 +1,40 @@
|
||||
- [Binance Server Time](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
import ololog from 'ololog'
|
||||
|
||||
const log = ololog.configure ({ locate: false })
|
||||
|
||||
const binance = new ccxt['binance'] ()
|
||||
const recvWindow = binance.options.recvWindow
|
||||
const aheadWindow = 1000
|
||||
|
||||
async function test () {
|
||||
const localStartTime = Date.now ()
|
||||
const { serverTime } = await binance.publicGetTime ()
|
||||
const localFinishTime = Date.now ()
|
||||
const estimatedLandingTime = (localFinishTime + localStartTime) / 2
|
||||
|
||||
const diff = serverTime - estimatedLandingTime
|
||||
|
||||
log (`request departure time: ${binance.iso8601 (localStartTime)}`)
|
||||
log (`response arrival time: ${binance.iso8601 (localFinishTime)}`)
|
||||
log (`server time: ${binance.iso8601 (serverTime)}`)
|
||||
log (`request landing time (est): ${binance.iso8601 (estimatedLandingTime)}, ${Math.abs (diff)} ms ${Math.sign (diff) > 0 ? 'behind' : 'ahead of'} server`)
|
||||
log ('\n')
|
||||
|
||||
if (diff < -aheadWindow) {
|
||||
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`)
|
||||
}
|
||||
|
||||
if (diff > recvWindow) {
|
||||
log.error.red (`your request will likely be rejected if local time is behind server time for more than ${recvWindow} ms\n`)
|
||||
}
|
||||
}
|
||||
|
||||
test ();
|
||||
|
||||
```
|
||||
@@ -0,0 +1,22 @@
|
||||
- [Binance Universal Transfer](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
|
||||
(async () => {
|
||||
|
||||
// apiKey must have universal transfer permissions
|
||||
const binance = new ccxt.binance ({
|
||||
"apiKey": "",
|
||||
"secret": "",
|
||||
})
|
||||
|
||||
console.log (await binance.transfer ('USDT', 1, 'spot', 'future'))
|
||||
const transfers = await binance.fetchTransfers ();
|
||||
console.log ('got ', transfers.length, ' transfers')
|
||||
console.log (await binance.transfer ('USDT', 1, 'spot', 'cross')) // For transfer to cross margin wallet
|
||||
console.log (await binance.transfer ('USDT', 1, 'spot', 'ADA/USDT')) // For transfer to an isolated margin wallet
|
||||
}) ()
|
||||
|
||||
```
|
||||
@@ -0,0 +1,40 @@
|
||||
- [Bitfinex Fetch Trades](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
import log from 'ololog';
|
||||
import asTable from 'as-table';
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
const // ----------------------------------------------------------------------------
|
||||
table = asTable.configure ({ delimiter: ' | ' });(async () => {
|
||||
|
||||
const exchange = new ccxt.bitfinex ({
|
||||
'verbose': process.argv.includes ('--verbose'),
|
||||
'timeout': 60000,
|
||||
})
|
||||
|
||||
try {
|
||||
|
||||
const response = await exchange.fetchTrades ('ETH/BTC', 1518983548636 - 2 * 24 * 60 * 60 * 1000)
|
||||
log (table (response))
|
||||
log (response.length.toString (), 'trades')
|
||||
log.green ('Succeeded.')
|
||||
|
||||
} catch (e) {
|
||||
|
||||
log.dim ('--------------------------------------------------------')
|
||||
log (e.constructor.name, e.message)
|
||||
log.dim ('--------------------------------------------------------')
|
||||
log.dim (exchange.last_http_response)
|
||||
log.error ('Failed.')
|
||||
}
|
||||
|
||||
}) ()
|
||||
```
|
||||
@@ -0,0 +1,40 @@
|
||||
- [Bitfinex2 Fetch Trades](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
import asTable from 'as-table';
|
||||
import log from 'ololog';
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
const // ----------------------------------------------------------------------------
|
||||
table = asTable.configure ({ delimiter: ' | ' });(async () => {
|
||||
|
||||
const exchange = new ccxt.bitfinex2 ({
|
||||
'verbose': process.argv.includes ('--verbose'),
|
||||
'timeout': 60000,
|
||||
})
|
||||
|
||||
try {
|
||||
|
||||
const response = await exchange.fetchTrades ('ETH/BTC', 1518983548636 - 2 * 24 * 60 * 60 * 1000)
|
||||
log (table (response))
|
||||
log (response.length.toString (), 'trades')
|
||||
log.green ('Succeeded.')
|
||||
|
||||
} catch (e) {
|
||||
|
||||
log.dim ('--------------------------------------------------------')
|
||||
log (e.constructor.name, e.message)
|
||||
log.dim ('--------------------------------------------------------')
|
||||
log.dim (exchange.last_http_response)
|
||||
log.error ('Failed.')
|
||||
}
|
||||
|
||||
}) ()
|
||||
```
|
||||
@@ -0,0 +1,13 @@
|
||||
- [Bitmex Browser Cors Proxy](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
// JavaScript CORS Proxy
|
||||
// Save this in a file like cors.js and run with `node cors [port]`
|
||||
// It will listen for your requests on the port you pass in command line or port 8080 by default
|
||||
let port = (process.argv.length > 2) ? parseInt (process.argv[2]) : 8080 // default
|
||||
require ('cors-anywhere').createServer ({
|
||||
setHeaders: { 'origin': 'https://www.bitmex.com' }
|
||||
}).listen (port, '0.0.0.0')
|
||||
|
||||
```
|
||||
@@ -0,0 +1,41 @@
|
||||
- [Bitpanda Fetchmytrades Reduce](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
|
||||
const bitpanda = new ccxt.bitpanda ({
|
||||
"apiKey": "INSERTYOURAPIKEY"
|
||||
})
|
||||
|
||||
|
||||
// output
|
||||
`
|
||||
fetching USDT/EUR trades on bitpanda
|
||||
---------------------------------------------
|
||||
maker volume 6621.81 USDT maker fee 5.62 USDT
|
||||
taker volume 2544.82 USDT taker fee 3.27 USDT
|
||||
|
||||
sold 9166.63 USDT for 7802.38 EUR
|
||||
bought 0.00 USDT for 0.00 EUR
|
||||
`
|
||||
|
||||
;(async () => {
|
||||
const market = {
|
||||
symbol: 'USDT/EUR',
|
||||
base: 'USDT',
|
||||
quote: 'EUR',
|
||||
}
|
||||
console.log ('fetching', market.symbol, 'trades on bitpanda')
|
||||
console.log ('---------------------------------------------')
|
||||
const trades = await bitpanda.fetchMyTrades ('USDT/EUR')
|
||||
const makers = trades.filter (x => x.takerOrMaker === 'maker')
|
||||
const takers = trades.filter (x => x.takerOrMaker === 'taker')
|
||||
console.log ('maker volume', makers.reduce ((a, b) => a + b.amount, 0).toFixed (2), market.base, 'maker fee', makers.reduce ((a, b) => a + b.fee['cost'], 0).toFixed (2), market.base)
|
||||
console.log ('taker volume', takers.reduce ((a, b) => a + b.amount, 0).toFixed (2), market.base, 'taker fee', takers.reduce ((a, b) => a + b.fee['cost'], 0).toFixed (2), market.base)
|
||||
const sells = trades.filter (x => x.side === 'sell')
|
||||
const buys = trades.filter (x => x.side === 'buy')
|
||||
console.log ('\nsold', sells.reduce ((a, b) => a + b.amount, 0).toFixed (2), market.base, 'for', sells.reduce ((a, b) => a + b.cost, 0).toFixed (2), market.quote)
|
||||
console.log ('bought', buys.reduce ((a, b) => a + b.amount, 0).toFixed (2), market.base, 'for', buys.reduce ((a, b) => a + b.cost, 0).toFixed (2), market.quote)
|
||||
}) ()
|
||||
```
|
||||
@@ -0,0 +1,34 @@
|
||||
- [Bitrue Fetch Balance](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
|
||||
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
|
||||
async function main () {
|
||||
|
||||
console.log ('CCXT Version:', ccxt.version)
|
||||
|
||||
const exchange = new ccxt.bitrue ({
|
||||
"apiKey": "YOUR_API_KEY",
|
||||
"secret": "YOUR_SECRET",
|
||||
})
|
||||
|
||||
await exchange.loadMarkets ()
|
||||
|
||||
exchange.verbose = true
|
||||
|
||||
try {
|
||||
|
||||
const balance = await exchange.fetchBalance ()
|
||||
console.log (balance)
|
||||
|
||||
} catch (e) {
|
||||
console.log (e.constructor.name, e.message);
|
||||
}
|
||||
}
|
||||
|
||||
main ()
|
||||
|
||||
```
|
||||
@@ -0,0 +1,120 @@
|
||||
- [Bitstamp Private Api](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
|
||||
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
import asTable from 'as-table';
|
||||
import ololog from 'ololog'
|
||||
import ansicolor from 'ansicolor';
|
||||
|
||||
const log = ololog.configure({ locate: false })
|
||||
|
||||
ansicolor.nice
|
||||
|
||||
;(async () => {
|
||||
let apiUrl = 'https://www.bitstamp.net/api';
|
||||
|
||||
// instantiate the exchange
|
||||
let exchange = new ccxt.bitstamp({
|
||||
'apiKey': 'APIKEY',
|
||||
'secret': 'APISECRET',
|
||||
'uid': 'ACCOUNTID',
|
||||
'urls': {
|
||||
'api': {
|
||||
'public': apiUrl,
|
||||
'private': apiUrl,
|
||||
'v1': apiUrl
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
try {
|
||||
// fetch account balance from the exchange
|
||||
let balance = await exchange.fetchBalance()
|
||||
log('balance'.green, balance.total)
|
||||
|
||||
// fetch fees
|
||||
let singleFee = await exchange.fetchTradingFee('BTC/USD')
|
||||
log('fee'.green, 'BTC/USD', singleFee)
|
||||
let tradingFees = await exchange.fetchTradingFees()
|
||||
log('tradingFees'.green, tradingFees)
|
||||
let fundingFees = await exchange.fetchFundingFees()
|
||||
log('fundingFees'.green, fundingFees)
|
||||
let fees = await exchange.fetchFees()
|
||||
log('fees'.green, fees)
|
||||
|
||||
// my trades
|
||||
let myTrades = await exchange.fetchMyTrades('BTC/USD', undefined, 5)
|
||||
log('myTrades'.green, asTable(myTrades))
|
||||
|
||||
// user transactions
|
||||
let transactions = await exchange.fetchTransactions()
|
||||
log('Transactions'.green, asTable(transactions))
|
||||
|
||||
// ledger
|
||||
let ledger = await exchange.fetchLedger()
|
||||
log('Ledger'.green, asTable(ledger))
|
||||
|
||||
// deposits
|
||||
let deposits = await exchange.fetchDeposits()
|
||||
log('Deposits'.green, asTable(deposits))
|
||||
|
||||
// create new limit order
|
||||
let newOrder = await exchange.createOrder('BTC/USD', 'limit', 'buy', 0.01, 8000)
|
||||
console.log('New limit order'.green, newOrder);
|
||||
|
||||
// open orders
|
||||
let openOrders = await exchange.fetchOpenOrders()
|
||||
log('Open orders'.green, asTable(openOrders))
|
||||
|
||||
// order data
|
||||
let orderData = await exchange.fetchOrder(newOrder.id)
|
||||
console.log('Order data'.green, orderData);
|
||||
|
||||
// cancel order
|
||||
let canceledOrder = await exchange.cancelOrder(newOrder.id)
|
||||
console.log('Canceled order'.green, canceledOrder);
|
||||
|
||||
// create market order
|
||||
let marketOrder = await exchange.createOrder('BTC/USD', 'market', 'buy', 0.01)
|
||||
console.log('New market order'.green, marketOrder);
|
||||
|
||||
// open orders
|
||||
let secondOpenOrders = await exchange.fetchOpenOrders()
|
||||
log('Open orders'.green, asTable(secondOpenOrders))
|
||||
|
||||
// deposit address
|
||||
let paxDeposit = await exchange.fetchDepositAddress("XLM")
|
||||
log('Pax deposit address'.green, paxDeposit)
|
||||
|
||||
// withdrawal
|
||||
let ethWithdraw = await exchange.withdraw("ETH", 0.01, "0x6c28cb9dd2f4e3bb6f56c822bc306f3b8a3e7c08")
|
||||
log('ETH withdrawal'.green, ethWithdraw)
|
||||
|
||||
// withdrawals
|
||||
let withdrawals = await exchange.fetchWithdrawals()
|
||||
log('Withdrawals'.green, asTable(withdrawals))
|
||||
|
||||
} catch (e) {
|
||||
|
||||
if (e instanceof ccxt.DDoSProtection || e.message.includes('ECONNRESET')) {
|
||||
log.bright.yellow('[DDoS Protection] ' + e.message)
|
||||
} else if (e instanceof ccxt.RequestTimeout) {
|
||||
log.bright.yellow('[Request Timeout] ' + e.message)
|
||||
} else if (e instanceof ccxt.AuthenticationError) {
|
||||
log.bright.yellow('[Authentication Error] ' + e.message)
|
||||
} else if (e instanceof ccxt.ExchangeNotAvailable) {
|
||||
log.bright.yellow('[Exchange Not Available Error] ' + e.message)
|
||||
} else if (e instanceof ccxt.ExchangeError) {
|
||||
log.bright.yellow('[Exchange Error] ' + e.message)
|
||||
} else if (e instanceof ccxt.NetworkError) {
|
||||
log.bright.yellow('[Network Error] ' + e.message)
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
})()
|
||||
```
|
||||
@@ -0,0 +1,44 @@
|
||||
- [Bitstamp Public Api](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
import log from 'ololog';
|
||||
import asTable from 'as-table';
|
||||
|
||||
|
||||
const table = asTable.configure ({ delimiter: ' | ' }), id = 'bitstamp', exchange = new ccxt[id] ({ enableRateLimit: true }), symbol = 'BTC/USD';(async function main () {
|
||||
|
||||
// Markets data
|
||||
const markets = await exchange.fetchMarkets ()
|
||||
console.log('Total number of markets: ', Object.keys(markets).length);
|
||||
|
||||
// Currencies
|
||||
const currencies = await exchange.fetchCurrencies ()
|
||||
console.log('Currencies: ', JSON.stringify(currencies));
|
||||
|
||||
// Order book data
|
||||
const orderbook = await exchange.fetchOrderBook (symbol)
|
||||
console.log ('Order book ', symbol, orderbook.asks[0], orderbook.bids[0])
|
||||
|
||||
// Ticker
|
||||
const ticker = await exchange.fetchTicker (symbol)
|
||||
console.log ('Ticker ', symbol, " bid ", ticker.bid, " ask ", ticker.ask)
|
||||
|
||||
// Trades
|
||||
const response = await exchange.fetchTrades (symbol, null, 10)
|
||||
log (table (response))
|
||||
|
||||
// OHLC data
|
||||
const candles = await exchange.fetchOHLCV (symbol, '1m', undefined, 10);
|
||||
const first = candles[0]
|
||||
const last = candles[candles.length - 1]
|
||||
console.log (
|
||||
'Fetched', candles.length, symbol, 'candles',
|
||||
'from', exchange.iso8601 (first[0]),
|
||||
'to', exchange.iso8601 (last[0])
|
||||
)
|
||||
|
||||
}) ()
|
||||
```
|
||||
@@ -0,0 +1,55 @@
|
||||
- [Bittrex Balance](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
|
||||
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
import asTable from 'as-table';
|
||||
import ansicolor from 'ansicolor';
|
||||
import ololog from 'ololog'
|
||||
|
||||
const log = ololog.configure ({ locate: false })
|
||||
|
||||
ansicolor.nice
|
||||
|
||||
let sleep = (ms) => new Promise (resolve => setTimeout (resolve, ms))
|
||||
|
||||
;(async () => {
|
||||
|
||||
// instantiate the exchange
|
||||
let exchange = new ccxt.bittrex ({
|
||||
"apiKey": "471b47a06c384e81b24072e9a8739064",
|
||||
"secret": "694025686e9445589787e8ca212b4cff",
|
||||
})
|
||||
|
||||
|
||||
try {
|
||||
|
||||
// fetch account balance from the exchange
|
||||
let balance = await exchange.fetchBalance ()
|
||||
|
||||
// output the result
|
||||
log (exchange.name.green, 'balance', balance)
|
||||
|
||||
} catch (e) {
|
||||
|
||||
if (e instanceof ccxt.DDoSProtection || e.message.includes ('ECONNRESET')) {
|
||||
log.bright.yellow ('[DDoS Protection] ' + e.message)
|
||||
} else if (e instanceof ccxt.RequestTimeout) {
|
||||
log.bright.yellow ('[Request Timeout] ' + e.message)
|
||||
} else if (e instanceof ccxt.AuthenticationError) {
|
||||
log.bright.yellow ('[Authentication Error] ' + e.message)
|
||||
} else if (e instanceof ccxt.ExchangeNotAvailable) {
|
||||
log.bright.yellow ('[Exchange Not Available Error] ' + e.message)
|
||||
} else if (e instanceof ccxt.ExchangeError) {
|
||||
log.bright.yellow ('[Exchange Error] ' + e.message)
|
||||
} else if (e instanceof ccxt.NetworkError) {
|
||||
log.bright.yellow ('[Network Error] ' + e.message)
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
}) ()
|
||||
```
|
||||
@@ -0,0 +1,75 @@
|
||||
- [Bittrex Fetch Closed Orders History](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
import ololog from 'ololog';
|
||||
import asTable from 'as-table';
|
||||
|
||||
|
||||
const { noLocate } = ololog;
|
||||
const log = noLocate;
|
||||
|
||||
const exchange = new ccxt.bittrex ({
|
||||
'enableRateLimit': true,
|
||||
'apiKey': 'YOUR_API_KEY',
|
||||
'secret': 'YOUR_API_SECRET',
|
||||
});(async () => {
|
||||
|
||||
await exchange.loadMarkets ()
|
||||
|
||||
const symbol = 'ETH/BTC'
|
||||
, market = exchange.markets[symbol]
|
||||
, startingDate = '2017-01-01T00:00:00'
|
||||
, now = exchange.milliseconds ()
|
||||
|
||||
log.bright.green ('\nFetching history for:', symbol, '\n')
|
||||
|
||||
let allOrders = []
|
||||
let since = exchange.parse8601 (startingDate)
|
||||
|
||||
while (since < now) {
|
||||
|
||||
try {
|
||||
|
||||
log.bright.blue ('Fetching history for', symbol, 'since', exchange.iso8601 (since))
|
||||
const orders = await exchange.fetchClosedOrders (symbol, since)
|
||||
log.green.dim ('Fetched', orders.length, 'orders')
|
||||
|
||||
allOrders = allOrders.concat (orders)
|
||||
|
||||
if (orders.length) {
|
||||
|
||||
const lastOrder = orders[orders.length - 1]
|
||||
since = lastOrder['timestamp'] + 1
|
||||
|
||||
} else {
|
||||
|
||||
break // no more orders left for this symbol, move to next one
|
||||
}
|
||||
|
||||
} catch (e) {
|
||||
|
||||
log.red.unlimited (e)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// omit the following keys for a compact table output
|
||||
// otherwise it won't fit into the screen width
|
||||
const omittedKeys = [
|
||||
'info',
|
||||
'timestamp',
|
||||
'lastTradeTimestamp',
|
||||
'fee',
|
||||
]
|
||||
|
||||
log.yellow (asTable (allOrders.map (order => exchange.omit (order, omittedKeys))))
|
||||
log.green ('Fetched', allOrders.length, symbol, 'orders in total')
|
||||
|
||||
// do whatever you want to do with them, calculate profit loss, etc...
|
||||
|
||||
}) ()
|
||||
|
||||
|
||||
```
|
||||
@@ -0,0 +1,65 @@
|
||||
- [Blockchaincom Withdrawal](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
"use strict";
|
||||
|
||||
const ccxt = require('../../ccxt.js')
|
||||
const asTable = require('as-table')
|
||||
const log = require('ololog').configure({ locate: false })
|
||||
|
||||
|
||||
const exchange = new ccxt.blockchaincom({
|
||||
'secret': 'YOUR_API_SECRET',
|
||||
})
|
||||
|
||||
// blockchaincom specific internal beneficiary id
|
||||
const address = 'BENEFICIARY_ID';
|
||||
|
||||
|
||||
(async () => {
|
||||
|
||||
const markets = await exchange.loadMarkets ()
|
||||
|
||||
try {
|
||||
const code = 'USDT'
|
||||
const amount = 5
|
||||
|
||||
// fetch withdrawal beneficiary ids
|
||||
const whiteList = await exchange.privateGetWhitelistCurrency({'currency': code})
|
||||
log('Withdrawl Whitelist', whiteList)
|
||||
//
|
||||
// [
|
||||
// {
|
||||
// "whitelistId":"adcd73fb-9ba6-41o7-8c0d-7013482cb88f", // unique id for each beneficiary, to be passed in as address into withdraw ()
|
||||
// "name":"John Doe",
|
||||
// "currency":"USDT"
|
||||
// }
|
||||
// ]
|
||||
//
|
||||
|
||||
// withdrawal
|
||||
let withdrawal = await exchange.withdraw(code, amount, address, undefined);
|
||||
log('Withdrawal', withdrawal)
|
||||
|
||||
} catch (e) {
|
||||
if (e instanceof ccxt.DDoSProtection || e.message.includes('ECONNRESET')) {
|
||||
log('[DDoS Protection] ' + e.message)
|
||||
} else if (e instanceof ccxt.RequestTimeout) {
|
||||
log('[Request Timeout] ' + e.message)
|
||||
} else if (e instanceof ccxt.AuthenticationError) {
|
||||
log('[Authentication Error] ' + e.message)
|
||||
} else if (e instanceof ccxt.ExchangeNotAvailable) {
|
||||
log('[Exchange Not Available Error] ' + e.message)
|
||||
} else if (e instanceof ccxt.ExchangeError) {
|
||||
log('[Exchange Error] ' + e.message)
|
||||
} else if (e instanceof ccxt.NetworkError) {
|
||||
log('[Network Error] ' + e.message)
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
})()
|
||||
|
||||
```
|
||||
@@ -0,0 +1,54 @@
|
||||
- [Build Ohlcv Bars](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
// AUTO-TRANSPILE //
|
||||
// Bulding OHLCV array from trades (executions) data is a bit tricky. For example, if you want to build 100 ohlcv bars of 1-minute timeframe, then you have to fetch the 100 minutes of trading data. So, higher timeframe bars require more trading data (i.e. building 100 bars of 1-day timeframe OHLCV would require massive amount of trading data, which might not be desirable for user, because of data-usage rate limits)
|
||||
async function example_with_fetch_trades() {
|
||||
const exch = new ccxt.binance({});
|
||||
const timeframe = '1m';
|
||||
const symbol = 'OGN/USDT';
|
||||
const since = exch.milliseconds() - 1000 * 60 * 30; // last 30 mins
|
||||
const limit = 1000;
|
||||
const trades = await exch.fetchTrades(symbol, since, limit);
|
||||
const generatedBars = exch.buildOHLCVC(trades, timeframe, since, limit);
|
||||
// you can ignore 6th index ("count" field) from ohlcv entries, which is not part of OHLCV standard structure and is just added internally by `buildOHLCVC` method
|
||||
console.log('[REST] Constructed', generatedBars.length, 'bars from trades: ', generatedBars);
|
||||
}
|
||||
async function example_with_watch_trades() {
|
||||
const exch = new ccxt.pro.binance({});
|
||||
const timeframe = '1m';
|
||||
const symbol = 'DOGE/USDT';
|
||||
const limit = 1000;
|
||||
const since = exch.milliseconds() - 10 * 60 * 1000 * 1000; // last 10 hrs
|
||||
let collectedTrades = [];
|
||||
const collectedBars = [];
|
||||
while (true) {
|
||||
const wsTrades = await exch.watchTrades(symbol, since, limit, {});
|
||||
collectedTrades = collectedTrades.concat(wsTrades);
|
||||
const generatedBars = exch.buildOHLCVC(collectedTrades, timeframe, since, limit);
|
||||
// Note: first bar would be partially constructed bar and its 'open' & 'high' & 'low' prices (except 'close' price) would probably have different values compared to real bar on chart, because the first obtained trade timestamp might be somewhere in the middle of timeframe period, so the pre-period would be missing because we would not have trades data. To fix that, you can get older data with `fetchTrades` to fill up bars till start bar.
|
||||
for (let i = 0; i < generatedBars.length; i++) {
|
||||
const bar = generatedBars[i];
|
||||
const barTimestamp = bar[0];
|
||||
const collectedBarsLength = collectedBars.length;
|
||||
const lastCollectedBarTimestamp = collectedBarsLength > 0 ? collectedBars[collectedBarsLength - 1][0] : 0;
|
||||
if (barTimestamp === lastCollectedBarTimestamp) {
|
||||
// if timestamps are same, just updarte the last bar
|
||||
collectedBars[collectedBarsLength - 1] = bar;
|
||||
}
|
||||
else if (barTimestamp > lastCollectedBarTimestamp) {
|
||||
collectedBars.push(bar);
|
||||
// remove the trades from saved array, which were till last collected bar's open timestamp
|
||||
collectedTrades = exch.filterBySinceLimit(collectedTrades, barTimestamp);
|
||||
}
|
||||
}
|
||||
// Note: first bar would carry incomplete values, please read comment in "buildOHLCVCFromWatchTrades" method definition for further explanation
|
||||
console.log('[WS] Constructed', collectedBars.length, 'bars from', symbol, 'trades: ', collectedBars);
|
||||
}
|
||||
}
|
||||
await example_with_fetch_trades();
|
||||
await example_with_watch_trades();
|
||||
|
||||
```
|
||||
@@ -0,0 +1,30 @@
|
||||
- [Builtin Rate Limiting Rest Poller](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
|
||||
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
import log from 'ololog';
|
||||
import { nice as ansi } from 'ansicolor';
|
||||
import asTable from 'as-table';
|
||||
|
||||
const exchange = new ccxt.coinbasepro ()
|
||||
const repeat = 100
|
||||
|
||||
async function test (symbol) {
|
||||
|
||||
for (let i = 0; i < repeat; i++) {
|
||||
let ticker = await exchange.fetchTicker (symbol)
|
||||
log (exchange.id.green, exchange.iso8601 (exchange.milliseconds ()), ticker['datetime'], symbol.green, ticker['last'])
|
||||
}
|
||||
}
|
||||
|
||||
const concurrent = [
|
||||
test ('BTC/USD'),
|
||||
test ('ETH/BTC'),
|
||||
test ('ETH/USD')
|
||||
]
|
||||
|
||||
Promise.all (concurrent)
|
||||
```
|
||||
@@ -0,0 +1,67 @@
|
||||
- [Bybit Trailing](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
'use strict';
|
||||
|
||||
const ccxt = require ('../../ccxt');
|
||||
|
||||
console.log ('CCXT Version:', ccxt.version)
|
||||
|
||||
const exchange = new ccxt.bybit({
|
||||
'apiKey': 'YOUR_API_KEY',
|
||||
'secret': 'YOUR_API_KEY',
|
||||
})
|
||||
|
||||
// exchange.set_sandbox_mode(true) // enable sandbox mode
|
||||
|
||||
// Example 1 :: Swap : open position and set trailing stop and close it
|
||||
async function example1 () {
|
||||
exchange['options']['defaultType'] = 'swap'; // very important set swap as default type
|
||||
await exchange.loadMarkets ();
|
||||
|
||||
const symbol = 'LTC/USDT:USDT';
|
||||
const market = exchange.market(symbol);
|
||||
|
||||
// fetch swap balance
|
||||
const balance = await exchange.fetchBalance ();
|
||||
console.log (balance)
|
||||
|
||||
// create order and open position
|
||||
const type = 'market';
|
||||
const side = 'buy';
|
||||
const amount = 0.1
|
||||
const price = undefined;
|
||||
const createOrder = await exchange.createOrder (symbol, type, side, amount, price);
|
||||
console.log ('Created order id:', createOrder['id'])
|
||||
|
||||
// set trailing stop
|
||||
const rawSide = 'Buy'; // or 'Sell'
|
||||
const trailing_stop = 30; // YOUR TRAILING STOP HERE
|
||||
const trailingParams = {
|
||||
'symbol': market['id'],
|
||||
'side': rawSide,
|
||||
'trailing_stop': trailing_stop
|
||||
}
|
||||
const trailing_response = await exchange.privatePostPrivateLinearPositionTradingStop (trailingParams);
|
||||
console.log(trailing_response)
|
||||
|
||||
// check opened position
|
||||
const symbols = [ symbol ];
|
||||
const positions = await exchange.fetchPositions (symbols);
|
||||
console.log (positions)
|
||||
|
||||
// Close position by issuing a order in the opposite direction
|
||||
const params = {
|
||||
'reduce_only': true
|
||||
}
|
||||
const closePositionOrder = await exchange.createOrder (symbol, type, side, amount, price, params);
|
||||
console.log (closePositionOrder);
|
||||
}
|
||||
|
||||
async function main () {
|
||||
await example1 ();
|
||||
}
|
||||
|
||||
main ();
|
||||
```
|
||||
@@ -0,0 +1,159 @@
|
||||
- [Bybit Updated](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
'use strict';
|
||||
|
||||
const ccxt = require ('../../dist/cjs/ccxt.js');
|
||||
|
||||
console.log ('CCXT Version:', ccxt.version)
|
||||
|
||||
const exchange = new ccxt.bybit ({
|
||||
'apiKey': 'YOUR_API_KEY',
|
||||
'secret': 'YOUR_SECRET_KEY',
|
||||
})
|
||||
|
||||
// Example 1: Spot : fetch balance, create order, cancel it and check canceled orders
|
||||
async function example1 () {
|
||||
exchange['options']['defaultType'] = 'spot'; // very important set spot as default type
|
||||
|
||||
await exchange.loadMarkets ();
|
||||
|
||||
// fetch spot balance
|
||||
const balance = await exchange.fetchBalance ();
|
||||
console.log (balance)
|
||||
|
||||
// create order
|
||||
const symbol = 'LTC/USDT';
|
||||
const createOrder = await exchange.createOrder (symbol, 'limit', 'buy', 50, 0.1);
|
||||
console.log ('Created order id:', createOrder['id'])
|
||||
|
||||
// cancel order
|
||||
const cancelOrder = await exchange.cancelOrder (createOrder['id'], symbol);
|
||||
|
||||
// Check canceled orders (bybit does not have a single endpoint to check orders
|
||||
// we have to choose whether to check open or closed orders and call fetchOpenOrders
|
||||
// or fetchClosedOrders respectively
|
||||
const canceledOrders = await exchange.fetchClosedOrders (symbol);
|
||||
console.log (canceledOrders);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------
|
||||
|
||||
// Example 2 :: Swap : fetch balance, open a position and close it
|
||||
async function example2 () {
|
||||
exchange['options']['defaultType'] = 'swap'; // very important set swap as default type
|
||||
await exchange.loadMarkets ();
|
||||
|
||||
// fetch swap balance
|
||||
const balance = await exchange.fetchBalance ();
|
||||
console.log (balance)
|
||||
|
||||
// create order and open position
|
||||
const symbol = 'LTC/USDT:USDT';
|
||||
const createOrder = await exchange.createOrder (symbol, 'market', 'buy', 0.1);
|
||||
console.log ('Created order id:', createOrder['id'])
|
||||
|
||||
// check opened position
|
||||
const symbols = [ symbol ];
|
||||
const positions = await exchange.fetchPositions (symbols);
|
||||
console.log (positions)
|
||||
|
||||
// Close position by issuing a order in the opposite direction
|
||||
const params = {
|
||||
'reduce_only': true
|
||||
}
|
||||
const closePositionOrder = await exchange.createOrder (symbol, 'market', 'sell', 0.1, undefined, params);
|
||||
console.log (closePositionOrder);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------
|
||||
|
||||
// Example 3 :: USDC Swap : fetch balance, open a position and close it
|
||||
async function example3 () {
|
||||
exchange['options']['defaultType'] = 'swap'; // very important set swap as default type
|
||||
await exchange.loadMarkets ();
|
||||
|
||||
// fetch USDC swap balance
|
||||
// when no symbol is available we can show our intent
|
||||
// of using USDC endpoints by either using defaultSettle in options or
|
||||
// settle in params
|
||||
// Using Options: exchange['options']['defaultSettle'] = 'USDC';
|
||||
// Using params:
|
||||
const balanceParams = {
|
||||
'settle': 'USDC'
|
||||
}
|
||||
const balance = await exchange.fetchBalance (balanceParams);
|
||||
console.log (balance)
|
||||
|
||||
// create order and open position
|
||||
// taking into consideration that USDC markets do not support
|
||||
// market orders
|
||||
const symbol = 'BTC/USD:USDC';
|
||||
const amount = 0.1;
|
||||
const price = 29940 // adjust this accordingly
|
||||
const createOrder = await exchange.createOrder (symbol, 'limit', 'buy', amount, price);
|
||||
console.log ('Created order id:', createOrder['id'])
|
||||
|
||||
// check if the order was filled and the position opened
|
||||
const symbols = [ symbol ];
|
||||
const positions = await exchange.fetchPositions (symbols);
|
||||
console.log (positions)
|
||||
|
||||
// close position (assuming it was already opened) by issuing an order in the opposite direction
|
||||
const params = {
|
||||
'reduce_only': true
|
||||
}
|
||||
const closePositionOrder = await exchange.createOrder (symbol, 'limit', 'sell', amount, price, params);
|
||||
console.log (closePositionOrder);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------
|
||||
|
||||
// Example 4 :: Future : fetch balance, create stop-order and check open stop-orders
|
||||
async function example4 () {
|
||||
exchange['options']['defaultType'] = 'future'; // very important set future as default type
|
||||
await exchange.loadMarkets ();
|
||||
|
||||
// fetch future balance
|
||||
const balance = await exchange.fetchBalance ();
|
||||
console.log (balance)
|
||||
|
||||
// create stop-order
|
||||
const symbol = 'ETH/USD:ETH-220930';
|
||||
const amount = 10; // in USD for inverse futures
|
||||
const price = 1200;
|
||||
const side = 'buy';
|
||||
const type = 'limit';
|
||||
const stopOrderParams = {
|
||||
'position_idx': 0, // 0 One-Way Mode, 1 Buy-side, 2 Sell-side, default = 0
|
||||
'stopPrice': 1000, // mandatory for stop orders
|
||||
'basePrice': 1100 // mandatory for stop orders
|
||||
}
|
||||
const stopOrder = await exchange.createOrder (symbol, type, side, amount, price, stopOrderParams);
|
||||
console.log ('Created order id:', stopOrder['id'])
|
||||
|
||||
// check opened stop-order
|
||||
const openOrderParams = {
|
||||
'stop': true
|
||||
}
|
||||
const openOrders = await exchange.fetchOpenOrders (symbol, undefined, undefined, openOrderParams);
|
||||
console.log (openOrders)
|
||||
|
||||
// Cancell open stop-order
|
||||
const cancelOrder = await exchange.cancelOrder (stopOrder['id'], symbol, openOrderParams);
|
||||
console.log (cancelOrder);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------
|
||||
|
||||
async function main () {
|
||||
await example1 ();
|
||||
await example2 ();
|
||||
await example3 ();
|
||||
await example4 ();
|
||||
|
||||
}
|
||||
|
||||
main ();
|
||||
```
|
||||
@@ -0,0 +1,44 @@
|
||||
- [Coinbase Fetch All Balances](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
"use strict";
|
||||
|
||||
const ccxt = require ('../../js/ccxt.js')
|
||||
|
||||
console.log ('CCXT Version:', ccxt.version)
|
||||
|
||||
async function fetchAllBalances (exchange) {
|
||||
const params = {}
|
||||
let balance = {}
|
||||
while (true) {
|
||||
const response = await exchange.fetchBalance (params)
|
||||
balance = exchange.extend (balance, response)
|
||||
const info = exchange.safeValue (response, 'info', {})
|
||||
const pagination = exchange.safeValue (info, 'pagination', {})
|
||||
const startingAfter = exchange.safeString (pagination, 'next_starting_after')
|
||||
if (startingAfter !== undefined) {
|
||||
params['starting_after'] = startingAfter
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
return balance
|
||||
}
|
||||
|
||||
async function main () {
|
||||
const exchange = new ccxt.coinbase ({
|
||||
// Value is the "name" field in the api_key.json file Coinbase will offer for download
|
||||
apiKey: 'organizations/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/apiKeys/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx',
|
||||
// This is the "privateKey" field in that JSON file
|
||||
secret: '-----BEGIN EC PRIVATE KEY-----\nxxx...xxx==\n-----END EC PRIVATE KEY-----',
|
||||
})
|
||||
const markets = await exchange.loadMarkets ()
|
||||
// coinbase.verbose = true // uncomment for debugging purposes if necessary
|
||||
const balance = await fetchAllBalances (exchange)
|
||||
console.log (balance)
|
||||
}
|
||||
|
||||
main ()
|
||||
|
||||
```
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
- [Coinex Fetch All Deposit Addresses Using Fetchdepositaddress](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
"use strict";
|
||||
|
||||
const ccxt = require ('../../ccxt')
|
||||
|
||||
console.log ('CCXT Version:', ccxt.version)
|
||||
|
||||
// https://github.com/ccxt/ccxt/issues/15405
|
||||
|
||||
async function main () {
|
||||
|
||||
const exchange = new ccxt.coinex ({
|
||||
'apiKey': 'YOUR_API_KEY',
|
||||
'secret': 'YOUR_API_SECRET',
|
||||
});
|
||||
|
||||
// exchange.verbose = true // uncomment for debugging purposes
|
||||
|
||||
await exchange.loadMarkets ();
|
||||
const addresses = {};
|
||||
const promises = [];
|
||||
|
||||
async function fetchDepositAddress (currency, network) {
|
||||
try {
|
||||
const response = await exchange.fetchDepositAddress(currency, { 'network': network });
|
||||
addresses[currency][network] = response['address']
|
||||
}
|
||||
catch (err) {
|
||||
console.error(err)
|
||||
}
|
||||
}
|
||||
|
||||
const currencies = Object.keys (exchange.currencies);
|
||||
|
||||
for (const currency of currencies) {
|
||||
const networks = Object.keys (exchange.currencies[currency]['networks']);
|
||||
for (const network of networks) {
|
||||
addresses[currency] = {};
|
||||
promises.push (fetchDepositAddress (currency, network));
|
||||
}
|
||||
}
|
||||
|
||||
await Promise.all (promises);
|
||||
|
||||
console.log (addresses)
|
||||
};
|
||||
|
||||
main ();
|
||||
|
||||
```
|
||||
@@ -0,0 +1,80 @@
|
||||
- [Coinex Futures](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
'use strict';
|
||||
|
||||
const ccxt = require ('../../ccxt');
|
||||
|
||||
console.log ('CCXT Version:', ccxt.version)
|
||||
|
||||
let exchange = new ccxt.coinex({
|
||||
'apiKey': 'YOUR_API_KEY',
|
||||
'secret': 'YOUR_SECRET_KEY',
|
||||
})
|
||||
|
||||
// Example 1 :: Swap : fetch balance, create a limit swap order with leverage
|
||||
async function example1 () {
|
||||
exchange['options']['defaultType'] = 'swap';
|
||||
exchange.options['defaultMarginMode'] = 'cross' // or isolated
|
||||
await exchange.loadMarkets ();
|
||||
|
||||
const symbol = 'ADA/USDT:USDT';
|
||||
|
||||
// fetchBalance
|
||||
const balance = await exchange.fetchBalance ();
|
||||
console.log (balance)
|
||||
|
||||
// set the desired leverage (has to be made before placing the order and for a specific symbol)
|
||||
const leverage = 8;
|
||||
const leverage_response = await exchange.setLeverage(leverage, symbol)
|
||||
|
||||
// create limit order
|
||||
const amount = 50;
|
||||
const price = 0.3 // adjust this accordingly
|
||||
const createOrder = await exchange.createOrder (symbol, 'limit', 'buy', amount, price);
|
||||
console.log ('Created order id:', createOrder['id'])
|
||||
}
|
||||
|
||||
// Example 2 :: Swap :: open a position and close it
|
||||
async function example2 () {
|
||||
exchange['options']['defaultType'] = 'swap';
|
||||
exchange.options['defaultMarginMode'] = 'cross' // or isolated
|
||||
await exchange.loadMarkets ();
|
||||
|
||||
const symbol = 'ADA/USDT:USDT';
|
||||
|
||||
// fetchBalance
|
||||
const balance = await exchange.fetchBalance ();
|
||||
console.log (balance)
|
||||
|
||||
// set the desired leverage (has to be made before placing the order and for a specific symbol)
|
||||
const leverage = 8;
|
||||
const leverage_response = await exchange.setLeverage(leverage, symbol)
|
||||
|
||||
// create market order and open position
|
||||
const amount = 50;
|
||||
const createOrder = await exchange.createOrder (symbol, 'market', 'buy', amount);
|
||||
console.log ('Created order id:', createOrder['id'])
|
||||
|
||||
// check if the order was filled and the position opened
|
||||
const position = await exchange.fetchPositions (symbol);
|
||||
console.log (position)
|
||||
|
||||
// close position (assuming it was already opened) by issuing an order in the opposite direction
|
||||
const params = {
|
||||
'reduce_only': true
|
||||
}
|
||||
const closePositionOrder = await exchange.createOrder (symbol, 'market', 'sell', amount, undefined, params);
|
||||
console.log (closePositionOrder);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------
|
||||
|
||||
async function main () {
|
||||
await example1 ();
|
||||
await example2 ();
|
||||
}
|
||||
|
||||
main ();
|
||||
```
|
||||
@@ -0,0 +1,60 @@
|
||||
- [Coinone Fetch Tickers](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
|
||||
|
||||
import { nice as ansi } from 'ansicolor';
|
||||
import ololog from 'ololog';
|
||||
import asTable from 'as-table';
|
||||
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
|
||||
const { noLocate } = ololog;
|
||||
const log = noLocate;
|
||||
|
||||
const table = asTable.configure ({
|
||||
delimiter: ' | '.dim,
|
||||
right: true,
|
||||
});
|
||||
|
||||
const exchange = new ccxt.coinone ({
|
||||
'verbose': process.argv.includes ('--verbose'),
|
||||
})
|
||||
|
||||
let printTickersAsTable = function (exchange, tickers) {
|
||||
log (exchange.id.green, exchange.iso8601 (exchange.milliseconds ()))
|
||||
log ('Fetched', Object.values (tickers).length.toString ().green, 'tickers:')
|
||||
log (table (ccxt.sortBy (Object.values (tickers), 'symbol', false)))
|
||||
}
|
||||
|
||||
async function fetchAllAndPrint () {
|
||||
const tickers = await exchange.fetchTickers ()
|
||||
log ('---------------------------------------- fetchTickers ----------------------------------------')
|
||||
printTickersAsTable (exchange, tickers)
|
||||
}
|
||||
|
||||
async function fetchOneByOneAndPrint () {
|
||||
const markets = await exchange.loadMarkets ()
|
||||
const symbols = Object.keys (markets)
|
||||
const tickers = []
|
||||
|
||||
log ('---------------------------------------- fetchTicker (one by one) ----------------------------------------')
|
||||
|
||||
for (let i = 0; i < symbols.length; i++) {
|
||||
const ticker = await exchange.fetchTicker (symbols[i])
|
||||
tickers.push (ticker)
|
||||
log (`${i+1} / ${symbols.length}`)
|
||||
log ('\u001b[1A'.repeat (2)) // cursor up
|
||||
}
|
||||
|
||||
printTickersAsTable (exchange, tickers)
|
||||
}
|
||||
|
||||
(async () => {
|
||||
await fetchAllAndPrint ()
|
||||
log ('\n')
|
||||
await fetchOneByOneAndPrint ()
|
||||
}) ()
|
||||
|
||||
```
|
||||
@@ -0,0 +1,22 @@
|
||||
- [Coinone Markets](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
|
||||
|
||||
import log from 'ololog';
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
|
||||
const exchange = new ccxt.coinone ({
|
||||
'verbose': process.argv.includes ('--verbose'),
|
||||
})
|
||||
|
||||
;(async function main () {
|
||||
|
||||
const markets = await exchange.loadMarkets ()
|
||||
log (markets)
|
||||
log ('\n' + exchange['name'] + ' supports ' + Object.keys (markets).length + ' pairs')
|
||||
|
||||
}) ()
|
||||
|
||||
```
|
||||
@@ -0,0 +1,42 @@
|
||||
- [Compare Two Exchanges Capabilities](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
// AUTO-TRANSPILE //
|
||||
async function example() {
|
||||
const prefix = '-';
|
||||
const exchange_1 = new ccxt.okx();
|
||||
const exchange_2 = new ccxt.htx();
|
||||
const keys_1 = Object.keys(exchange_1.has);
|
||||
const keys_2 = Object.keys(exchange_2.has);
|
||||
// check missing from exchange-1
|
||||
console.log('### checking missing functionalities from exchange-1:', exchange_1.id);
|
||||
for (let i = 0; i < keys_2.length; i++) {
|
||||
const key = keys_2[i];
|
||||
if (exchange_2.has[key]) {
|
||||
if (!keys_1.includes(key)) {
|
||||
console.log(prefix, key, 'does not exist in', exchange_1.id, 'as opposed to', exchange_2.id);
|
||||
}
|
||||
else if (exchange_2.has[key] !== exchange_1.has[key]) {
|
||||
console.log(prefix, key, '> ', exchange_1.id, ':', exchange_1.has[key], ',', exchange_2.id, ':', exchange_2.has[key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
// check missing from exchange-2
|
||||
console.log('### checking missing functionalities from exchange-2:', exchange_2.id);
|
||||
for (let i = 0; i < keys_1.length; i++) {
|
||||
const key = keys_1[i];
|
||||
if (exchange_1.has[key]) {
|
||||
if (!keys_2.includes(key)) {
|
||||
console.log(prefix, key, 'does not exist in', exchange_2.id, 'as opposed to', exchange_1.id);
|
||||
}
|
||||
else if (exchange_1.has[key] !== exchange_2.has[key]) {
|
||||
console.log(prefix, key, '> ', exchange_2.id, ':', exchange_2.has[key], ',', exchange_1.id, ':', exchange_1.has[key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
await example();
|
||||
|
||||
```
|
||||
@@ -0,0 +1,11 @@
|
||||
- [Cors Proxy](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
// JavaScript CORS Proxy
|
||||
// Save this in a file like cors.js and run with `node cors [port]`
|
||||
// It will listen for your requests on the port you pass in command line or port 8080 by default
|
||||
let port = (process.argv.length > 2) ? parseInt (process.argv[2]) : 8080 // default
|
||||
require ('cors-anywhere').createServer ().listen (port, '0.0.0.0')
|
||||
|
||||
```
|
||||
@@ -0,0 +1,61 @@
|
||||
- [Create Order Handle Errors](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
(async () => {
|
||||
|
||||
const exchange = new ccxt.bittrex ({
|
||||
'apiKey': 'YOUR_API_KEY',
|
||||
'secret': 'YOUR_SECRET_KEY',
|
||||
'verbose': false, // set to true to see more debugging output
|
||||
'timeout': 60000,
|
||||
})
|
||||
|
||||
// try to load markets first, retry on request timeouts until it succeeds:
|
||||
|
||||
while (true) {
|
||||
|
||||
try {
|
||||
|
||||
await exchange.loadMarkets ();
|
||||
break;
|
||||
|
||||
} catch (e) {
|
||||
|
||||
if (e instanceof ccxt.RequestTimeout)
|
||||
console.log (exchange.iso8601 (Date.now ()), e.constructor.name, e.message)
|
||||
}
|
||||
}
|
||||
|
||||
const symbol = 'ETH/BTC'
|
||||
const orderType = 'limit'
|
||||
const side = 'sell'
|
||||
const amount = 0.321;
|
||||
const price = 0.123;
|
||||
|
||||
// try just one attempt to create an order
|
||||
|
||||
try {
|
||||
|
||||
const response = await exchange.createOrder (symbol, orderType, side, amount, price);
|
||||
console.log (response);
|
||||
console.log ('Succeeded');
|
||||
|
||||
} catch (e) {
|
||||
|
||||
console.log (exchange.iso8601 (Date.now ()), e.constructor.name, e.message)
|
||||
console.log ('Failed');
|
||||
|
||||
}
|
||||
|
||||
}) ()
|
||||
|
||||
```
|
||||
@@ -0,0 +1,77 @@
|
||||
- [Create Order Position With Takeprofit Stoploss](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
// @ts-nocheck
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
// AUTO-TRANSPILE //
|
||||
console.log('CCXT Version:', ccxt.version);
|
||||
// ------------------------------------------------------------------------------
|
||||
async function example() {
|
||||
// at this moment, only OKX support embedded stop-loss & take-profit orders in unified manner. other exchanges are being added actively and will be available soon.
|
||||
const exchange = new ccxt.okx({
|
||||
"apiKey": "YOUR_API_KEY",
|
||||
"secret": "YOUR_API_SECRET",
|
||||
"password": "YOUR_API_PASSWORD", // if exchange does not require password, comment out this line
|
||||
});
|
||||
const symbol = 'DOGE/USDT:USDT';
|
||||
const side = 'buy'; // 'buy' | 'sell'
|
||||
const order_type = 'limit'; // 'market' | 'limit'
|
||||
const amount = 1; // how many contracts (see `market(symbol).contractSize` to find out coin portion per one contract)
|
||||
await exchange.loadMarkets();
|
||||
const market = exchange.market(symbol);
|
||||
const ticker = await exchange.fetchTicker(symbol);
|
||||
const last_price = ticker['last'];
|
||||
const ask_price = ticker['ask'];
|
||||
const bid_price = ticker['bid'];
|
||||
// if order_type is 'market', then price is not needed
|
||||
let price = undefined;
|
||||
// if order_type is 'limit', then set a price at your desired level
|
||||
if (order_type === 'limit') {
|
||||
price = (side === 'buy') ? bid_price * 0.95 : ask_price * 1.05; // i.e. 5% from current price
|
||||
}
|
||||
// set trigger price for stop-loss/take-profit to 2% from current price
|
||||
// (note, across different exchanges "trigger" price can be also mentioned with different synonyms, like "activation price", "stop price", "conditional price", etc. )
|
||||
const stop_loss_trigger_price = (order_type === 'market' ? last_price : price) * (side === 'buy' ? 0.98 : 1.02);
|
||||
const take_profit_trigger_price = (order_type === 'market' ? last_price : price) * (side === 'buy' ? 1.02 : 0.98);
|
||||
// when symbol's price reaches your predefined "trigger price", stop-loss order would be activated as a "market order". but if you want it to be activated as a "limit order", then set a 'price' parameter for it
|
||||
const params = {
|
||||
'stopLoss': {
|
||||
'triggerPrice': stop_loss_trigger_price,
|
||||
// set a 'price' to act as limit order, otherwise remove it for a market order
|
||||
'price': stop_loss_trigger_price * 0.98,
|
||||
},
|
||||
'takeProfit': {
|
||||
'triggerPrice': take_profit_trigger_price,
|
||||
// set a 'price' to act as limit order, otherwise remove it for a market order
|
||||
'price': take_profit_trigger_price * 0.98,
|
||||
},
|
||||
// note that some exchanges might require some exchange specific parameter when opening a position, i.e.:
|
||||
// 'posSide': 'long', // for phemex hedge-mode api
|
||||
};
|
||||
const position_amount = market['contractSize'] * amount;
|
||||
const position_value = position_amount * last_price;
|
||||
// log
|
||||
console.log('Going to open a position', 'for', amount, 'contracts worth', position_amount, market['base'], '~', position_value, market['settle'], 'using', side, order_type, 'order (', (order_type === 'limit' ? exchange.priceToPrecision(symbol, price) : ''), '), using the following params:');
|
||||
console.log(params);
|
||||
console.log('-----------------------------------------------------------------------');
|
||||
// exchange.verbose = True // uncomment for debugging purposes if necessary
|
||||
try {
|
||||
const created_order = await exchange.createOrder(symbol, order_type, side, amount, price, params);
|
||||
console.log("Created an order", created_order);
|
||||
// Fetch all your open orders for this symbol
|
||||
// - use 'fetchOpenOrders' or 'fetchOrders' and filter with 'open' status
|
||||
// - note, that some exchanges might return one order object with embedded stoploss/takeprofit fields, while other exchanges might have separate stoploss/takeprofit order objects
|
||||
const all_open_orders = await exchange.fetchOpenOrders(symbol);
|
||||
console.log("Fetched all your orders for this symbol", all_open_orders);
|
||||
// To cancel a limit order, use "exchange.cancel_order(created_order['id'], symbol)""
|
||||
}
|
||||
catch (e) {
|
||||
console.log(e.toString());
|
||||
}
|
||||
}
|
||||
await example();
|
||||
// NOTES:
|
||||
// - Sometimes you might experience, when their stop-loss/take-profit order might not become activated, even though on chart the price had crossed that "trigger-price" order was not executed . That happens because some exchange might be using mark-price (instead of last-price) as a reference-price, so that mark-price might reach your trigger-price and it would activate your SL/TP order (even though on your symbol's chart you are viewing the "last-price" by default, which could have different movements than the mark-price).
|
||||
|
||||
```
|
||||
@@ -0,0 +1,71 @@
|
||||
- [Create Order With Retry](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
|
||||
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
const tryToCreateOrder = async function (exchange, symbol, type, side, amount, price, params) {
|
||||
|
||||
try {
|
||||
|
||||
const order = await exchange.createOrder (symbol, type, side, amount, price, params)
|
||||
return order
|
||||
|
||||
} catch (e) {
|
||||
|
||||
console.log (e.constructor.name, e.message)
|
||||
|
||||
if (e instanceof ccxt.NetworkError) {
|
||||
|
||||
// retry on networking errors
|
||||
return false
|
||||
|
||||
} else {
|
||||
|
||||
throw e // break on all other exceptions
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
const exchange = new ccxt.bytetrade ({
|
||||
'apiKey': 'classic123', // edit here
|
||||
'secret': 'ebcefff7de475ffe15e864ca3e3e410edf7e94fffd1f9af34edf9434e2bfff1b', // edit here
|
||||
})
|
||||
|
||||
//
|
||||
// make a classic bytetrade account - one that is linked to an email or phone number
|
||||
// then click on your username in the top right and then export
|
||||
// you will get a file like this:
|
||||
//
|
||||
// future garage icon motion panda garage motion task science head garage notable
|
||||
// ebcefff7de475ffe15e864ca3e3e410edf7e94fffd1f9af34edf9434e2bfff1b
|
||||
// classic123
|
||||
//
|
||||
// the second line is your secret and the third line is your apiKey
|
||||
//
|
||||
|
||||
const symbol = 'XRP/USDT' // edit here
|
||||
const type = 'limit ' // edit here
|
||||
const side = 'buy' // edit here
|
||||
const amount = 10 // edit here
|
||||
const price = 1 // edit here
|
||||
const params = {} // edit here
|
||||
|
||||
;(async () => {
|
||||
let order = false
|
||||
while (true) {
|
||||
order = await tryToCreateOrder (exchange, symbol, type, side, amount, price, params)
|
||||
if (order !== false) {
|
||||
break
|
||||
}
|
||||
}
|
||||
console.log (order)
|
||||
}) ()
|
||||
|
||||
```
|
||||
@@ -0,0 +1,31 @@
|
||||
- [Create Order Ws Example](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
// AUTO-TRANSPILE //
|
||||
async function example() {
|
||||
const exchange = new ccxt.pro.binance({
|
||||
'apiKey': 'MY_API_KEY',
|
||||
'secret': 'MY_SECRET',
|
||||
});
|
||||
exchange.setSandboxMode(true);
|
||||
exchange.verbose = true; // uncomment for debugging purposes if necessary
|
||||
// load markets
|
||||
await exchange.loadMarkets();
|
||||
const symbol = 'ETH/USDT';
|
||||
const type = 'limit';
|
||||
const side = 'buy';
|
||||
const amount = 0.01;
|
||||
let price = 1000;
|
||||
let orders = [];
|
||||
for (let i = 1; i < 5; i++) {
|
||||
const response = await exchange.createOrderWs(symbol, type, side, amount, price);
|
||||
price += i;
|
||||
orders.push(response);
|
||||
}
|
||||
console.log(orders);
|
||||
}
|
||||
await example();
|
||||
|
||||
```
|
||||
@@ -0,0 +1,23 @@
|
||||
- [Create Orders Example](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
// AUTO-TRANSPILE //
|
||||
async function example() {
|
||||
const exchange = new ccxt.binance({
|
||||
'apiKey': 'MY_API_KEY',
|
||||
'secret': 'MY_SECRET',
|
||||
});
|
||||
exchange.setSandboxMode(true);
|
||||
await exchange.loadMarkets();
|
||||
exchange.verbose = true; // uncomment for debugging purposes if necessary
|
||||
const orders = await exchange.createOrders([
|
||||
{ 'symbol': 'LTC/USDT:USDT', 'type': 'limit', 'side': 'buy', 'amount': 10, 'price': 55 },
|
||||
{ 'symbol': 'ETH/USDT:USDT', 'type': 'market', 'side': 'buy', 'amount': 0.5 },
|
||||
]);
|
||||
console.log(orders);
|
||||
}
|
||||
await example();
|
||||
|
||||
```
|
||||
@@ -0,0 +1,42 @@
|
||||
- [Create Trailing Amount Order](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
// AUTO-TRANSPILE //
|
||||
async function example() {
|
||||
const exchange = new ccxt.bingx({
|
||||
'apiKey': 'MY_API_KEY',
|
||||
'secret': 'MY_SECRET',
|
||||
});
|
||||
// exchange.setSandboxMode (true);
|
||||
// exchange.verbose = true; // uncomment for debugging purposes if necessary
|
||||
await exchange.loadMarkets();
|
||||
const symbol = 'BTC/USDT:USDT';
|
||||
const order_type = 'market';
|
||||
const side = 'sell';
|
||||
const amount = 0.0001;
|
||||
const price = undefined;
|
||||
const reduceOnly = true;
|
||||
const trailingAmount = 100;
|
||||
// const trailingTriggerPrice = undefined; // not supported on all exchanges
|
||||
const params = {
|
||||
'reduceOnly': reduceOnly,
|
||||
'trailingAmount': trailingAmount,
|
||||
// 'trailingTriggerPrice': trailingTriggerPrice,
|
||||
};
|
||||
try {
|
||||
const create_order = await exchange.createOrder(symbol, order_type, side, amount, price, params);
|
||||
// Alternatively use the createTrailingAmountOrder method:
|
||||
// const create_order = await exchange.createTrailingAmountOrder (symbol, order_type, side, amount, price, trailingAmount, trailingTriggerPrice, {
|
||||
// 'reduceOnly': reduceOnly,
|
||||
// });
|
||||
console.log(create_order);
|
||||
}
|
||||
catch (e) {
|
||||
console.log(e.toString());
|
||||
}
|
||||
}
|
||||
await example();
|
||||
|
||||
```
|
||||
@@ -0,0 +1,42 @@
|
||||
- [Create Trailing Percent Order](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
// AUTO-TRANSPILE //
|
||||
async function example() {
|
||||
const exchange = new ccxt.bingx({
|
||||
'apiKey': 'MY_API_KEY',
|
||||
'secret': 'MY_SECRET',
|
||||
});
|
||||
// exchange.setSandboxMode (true);
|
||||
// exchange.verbose = true; // uncomment for debugging purposes if necessary
|
||||
await exchange.loadMarkets();
|
||||
const symbol = 'BTC/USDT:USDT';
|
||||
const order_type = 'market';
|
||||
const side = 'sell';
|
||||
const amount = 0.0001;
|
||||
const price = undefined;
|
||||
const reduceOnly = true;
|
||||
const trailingPercent = 10;
|
||||
// const trailingTriggerPrice = undefined; // not supported on all exchanges
|
||||
const params = {
|
||||
'reduceOnly': reduceOnly,
|
||||
'trailingPercent': trailingPercent,
|
||||
// 'trailingTriggerPrice': trailingTriggerPrice,
|
||||
};
|
||||
try {
|
||||
const create_order = await exchange.createOrder(symbol, order_type, side, amount, price, params);
|
||||
// Alternatively use the createTrailingAmountOrder method:
|
||||
// const create_order = await exchange.createTrailingPercentOrder (symbol, order_type, side, amount, price, trailingPercent, trailingTriggerPrice, {
|
||||
// 'reduceOnly': reduceOnly,
|
||||
// });
|
||||
console.log(create_order);
|
||||
}
|
||||
catch (e) {
|
||||
console.log(e.toString());
|
||||
}
|
||||
}
|
||||
await example();
|
||||
|
||||
```
|
||||
@@ -0,0 +1,11 @@
|
||||
- [Credentials](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
{
|
||||
"hitbtc": { "apiKey": "b6aad581670b30fb25d1c91cdbe8ca5c", "secret": "fa394ced37a488f9b5826a2d9ce39ae3" },
|
||||
"bitso": { "apiKey": "xZnHRmdlgJ", "secret": "e156bb7f7ab3a831afbc7a80f7866b9e" },
|
||||
"coincheck": { "apiKey": "dCyzY2T6w0DFhaco", "secret": "JpI0eMmxfa0tEpk3X-dNwyclSASJkl-S" }
|
||||
}
|
||||
|
||||
```
|
||||
@@ -0,0 +1,18 @@
|
||||
- [Custom Proxy Agent For Js](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
// @ts-nocheck
|
||||
// to set custom "proxy-agent" for ccxt
|
||||
import ccxt from 'ccxt';
|
||||
import HttpProxyAgent from 'http-proxy-agent';
|
||||
import HttpsProxyAgent from 'https-proxy-agent';
|
||||
const proxy = 'http://1.2.3.4:5678';
|
||||
const httpAgent = new HttpProxyAgent(proxy);
|
||||
const httpsAgent = new HttpsProxyAgent(proxy);
|
||||
// then pass it through constructor
|
||||
const kraken = new ccxt.kraken({ agent: httpAgent /* or httpsAgent */ });
|
||||
// or set it later
|
||||
kraken.agent = agent;
|
||||
|
||||
```
|
||||
@@ -0,0 +1,28 @@
|
||||
- [Custom Proxy Url](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
|
||||
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
|
||||
(async function main () {
|
||||
|
||||
const kraken1 = new ccxt.kraken ({
|
||||
proxy: function (url) {
|
||||
return 'https://example.com/?url=' + encodeURIComponent (url)
|
||||
},
|
||||
})
|
||||
|
||||
console.log (await kraken1.loadMarkets ())
|
||||
|
||||
const kraken2 = new ccxt.kraken ({
|
||||
proxy: function (url) {
|
||||
return 'https://cors-anywhere.herokuapp.com/' + url
|
||||
},
|
||||
})
|
||||
|
||||
console.log (await kraken2.loadMarkets ())
|
||||
|
||||
}) ()
|
||||
```
|
||||
@@ -0,0 +1,66 @@
|
||||
- [Delta Maintenance Margin Rate Max Leverage](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
|
||||
console.log ('CCXT Version:', ccxt.version);
|
||||
|
||||
function getMaxLeverage (market, positionSize) {
|
||||
/**
|
||||
* @description Equation taken from https://www.delta.exchange/contracts/
|
||||
* @param {object} market CCXT market
|
||||
* @param {float} positionSize The value of the position in quote currency
|
||||
* @returns The maximum leverage available for the market for the given position size
|
||||
*/
|
||||
const info = market['info'];
|
||||
const maxLeverageNotional = Number (info['max_leverage_notional']);
|
||||
const initialMarginScalingFactor = Number (info['initial_margin_scaling_factor']);
|
||||
let initialMargin = Number (info['initial_margin']);
|
||||
|
||||
if (positionSize <= maxLeverageNotional) {
|
||||
const initialMarginRatio = initialMargin / 100;
|
||||
return 1 / initialMarginRatio;
|
||||
} else {
|
||||
initialMargin = initialMargin + (initialMarginScalingFactor * (positionSize - maxLeverageNotional));
|
||||
const initialMarginRatio = initialMargin / 100;
|
||||
return 1 / initialMarginRatio;
|
||||
}
|
||||
}
|
||||
|
||||
function getMaintenanceMarginRate (market, positionSize) {
|
||||
/**
|
||||
* @description Equation taken from https://www.delta.exchange/contracts/
|
||||
* @param {object} market CCXT market
|
||||
* @param {float} positionSize The value of the position in quote currency
|
||||
* @returns The maintenance margin rate as a percentage for the market with the given position size
|
||||
*/
|
||||
const info = market['info'];
|
||||
const maxLeverageNotional = Number (info['max_leverage_notional']);
|
||||
const maintenanceMarginScalingFactor = Number (info['maintenance_margin_scaling_factor']);
|
||||
const maintenanceMargin = Number (info['maintenance_margin']);
|
||||
|
||||
if (positionSize <= maxLeverageNotional) {
|
||||
return maintenanceMargin;
|
||||
} else {
|
||||
return maintenanceMargin + (maintenanceMarginScalingFactor * (positionSize - maxLeverageNotional));
|
||||
}
|
||||
}
|
||||
|
||||
async function main () {
|
||||
|
||||
const exchange = new ccxt.delta();
|
||||
await exchange.loadMarkets ();
|
||||
|
||||
const symbol = 'ADA/USDT:USDT';
|
||||
const market = exchange.market (symbol);
|
||||
|
||||
// Gets the maximum leverage and maintenance margin rate for a position worth 100,000 USDT on the ADA/USDT:USDT market
|
||||
const maxLeverage = getMaxLeverage(market, 100000);
|
||||
const maintenanceMarginRate = getMaintenanceMarginRate(market, 100000);
|
||||
console.log(maxLeverage, maintenanceMarginRate);
|
||||
}
|
||||
|
||||
main ()
|
||||
|
||||
```
|
||||
@@ -0,0 +1,32 @@
|
||||
- [Env Variables](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
import ololog from 'ololog'
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
const log = ololog.configure.handleNodeErrors (), asTable = require("as-table").configure({ delimiter: " | " });
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
(async () => {
|
||||
|
||||
const exchange = new ccxt.coinbase ({
|
||||
verbose: process.argv.includes ('--verbose'),
|
||||
timeout: 60000,
|
||||
apiKey: process.env.KEY,
|
||||
secret: process.env.SECRET
|
||||
});
|
||||
|
||||
const balance = await exchange.fetchBalance ()
|
||||
log.green (balance)
|
||||
|
||||
})()
|
||||
|
||||
```
|
||||
@@ -0,0 +1,94 @@
|
||||
- [Error Handling](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
|
||||
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
|
||||
const verbose = process.argv.includes ('--verbose');
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
const printSupportedExchanges = () => console.log ('Supported exchanges:', ccxt.exchanges.join (', '))
|
||||
|
||||
const printUsage = () => {
|
||||
console.log ('Usage: node', process.argv[1], 'id'.green)
|
||||
printSupportedExchanges ()
|
||||
}
|
||||
|
||||
const run = async (id) => {
|
||||
|
||||
// check if the exchange is supported by ccxt
|
||||
const exchangeFound = ccxt.exchanges.indexOf (id) > -1
|
||||
|
||||
if (exchangeFound) {
|
||||
|
||||
console.log ('Instantiating', id, 'exchange')
|
||||
|
||||
// instantiate the exchange by id
|
||||
const exchange = new ccxt[id] ({ verbose })
|
||||
|
||||
// try to load markets and catch the errors if any
|
||||
try {
|
||||
|
||||
await exchange.loadMarkets ()
|
||||
|
||||
} catch (e) {
|
||||
|
||||
if (e instanceof ccxt.NetworkError) {
|
||||
console.log (exchange.id, 'loadMarkets failed due to a network error:', e.message)
|
||||
} else if (e instanceof ccxt.ExchangeError) {
|
||||
console.log (exchange.id, 'loadMarkets failed due to exchange error:', e.message)
|
||||
} else {
|
||||
console.log (exchange.id, 'loadMarkets failed with:', e.message)
|
||||
}
|
||||
|
||||
// rethrow the error "higher up" the call chain
|
||||
throw e
|
||||
}
|
||||
|
||||
// try to fetch a ticker and catch the errors if any
|
||||
try {
|
||||
|
||||
const symbol = 'ETH/BTC'
|
||||
const response = await exchange.fetchTicker (symbol)
|
||||
console.log (response)
|
||||
|
||||
} catch (e) {
|
||||
|
||||
if (e instanceof ccxt.NetworkError) {
|
||||
console.log (exchange.id, 'fetchTicker failed due to a network error:', e.message)
|
||||
} else if (e instanceof ccxt.ExchangeError) {
|
||||
console.log (exchange.id, 'fetchTicker failed due to exchange error:', e.message)
|
||||
} else {
|
||||
console.log (exchange.id, 'fetchTicker failed with:', e.message)
|
||||
}
|
||||
|
||||
// rethrow the error "higher up" the call chain
|
||||
throw e
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
console.log ('Exchange', id, 'not found')
|
||||
printSupportedExchanges ()
|
||||
}
|
||||
}
|
||||
|
||||
;(async function main () {
|
||||
|
||||
if (process.argv.length > 2) {
|
||||
|
||||
let id = process.argv[2]
|
||||
await run (id)
|
||||
|
||||
} else {
|
||||
|
||||
printUsage ()
|
||||
}
|
||||
|
||||
process.exit ()
|
||||
|
||||
}) ()
|
||||
```
|
||||
@@ -0,0 +1,141 @@
|
||||
- [Exchange Capabilities](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
|
||||
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
import ololog from 'ololog';
|
||||
import ansicolor from 'ansicolor';
|
||||
import asTable from 'as-table';
|
||||
|
||||
const { noLocate } = ololog;
|
||||
const log = noLocate;
|
||||
|
||||
ansicolor.nice
|
||||
|
||||
|
||||
|
||||
const csv = process.argv.includes ('--csv'), delimiter = csv ? ',' : '|', asTableConfig = { delimiter: ' ' + delimiter + ' ', /* print: require ('string.ify').noPretty */ }
|
||||
|
||||
asTable.configure (asTableConfig);
|
||||
|
||||
const sortCertified = process.argv.includes ('--sort-certified') || process.argv.includes ('--certified')
|
||||
const exchangesArgument = process.argv.find (arg => arg.startsWith ('--exchanges='))
|
||||
const exchangesArgumentParts = exchangesArgument ? exchangesArgument.split ('=') : []
|
||||
const selectedExchanges = (exchangesArgumentParts.length > 1) ? exchangesArgumentParts[1].split (',') : []
|
||||
|
||||
console.log (ccxt.iso8601 (ccxt.milliseconds ()))
|
||||
console.log ('CCXT v' + ccxt.version)
|
||||
|
||||
async function main () {
|
||||
|
||||
let total = 0
|
||||
let notImplemented = 0
|
||||
let inexistentApi = 0
|
||||
let implemented = 0
|
||||
let emulated = 0
|
||||
|
||||
const exchangeNames = ccxt.exchanges
|
||||
let exchanges = exchangeNames.map (id => new ccxt[id] ())
|
||||
exchanges = exchanges.map (exchange => exchange.pro ? new ccxt.pro[exchange.id] () : exchange)
|
||||
if (sortCertified) {
|
||||
exchanges.sort((a, b) => {
|
||||
if (a.certified && !b.certified) {
|
||||
return -1;
|
||||
} else if (!a.certified && b.certified) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
});
|
||||
}
|
||||
const metainfo = ccxt.flatten (exchanges.map (exchange => Object.keys (exchange.has)))
|
||||
const reduced = metainfo.reduce ((previous, current) => {
|
||||
previous[current] = (previous[current] || 0) + 1
|
||||
return previous
|
||||
}, {})
|
||||
const unified = Object.entries (reduced).filter (([ _, count ]) => count > 1)
|
||||
const methods = unified.map (([ method, _ ]) => method).sort ()
|
||||
if (selectedExchanges.length > 0) {
|
||||
exchanges = exchanges.filter ((exchange) => selectedExchanges.includes(exchange.id))
|
||||
}
|
||||
const table = asTable (exchanges.map (exchange => {
|
||||
let result = {};
|
||||
const basics = [
|
||||
'CORS',
|
||||
'spot',
|
||||
'margin',
|
||||
'swap',
|
||||
'future',
|
||||
'option',
|
||||
];
|
||||
|
||||
ccxt.unique (basics.concat (methods)).forEach (key => {
|
||||
|
||||
total += 1
|
||||
|
||||
let coloredString = '';
|
||||
|
||||
const feature = exchange.has[key]
|
||||
const isFunction = (typeof exchange[key] === 'function')
|
||||
const isBasic = basics.includes (key)
|
||||
|
||||
if (feature === false) {
|
||||
// if explicitly set to 'false' in exchange.has (to exclude mistake, we check if it's undefined too)
|
||||
coloredString = exchange.id.red.dim
|
||||
inexistentApi += 1
|
||||
} else if (feature === 'emulated') {
|
||||
// if explicitly set to 'emulated' in exchange.has
|
||||
coloredString = exchange.id.yellow
|
||||
emulated += 1
|
||||
} else if (feature) {
|
||||
if (isBasic) {
|
||||
// if neither 'false' nor 'emulated', and if method exists
|
||||
coloredString = exchange.id.green
|
||||
implemented += 1
|
||||
} else {
|
||||
if (isFunction) {
|
||||
coloredString = exchange.id.green
|
||||
implemented += 1
|
||||
} else {
|
||||
// the feature is available in exchange.has and not implemented
|
||||
// this is an error
|
||||
coloredString = exchange.id.lightMagenta
|
||||
}
|
||||
}
|
||||
} else {
|
||||
coloredString = exchange.id.lightRed
|
||||
notImplemented += 1
|
||||
}
|
||||
|
||||
result[key] = coloredString
|
||||
})
|
||||
|
||||
return result
|
||||
}))
|
||||
|
||||
if (csv) {
|
||||
let lines = table.split ("\n")
|
||||
lines = lines.slice (0, 1).concat (lines.slice (2))
|
||||
log (lines.join ("\n"))
|
||||
} else {
|
||||
log (table)
|
||||
}
|
||||
|
||||
log ('Summary: ',
|
||||
ccxt.exchanges.length.toString (), 'exchanges; ',
|
||||
'Methods [' + total.toString () + ' total]: ',
|
||||
implemented.toString ().green, 'implemented,',
|
||||
emulated.toString ().yellow, 'emulated,',
|
||||
(inexistentApi.toString ().red.dim), 'inexistentApi,',
|
||||
(notImplemented.toString ().lightRed), 'notImplemented',
|
||||
)
|
||||
|
||||
log("\nMessy? Try piping to less (e.g. node script.js | less -S -R --header=3 )\n".red)
|
||||
|
||||
}
|
||||
|
||||
main ()
|
||||
|
||||
```
|
||||
@@ -0,0 +1,65 @@
|
||||
- [Exchanges By Volume](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
|
||||
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
|
||||
(async () => {
|
||||
|
||||
// const exchanges = [
|
||||
// 'bittrex',
|
||||
// 'poloniex',
|
||||
// 'bitfinex'
|
||||
// ]
|
||||
|
||||
const exchanges = ccxt.exchanges
|
||||
|
||||
const symbol = 'BTC/USDT'
|
||||
const tickers = {}
|
||||
const volumeField = 'baseVolume'
|
||||
|
||||
console.log ('-----------------------------------------------------------')
|
||||
|
||||
await Promise.all (exchanges.map (exchangeId =>
|
||||
|
||||
new Promise (async (resolve, reject) => {
|
||||
|
||||
try {
|
||||
|
||||
const exchange = new ccxt[exchangeId] ()
|
||||
|
||||
const ticker = await exchange.fetchTicker (symbol)
|
||||
|
||||
if (ticker[volumeField] !== undefined) {
|
||||
tickers[exchangeId] = ticker
|
||||
}
|
||||
|
||||
} catch (e) {
|
||||
|
||||
console.log (exchangeId, e.message.slice (0, 100))
|
||||
}
|
||||
|
||||
resolve ()
|
||||
|
||||
})
|
||||
|
||||
))
|
||||
|
||||
console.log ('-----------------------------------------------------------')
|
||||
|
||||
console.log (Object
|
||||
.keys (tickers)
|
||||
.sort ((a, b) =>
|
||||
((tickers[a][volumeField] > tickers[b][volumeField]) ? 1 : ((tickers[a][volumeField] < tickers[b][volumeField]) ? -1 : 0)))
|
||||
.reverse ()
|
||||
.map (id => ({
|
||||
id,
|
||||
symbol,
|
||||
'volume': tickers[id][volumeField],
|
||||
}))
|
||||
)
|
||||
|
||||
}) ()
|
||||
```
|
||||
@@ -0,0 +1,46 @@
|
||||
- [Exchanges](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
|
||||
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
import countries from '../../build/countries.js';
|
||||
import asTable from 'as-table';
|
||||
import ololog from 'ololog'
|
||||
import ansicolor from 'ansicolor';
|
||||
const log = ololog.configure ({ locate: false })
|
||||
|
||||
ansicolor.nice
|
||||
|
||||
process.on ('uncaughtException', e => { log.bright.red.error (e); process.exit (1) })
|
||||
process.on ('unhandledRejection', e => { log.bright.red.error (e); process.exit (1) })
|
||||
|
||||
let exchanges = {}
|
||||
|
||||
ccxt.exchanges.forEach (id => { exchanges[id] = new (ccxt)[id] () })
|
||||
|
||||
log ('The ccxt library supports', (ccxt.exchanges.length.toString ()).green, 'exchanges:')
|
||||
|
||||
var countryName = function (code) {
|
||||
return ((countries[code] !== undefined) ? countries[code] : code)
|
||||
}
|
||||
|
||||
log (asTable.configure ({ delimiter: ' | ' }) (Object.values (exchanges).map (exchange => {
|
||||
|
||||
let countries = Array.isArray (exchange.countries) ?
|
||||
exchange.countries.map (countryName).join (', ') :
|
||||
countryName (exchange.countries)
|
||||
|
||||
let website = Array.isArray (exchange.urls.www) ? exchange.urls.www[0] : exchange.urls.www
|
||||
|
||||
return {
|
||||
id: exchange.id,
|
||||
name: exchange.name,
|
||||
url: website,
|
||||
countries: countries,
|
||||
}
|
||||
|
||||
})))
|
||||
|
||||
```
|
||||
@@ -0,0 +1,225 @@
|
||||
- [Fetch All Balances](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
import { PAD_WITH_ZERO } from '../../js/src/base/functions/number.js';
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import ansicolor from 'ansicolor';
|
||||
import asTable from 'as-table';
|
||||
import ololog from 'ololog';
|
||||
|
||||
ansicolor.nice
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
const table = asTable.configure ({
|
||||
delimiter: '|'.lightGray.dim,
|
||||
right: true,
|
||||
title: x => String (x).lightGray,
|
||||
print: x => {
|
||||
if (typeof x === 'object') {
|
||||
const j = JSON.stringify (x).trim ()
|
||||
if (j.length < 100) return j
|
||||
}
|
||||
return String (x)
|
||||
}
|
||||
}),
|
||||
{ ROUND, DECIMAL_PLACES, decimalToPrecision, omit, unique, flatten, extend } = ccxt,
|
||||
log = ololog.handleNodeErrors ().noLocate.unlimited;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// set up keys and settings, if any
|
||||
const keysGlobal = path.resolve ('keys.json')
|
||||
const keysLocal = path.resolve ('keys.local.json')
|
||||
|
||||
const keysGlobalExists = fs.existsSync (keysGlobal)
|
||||
const keysLocalExists = fs.existsSync (keysLocal)
|
||||
|
||||
if (!(keysGlobalExists || keysLocalExists)) {
|
||||
const lines = [
|
||||
'This script requires a keys.json or a keys.local.json file containing the API keys in JSON format',
|
||||
'{',
|
||||
' "binance": {',
|
||||
' "apiKey": "YOUR_API_KEY",',
|
||||
' "secret": "YOUR_SECRET"',
|
||||
' }',
|
||||
' "bitfinex": {',
|
||||
' "apiKey": "YOUR_API_KEY",',
|
||||
' "secret": "YOUR_SECRET"',
|
||||
' }',
|
||||
'}'
|
||||
]
|
||||
const errorMessage = lines.join ("\n")
|
||||
log.red.bright (errorMessage)
|
||||
process.exit ()
|
||||
}
|
||||
|
||||
let globalKeysFile = keysGlobalExists ? keysGlobal : false
|
||||
let localKeysFile = keysLocalExists ? keysLocal : globalKeysFile
|
||||
const dynamicLocalKeysFile = JSON.parse (fs.readFileSync (localKeysFile));
|
||||
let settings = localKeysFile ? (dynamicLocalKeysFile || {}) : {}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
const timeout = 30000
|
||||
|
||||
const coins = [
|
||||
'BTC',
|
||||
'ETH',
|
||||
'BNB',
|
||||
'EUR',
|
||||
'LTC',
|
||||
'USD',
|
||||
'USDC',
|
||||
'USDT',
|
||||
'BUSD',
|
||||
'XRP',
|
||||
'DOGE',
|
||||
'YFI',
|
||||
'LINK',
|
||||
'XLM',
|
||||
'ADA',
|
||||
'SOL',
|
||||
]
|
||||
|
||||
function initializeAllExchanges () {
|
||||
let numErrors = 0
|
||||
const ignore = [
|
||||
'bcex',
|
||||
'bitsane',
|
||||
'chbtc',
|
||||
'coinbasepro',
|
||||
'jubi',
|
||||
'hitbtc',
|
||||
'bitstamp1',
|
||||
'bitfinex2',
|
||||
'upbit',
|
||||
'huobipro',
|
||||
]
|
||||
const result = []
|
||||
ccxt.exchanges.filter (exchangeId => (!ignore.includes (exchangeId))).forEach (exchangeId => {
|
||||
try {
|
||||
const verbose = false
|
||||
const exchange = new ccxt[exchangeId] ({
|
||||
timeout,
|
||||
verbose,
|
||||
... (settings[exchangeId] || {})
|
||||
})
|
||||
exchange.checkRequiredCredentials ()
|
||||
result.push (exchange)
|
||||
} catch (e) {
|
||||
numErrors++
|
||||
log.red (exchangeId, 'initialization failed', e.constructor.name, e.message.slice (0, 100));
|
||||
}
|
||||
})
|
||||
log ('Initialized', ccxt.exchanges.length - numErrors, 'of', ccxt.exchanges.length, 'exchanges,',
|
||||
numErrors, 'error' + (((numErrors < 1) || (numErrors > 1)) ? 's' : '') + ',',
|
||||
ignore.length, 'skipped')
|
||||
return result
|
||||
}
|
||||
|
||||
(async () => {
|
||||
|
||||
const exchanges = initializeAllExchanges ()
|
||||
console.log (exchanges.map (exchange => exchange.id))
|
||||
let results = []
|
||||
const priceOracle = new ccxt.gate ()
|
||||
const tickers = await priceOracle.fetchTickers ()
|
||||
await Promise.all (exchanges.map ((exchange) => (async function () {
|
||||
|
||||
try {
|
||||
|
||||
if (exchange.has['signIn']) {
|
||||
await exchange.signIn ()
|
||||
}
|
||||
|
||||
const balance = await exchange.fetchTotalBalance ()
|
||||
if (!balance) {
|
||||
throw new Error (exchange.id + ' erroneous balance')
|
||||
}
|
||||
const keys = Object.keys (balance).sort ()
|
||||
const nonzeroBalance = {}
|
||||
for (let i = 0; i < keys.length; i++) {
|
||||
const key = keys[i]
|
||||
if (coins.includes (key)) {
|
||||
const value = balance[key]
|
||||
const valueToPrecision = decimalToPrecision (value, ROUND, 8, DECIMAL_PLACES)
|
||||
if (valueToPrecision !== '0') {
|
||||
nonzeroBalance[key] = valueToPrecision
|
||||
}
|
||||
}
|
||||
}
|
||||
const numNonzeroKeys = Object.keys (nonzeroBalance).length
|
||||
if (numNonzeroKeys < 1) {
|
||||
log.yellow (exchange.id + ' empty balance')
|
||||
} else {
|
||||
log.green (exchange.id, numNonzeroKeys, 'currencies')
|
||||
results.push ({ exchange: exchange.id, ... nonzeroBalance })
|
||||
}
|
||||
|
||||
} catch (e) {
|
||||
log.red (exchange.id, e.constructor.name, e.message.split ("\n")[0].slice (0, 100))
|
||||
}
|
||||
|
||||
}) ()))
|
||||
|
||||
results = ccxt.sortBy (results, 'exchange')
|
||||
|
||||
const currencies = unique (flatten (results.map (result => Object.keys (omit (result, 'exchange')))))
|
||||
currencies.sort ()
|
||||
|
||||
const total = {}
|
||||
for (let i = 0; i < currencies.length; i++) {
|
||||
const currency = currencies[i]
|
||||
let sum = 0
|
||||
results.forEach (result => {
|
||||
if (currency in result) {
|
||||
sum += parseFloat (result[currency])
|
||||
}
|
||||
})
|
||||
total[currency] = decimalToPrecision (sum, ROUND, 8, DECIMAL_PLACES)
|
||||
}
|
||||
|
||||
results.push (extend ({ 'exchange': 'total' }, total))
|
||||
|
||||
results = results.map (result => {
|
||||
let value = 0;
|
||||
const convertTo = 'USD'
|
||||
currencies.forEach (currency => {
|
||||
if (currency === convertTo) {
|
||||
if (currency in result) {
|
||||
value += parseFloat (result[currency])
|
||||
}
|
||||
} else {
|
||||
const symbol = currency + '/' + convertTo
|
||||
if (symbol in tickers) {
|
||||
if (currency in result) {
|
||||
const ticker = tickers[symbol]
|
||||
value += parseFloat (result[currency]) * ticker['last']
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
return extend ({
|
||||
'exchange': result.exchange,
|
||||
'$': decimalToPrecision (value, ROUND, 2, DECIMAL_PLACES, PAD_WITH_ZERO),
|
||||
}, result);
|
||||
})
|
||||
|
||||
const tableResults = table (results)
|
||||
|
||||
log (tableResults)
|
||||
|
||||
log.green ('Currencies:', currencies)
|
||||
|
||||
console.log (new Date ())
|
||||
|
||||
}) ()
|
||||
|
||||
```
|
||||
@@ -0,0 +1,58 @@
|
||||
- [Fetch All Tickers To Files 2](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
import { writeFileSync } from 'fs';
|
||||
import path from 'path';
|
||||
|
||||
const enableRateLimit = true, exchanges = {}, tickers = {};
|
||||
|
||||
|
||||
ccxt.exchanges.forEach (id => {
|
||||
try {
|
||||
const exchange = new ccxt[id] ()
|
||||
if (exchange.has['fetchTickers']) {
|
||||
exchanges[id] = exchange
|
||||
}
|
||||
} catch (e) {
|
||||
console.log ('Failed to initialize', id, e.constructor.name, e.message)
|
||||
}
|
||||
})
|
||||
|
||||
async function main () {
|
||||
|
||||
console.log ('Started')
|
||||
const start = Date.now ()
|
||||
|
||||
try {
|
||||
const promises = Object.values (exchanges).map (exchange => (
|
||||
(async () => {
|
||||
console.log (exchange.id)
|
||||
try {
|
||||
const response = await exchange.fetchTickers ()
|
||||
tickers[exchange.id] = response
|
||||
} catch (e) {
|
||||
console.log ('Failed to fetchTickers() from', exchange.id)
|
||||
}
|
||||
}) ()
|
||||
))
|
||||
await Promise.all (promises)
|
||||
} catch (e) {
|
||||
console.log ('Failed awaiting all exchanges to complete')
|
||||
}
|
||||
|
||||
Object.entries (tickers).forEach (([ id, response ]) => {
|
||||
const folder = 'C:/myproject/tickers'
|
||||
const filename = `${id}-tickers.json`
|
||||
console.log (path.join (folder, filename))
|
||||
writeFileSync (path.join (folder, filename), JSON.stringify (response))
|
||||
})
|
||||
|
||||
const end = Date.now ()
|
||||
console.log (`Fetched tickers in ${(end - start) / 1000} seconds`)
|
||||
|
||||
}
|
||||
|
||||
main ()
|
||||
```
|
||||
@@ -0,0 +1,83 @@
|
||||
- [Fetch All Tickers To Files](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
|
||||
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
import ololog from 'ololog';
|
||||
|
||||
const { noLocate } = ololog;
|
||||
const log = noLocate;
|
||||
|
||||
import fs from 'fs';
|
||||
|
||||
// the numWorkers constant defines the number of concurrent workers
|
||||
// those aren't really threads in terms of the async environment
|
||||
// set this to the number of cores in your CPU * 2
|
||||
// or play with this number to find a setting that works best for you
|
||||
|
||||
const numWorkers = 8;(async () => {
|
||||
|
||||
// make an array of all exchanges
|
||||
const exchanges = ccxt.exchanges
|
||||
|
||||
// filter coinmarketcap and theocean
|
||||
// coinmarketcap isn't really an exchange
|
||||
// theocean requires web3 dependencies to be installed
|
||||
|
||||
.filter (id => ![ 'coinmarketcap', 'theocean' ].includes (id))
|
||||
|
||||
// instantiate each exchange and save it to the exchanges list
|
||||
|
||||
.map (id => new ccxt[id] ())
|
||||
|
||||
// the worker function for each "async thread"
|
||||
const worker = async function () {
|
||||
|
||||
// while the array of all exchanges is not empty
|
||||
while (exchanges.length > 0) {
|
||||
|
||||
// pop one exchange from the array
|
||||
const exchange = exchanges.pop ()
|
||||
|
||||
// check if it has the necessary method implemented
|
||||
if (exchange.has['fetchTickers']) {
|
||||
|
||||
// try to do "the work" and handle errors if any
|
||||
try {
|
||||
|
||||
// fetch the response for all tickers from the exchange
|
||||
const tickers = await exchange.fetchTickers ()
|
||||
|
||||
// make a filename from exchange id
|
||||
const filename = exchange.id + '.json'
|
||||
|
||||
// save the response to a file
|
||||
fs.writeFileSync (filename, JSON.stringify ({ tickers }));
|
||||
|
||||
// print out a message on success
|
||||
log.green (exchange.id, 'tickers saved to', filename)
|
||||
|
||||
} catch (e) {
|
||||
|
||||
// in case of error - print it out and ignore it further
|
||||
log.red (e.constructor.name, e.message)
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
log.red (exchange.id, "has['fetchTickers'] = false");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// create numWorkers "threads" (they aren't really threads)
|
||||
const workers = [ ... Array (numWorkers) ].map (_ => worker ())
|
||||
|
||||
// wait for all of them to execute or fail
|
||||
await Promise.all (workers)
|
||||
|
||||
}) ()
|
||||
|
||||
```
|
||||
@@ -0,0 +1,33 @@
|
||||
- [Fetch Balance](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
"use strict";
|
||||
|
||||
const ccxt = require ('../../ccxt.js');
|
||||
|
||||
// instantiate the exchange
|
||||
let exchange = new ccxt.coinbasepro ({
|
||||
'apiKey': 'XXXXXXXXXXXXXX',
|
||||
'secret': 'YYYYYYYYYYYYYY',
|
||||
'password': 'ZZZZZZ', // if exchange requires password
|
||||
});
|
||||
|
||||
|
||||
async function checkMyBalance() {
|
||||
try {
|
||||
// fetch account balance from the exchange
|
||||
let myBalance = await exchange.fetchBalance ();
|
||||
|
||||
// output the result
|
||||
console.log (exchange.id, 'fetched balance', myBalance);
|
||||
|
||||
} catch (e) {
|
||||
// fpr advanced error-handling, see the "advanced-error-handling.js" example file
|
||||
console.log ('[' + e.constructor.name + '] ' + e.message);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
checkMyBalance();
|
||||
```
|
||||
@@ -0,0 +1,106 @@
|
||||
- [Fetch Create Deposit Address](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
// ----------------------------------------------------------------------------
|
||||
// setup
|
||||
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// setup
|
||||
|
||||
const // change me
|
||||
defaultCurrencyCode = 'BTC',
|
||||
// change me
|
||||
// currency code specified in commandline args ↓
|
||||
// you can call this script like node examples/js/fetch-create-deposit-address ETH
|
||||
exchangeId = 'poloniex',
|
||||
currencyCode = process.argv[3] || defaultCurrencyCode,
|
||||
exchange = new ccxt[exchangeId] ({
|
||||
|
||||
'apiKey': 'YOUR_API_KEY',
|
||||
'secret': 'YOUR_SECRET',
|
||||
|
||||
'enableRateLimit': true, // ←- required! https://github.com/ccxt/ccxt/wiki/Manual#rate-limit
|
||||
|
||||
// 'verbose': true, // ←- uncomment this for verbose output
|
||||
|
||||
// additional credentials might be required in exchange-specific cases:
|
||||
// uid or password for Coinbase Pro, etc...
|
||||
});
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
if (!exchange.has['fetchDepositAddress']) {
|
||||
|
||||
console.log ('The exchange does not support fetchDepositAddress() yet')
|
||||
process.exit ()
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
;(async () => {
|
||||
|
||||
try {
|
||||
|
||||
console.log ('Trying to fetch deposit address for ' + currencyCode + ' from ' + exchangeId + '...')
|
||||
|
||||
let fetchResult = await exchange.fetchDepositAddress (currencyCode)
|
||||
|
||||
console.log ('Successfully fetched deposit address for ' + currencyCode)
|
||||
console.log (fetchResult)
|
||||
|
||||
} catch (e) {
|
||||
|
||||
// never skip proper error handling, whatever it is you're building
|
||||
// actually, with crypto error handling should be the largest part of your code
|
||||
|
||||
if (e instanceof ccxt.InvalidAddress) {
|
||||
|
||||
console.log ('The address for ' + currencyCode + ' does not exist yet')
|
||||
|
||||
if (exchange.has['createDepositAddress']) {
|
||||
|
||||
console.log ('Attempting to create a deposit address for ' + currencyCode + '...')
|
||||
|
||||
try {
|
||||
|
||||
const createResult = await exchange.createDepositAddress (currencyCode)
|
||||
|
||||
// console.log (createResult) // for debugging
|
||||
|
||||
console.log ('Successfully created a deposit address for ' + currencyCode + ', fetching the deposit address now...')
|
||||
|
||||
try {
|
||||
|
||||
let fetchResult = await exchange.fetchDepositAddress (currencyCode)
|
||||
|
||||
console.log ('Successfully fetched deposit address for ' + currencyCode)
|
||||
console.log (fetchResult);
|
||||
|
||||
|
||||
} catch (e) {
|
||||
|
||||
console.log ('Failed to fetch deposit address for ' + currencyCode, e.constructor.name, e.message)
|
||||
}
|
||||
|
||||
} catch (e) {
|
||||
|
||||
console.log ('Failed to create deposit address for ' + currencyCode, e.constructor.name, e.message)
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
console.log ('The exchange does not support createDepositAddress()')
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
console.log ('There was an error while fetching deposit address for ' + currencyCode, e.constructor.name, e.message)
|
||||
}
|
||||
}
|
||||
|
||||
}) ()
|
||||
```
|
||||
@@ -0,0 +1,85 @@
|
||||
- [Fetch First Ohlcv Timestamp](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
// AUTO-TRANSPILE //
|
||||
// ###### Description ######
|
||||
//
|
||||
// This function tries to fetch the "listing time" of a symbol by fetching the earliest available bar in daily resolution.
|
||||
// Top-tier exchanges also support fetching smaller timeframes (eg. 1 minute) even several years back, so for those exchanges you can also use `useMinuteTimeframe = true` argument to get the timestamp rounded to the earliest minute bar (instead of daily bar timestamp).
|
||||
// See usage in the end of this file
|
||||
async function fetchFirstBarTimestamp(exchange, symbol, useMinuteTimeframe = false) {
|
||||
// set some constants
|
||||
const millisecondsPerDay = 86400000;
|
||||
const minutesPerDay = 1440;
|
||||
const minimumTimestamp = 1230768000000; // 2009-01-01 (bitcoin created year)
|
||||
// get market features
|
||||
const market = exchange.market(symbol);
|
||||
const marketType = exchange.safeString(market, 'type');
|
||||
let features = exchange.safeDict(exchange.features, marketType, {});
|
||||
if (market['subType'] !== undefined) {
|
||||
features = exchange.safeDict(features, market['subType'], {});
|
||||
}
|
||||
const ohlcv = exchange.safeDict(features, 'fetchOHLCV');
|
||||
if (ohlcv === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
const limit = exchange.safeInteger(ohlcv, 'limit');
|
||||
const fetchParams = { 'maxRetriesOnFailure': 3 };
|
||||
// start loop
|
||||
let currentSince = exchange.milliseconds() - millisecondsPerDay * (limit - 1);
|
||||
let foundStartTime = 0;
|
||||
// eslint-disable-next-line
|
||||
while (true) {
|
||||
currentSince = Math.max(currentSince, minimumTimestamp);
|
||||
const dailyBars = await exchange.fetchOHLCV(symbol, '1d', currentSince, limit, fetchParams);
|
||||
if (dailyBars.length <= 0) {
|
||||
break; // if no days returned, then probably start date was passed
|
||||
}
|
||||
const firstTs = dailyBars[0][0];
|
||||
if (firstTs === foundStartTime) {
|
||||
// if the first timestamp is equal to the last-fetched timestamp, then break here, because some exchanges still return initial bar even if since is much ahead to listing time
|
||||
break;
|
||||
}
|
||||
foundStartTime = firstTs;
|
||||
currentSince = foundStartTime - millisecondsPerDay * (limit - 1); // shift 'since' one step back
|
||||
if (dailyBars.length === 1) {
|
||||
// in some cases, some exchanges might still return first bar of chart when endtime overlaps previous day
|
||||
break;
|
||||
}
|
||||
}
|
||||
// if minute resolution needed
|
||||
if (useMinuteTimeframe) {
|
||||
const maxIteration = Math.ceil(minutesPerDay / limit) * 2;
|
||||
const allPromises = [];
|
||||
for (let i = 0; i < maxIteration; i++) {
|
||||
currentSince = foundStartTime - millisecondsPerDay + i * limit * 60 * 1000; // shift one-duration back for more accuracy for different kind of exchanges, like OKX, where first daily bar is offset by one day, but minute bars present
|
||||
allPromises.push(exchange.fetchOHLCV(symbol, '1m', currentSince, limit, fetchParams));
|
||||
}
|
||||
const allResponses = await Promise.all(allPromises);
|
||||
// find earliest bar
|
||||
for (let i = 0; i < allResponses.length; i++) {
|
||||
const response = allResponses[i];
|
||||
if (response.length > 0) {
|
||||
foundStartTime = response[0][0];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return foundStartTime;
|
||||
}
|
||||
// ###### Usage ######
|
||||
const runExample = false; // set to true to run example
|
||||
if (runExample) {
|
||||
const myEx = new ccxt.binance();
|
||||
await myEx.loadMarkets();
|
||||
const symbol = 'TRUMP/USDT';
|
||||
const earliest_timestamp = await fetchFirstBarTimestamp(myEx, symbol, true);
|
||||
console.log('- Earliest bar timestamp:', earliest_timestamp, ', readable: ', myEx.iso8601(earliest_timestamp));
|
||||
console.log('- market.created value:', myEx.market(symbol)['created']);
|
||||
}
|
||||
export default fetchFirstBarTimestamp;
|
||||
|
||||
```
|
||||
@@ -0,0 +1,26 @@
|
||||
- [Fetch From Many Exchanges Simultaneously](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
|
||||
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
import log from 'ololog';
|
||||
|
||||
const symbol = 'ETH/BTC'
|
||||
const exchanges = [ 'coinbasepro', 'hitbtc2', 'poloniex' ]
|
||||
|
||||
;(async () => {
|
||||
|
||||
const result = await Promise.all (exchanges.map (async id => {
|
||||
|
||||
const exchange = new ccxt[id] ()
|
||||
const ticker = await exchange.fetchTicker (symbol)
|
||||
return exchange.extend ({ 'exchange': id }, ticker)
|
||||
|
||||
}))
|
||||
|
||||
log (result);
|
||||
|
||||
}) ()
|
||||
```
|
||||
@@ -0,0 +1,31 @@
|
||||
- [Fetch Funding Rate History](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
import asTable from 'as-table';
|
||||
|
||||
const table = asTable.configure ({ delimiter: ' | ' });
|
||||
|
||||
console.log ('CCXT Version:', ccxt.version)
|
||||
|
||||
async function main () {
|
||||
|
||||
const exchange = new ccxt.binanceusdm()
|
||||
, symbol = 'ETH/USDT'
|
||||
, since = undefined
|
||||
, limit = undefined
|
||||
, params = {}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// fetch the history of the funding rate for a symbol
|
||||
|
||||
const response = await exchange.fetchFundingRateHistory (symbol, since, limit, params)
|
||||
|
||||
console.log (table (response))
|
||||
|
||||
}
|
||||
|
||||
main ()
|
||||
|
||||
```
|
||||
@@ -0,0 +1,78 @@
|
||||
- [Fetch Ohlcv From To Mark Index Premium](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
"use strict";
|
||||
|
||||
const ccxt = require ('../../ccxt')
|
||||
|
||||
const exchange = new ccxt.binance ();
|
||||
|
||||
const symbols = [ 'BTC/USDT', 'ETH/USDT', 'ADA/USDT'];
|
||||
// start from i.e. 01 february 2022
|
||||
// you can use milliseconds integer or also parse uniform datetime string, i.e. exchange.parse8601 ('2020-02-01T00:00:00Z')
|
||||
const fromTimestamp = 1643659200000;
|
||||
const tillTimestamp = exchange.milliseconds ();
|
||||
const timeframe = '1h';
|
||||
const itemsLimit = 1000;
|
||||
const fetchMethod = 'fetchOHLCV'; // if using swap exchanges, you can also use fetchMarkOHLCV, fetchIndexOHLCV, fetchPremiumIndexOHLCV
|
||||
|
||||
async function myDataFetch (symbol) {
|
||||
|
||||
await exchange.loadMarkets ();
|
||||
|
||||
// get the duration of one timeframe period in milliseconds
|
||||
const duration = exchange.parseTimeframe (timeframe) * 1000;
|
||||
console.log ('Fetching', symbol, timeframe, 'candles', 'from', exchange.iso8601 (fromTimestamp), 'to', exchange.iso8601 (tillTimestamp), '...');
|
||||
|
||||
let result = [];
|
||||
let since = fromTimestamp;
|
||||
do {
|
||||
|
||||
try {
|
||||
|
||||
const candles = await exchange[fetchMethod] (symbol, timeframe, since, itemsLimit);
|
||||
|
||||
const message = '[' + symbol + '] Fetched ' + candles.length + ' ' + timeframe + ' candles since ' + exchange.iso8601 (since);
|
||||
|
||||
if (candles.length) {
|
||||
|
||||
const first = candles[0];
|
||||
const last = candles[candles.length - 1];
|
||||
console.log ( message, ' | first', exchange.iso8601 (first[0]), ' | last', exchange.iso8601 (last[0]) );
|
||||
|
||||
// store your candles to a database or to a file here
|
||||
// ...
|
||||
result = result.concat (candles);
|
||||
since = last[0] + duration // next start from last candle timestamp + duration
|
||||
|
||||
} else {
|
||||
console.log ( message, ' | moving into next period');
|
||||
since = since + duration * itemsLimit; // next start from the current period's end
|
||||
}
|
||||
|
||||
} catch (e) {
|
||||
|
||||
console.log (symbol, e.constructor.name, e.message, ' Taking small pause...');
|
||||
await exchange.sleep (2000);
|
||||
// retry on next iteration
|
||||
}
|
||||
|
||||
} while (since + duration <= tillTimestamp)
|
||||
|
||||
console.log (symbol + ' completed !');
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
async function checkAllSymbols() {
|
||||
// download in parallel
|
||||
await Promise.all (symbols.map (symbol => myDataFetch (symbol)));
|
||||
// you can also do one by one (but that is not much optimal)
|
||||
//for (const symbol of symbols) {
|
||||
// const data = await myDataFetch (symbol);
|
||||
}
|
||||
checkAllSymbols();
|
||||
|
||||
```
|
||||
@@ -0,0 +1,45 @@
|
||||
- [Fetch Ohlcv Many Exchanges Continuosly](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
// AUTO-TRANSPILE //
|
||||
// fetch and handle constinuosly
|
||||
async function fetchOHLCVContinuously(exchange, symbol) {
|
||||
while (true) {
|
||||
try {
|
||||
const ohlcv = await exchange.fetchOHLCV(symbol);
|
||||
const ohlcvLength = ohlcv.length;
|
||||
console.log('Fetched ', exchange.id, ' - ', symbol, ' candles. last candle: ', ohlcv[ohlcvLength - 1]);
|
||||
}
|
||||
catch (e) {
|
||||
console.log(e);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// start exchanges and fetch OHLCV loop
|
||||
async function startExchange(exchangeName, symbols) {
|
||||
const ex = new ccxt[exchangeName]({});
|
||||
const promises = [];
|
||||
for (let i = 0; i < symbols.length; i++) {
|
||||
const symbol = symbols[i];
|
||||
promises.push(fetchOHLCVContinuously(ex, symbol));
|
||||
}
|
||||
await Promise.all(promises);
|
||||
await ex.close();
|
||||
}
|
||||
// main function
|
||||
async function example() {
|
||||
const exchanges = ['binance', 'okx', 'kraken'];
|
||||
const symbols = ['BTC/USDT', 'ETH/USDT'];
|
||||
const promises = [];
|
||||
for (let i = 0; i < exchanges.length; i++) {
|
||||
const exchangeName = exchanges[i];
|
||||
promises.push(startExchange(exchangeName, symbols));
|
||||
}
|
||||
await Promise.all(promises);
|
||||
}
|
||||
await example();
|
||||
|
||||
```
|
||||
@@ -0,0 +1,22 @@
|
||||
- [Fetch Ohlcv](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
// AUTO-TRANSPILE //
|
||||
async function example() {
|
||||
const myex = new ccxt.okx({});
|
||||
const fromTimestamp = myex.milliseconds() - 86400 * 1000; // last 24 hrs
|
||||
const ohlcv = await myex.fetchOHLCV('BTC/USDT', '1m', fromTimestamp, 3, { 'whatever': 123 });
|
||||
const length = ohlcv.length;
|
||||
if (length > 0) {
|
||||
const lastPrice = ohlcv[length - 1][4];
|
||||
console.log('Fetched ', length, ' candles for ', myex.id, ': last close ', lastPrice);
|
||||
}
|
||||
else {
|
||||
console.log('No candles have been fetched');
|
||||
}
|
||||
}
|
||||
await example();
|
||||
|
||||
```
|
||||
@@ -0,0 +1,28 @@
|
||||
- [Fetch Okex Futures](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
|
||||
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
|
||||
async function test () {
|
||||
|
||||
const exchange = new ccxt.okex ()
|
||||
await exchange.loadMarkets ()
|
||||
|
||||
for (let symbol in exchange.markets) {
|
||||
|
||||
const market = exchange.markets[symbol]
|
||||
|
||||
if (market['future']) {
|
||||
console.log ('----------------------------------------------------')
|
||||
console.log (symbol, await exchange.fetchTicker (symbol))
|
||||
await ccxt.sleep (exchange.rateLimit)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
test ()
|
||||
|
||||
```
|
||||
@@ -0,0 +1,32 @@
|
||||
- [Fetch Orders](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
|
||||
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
import asTable from 'as-table';
|
||||
import log from 'ololog';
|
||||
import ansicolor from 'ansicolor';
|
||||
|
||||
|
||||
ansicolor.nice
|
||||
|
||||
const exchange = new ccxt.bittrex ({
|
||||
apiKey: "YOUR_API_KEY",
|
||||
secret: "YOUR_SECRET",
|
||||
})
|
||||
|
||||
async function test () {
|
||||
|
||||
const orders = await exchange.fetchOrders ()
|
||||
|
||||
log (asTable (orders.map (order => ccxt.omit (order, [ 'timestamp', 'info' ]))))
|
||||
|
||||
const order = await exchange.fetchOrder (orders[0]['id'])
|
||||
|
||||
log (order)
|
||||
}
|
||||
|
||||
test ()
|
||||
```
|
||||
@@ -0,0 +1,40 @@
|
||||
- [Fetch Ticker From Multiple Exchanges](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
|
||||
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
(async () => {
|
||||
|
||||
const exchanges = [
|
||||
'bittrex',
|
||||
'poloniex',
|
||||
]
|
||||
|
||||
const symbol = 'BTC/USDT'
|
||||
const tickers = {}
|
||||
|
||||
await Promise.all (exchanges.map (exchangeId =>
|
||||
|
||||
new Promise (async (resolve, reject) => {
|
||||
|
||||
const exchange = new ccxt[exchangeId] ()
|
||||
|
||||
while (true) {
|
||||
|
||||
const ticker = await exchange.fetchTicker (symbol)
|
||||
tickers[exchangeId] = ticker
|
||||
|
||||
Object.keys (tickers).map (exchangeId => {
|
||||
const ticker = tickers[exchangeId]
|
||||
console.log (ticker['datetime'], exchangeId, ticker['bid'], ticker['ask'])
|
||||
})
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
))
|
||||
|
||||
}) ()
|
||||
```
|
||||
@@ -0,0 +1,80 @@
|
||||
- [Fetch Ticker Where Available](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
|
||||
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
import asTable from 'as-table';
|
||||
import log from 'ololog';
|
||||
import ansicolor from 'ansicolor';
|
||||
|
||||
|
||||
ansicolor.nice
|
||||
|
||||
let printUsage = function () {
|
||||
log ('Usage: node', process.argv[1], 'symbol'.green)
|
||||
}
|
||||
|
||||
;(async function main () {
|
||||
|
||||
if (process.argv.length > 2) {
|
||||
|
||||
let symbol = process.argv[2].toUpperCase ()
|
||||
|
||||
for (let i = 0; i < ccxt.exchanges.length; i++) {
|
||||
|
||||
let id = ccxt.exchanges[i]
|
||||
|
||||
const exchange = new ccxt[id] ()
|
||||
if (exchange.has.fetchTicker) {
|
||||
|
||||
try {
|
||||
|
||||
await exchange.loadMarkets ()
|
||||
|
||||
if (exchange.symbols.includes (symbol)) {
|
||||
|
||||
log (id.green)
|
||||
|
||||
const ticker = await exchange.fetchTicker (symbol)
|
||||
|
||||
log.dim (ticker)
|
||||
|
||||
if (ticker['baseVolume'] && ticker['quoteVolume']) {
|
||||
|
||||
if (ticker['bid'] > 1) {
|
||||
|
||||
if (ticker['baseVolume'] > ticker['quoteVolume'])
|
||||
log (id.bright, 'baseVolume > quoteVolume ← !'.bright)
|
||||
|
||||
} else {
|
||||
|
||||
if (ticker['baseVolume'] < ticker['quoteVolume'])
|
||||
log (id.bright, 'baseVolume < quoteVolume ← !'.bright)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
log (id.yellow)
|
||||
}
|
||||
|
||||
} catch (e) {
|
||||
|
||||
log.error (id.red, e.toString ().red)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
printUsage ()
|
||||
}
|
||||
|
||||
process.exit ()
|
||||
|
||||
}) ()
|
||||
```
|
||||
@@ -0,0 +1,48 @@
|
||||
- [Gateio Create Batch Order](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
const ccxt = require ('../../ccxt');
|
||||
|
||||
console.log ('CCXT Version:', ccxt.version);
|
||||
|
||||
async function main () {
|
||||
|
||||
const exchange = new ccxt.gateio ({
|
||||
'apiKey': 'YOUR_API_KEY',
|
||||
'secret': 'YOUR_API_SECRET',
|
||||
});
|
||||
await exchange.loadMarkets ();
|
||||
|
||||
const ada = exchange.market ('ADA/USDT');
|
||||
const xrp = exchange.market ('XRP/USDT');
|
||||
|
||||
const orders = await exchange.privateSpotPostBatchOrders (
|
||||
[
|
||||
{
|
||||
text: "t-123456",
|
||||
currency_pair: ada['id'],
|
||||
type: "limit",
|
||||
account: "spot",
|
||||
side: "buy",
|
||||
amount: "3",
|
||||
price: "0.4",
|
||||
},
|
||||
{
|
||||
text: "t-123456",
|
||||
currency_pair: xrp['id'],
|
||||
type: "limit",
|
||||
account: "spot",
|
||||
side: "buy",
|
||||
amount: "3",
|
||||
price: "0.47",
|
||||
},
|
||||
]
|
||||
);
|
||||
|
||||
console.log (orders);
|
||||
|
||||
};
|
||||
|
||||
main ();
|
||||
```
|
||||
@@ -0,0 +1,55 @@
|
||||
- [Gateio Futures](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
|
||||
|
||||
const exchange = new ccxt.gateio ({
|
||||
'apiKey': 'YOUR_API_KEY',
|
||||
'secret': 'YOUR_SECRET_KEY',
|
||||
'options': {
|
||||
'defaultType': 'future',
|
||||
},
|
||||
})
|
||||
|
||||
;(async () => {
|
||||
// exchange.setSandboxMode (true)
|
||||
|
||||
const markets = await exchange.loadMarkets ()
|
||||
|
||||
// exchange.verbose = true // uncomment for debugging purposes if necessary
|
||||
|
||||
// Example 1: Creating a future (market) order
|
||||
try {
|
||||
|
||||
// find a future
|
||||
const futures = []
|
||||
for (const [key, market] of Object.entries(markets)) {
|
||||
if (market['future']) {
|
||||
futures.push(market);
|
||||
}
|
||||
}
|
||||
if (futures.length > 0) {
|
||||
const market = futures[0];
|
||||
const symbol = market['symbol'] // example: BTC/USDT:USDT-220318
|
||||
const type = 'market'
|
||||
const side = 'buy'
|
||||
const amount = 1
|
||||
|
||||
// placing an order
|
||||
const order = await exchange.createOrder (symbol, type, side, amount)
|
||||
console.log (order)
|
||||
|
||||
// fetching open orders
|
||||
const openOrders = await exchange.fetchOpenOrders(symbol)
|
||||
console.log(openOrders)
|
||||
}
|
||||
|
||||
} catch (e) {
|
||||
console.log (e.constructor.name, e.message)
|
||||
}
|
||||
|
||||
}) ()
|
||||
|
||||
```
|
||||
@@ -0,0 +1,55 @@
|
||||
- [Gateio Open Close Contract](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
const ccxt = require ('../../ccxt');
|
||||
|
||||
|
||||
const exchange = new ccxt.gateio ({
|
||||
'apiKey': 'YOUR_API_KEY',
|
||||
'secret': 'YOUR_SECRET',
|
||||
'options': {
|
||||
'defaultType': 'swap',
|
||||
'marginMode': 'cross'
|
||||
},
|
||||
})
|
||||
|
||||
|
||||
;(async () => {
|
||||
|
||||
// exchange.setSandboxMode (true)
|
||||
|
||||
const markets = await exchange.loadMarkets ()
|
||||
|
||||
// exchange.verbose = true // uncomment for debugging purposes if necessary
|
||||
|
||||
// Example: creating and closing a contract
|
||||
let symbol = 'LTC/USDT:USDT'
|
||||
let type = 'market'
|
||||
let side = 'buy'
|
||||
let amount = 1
|
||||
let price = undefined
|
||||
|
||||
try {
|
||||
// fetching current balance
|
||||
const balance = await exchange.fetchBalance()
|
||||
console.log(balance)
|
||||
|
||||
// placing an order / opening contract position
|
||||
const order = await exchange.createOrder (symbol, type, side, amount, price)
|
||||
console.log (order)
|
||||
|
||||
// closing it by issuing an oposite contract
|
||||
// and therefore close our previous position
|
||||
side = 'sell'
|
||||
type = 'market'
|
||||
reduce_only = true
|
||||
params = {'reduce_only': reduce_only}
|
||||
const opositeOrder = await exchange.createOrder (symbol, type, side, amount, price, params)
|
||||
console.log (opositeOrder)
|
||||
} catch (e) {
|
||||
console.log (e.constructor.name, e.message)
|
||||
}
|
||||
}) ()
|
||||
|
||||
```
|
||||
@@ -0,0 +1,80 @@
|
||||
- [Gateio Swaps](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
|
||||
const exchange = new ccxt.gateio ({
|
||||
'apiKey': 'YOUR_API_KEY',
|
||||
'secret': 'YOUR_SECRET_KEY',
|
||||
'options': {
|
||||
'defaultType': 'swap',
|
||||
},
|
||||
})
|
||||
|
||||
;(async () => {
|
||||
// exchange.setSandboxMode (true)
|
||||
|
||||
const markets = await exchange.loadMarkets ()
|
||||
|
||||
exchange.verbose = true // uncomment for debugging purposes if necessary
|
||||
|
||||
// Example 1: Creating and canceling a linear swap (limit) order
|
||||
try {
|
||||
const symbol = 'LTC/USDT:USDT'
|
||||
const type = 'limit'
|
||||
const side = 'buy'
|
||||
const amount = 1
|
||||
const price = 55
|
||||
|
||||
// placing an order
|
||||
const order = await exchange.createOrder (symbol, type, side, amount, price)
|
||||
console.log (order)
|
||||
|
||||
// fetching open orders
|
||||
const openOrders = await exchange.fetchOpenOrders(symbol)
|
||||
console.log(openOrders)
|
||||
|
||||
// canceling an order
|
||||
const cancel = await exchange.cancelOrder (order['id'], symbol)
|
||||
console.log (cancel)
|
||||
} catch (e) {
|
||||
console.log (e.constructor.name, e.message)
|
||||
}
|
||||
|
||||
// Example 2: Creating and canceling a linear swap (stop-limit) order with leverage
|
||||
try {
|
||||
const symbol = 'LTC/USDT:USDT'
|
||||
const type = 'limit'
|
||||
const side = 'buy'
|
||||
const amount = 1
|
||||
const price = 55
|
||||
|
||||
const stopPrice = 130
|
||||
const params = {
|
||||
'stopPrice': stopPrice,
|
||||
}
|
||||
//set leverage
|
||||
const leverage = await exchange.setLeverage(3, symbol);
|
||||
console.log(leverage)
|
||||
|
||||
// placing an order
|
||||
const order = await exchange.createOrder (symbol, type, side, amount, price, params)
|
||||
console.log (order)
|
||||
|
||||
// canceling an order
|
||||
const cancelParams = {
|
||||
isStop: true,
|
||||
};
|
||||
const cancel = await exchange.cancelOrder (order['id'], symbol, cancelParams)
|
||||
console.log (cancel)
|
||||
|
||||
//reset leverage
|
||||
exchange.setLeverage(1, symbol);
|
||||
} catch (e) {
|
||||
console.log (e.constructor.name, e.message)
|
||||
}
|
||||
|
||||
}) ()
|
||||
|
||||
```
|
||||
@@ -0,0 +1,35 @@
|
||||
- [Gdax Fetch Trades Pagination](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
import ololog from 'ololog';
|
||||
|
||||
const { noLocate } = ololog;
|
||||
const log = noLocate;
|
||||
|
||||
const exchange = new ccxt.coinbasepro ()
|
||||
|
||||
;(async () => {
|
||||
|
||||
const symbol = 'ETH/BTC'
|
||||
const params = {}
|
||||
await exchange.loadMarkets ()
|
||||
while (true) {
|
||||
const trades = await exchange.fetchTrades (symbol, undefined, undefined, params)
|
||||
if (trades.length) {
|
||||
const firstTrade = trades[0]
|
||||
const lastTrade = trades[trades.length - 1]
|
||||
log.yellow ('Fetched', trades.length, symbol, 'trades from', firstTrade['datetime'], 'to', lastTrade['datetime'])
|
||||
if ('Cb-After' in exchange.last_response_headers) {
|
||||
params['after'] = exchange.last_response_headers['Cb-After'];
|
||||
}
|
||||
} else {
|
||||
log.green ('Done.')
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}) ()
|
||||
|
||||
```
|
||||
@@ -0,0 +1,119 @@
|
||||
- [Hibachi Example](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
import { hibachi } from '../../js/ccxt.js';
|
||||
import fs from 'fs';
|
||||
/*
|
||||
In order to run the examples, you need to setup keys.local.json file like this:
|
||||
```
|
||||
{
|
||||
"hibachi": {
|
||||
"accountId": 111,
|
||||
"apiKey": "1111111111111111111111111111111111111111111=",
|
||||
"privateKey": "0x1111111111111111111111111111111111111111111111111111111111111111",
|
||||
"publicKey": "0x11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111",
|
||||
"withdrawAddress": "0x1111111111111111111111111111111111111111"
|
||||
}
|
||||
}
|
||||
```
|
||||
You can get the accountId, apiKey and privateKey from Hibachi App by creating an API key
|
||||
After that you can view the API key, it will show the publicKey (only for trustless account, you can ignore it for exchange managed account)
|
||||
Note: if you are using exchange managed account, the privateKey's length will be 44 instead
|
||||
The withdrawAddress can be any ethereum wallet address, that is used to receive funds for withdraw tests
|
||||
*/
|
||||
async function example() {
|
||||
const keys = JSON.parse(fs.readFileSync('keys.local.json', 'utf-8'));
|
||||
const exchange = new hibachi(keys.hibachi);
|
||||
exchange.verbose = true;
|
||||
const markets = await exchange.fetchMarkets();
|
||||
console.log('fetchMarkets', markets.length, markets[0]);
|
||||
const currencies = await exchange.fetchCurrencies();
|
||||
console.dir(currencies, { depth: null, colors: true });
|
||||
const trades = await exchange.fetchTrades("BTC/USDT:USDT");
|
||||
console.log('fetchTrades', trades.length, trades[0]);
|
||||
const tenMinutes = 10 * 60 * 1000;
|
||||
const until = Date.now();
|
||||
const since = until - tenMinutes;
|
||||
const ohlcv = await exchange.fetchOHLCV('BTC/USDT:USDT', '5min', since, 100, { until });
|
||||
console.log('fetchOHLCV', ohlcv.length, ohlcv[0]);
|
||||
const balance = await exchange.fetchBalance();
|
||||
console.dir(balance, { depth: null, colors: true });
|
||||
const ticker = await exchange.fetchTicker('BTC/USDT:USDT');
|
||||
console.log('fetchTicker', ticker);
|
||||
// createOrder, editOrder and cancelOrder
|
||||
const order1 = await exchange.createOrder('BTC/USDT:USDT', 'market', 'buy', 0.00002);
|
||||
const order2 = await exchange.createOrder('BTC/USDT:USDT', 'market', 'sell', 0.00002);
|
||||
console.log('create market order', order1.id, order2.id);
|
||||
const order3 = await exchange.createOrder('ETH/USDT:USDT', 'limit', 'buy', 1.234, 1.234);
|
||||
const order4 = await exchange.editOrder(order3.id, 'ETH/USDT:USDT', 'limit', 'buy', 0.987, 1.123);
|
||||
const order5 = await exchange.cancelOrder(order3.id);
|
||||
console.log('create, edit and cancel limit order', order3.id, order4.id, order5.id);
|
||||
// advanced order parameters
|
||||
const postOnlyOrder = await exchange.createOrder('BTC/USDT:USDT', 'limit', 'buy', 2.0, 2.0, { 'timeInForce': 'PO' });
|
||||
await exchange.cancelOrder(postOnlyOrder.id);
|
||||
const iocOrder = await exchange.createOrder('BTC/USDT:USDT', 'limit', 'buy', 2.0, 2.0, { 'timeInForce': 'IOC' });
|
||||
await exchange.createOrder('BTC/USDT:USDT', 'market', 'buy', 0.00002);
|
||||
const reduceOnlyOrder = await exchange.createOrder('BTC/USDT:USDT', 'market', 'sell', 0.00002, undefined, { 'reduceOnly': true });
|
||||
const triggerOrder = await exchange.createOrder('BTC/USDT:USDT', 'limit', 'sell', 2.0, 2.0, { 'triggerPrice': '2.0' });
|
||||
await exchange.cancelOrder(triggerOrder.id);
|
||||
console.log('postOnly, IOC, reduceOnly, trigger order', postOnlyOrder.id, iocOrder.id, reduceOnlyOrder.id, triggerOrder.id);
|
||||
const order1_info = await exchange.fetchOrder(order1.id, 'BTC/USDT:USDT');
|
||||
console.log('fetchOrder', order1_info);
|
||||
const orderbook = await exchange.fetchOrderBook('BTC/USDT:USDT');
|
||||
console.log('fetchOrderBook', orderbook);
|
||||
const withdrawResponse = await exchange.withdraw('USDT', 0.02, keys.hibachi.withdrawAddress);
|
||||
console.log(withdrawResponse);
|
||||
const myTrades = await exchange.fetchMyTrades('BTC/USDT:USDT', undefined, 1);
|
||||
console.log('fetchMyTrades', myTrades);
|
||||
const tradingFees = await exchange.fetchTradingFees();
|
||||
console.log('fetchTradingFees', tradingFees);
|
||||
const openOrders = await exchange.fetchOpenOrders();
|
||||
console.log('fetchOpenOrders', openOrders);
|
||||
const openOrdersWithLimit = await exchange.fetchOpenOrders(undefined, undefined, 1);
|
||||
console.log('fetchOpenOrdersWithLimit', openOrdersWithLimit);
|
||||
const openOrdersBTC = await exchange.fetchOpenOrders('BTC/USDT:USDT');
|
||||
console.log('fetchOpenOrdersBTC', openOrdersBTC);
|
||||
const openOrdersSince = await exchange.fetchOpenOrders(undefined, 1752552000000); // 7/15/2025 00:00 UTC
|
||||
console.log('fetchOpenOrdersSince', openOrdersSince);
|
||||
if (keys.hibachi.publicKey !== undefined) {
|
||||
const depositAddress = await exchange.fetchDepositAddress('USDT', { 'publicKey': keys.hibachi.publicKey });
|
||||
console.log('fetchDepositAddress', depositAddress);
|
||||
}
|
||||
const ledger = await exchange.fetchLedger('USDT', undefined, 2);
|
||||
console.log('fetchLedger', ledger);
|
||||
const deposits = await exchange.fetchDeposits();
|
||||
console.log('fetchDeposits', deposits);
|
||||
const withdrawals = await exchange.fetchWithdrawals();
|
||||
console.log('fetchWithdrawals', withdrawals);
|
||||
const timestamp = await exchange.fetchTime();
|
||||
console.log('fetchTime', timestamp);
|
||||
const openInterest = await exchange.fetchOpenInterest('BTC/USDT:USDT');
|
||||
console.log('fetchOpenInterest', openInterest);
|
||||
const fundingRate = await exchange.fetchFundingRate('BTC/USDT:USDT');
|
||||
console.log('fetchFundingRate', fundingRate);
|
||||
const fundingRateHistory = await exchange.fetchFundingRateHistory('BTC/USDT:USDT', undefined, 2);
|
||||
console.log('fetchFundingRateHistory', fundingRateHistory);
|
||||
// Batch orders
|
||||
const createOrders = await exchange.createOrders([
|
||||
{ 'symbol': 'ETH/USDT:USDT', 'type': 'limit', 'side': 'buy', 'amount': 1.234, 'price': 1.234 },
|
||||
{ 'symbol': 'BTC/USDT:USDT', 'type': 'limit', 'side': 'buy', 'amount': 1.001, 'price': 1.001 },
|
||||
{ 'symbol': 'ETH/USDT:USDT', 'type': 'limit', 'side': 'buy', 'amount': 1.002, 'price': 1.002 },
|
||||
{ 'symbol': 'ETH/USDT:USDT', 'type': 'limit', 'side': 'buy', 'amount': 1.003, 'price': 1.003 },
|
||||
]);
|
||||
console.log('createOrders', createOrders);
|
||||
const editOrders = await exchange.editOrders([
|
||||
// @ts-expect-error OrderRequest lacks `id` but we expects it for editing
|
||||
{ 'id': createOrders[0].id, 'symbol': 'ETH/USDT:USDT', 'type': 'limit', 'side': 'buy', 'amount': 1.111, 'price': 0.999 },
|
||||
// @ts-expect-error OrderRequest lacks `id` but we expects it for editing
|
||||
{ 'id': createOrders[1].id, 'symbol': 'BTC/USDT:USDT', 'type': 'limit', 'side': 'buy', 'amount': 1.112, 'price': 0.998 },
|
||||
]);
|
||||
console.log('editOrders', editOrders);
|
||||
const cancelOrders = await exchange.cancelOrders([createOrders[0].id, createOrders[1].id]);
|
||||
console.log('cancelOrders', cancelOrders);
|
||||
const cancelAll = await exchange.cancelAllOrders('ETH/USDT:USDT');
|
||||
console.log(cancelAll);
|
||||
}
|
||||
example();
|
||||
|
||||
```
|
||||
@@ -0,0 +1,66 @@
|
||||
- [Hitbtc2 Withdraw](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
|
||||
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
import asTable from 'as-table';
|
||||
import ololog from 'ololog';
|
||||
const log = ololog.configure ({ locate: false })
|
||||
|
||||
require ('ansicolor').nice
|
||||
|
||||
const getPositiveAccounts = function (balance) {
|
||||
const result = {}
|
||||
Object.keys (balance)
|
||||
.filter (currency => balance[currency] && (balance[currency] > 0))
|
||||
.forEach (currency => {
|
||||
result[currency] = balance[currency]
|
||||
})
|
||||
return result
|
||||
}
|
||||
|
||||
;(async () => {
|
||||
|
||||
// instantiate the exchange
|
||||
let exchange = new ccxt.hitbtc2 ({
|
||||
"apiKey": "YOUR_API_KEY",
|
||||
"secret": "YOUR_SECRET",
|
||||
})
|
||||
|
||||
try {
|
||||
|
||||
let tradingBalance = await exchange.fetchBalance ()
|
||||
let accountBalance = await exchange.fetchBalance ({ type: 'account' })
|
||||
|
||||
log.cyan ('Trading balance:', getPositiveAccounts (tradingBalance.total))
|
||||
log.magenta ('Account balance:', getPositiveAccounts (accountBalance.total))
|
||||
|
||||
// withdraw
|
||||
let withdraw = await exchange.withdraw ('ETH', 0.01, '0x811DCfeb6dC0b9ed825808B6B060Ca469b83fB81')
|
||||
|
||||
// output the result
|
||||
log (exchange.name.green, 'withdraw', withdraw)
|
||||
|
||||
} catch (e) {
|
||||
|
||||
if (e instanceof ccxt.DDoSProtection || e.message.includes ('ECONNRESET')) {
|
||||
log.bright.yellow ('[DDoS Protection] ' + e.message)
|
||||
} else if (e instanceof ccxt.RequestTimeout) {
|
||||
log.bright.yellow ('[Request Timeout] ' + e.message)
|
||||
} else if (e instanceof ccxt.AuthenticationError) {
|
||||
log.bright.yellow ('[Authentication Error] ' + e.message)
|
||||
} else if (e instanceof ccxt.ExchangeNotAvailable) {
|
||||
log.bright.yellow ('[Exchange Not Available Error] ' + e.message)
|
||||
} else if (e instanceof ccxt.ExchangeError) {
|
||||
log.bright.yellow ('[Exchange Error] ' + e.message)
|
||||
} else if (e instanceof ccxt.NetworkError) {
|
||||
log.bright.yellow ('[Network Error] ' + e.message)
|
||||
} else {
|
||||
throw e
|
||||
}
|
||||
}
|
||||
|
||||
}) ()
|
||||
```
|
||||
@@ -0,0 +1,16 @@
|
||||
- [How To Import One Exchange Esm](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
import { binance } from '../../js/ccxt.js';
|
||||
async function example() {
|
||||
const exchange = new binance({});
|
||||
const ob = await exchange.fetchOrderBook('BTC/USDT', 3);
|
||||
const asks = ob['asks'];
|
||||
const bids = ob['bids'];
|
||||
console.log(asks);
|
||||
console.log(bids);
|
||||
}
|
||||
example();
|
||||
|
||||
```
|
||||
@@ -0,0 +1,77 @@
|
||||
- [Huobi Futures](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
|
||||
const exchange = new ccxt.huobi ({
|
||||
'apiKey': 'YOUR_API_KEY',
|
||||
'secret': 'YOUR_SECRET',
|
||||
'options': {
|
||||
'defaultType': 'future',
|
||||
},
|
||||
})
|
||||
|
||||
;(async () => {
|
||||
const markets = await exchange.loadMarkets ()
|
||||
|
||||
// exchange.verbose = true // uncomment for debugging purposes if necessary
|
||||
|
||||
// creating and canceling a linear future (limit) order
|
||||
let symbol = 'ETH/USDT:USDT-220121' // the last segment is the date of expiration (can be next week, next quarter, ...) adjust it accordingly
|
||||
let type = 'limit'
|
||||
let side = 'buy'
|
||||
let offset= 'open'
|
||||
let leverage = 1
|
||||
let amount = 1
|
||||
let price = 1
|
||||
let params = {
|
||||
'offset': offset,
|
||||
'lever_rate': leverage,
|
||||
}
|
||||
|
||||
try {
|
||||
// fetching current balance
|
||||
const balance = await exchange.fetchBalance()
|
||||
// console.log(balance)
|
||||
|
||||
// placing an order
|
||||
const order = await exchange.createOrder (symbol, type, side, amount, price, params)
|
||||
console.log (order)
|
||||
|
||||
// fetching open orders
|
||||
const openOrders = await exchange.fetchOpenOrders(symbol)
|
||||
console.log(openOrders)
|
||||
|
||||
// canceling an order
|
||||
const cancel = await exchange.cancelOrder (order['id'], symbol)
|
||||
console.log (cancel)
|
||||
} catch (e) {
|
||||
console.log (e.constructor.name, e.message)
|
||||
}
|
||||
|
||||
// creating and canceling a inverse future (limit) order
|
||||
symbol = 'ADA/USD:ADA-220121' // the last segment is the date of expiration (can be next week, next quarter, ...) adjust it accordingly
|
||||
type = 'limit'
|
||||
side = 'buy'
|
||||
offset= 'open'
|
||||
leverage = 1
|
||||
amount = 1
|
||||
price = 1 // 1 contract = 10 ADA = 10 usd in this case
|
||||
params = {
|
||||
'offset': offset,
|
||||
'lever_rate': leverage,
|
||||
}
|
||||
|
||||
try {
|
||||
const order = await exchange.createOrder (symbol, type, side, amount, price, params)
|
||||
console.log (order)
|
||||
const cancel = await exchange.cancelOrder (order['id'], symbol)
|
||||
console.log (cancel)
|
||||
} catch (e) {
|
||||
console.log (e.constructor.name, e.message)
|
||||
}
|
||||
|
||||
}) ()
|
||||
|
||||
```
|
||||
@@ -0,0 +1,69 @@
|
||||
- [Huobi Open Close Contract](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
|
||||
const exchange = new ccxt.huobi ({
|
||||
'apiKey': 'YOUR_API_KEY',
|
||||
'secret': 'YOUR_SECRET',
|
||||
'options': {
|
||||
'defaultType': 'swap',
|
||||
'marginMode': 'cross'
|
||||
},
|
||||
})
|
||||
|
||||
;(async () => {
|
||||
const markets = await exchange.loadMarkets ()
|
||||
|
||||
// exchange.verbose = true // uncomment for debugging purposes if necessary
|
||||
|
||||
// Example: creating and closing a contract
|
||||
let symbol = 'ADA/USDT:USDT' // market positions for contracts not available
|
||||
let type = 'limit'
|
||||
let side = 'buy'
|
||||
let offset= 'open'
|
||||
let leverage = 1
|
||||
let amount = 1
|
||||
let price = 1
|
||||
let clientOrderId = 6;
|
||||
let params = {
|
||||
'offset': offset,
|
||||
'lever_rate': leverage,
|
||||
'client_order_id': clientOrderId
|
||||
}
|
||||
|
||||
try {
|
||||
// fetching current balance
|
||||
const balance = await exchange.fetchBalance()
|
||||
console.log(balance)
|
||||
|
||||
// placing an order
|
||||
const order = await exchange.createOrder (symbol, type, side, amount, price, params)
|
||||
console.log (order)
|
||||
|
||||
// fetching position
|
||||
const position = await exchange.fetchPosition(symbol)
|
||||
console.log(position)
|
||||
|
||||
|
||||
// closing it by issuing an oposite contract
|
||||
// warning: since we can only place limit orders
|
||||
// it might take a while (depending on the price we choose and market fluctuations)
|
||||
// to the order be fulfilled
|
||||
// and therefore close our previous position
|
||||
side = 'sell'
|
||||
type = 'limit'
|
||||
offset = 'close'
|
||||
reduce_only = 1 // 1 : yes, 0: no
|
||||
clientOrderId = 9
|
||||
price = 1.147 // adjust this accordingly
|
||||
params = {'offset': offset, 'reduce_only': reduce_only, 'client_order_id': clientOrderId}
|
||||
const opositeOrder = await exchange.createOrder (symbol, type, side, amount, price, params)
|
||||
console.log (opositeOrder)
|
||||
} catch (e) {
|
||||
console.log (e.constructor.name, e.message)
|
||||
}
|
||||
}) ()
|
||||
|
||||
```
|
||||
@@ -0,0 +1,76 @@
|
||||
- [Huobi Swaps](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
|
||||
const exchange = new ccxt.huobi ({
|
||||
'apiKey': 'YOUR_API_KEY',
|
||||
'secret': 'YOUR_SECRET_KEY',
|
||||
'options': {
|
||||
'defaultType': 'swap',
|
||||
},
|
||||
})
|
||||
|
||||
;(async () => {
|
||||
const markets = await exchange.loadMarkets ()
|
||||
|
||||
// exchange.verbose = true // uncomment for debugging purposes if necessary
|
||||
|
||||
// creating and canceling a linear swap (limit) order
|
||||
let symbol = 'ADA/USDT:USDT'
|
||||
let type = 'limit'
|
||||
let side = 'buy'
|
||||
let offset= 'open'
|
||||
let leverage = 1
|
||||
let amount = 1
|
||||
let price = 1 // 1 contract = 10 ADA = 10 usd in this case
|
||||
let params = {
|
||||
'offset': offset,
|
||||
'lever_rate': leverage,
|
||||
}
|
||||
|
||||
try {
|
||||
// fetching current balance
|
||||
const balance = await exchange.fetchBalance()
|
||||
// console.log(balance)
|
||||
|
||||
// placing an order
|
||||
const order = await exchange.createOrder (symbol, type, side, amount, price, params)
|
||||
console.log (order)
|
||||
|
||||
// fetching open orders
|
||||
const openOrders = await exchange.fetchOpenOrders(symbol)
|
||||
console.log(openOrders)
|
||||
|
||||
// canceling an order
|
||||
const cancel = await exchange.cancelOrder (order['id'], symbol)
|
||||
console.log (cancel)
|
||||
} catch (e) {
|
||||
console.log (e.constructor.name, e.message)
|
||||
}
|
||||
|
||||
// creating and canceling an inverse swap (limit) order
|
||||
symbol = 'ADA/USD:ADA'
|
||||
type = 'limit'
|
||||
side = 'buy'
|
||||
offset = 'open'
|
||||
leverage = 1
|
||||
amount = 1
|
||||
price = 1 // 1 contract = 10 ADA = 10 usd in this case
|
||||
params = {
|
||||
'offset': offset,
|
||||
'lever_rate': leverage,
|
||||
}
|
||||
|
||||
try {
|
||||
const order = await exchange.createOrder (symbol, type, side, amount, price, params)
|
||||
console.log (order)
|
||||
const cancel = await exchange.cancelOrder (order['id'], symbol)
|
||||
console.log (cancel)
|
||||
} catch (e) {
|
||||
console.log (e.constructor.name, e.message)
|
||||
}
|
||||
}) ()
|
||||
|
||||
```
|
||||
@@ -0,0 +1,103 @@
|
||||
- [Huobipro Market Buy Sell Fetch Trading Limits](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
import ololog from 'ololog'
|
||||
|
||||
const log = ololog.configure .unlimited.handleNodeErrors (),
|
||||
{ NotSupported } = ccxt,
|
||||
enableRateLimit = true,
|
||||
symbol = 'ADA/BTC',
|
||||
side = 'buy',
|
||||
// set createMarketBuyOrderRequiresPrice to true or false to see the difference
|
||||
type = 'market',
|
||||
// default is true
|
||||
createMarketBuyOrderRequiresPrice = true,
|
||||
amount = 191.03,
|
||||
price = 0.000011,
|
||||
options = { createMarketBuyOrderRequiresPrice },
|
||||
exchange = new ccxt.huobipro ({ enableRateLimit, options });
|
||||
|
||||
// This is an example that demonstrates the issues discussed here:
|
||||
// https://github.com/ccxt/ccxt/issues/564
|
||||
// https://github.com/ccxt/ccxt/issues/3427
|
||||
// https://github.com/ccxt/ccxt/issues/3460
|
||||
// https://github.com/ccxt/ccxt/issues/4799
|
||||
|
||||
log.green ('CCXT', ccxt.version)
|
||||
|
||||
;(async () => {
|
||||
|
||||
// preload them first
|
||||
await exchange.loadMarkets ()
|
||||
|
||||
// huobipro has this
|
||||
if (!exchange.has['fetchTradingLimits']) {
|
||||
throw new NotSupported (exchange.id + ' does not have fetchTradingLimits() yet, make sure your version of CCXT is up to date');
|
||||
}
|
||||
|
||||
// In this particular case it requires an array of symbols
|
||||
// otherwise it will load all of them one by one.
|
||||
// Loading all limits without specifying
|
||||
// the array of symbols might take a lot of time.
|
||||
|
||||
// The array of symbols will contain just one symbol of interest.
|
||||
const arrayOfSymbols = [ symbol ]
|
||||
|
||||
const allLimits = await exchange.fetchTradingLimits (arrayOfSymbols)
|
||||
|
||||
// { 'ADA/BTC': { info: { symbol: "adabtc",
|
||||
// 'buy-limit-must-less-than': 1.1,
|
||||
// 'sell-limit-must-greater-than': 0.9,
|
||||
// 'limit-order-must-greater-than': 0.1,
|
||||
// 'limit-order-must-less-than': 5000000,
|
||||
// 'market-buy-order-must-greater-than': 0.0001,
|
||||
// 'market-buy-order-must-less-than': 100,
|
||||
// 'market-sell-order-must-greater-than': 0.1,
|
||||
// 'market-sell-order-must-less-than': 500000,
|
||||
// 'limit-order-before-open-greater-than': 999999999,
|
||||
// 'limit-order-before-open-less-than': 0,
|
||||
// 'circuit-break-when-greater-than': 10000,
|
||||
// 'circuit-break-when-less-than': 10,
|
||||
// 'market-sell-order-rate-must-less-than': 0.1,
|
||||
// 'market-buy-order-rate-must-less-than': 0.1 },
|
||||
// limits: { amount: { min: 0.1, max: 5000000 } } } }
|
||||
|
||||
const limits = allLimits[symbol]
|
||||
log.yellow (symbol, 'limits:')
|
||||
log.yellow (limits)
|
||||
|
||||
// To make things a bit more complicated huobipro specifies
|
||||
// different minimums for market and limit orders
|
||||
// and different minimums for buy/sell directions
|
||||
// therefore we have to work with it in an exchange-specific way
|
||||
// using the 'info' field from the response – that is
|
||||
// until this aspect is completely unified in ccxt.
|
||||
|
||||
const info = limits['info']
|
||||
const typeSide = type + '-' + side
|
||||
|
||||
const min = info[typeSide + '-order-must-greater-than']
|
||||
const max = info[typeSide + '-order-must-less-than']
|
||||
|
||||
// huobipro requires the amount in quote currency for market sell orders
|
||||
// huobipro requires the cost in quote currency for market buy orders
|
||||
// cost = amount * price
|
||||
|
||||
const cost = createMarketBuyOrderRequiresPrice ? (amount * price) : amount
|
||||
|
||||
let color = 'red'
|
||||
|
||||
if ((min !== undefined) && (cost < min)) {
|
||||
log[color] ('The cost is below minimum:', cost, '<', min)
|
||||
} else if ((max !== undefined) && (cost > max)) {
|
||||
log[color] ('The cost is above maximum:', cost, '>', max)
|
||||
} else {
|
||||
color = 'green'
|
||||
}
|
||||
|
||||
log[color] ({ min, max, cost })
|
||||
|
||||
}) ()
|
||||
```
|
||||
@@ -0,0 +1,24 @@
|
||||
- [Hybridcjsexample](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
|
||||
const ccxt = require('ccxt');
|
||||
|
||||
console.log('--------------------------------------------')
|
||||
console.log('Yey importing ccxt as a cjs module!!!!!')
|
||||
console.log('Version:', ccxt.version)
|
||||
console.log('--------------------------------------------')
|
||||
|
||||
const exchange = new ccxt.huobi ({
|
||||
'apiKey': 'YOUR_API_KEY',
|
||||
'secret': 'YOUR_SECRET_KEY',
|
||||
'options': {
|
||||
'defaultType': 'swap',
|
||||
},
|
||||
})
|
||||
;(async () => {
|
||||
const result = await exchange.fetchBalance();
|
||||
console.log(result)
|
||||
}) ()
|
||||
```
|
||||
@@ -0,0 +1,24 @@
|
||||
- [Hybridesmexample](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
import {version, huobi} from 'ccxt';
|
||||
|
||||
console.log('--------------------------------------------')
|
||||
console.log('Yey importing ccxt as an ESM module!!!!!')
|
||||
console.log('Version:', version)
|
||||
console.log('--------------------------------------------')
|
||||
|
||||
const exchange = new huobi ({
|
||||
'apiKey': 'YOUR_API_KEY',
|
||||
'secret': 'YOUR_SECRET_KEY',
|
||||
'options': {
|
||||
'defaultType': 'swap',
|
||||
},
|
||||
})
|
||||
|
||||
;(async () => {
|
||||
const result = await exchange.fetchBalance();
|
||||
console.log(result)
|
||||
}) ()
|
||||
```
|
||||
@@ -0,0 +1,19 @@
|
||||
- [Idex Fetch Balance](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
|
||||
const idex = ccxt.idex ({
|
||||
'apiKey': 'YOUR_IDEX_API_KEY',
|
||||
'secret': 'YOUR_IDEX_SECRET',
|
||||
'walletAddress': '0xYOUR_ETHEREUM_WALLET_ADDRESS',
|
||||
'privateKey': '0xYOUR_ETHEREUM_PRIVATE_KEY',
|
||||
'verbose': 0,
|
||||
})
|
||||
|
||||
;(async () => {
|
||||
console.log (await idex.fetchBalance ())
|
||||
}) ()
|
||||
|
||||
```
|
||||
@@ -0,0 +1,52 @@
|
||||
- [Instantiate All At Once](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
|
||||
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
|
||||
async function test () {
|
||||
|
||||
let exchanges = {
|
||||
"bittrex": {
|
||||
"apiKey": "YOUR_API_KEY",
|
||||
"secret": "YOUR_SECRET",
|
||||
},
|
||||
"bitfinex": {
|
||||
"apiKey": "YOUR_API_KEY",
|
||||
"secret": "YOUR_SECRET"
|
||||
},
|
||||
}
|
||||
|
||||
let ids = ccxt.exchanges.filter (id => id in exchanges)
|
||||
|
||||
await Promise.all (ids.map (async id => {
|
||||
|
||||
console.log (exchanges[id])
|
||||
|
||||
// instantiate the exchange
|
||||
let exchange = new ccxt[id] (exchanges[id])
|
||||
console.log (exchange.id, exchange.apiKey)
|
||||
exchanges[id] = exchange
|
||||
|
||||
// load markets
|
||||
await exchange.loadMarkets ()
|
||||
console.log (exchange.id, 'loaded')
|
||||
|
||||
// check the balance
|
||||
if (exchange.apiKey) {
|
||||
let balance = await exchange.fetchBalance ()
|
||||
console.log (exchange.id, balance)
|
||||
}
|
||||
|
||||
return exchange
|
||||
}))
|
||||
|
||||
// when all of them are ready, do your other things
|
||||
console.log ('Loaded exchanges:', ids.join (', '))
|
||||
}
|
||||
|
||||
test ()
|
||||
|
||||
```
|
||||
@@ -0,0 +1,37 @@
|
||||
- [Instantiate All From Json](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
|
||||
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
import settings from './credentials.json';
|
||||
|
||||
async function test () {
|
||||
|
||||
const ids = ccxt.exchanges.filter (id => id in settings)
|
||||
|
||||
const exchanges = ccxt.indexBy (await Promise.all (ids.map (async id => {
|
||||
|
||||
// instantiate the exchange
|
||||
let exchange = new ccxt[id] (settings[id])
|
||||
|
||||
// load markets
|
||||
await exchange.loadMarkets ()
|
||||
|
||||
// check the balance
|
||||
if (exchange.apiKey) {
|
||||
let balance = await exchange.fetchBalance ()
|
||||
console.log (exchange.id, balance['free'])
|
||||
}
|
||||
|
||||
return exchange
|
||||
})), 'id')
|
||||
|
||||
// when all of them are ready, do your other things
|
||||
console.log ('Loaded exchanges:', Object.keys (exchanges).join (', '))
|
||||
}
|
||||
|
||||
test ()
|
||||
|
||||
```
|
||||
@@ -0,0 +1,60 @@
|
||||
- [Kraken Create And Close Position](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
// @ts-nocheck
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
// AUTO-TRANSPILE //
|
||||
console.log('CCXT Version:', ccxt.version);
|
||||
// ------------------------------------------------------------------------------
|
||||
async function example() {
|
||||
const exchange = new ccxt.kraken({
|
||||
"apiKey": "YOUR_API_KEY",
|
||||
"secret": "YOUR_API_SECRET",
|
||||
});
|
||||
const symbol = 'UNI/USD';
|
||||
let side = 'buy'; // set it to 'buy' for a long position, 'sell' for a short position
|
||||
const order_type = 'market'; // set it to 'market' or 'limit'
|
||||
const amount = 1;
|
||||
const leverage = 2;
|
||||
await exchange.loadMarkets();
|
||||
const market = exchange.market(symbol);
|
||||
// if order_type is 'market', then price is not needed
|
||||
let price = undefined;
|
||||
// if order_type is 'limit', then set a price at your desired level
|
||||
// you can fetch the ticker and update price
|
||||
// const ticker = await exchange.fetchTicker (symbol);
|
||||
// const last_price = ticker['last'];
|
||||
// const ask_price = ticker['ask'];
|
||||
// const bid_price = ticker['bid'];
|
||||
// if (order_type === 'limit') {
|
||||
// price = (side === 'buy') ? bid_price * 0.95 : ask_price * 1.05; // i.e. 5% from current price
|
||||
// }
|
||||
const params = {
|
||||
'leverage': leverage,
|
||||
};
|
||||
// log
|
||||
console.log('Going to open a position', 'for', amount, 'worth', amount, market['base'], '~', market['settle'], 'using', side, order_type, 'order (', (order_type === 'limit' ? exchange.priceToPrecision(symbol, price) : ''), '), using the following params:');
|
||||
console.log(params);
|
||||
console.log('-----------------------------------------------------------------------');
|
||||
// exchange.verbose = True // uncomment for debugging purposes if necessary
|
||||
try {
|
||||
const created_order = await exchange.createOrder(symbol, order_type, side, amount, price, params);
|
||||
console.log("Created an order", created_order);
|
||||
// Fetch all your closed orders for this symbol (because we used market order)
|
||||
// - use 'fetchClosedOrders' or 'fetchOrders' and filter with 'closed' status
|
||||
const all_closed_orders = await exchange.fetchClosedOrders(symbol);
|
||||
console.log("Fetched all your closed orders for this symbol", all_closed_orders);
|
||||
const all_open_positions = await exchange.fetchPositions(symbol);
|
||||
console.log("Fetched all your positions for this symbol", all_open_positions);
|
||||
// To close a position:
|
||||
// - long position (buy), you can create a sell order: exchange.createOrder (symbol, order_type, 'sell', amount, price, params);
|
||||
// - short position (sell), you can create a buy order: exchange.createOrder (symbol, order_type, 'buy', amount, price, params);
|
||||
}
|
||||
catch (e) {
|
||||
console.log(e.toString());
|
||||
}
|
||||
}
|
||||
await example();
|
||||
|
||||
```
|
||||
@@ -0,0 +1,39 @@
|
||||
- [Kraken Fetch Order Trades](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
|
||||
(async () => {
|
||||
|
||||
const exchange = new ccxt.kraken ({
|
||||
'apiKey': 'YOUR_API_KEY',
|
||||
'secret': 'YOUR_SECRET',
|
||||
// 'verbose': true,
|
||||
})
|
||||
|
||||
const orders = await exchange.fetchClosedOrders ();
|
||||
|
||||
for (let i = 0; i < orders.length; i++) {
|
||||
const order = await exchange.fetchOrder (orders[i]['id']);
|
||||
const trades = await exchange.fetchOrderTrades (order['id'], undefined, undefined, undefined, order);
|
||||
console.log (trades);
|
||||
}
|
||||
|
||||
//
|
||||
// alternatively:
|
||||
//
|
||||
// const params = {
|
||||
// 'trades': [
|
||||
// 'TT5UC3-GOIRW-6AZZ6R',
|
||||
// 'TIY6G4-LKLAI-Y3GD4A',
|
||||
// 'T57FVC-OB4LN-Z55WUL',
|
||||
// 'TIMIRG-WUNNE-RRJ6GT',
|
||||
// ]
|
||||
// }
|
||||
//
|
||||
// const trades = await exchange.fetchOrderTrades (order['id'], undefined, undefined, undefined, params);
|
||||
|
||||
}) ()
|
||||
|
||||
```
|
||||
@@ -0,0 +1,94 @@
|
||||
- [Kraken Margin Trading](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
|
||||
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
|
||||
console.log ('CCXT Version:', ccxt.version)
|
||||
|
||||
async function main () {
|
||||
|
||||
const exchange = new ccxt.kraken ({
|
||||
"apiKey": "YOUR_API_KEY",
|
||||
"secret": "YOUR_SECRET",
|
||||
})
|
||||
|
||||
console.log ('-----------------------------------------------------------')
|
||||
|
||||
console.log ('Loading markets...')
|
||||
const markets = await exchange.loadMarkets ()
|
||||
console.log ('Markets loaded')
|
||||
|
||||
// exchange.verbose = true // uncomment for debugging purposes
|
||||
|
||||
try {
|
||||
|
||||
const symbol = 'ETH/USDT'
|
||||
, market = exchange.market (symbol)
|
||||
, { base, quote } = market
|
||||
, type = 'market'
|
||||
, amount = market['limits']['amount']['min']
|
||||
, price = undefined
|
||||
, params = {
|
||||
'leverage': 2,
|
||||
}
|
||||
|
||||
console.log ('-----------------------------------------------------------')
|
||||
|
||||
// https://www.kraken.com/en-us/features/api#add-standard-order
|
||||
|
||||
console.log ('Placing order...')
|
||||
let order = await exchange.createOrder (symbol, type, 'buy', amount, price, params)
|
||||
console.log ('Order placed:')
|
||||
console.log (order)
|
||||
|
||||
console.log ('-----------------------------------------------------------')
|
||||
|
||||
// https://www.kraken.com/en-us/features/api#get-open-positions
|
||||
|
||||
console.log ('Fetching open positions...')
|
||||
const positionsParams = { 'docalcs': true }
|
||||
let openPositions = await exchange.fetchPositions (positionsParams)
|
||||
console.log ('Current positions:')
|
||||
console.log (openPositions)
|
||||
|
||||
console.log ('-----------------------------------------------------------')
|
||||
|
||||
console.log ('Fetching balance...')
|
||||
let balance = await exchange.fetchTotalBalance ()
|
||||
console.log ('Fetched balance:')
|
||||
console.log (base, balance[base], '(base)')
|
||||
console.log (quote, balance[quote], '(quote)')
|
||||
|
||||
console.log ('-----------------------------------------------------------')
|
||||
|
||||
console.log ('Closing the position...')
|
||||
order = await exchange.createOrder (symbol, type, 'sell', amount, price, params)
|
||||
console.log ('Got a response:')
|
||||
console.log (order)
|
||||
|
||||
console.log ('-----------------------------------------------------------')
|
||||
|
||||
console.log ('Fetching open positions again...')
|
||||
openPositions = await exchange.fetchPositions (positionsParams)
|
||||
console.log ('Current positions:')
|
||||
console.log (openPositions)
|
||||
|
||||
console.log ('-----------------------------------------------------------')
|
||||
|
||||
console.log ('Fetching balance...')
|
||||
balance = await exchange.fetchTotalBalance ()
|
||||
console.log ('Fetched balance:')
|
||||
console.log (base, balance[base], '(base)')
|
||||
console.log (quote, balance[quote], '(quote)')
|
||||
|
||||
} catch (e) {
|
||||
|
||||
console.log (e.constructor.name, e.message)
|
||||
}
|
||||
}
|
||||
|
||||
main ()
|
||||
```
|
||||
@@ -0,0 +1,44 @@
|
||||
- [Kucoin Rate Limit](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
|
||||
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
|
||||
async function main () {
|
||||
|
||||
const exchange = new ccxt.kucoin()
|
||||
const markets = await exchange.loadMarkets ()
|
||||
const timeframe = '5m'
|
||||
const symbol = 'BTC/USDT'
|
||||
const since = undefined
|
||||
const limit = 1000
|
||||
|
||||
let i = 0
|
||||
while (true) {
|
||||
try {
|
||||
const ohlcvs = await exchange.fetchOHLCV(symbol, timeframe, since, limit)
|
||||
const now = exchange.milliseconds()
|
||||
const datetime = exchange.iso8601(now)
|
||||
console.log(datetime, i, 'fetched', ohlcvs.length, symbol, timeframe, 'candles',
|
||||
'from', exchange.iso8601(ohlcvs[0][0]),
|
||||
'to', exchange.iso8601(ohlcvs[ohlcvs.length-1][0]))
|
||||
} catch (e) {
|
||||
if (e instanceof ccxt.RateLimitExceeded) {
|
||||
const now = exchange.milliseconds()
|
||||
const datetime = exchange.iso8601(now)
|
||||
console.log(datetime, i, e.constructor.name, e.message)
|
||||
await exchange.sleep(10000)
|
||||
} else {
|
||||
console.log(e.constructor.name, e.message)
|
||||
throw e
|
||||
}
|
||||
}
|
||||
i += 1
|
||||
}
|
||||
}
|
||||
|
||||
main ()
|
||||
|
||||
```
|
||||
@@ -0,0 +1,113 @@
|
||||
- [Latoken Example](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
|
||||
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
import ololog from 'ololog';
|
||||
import asTable from 'as-table';
|
||||
|
||||
|
||||
const table = asTable.configure ({ delimiter: ' | ' }),
|
||||
//-----------------------------------------------------------------------------
|
||||
log = ololog.unlimited.noLocate.handleNodeErrors ();(async function main () {
|
||||
|
||||
const symbol = 'BTC/USDT'
|
||||
|
||||
const exchange = new ccxt.latoken ({
|
||||
'verbose': process.argv.includes ('--verbose'),
|
||||
// uncomment and change for your keys to enable private calls
|
||||
// 'apiKey': 'YOUR_API_KEY',
|
||||
// 'secret': 'YOUR_API_SECRET',
|
||||
})
|
||||
|
||||
await exchange.loadMarkets ()
|
||||
|
||||
log ('-------------------------------------------------------------------')
|
||||
|
||||
log (exchange.id, 'has', exchange.has)
|
||||
|
||||
// public API
|
||||
|
||||
log ('-------------------------------------------------------------------')
|
||||
|
||||
const markets = Object.values (exchange.markets)
|
||||
log ('Loaded', markets.length, exchange.id, 'markets:')
|
||||
log (table (markets.map (x => exchange.omit (x, [ 'info', 'limits', 'precision' ]))))
|
||||
|
||||
log ('-------------------------------------------------------------------')
|
||||
|
||||
const currencies = Object.values (exchange.currencies)
|
||||
log ('Loaded', currencies.length, exchange.id, 'currencies:')
|
||||
log (table (currencies.map (x => exchange.omit (x, [ 'info', 'limits' ]))))
|
||||
|
||||
log ('-------------------------------------------------------------------')
|
||||
|
||||
const time = await exchange.fetchTime ()
|
||||
log ('Exchange time:', exchange.iso8601 (time))
|
||||
|
||||
log ('-------------------------------------------------------------------')
|
||||
|
||||
const ticker = await exchange.fetchTicker (symbol)
|
||||
log (ticker)
|
||||
|
||||
log ('-------------------------------------------------------------------')
|
||||
|
||||
const tickers = await exchange.fetchTickers ()
|
||||
log (table (Object.values (tickers).map (x =>
|
||||
exchange.omit (x, [ 'info', 'bid', 'ask', 'bidVolume', 'askVolume', 'timestamp' ]))))
|
||||
|
||||
log ('-------------------------------------------------------------------')
|
||||
|
||||
const orderbook = await exchange.fetchOrderBook (symbol)
|
||||
log (orderbook)
|
||||
|
||||
log ('-------------------------------------------------------------------')
|
||||
|
||||
const trades = await exchange.fetchTrades (symbol)
|
||||
log (table (trades.map (x => exchange.omit (x, [ 'info', 'timestamp' ]))))
|
||||
|
||||
log ('-------------------------------------------------------------------')
|
||||
|
||||
// private API
|
||||
|
||||
if (exchange.checkRequiredCredentials (false)) {
|
||||
|
||||
const balance = await exchange.fetchBalance ()
|
||||
log (exchange.omit (balance, [ 'info' ]))
|
||||
|
||||
log ('-------------------------------------------------------------------')
|
||||
|
||||
const order = await exchange.createOrder (symbol, 'limit', 'buy', 0.001, 10000)
|
||||
log (order)
|
||||
|
||||
log ('-------------------------------------------------------------------')
|
||||
|
||||
const openOrders = await exchange.fetchOpenOrders (symbol)
|
||||
log (table (openOrders.map (x => exchange.omit (x, [ 'info', 'timestamp' ]))))
|
||||
|
||||
log ('-------------------------------------------------------------------')
|
||||
|
||||
const canceled = await exchange.cancelOrder (order['id'], order['symbol'])
|
||||
log (canceled)
|
||||
|
||||
log ('-------------------------------------------------------------------')
|
||||
|
||||
const closedOrders = await exchange.fetchClosedOrders (symbol)
|
||||
log (table (closedOrders.map (x => exchange.omit (x, [ 'info', 'timestamp' ]))))
|
||||
|
||||
log ('-------------------------------------------------------------------')
|
||||
|
||||
const canceledOrders = await exchange.fetchCanceledOrders (symbol)
|
||||
log (table (canceledOrders.map (x => exchange.omit (x, [ 'info', 'timestamp' ]))))
|
||||
|
||||
log ('-------------------------------------------------------------------')
|
||||
|
||||
const myTrades = await exchange.fetchMyTrades (symbol)
|
||||
log (table (myTrades.map (x => exchange.omit (x, [ 'info', 'timestamp' ]))))
|
||||
|
||||
}
|
||||
|
||||
}) ()
|
||||
```
|
||||
@@ -0,0 +1,111 @@
|
||||
- [Live Orderbook](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
|
||||
|
||||
import asTable from 'as-table';
|
||||
import ololog from 'ololog';
|
||||
import ansicolor from 'ansicolor';
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
|
||||
const { noLocate } = ololog;
|
||||
const log = noLocate;
|
||||
|
||||
ansicolor.nice
|
||||
|
||||
let printSupportedExchanges = function () {
|
||||
log ('Supported exchanges:', ccxt.exchanges.join (', ').green)
|
||||
}
|
||||
|
||||
let printUsage = function () {
|
||||
log ('Usage: node', process.argv[1], 'exchange'.green, 'symbol'.yellow, 'depth'.cyan)
|
||||
printSupportedExchanges ()
|
||||
}
|
||||
|
||||
let printOrderBook = async (id, symbol, depth) => {
|
||||
|
||||
// check if the exchange is supported by ccxt
|
||||
let exchangeFound = ccxt.exchanges.indexOf (id) > -1
|
||||
if (exchangeFound) {
|
||||
|
||||
log ('Instantiating', id.green, 'exchange')
|
||||
|
||||
// instantiate the exchange by id
|
||||
let exchange = new ccxt[id] ()
|
||||
|
||||
// load all markets from the exchange
|
||||
let markets = await exchange.loadMarkets ()
|
||||
|
||||
// output a list of all market symbols
|
||||
// log (id.green, 'has', exchange.symbols.length, 'symbols:', exchange.symbols.join (', ').yellow)
|
||||
|
||||
if (symbol in exchange.markets) {
|
||||
|
||||
const market = exchange.markets[symbol]
|
||||
const pricePrecision = market.precision ? market.precision.price : 8
|
||||
const amountPrecision = market.precision ? market.precision.amount : 8
|
||||
|
||||
// Object.values (markets).forEach (market => log (market))
|
||||
|
||||
// make a table of all markets
|
||||
// const table = asTable.configure ({ delimiter: ' | ' }) (Object.values (markets))
|
||||
// log (table)
|
||||
|
||||
const priceVolumeHelper = color => ([price, amount]) => ({
|
||||
price: price.toFixed (pricePrecision)[color],
|
||||
amount: amount.toFixed (amountPrecision)[color],
|
||||
' ': ' ',
|
||||
})
|
||||
|
||||
const cursorUp = '\u001b[1A'
|
||||
const tableHeight = depth * 2 + 4 // bids + asks + headers
|
||||
|
||||
log (' ') // empty line
|
||||
|
||||
while (true) {
|
||||
|
||||
const orderbook = await exchange.fetchOrderBook (symbol)
|
||||
|
||||
log (symbol.green, exchange.iso8601 (exchange.milliseconds ()))
|
||||
|
||||
log (asTable.configure ({ delimiter: ' | '.dim, right: true }) ([
|
||||
... orderbook.asks.slice (0, depth).reverse ().map (priceVolumeHelper ('red')),
|
||||
// { price: '--------'.dim, amount: '--------'.dim },
|
||||
... orderbook.bids.slice (0, depth).map (priceVolumeHelper ('green')),
|
||||
]))
|
||||
|
||||
log (cursorUp.repeat (tableHeight))
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
log.error ('Symbol', symbol.bright, 'not found')
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
|
||||
log ('Exchange ' + id.red + ' not found')
|
||||
printSupportedExchanges ()
|
||||
}
|
||||
}
|
||||
|
||||
;(async function main () {
|
||||
|
||||
if (process.argv.length > 4) {
|
||||
|
||||
const id = process.argv[2]
|
||||
const symbol = process.argv[3].toUpperCase ()
|
||||
const depth = parseInt (process.argv[4])
|
||||
await printOrderBook (id, symbol, depth)
|
||||
|
||||
} else {
|
||||
|
||||
printUsage ()
|
||||
}
|
||||
|
||||
process.exit ()
|
||||
|
||||
}) ()
|
||||
```
|
||||
@@ -0,0 +1,85 @@
|
||||
- [Live Ticker](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
|
||||
|
||||
import asTable from 'as-table';
|
||||
import ololog from 'ololog';
|
||||
import ansicolor from 'ansicolor';
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
|
||||
const { noLocate } = ololog;
|
||||
const log = noLocate;
|
||||
|
||||
ansicolor.nice
|
||||
|
||||
let printSupportedExchanges = function () {
|
||||
log ('Supported exchanges:', ccxt.exchanges.join (', ').green)
|
||||
}
|
||||
|
||||
let printUsage = function () {
|
||||
log ('Usage: node', process.argv[1], 'exchange'.green, 'symbol'.yellow, '[rateLimit]'.magenta)
|
||||
printSupportedExchanges ()
|
||||
}
|
||||
|
||||
let printTicker = async (id, symbol, rateLimit = undefined) => {
|
||||
|
||||
// check if the exchange is supported by ccxt
|
||||
let exchangeFound = ccxt.exchanges.indexOf (id) > -1
|
||||
if (exchangeFound) {
|
||||
|
||||
log ('Instantiating', id.green, 'exchange')
|
||||
|
||||
// instantiate the exchange by id
|
||||
let exchange = new ccxt[id] ()
|
||||
|
||||
exchange.rateLimit = rateLimit ? rateLimit : exchange.rateLimit
|
||||
|
||||
log.green ('Rate limit:', exchange.rateLimit.toString ().bright)
|
||||
|
||||
// load all markets from the exchange
|
||||
let markets = await exchange.loadMarkets ()
|
||||
|
||||
if (symbol in exchange.markets) {
|
||||
|
||||
while (true) {
|
||||
|
||||
const ticker = await exchange.fetchTicker (symbol)
|
||||
|
||||
log ('--------------------------------------------------------')
|
||||
log (exchange.id.green, symbol.yellow, exchange.iso8601 (exchange.milliseconds ()))
|
||||
log (ccxt.omit (ticker, 'info'))
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
log.error ('Symbol', symbol.bright, 'not found')
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
|
||||
log ('Exchange ' + id.red + ' not found')
|
||||
printSupportedExchanges ()
|
||||
}
|
||||
}
|
||||
|
||||
;(async function main () {
|
||||
|
||||
if (process.argv.length > 3) {
|
||||
|
||||
const id = process.argv[2]
|
||||
const symbol = process.argv[3].toUpperCase ()
|
||||
const rateLimit = process.argv[4] ? parseInt (process.argv[4]) : undefined
|
||||
await printTicker (id, symbol, rateLimit)
|
||||
|
||||
} else {
|
||||
|
||||
printUsage ()
|
||||
}
|
||||
|
||||
process.exit ()
|
||||
|
||||
}) ()
|
||||
```
|
||||
@@ -0,0 +1,79 @@
|
||||
- [Live Tickers](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
|
||||
|
||||
import asTable from 'as-table';
|
||||
import ololog from 'ololog';
|
||||
import ansicolor from 'ansicolor';
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
|
||||
ansicolor.nice
|
||||
|
||||
const { noLocate } = ololog;
|
||||
const log = noLocate;
|
||||
|
||||
let printSupportedExchanges = function () {
|
||||
log ('Supported exchanges:', ccxt.exchanges.join (', ').green)
|
||||
}
|
||||
|
||||
let printUsage = function () {
|
||||
log ('Usage: node', process.argv[1], 'exchange'.green)
|
||||
printSupportedExchanges ()
|
||||
}
|
||||
|
||||
let printTickers = async (id) => {
|
||||
|
||||
// check if the exchange is supported by ccxt
|
||||
let exchangeFound = ccxt.exchanges.indexOf (id) > -1
|
||||
if (exchangeFound) {
|
||||
|
||||
log ('Instantiating', id.green, 'exchange')
|
||||
|
||||
// instantiate the exchange by id
|
||||
let exchange = new ccxt[id] ()
|
||||
|
||||
// load all markets from the exchange
|
||||
let markets = await exchange.loadMarkets ()
|
||||
|
||||
while (true) {
|
||||
|
||||
const tickers = await exchange.fetchTickers ()
|
||||
|
||||
log ('--------------------------------------------------------')
|
||||
log (exchange.id.green, exchange.iso8601 (exchange.milliseconds ()))
|
||||
log ('Fetched', Object.values (tickers).length.toString ().green, 'tickers:')
|
||||
log (asTable.configure ({ delimiter: ' | '.dim, right: true }) (
|
||||
ccxt.sortBy (Object.values (tickers), 'quoteVolume', true)
|
||||
.slice (0,20)
|
||||
.map (ticker => ({
|
||||
symbol: ticker['symbol'],
|
||||
price: ticker['last'].toFixed (8),
|
||||
datetime: ticker['datetime'],
|
||||
}))))
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
log ('Exchange ' + id.red + ' not found')
|
||||
printSupportedExchanges ()
|
||||
}
|
||||
}
|
||||
|
||||
;(async function main () {
|
||||
|
||||
if (process.argv.length > 2) {
|
||||
|
||||
const id = process.argv[2]
|
||||
await printTickers (id)
|
||||
|
||||
} else {
|
||||
|
||||
printUsage ()
|
||||
}
|
||||
|
||||
process.exit ()
|
||||
|
||||
}) ()
|
||||
```
|
||||
@@ -0,0 +1,46 @@
|
||||
- [Load All Contracts](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
"use strict";
|
||||
|
||||
const ccxt = require ('../../js/ccxt.js')
|
||||
|
||||
console.log ('CCXT Version:', ccxt.version)
|
||||
|
||||
async function loadExchange (exchange) {
|
||||
try {
|
||||
await exchange.loadMarkets ()
|
||||
exchange.symbols.map (symbol => {
|
||||
const market = exchange.market (symbol)
|
||||
if (market['contract']) {
|
||||
console.log (exchange.id, 'loaded', market['type'], symbol, 'market')
|
||||
}
|
||||
})
|
||||
} catch (e) {
|
||||
console.log (e.constructor.name, e.message)
|
||||
}
|
||||
}
|
||||
|
||||
async function loadAllExchanges (exchangeId) {
|
||||
try {
|
||||
|
||||
const exchanges = [];
|
||||
[ 'swap', 'future', 'options' ].forEach (defaultType => {
|
||||
const exchange = new ccxt[exchangeId]()
|
||||
if (exchange.has[defaultType]) {
|
||||
exchanges.push (exchange);
|
||||
}
|
||||
})
|
||||
await Promise.all (exchanges.map (exchange => loadExchange (exchange)))
|
||||
} catch (e) {
|
||||
console.log (e.constructor.name, e.message)
|
||||
}
|
||||
}
|
||||
|
||||
async function main () {
|
||||
await Promise.all (ccxt.exchanges.map (exchangeId => loadAllExchanges (exchangeId)))
|
||||
}
|
||||
|
||||
main ()
|
||||
```
|
||||
@@ -0,0 +1,75 @@
|
||||
- [Load All Symbols At Once](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
|
||||
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
import asTable from 'as-table';
|
||||
import ololog from 'ololog';
|
||||
import ansicolor from 'ansicolor';
|
||||
const log = ololog.configure ({ locate: false })
|
||||
|
||||
ansicolor.nice
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
process.on ('uncaughtException', e => { log.bright.red.error (e); process.exit (1) })
|
||||
process.on ('unhandledRejection', e => { log.bright.red.error (e); process.exit (1) })
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
let test = async function (exchange) {
|
||||
|
||||
try {
|
||||
|
||||
await exchange.loadMarkets ()
|
||||
log (exchange.id.green, 'loaded', exchange.symbols.length.toString ().bright.green, 'symbols')
|
||||
|
||||
} catch (e) {
|
||||
|
||||
if (e instanceof ccxt.DDoSProtection) {
|
||||
log.bright.yellow (exchange.id, '[DDoS Protection] ' + e.message)
|
||||
} else if (e instanceof ccxt.RequestTimeout) {
|
||||
log.bright.yellow (exchange.id, '[Request Timeout] ' + e.message)
|
||||
} else if (e instanceof ccxt.AuthenticationError) {
|
||||
log.bright.yellow (exchange.id, '[Authentication Error] ' + e.message)
|
||||
} else if (e instanceof ccxt.ExchangeNotAvailable) {
|
||||
log.bright.yellow (exchange.id, '[Exchange Not Available] ' + e.message)
|
||||
} else if (e instanceof ccxt.ExchangeError) {
|
||||
log.bright.yellow (exchange.id, '[Exchange Error] ' + e.message)
|
||||
} else if (e instanceof ccxt.NetworkError) {
|
||||
log.bright.yellow (exchange.id, '[Network Error] ' + e.message)
|
||||
} else {
|
||||
throw e
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
let exchanges = []
|
||||
|
||||
async function main () {
|
||||
|
||||
// instantiate all exchanges
|
||||
await Promise.all (ccxt.exchanges.map (async id => {
|
||||
let exchange = new (ccxt)[id] ()
|
||||
exchanges.push (exchange)
|
||||
await test (exchange)
|
||||
}))
|
||||
|
||||
let succeeded = exchanges.filter (exchange => exchange.markets ? true : false).length.toString ().bright.green
|
||||
let failed = exchanges.filter (exchange => exchange.markets ? false : true).length
|
||||
let total = ccxt.exchanges.length.toString ().bright.white
|
||||
let numSymbols = 0;
|
||||
exchanges.map (exchange => {
|
||||
numSymbols += exchange.symbols ? exchange.symbols.length : 0;
|
||||
})
|
||||
log (numSymbols, 'symbols from', succeeded, 'of', total, 'exchanges loaded', ('(' + failed + ' errors)').red)
|
||||
|
||||
}
|
||||
|
||||
main ()
|
||||
|
||||
```
|
||||
@@ -0,0 +1,97 @@
|
||||
- [Load All Tickers At Once](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
|
||||
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
import asTable from 'as-table';
|
||||
import ololog from 'ololog';
|
||||
import ansicolor from 'ansicolor';
|
||||
|
||||
const log = ololog.configure ({ locate: false })
|
||||
|
||||
ansicolor.nice
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
process.on ('uncaughtException', e => { log.bright.red.error (e); process.exit (1) })
|
||||
process.on ('unhandledRejection', e => { log.bright.red.error (e); process.exit (1) })
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
let human_value = function (price) {
|
||||
return price === undefined ? 'N/A' : price
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
let test = async function (exchange, symbol) {
|
||||
|
||||
try {
|
||||
|
||||
await exchange.loadMarkets ()
|
||||
|
||||
if (symbol in exchange.markets) {
|
||||
|
||||
let ticker = await exchange.fetchTicker (symbol)
|
||||
|
||||
log (exchange.id.green, symbol.green, 'ticker',
|
||||
ticker['datetime'],
|
||||
'high: ' + human_value (ticker['high']),
|
||||
'low: ' + human_value (ticker['low']),
|
||||
'bid: ' + human_value (ticker['bid']),
|
||||
'ask: ' + human_value (ticker['ask']),
|
||||
'volume: ' + human_value (ticker['quoteVolume']))
|
||||
} else {
|
||||
|
||||
// do nothing or throw an error
|
||||
log.bright.yellow (exchange.id + ' does not have ' + symbol)
|
||||
}
|
||||
|
||||
} catch (e) {
|
||||
|
||||
if (e instanceof ccxt.DDoSProtection) {
|
||||
log.bright.yellow (exchange.id, '[DDoS Protection]')
|
||||
} else if (e instanceof ccxt.RequestTimeout) {
|
||||
log.bright.yellow (exchange.id, '[Request Timeout]')
|
||||
} else if (e instanceof ccxt.AuthenticationError) {
|
||||
log.bright.yellow (exchange.id, '[Authentication Error]')
|
||||
} else if (e instanceof ccxt.ExchangeNotAvailable) {
|
||||
log.bright.yellow (exchange.id, '[Exchange Not Available]')
|
||||
} else if (e instanceof ccxt.ExchangeError) {
|
||||
log.bright.yellow (exchange.id, '[Exchange Error]')
|
||||
} else if (e instanceof ccxt.NetworkError) {
|
||||
log.bright.yellow (exchange.id, '[Network Error]')
|
||||
} else {
|
||||
throw e
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
const symbol = 'BTC/USD'
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
async function main () {
|
||||
|
||||
let exchanges = []
|
||||
|
||||
// instantiate all exchanges
|
||||
await Promise.all (ccxt.exchanges.map (async id => {
|
||||
let exchange = new (ccxt)[id] ()
|
||||
exchanges.push (exchange)
|
||||
await test (exchange, symbol)
|
||||
}))
|
||||
|
||||
let succeeded = exchanges.filter (exchange => exchange.markets ? true : false).length.toString ().bright.green
|
||||
let failed = exchanges.filter (exchange => exchange.markets ? false : true).length
|
||||
let total = ccxt.exchanges.length.toString ().bright.white
|
||||
console.log (succeeded, 'of', total, 'exchanges loaded', ('(' + failed + ' errors)').red)
|
||||
}
|
||||
|
||||
main ()
|
||||
|
||||
```
|
||||
@@ -0,0 +1,63 @@
|
||||
- [Load Markets To Files](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
|
||||
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
import path from 'path';
|
||||
import fs from 'fs';
|
||||
|
||||
const enableRateLimit = true,
|
||||
// exchange defaults
|
||||
// ------------------------------------------------------------------------
|
||||
// path to your folder, for example '/myproject/markets' or 'C:/myproject/markets'
|
||||
options = { enableRateLimit },
|
||||
// writes to current working directory if left empty
|
||||
// ------------------------------------------------------------------------
|
||||
// use a reasonable value for maxConcurrency to avoid network congestion
|
||||
// a burst of requests in a short period of time will cause
|
||||
// excessive competition for networking resources within the application
|
||||
folder = '',
|
||||
maxConcurrency = 7;
|
||||
|
||||
async function main () {
|
||||
|
||||
const allExchanges = ccxt.exchanges.map (id => {
|
||||
try {
|
||||
return new ccxt[id] (options)
|
||||
} catch (e) {
|
||||
console.log ('Failed to initialize', id, e.constructor.name)
|
||||
}
|
||||
}).filter (x => x)
|
||||
, allExchangesByIds = ccxt.indexBy (allExchanges, 'id')
|
||||
, exchangeIds = Object.keys (allExchangesByIds)
|
||||
|
||||
const load = async () => {
|
||||
while (exchangeIds.length > 0) {
|
||||
const id = exchangeIds.pop ()
|
||||
const exchange = allExchangesByIds[id]
|
||||
const file = path.join (folder, `saved-markets-${exchange.id}.json`)
|
||||
try {
|
||||
await exchange.loadMarkets ()
|
||||
const { id, markets } = exchange
|
||||
await writeFile (file, JSON.stringify ({ id, markets }))
|
||||
console.log ('Loaded markets from', id, 'to', file)
|
||||
} catch (e) {
|
||||
console.log ('Failed to load markets from', id, 'to', file, e.constructor.name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const started = ccxt.milliseconds ()
|
||||
const loaders = Array (maxConcurrency).fill ().map (x => load ())
|
||||
await Promise.all (loaders)
|
||||
const stopped = ccxt.milliseconds ()
|
||||
console.log ('Done loading', allExchanges.length, 'exchanges in', ((stopped - started) / 1000).toFixed (2), 'seconds')
|
||||
|
||||
// other code...
|
||||
}
|
||||
|
||||
main ()
|
||||
|
||||
```
|
||||
@@ -0,0 +1,67 @@
|
||||
- [Looping Over All Symbols Of Specific Exchanges](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
|
||||
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
import asTable from 'as-table';
|
||||
import ansicolor from 'ansicolor';
|
||||
import ololog from 'ololog';
|
||||
|
||||
const log = ololog.configure ({ locate: false }), verbose = process.argv.includes ('--verbose');
|
||||
|
||||
ansicolor.nice
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
;(async () => {
|
||||
|
||||
const exchanges = [ 'bittrex', 'poloniex', 'hitbtc2' ]
|
||||
|
||||
for (let exchangeId of exchanges) {
|
||||
|
||||
// create the exchange instance
|
||||
const exchange = new ccxt[exchangeId] ()
|
||||
|
||||
// preload all markets first, as explained in the Manual:
|
||||
// https://github.com/ccxt/ccxt/wiki/Manual#loading-markets
|
||||
|
||||
// add error/exception handling as required by the Manual:
|
||||
// https://github.com/ccxt/ccxt/wiki/Manual#error-handling
|
||||
|
||||
try {
|
||||
|
||||
await exchange.loadMarkets ();
|
||||
|
||||
} catch (e) {
|
||||
|
||||
log.red ('Could not load markets from', exchange.id + ':', e.constructor.name, e.message)
|
||||
|
||||
continue; // skip this exchange if markets failed to load
|
||||
|
||||
}
|
||||
|
||||
for (let symbol in exchange.markets) {
|
||||
|
||||
console.log (exchange.id, symbol)
|
||||
|
||||
// add error/exception handling as required by the Manual:
|
||||
// https://github.com/ccxt/ccxt/wiki/Manual#error-handling
|
||||
|
||||
try { // try fetching the ticker for a symbol existing with that exchange
|
||||
|
||||
const ticker = await exchange.fetchTicker (symbol)
|
||||
log.green (ticker)
|
||||
|
||||
} catch (e) { // catch the error (if any) and handle it or ignore it
|
||||
|
||||
log.red ('Could not fetch', symbol, 'ticker from', exchange.id + ':', e.constructor.name, e.message)
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}) ()
|
||||
|
||||
```
|
||||
@@ -0,0 +1,97 @@
|
||||
- [Looping Over Specific Symbols Of All Exchanges](./examples/js/)
|
||||
|
||||
|
||||
```javascript
|
||||
|
||||
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
import asTable from 'as-table';
|
||||
import ololog from 'ololog';
|
||||
import ansicolor from 'ansicolor';
|
||||
|
||||
const log = ololog.configure ({ locate: false }), verbose = process.argv.includes ('--verbose');
|
||||
|
||||
ansicolor.nice
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
;(async () => {
|
||||
|
||||
const exchanges = {};
|
||||
const symbols = [ 'ETH/BTC', 'XRP/BTC', 'BTC/USDT' ]
|
||||
|
||||
for (let symbol of symbols) {
|
||||
|
||||
for (let exchangeId of ccxt.exchanges) {
|
||||
|
||||
let exchange = undefined
|
||||
|
||||
try { // try creating the exchange instance first and handle errors if any
|
||||
|
||||
// check if we have created an instance of this exchange already
|
||||
|
||||
exchange = exchanges[exchangeId]
|
||||
|
||||
if (exchange === undefined) {
|
||||
|
||||
// create the exchange instance
|
||||
exchange = new ccxt[exchangeId] ()
|
||||
}
|
||||
|
||||
exchanges[exchangeId] = exchange // save it for later use
|
||||
|
||||
} catch (e) {
|
||||
|
||||
log.red ('Could not create exchange', exchangeId + ':', e.constructor.name, e.message)
|
||||
|
||||
// uncomment the following line to interrupt program execution on error
|
||||
// or leave it commented out to do nothing
|
||||
|
||||
// process.exit ()
|
||||
|
||||
}
|
||||
|
||||
if (exchange !== undefined) {
|
||||
|
||||
// preload all markets first, as explained in the Manual:
|
||||
// https://github.com/ccxt/ccxt/wiki/Manual#loading-markets
|
||||
|
||||
// add error/exception handling as required by the Manual:
|
||||
// https://github.com/ccxt/ccxt/wiki/Manual#error-handling
|
||||
|
||||
try {
|
||||
|
||||
await exchange.loadMarkets ();
|
||||
|
||||
} catch (e) {
|
||||
|
||||
log.red ('Could not load markets from', exchange.id + ':', e.constructor.name, e.message)
|
||||
continue; // skip this exchange if markets failed to load
|
||||
|
||||
}
|
||||
|
||||
for (let symbol of symbols) {
|
||||
|
||||
console.log (exchange.id, symbol)
|
||||
|
||||
// add error/exception handling as required by the Manual:
|
||||
// https://github.com/ccxt/ccxt/wiki/Manual#error-handling
|
||||
|
||||
try { // try fetching the ticker for a symbol existing with that exchange
|
||||
|
||||
const ticker = await exchange.fetchTicker (symbol)
|
||||
log.green (ticker)
|
||||
|
||||
} catch (e) { // catch the error (if any) and handle it or ignore it
|
||||
|
||||
log.red ('Could not fetch', symbol, 'ticker from', exchange.id + ':', e.constructor.name, e.message)
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}) ()
|
||||
|
||||
```
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user