This commit is contained in:
discountry
2025-10-03 15:28:16 +08:00
parent d5c4b04746
commit fcb83bd16b
925 changed files with 165721 additions and 4 deletions
+15
View File
@@ -0,0 +1,15 @@
# 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
```
@@ -0,0 +1,39 @@
"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,54 @@
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))
})();
+97
View File
@@ -0,0 +1,97 @@
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();
+130
View File
@@ -0,0 +1,130 @@
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 ()
}) ()
+29
View File
@@ -0,0 +1,29 @@
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,13 @@
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])
}
}) ()
+115
View File
@@ -0,0 +1,115 @@
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 ()
}) ()
+104
View File
@@ -0,0 +1,104 @@
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,45 @@
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,34 @@
'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,33 @@
'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,31 @@
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,41 @@
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 futures2 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 futures2 for coin-margined futures
'asset': currency['id'],
'amount': exchange.currencyToPrecision (code, amount),
})
console.log (response)
}
main ()
@@ -0,0 +1,39 @@
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,34 @@
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,16 @@
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,35 @@
// ----------------------------------------------------------------------------
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,35 @@
// ----------------------------------------------------------------------------
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,7 @@
// 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,36 @@
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,28 @@
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,115 @@
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,39 @@
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])
)
}) ()
+50
View File
@@ -0,0 +1,50 @@
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,69 @@
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,59 @@
"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;
}
}
})()
+48
View File
@@ -0,0 +1,48 @@
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,25 @@
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)
+62
View File
@@ -0,0 +1,62 @@
'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 ();
+154
View File
@@ -0,0 +1,154 @@
'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,38 @@
"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 ()
@@ -0,0 +1,47 @@
"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 ();
+75
View File
@@ -0,0 +1,75 @@
'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,54 @@
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 ()
}) ()
+16
View File
@@ -0,0 +1,16 @@
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,36 @@
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();
+5
View File
@@ -0,0 +1,5 @@
// 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,55 @@
// ----------------------------------------------------------------------------
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,71 @@
// @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,65 @@
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,25 @@
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,17 @@
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,36 @@
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,36 @@
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();
+5
View File
@@ -0,0 +1,5 @@
{
"hitbtc": { "apiKey": "b6aad581670b30fb25d1c91cdbe8ca5c", "secret": "fa394ced37a488f9b5826a2d9ce39ae3" },
"bitso": { "apiKey": "xZnHRmdlgJ", "secret": "e156bb7f7ab3a831afbc7a80f7866b9e" },
"coincheck": { "apiKey": "dCyzY2T6w0DFhaco", "secret": "JpI0eMmxfa0tEpk3X-dNwyclSASJkl-S" }
}
@@ -0,0 +1,12 @@
// @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;
+23
View File
@@ -0,0 +1,23 @@
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,60 @@
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 ()
+26
View File
@@ -0,0 +1,26 @@
// ----------------------------------------------------------------------------
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)
})()
+89
View File
@@ -0,0 +1,89 @@
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,135 @@
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,60 @@
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],
}))
)
}) ()
+40
View File
@@ -0,0 +1,40 @@
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,
}
})))
+219
View File
@@ -0,0 +1,219 @@
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,53 @@
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,77 @@
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)
}) ()
+28
View File
@@ -0,0 +1,28 @@
"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,101 @@
// ----------------------------------------------------------------------------
// 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,79 @@
// 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,21 @@
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,25 @@
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,5 @@
"use strict";
module.exports = {
singleQuote: true,
trailingComma: 'es5',
};
@@ -0,0 +1,25 @@
// Example code in typescript
// Based on /examples/js/fetch-okex-futures.js
import * as ccxt from 'ccxt';
const log = require('ololog');
const fetchFutures = async () => {
const exchange = new ccxt.bitmex();
exchange.markets = await exchange.loadMarkets(true);
for (let symbol in exchange.markets) {
log('----------------------------------------------------');
log(`symbol = ${symbol}`);
try {
const market = exchange.markets[symbol];
if (market['future']) {
const ticker = await exchange.fetchTicker(symbol);
log('----------------------------------------------------');
log(symbol, ticker);
await ccxt.sleep(exchange.rateLimit); // Missing type information.
}
}
catch (error) {
log('error =', error);
}
}
};
fetchFutures();
@@ -0,0 +1,72 @@
"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,39 @@
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();
+16
View File
@@ -0,0 +1,16 @@
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,22 @@
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 ()
+27
View File
@@ -0,0 +1,27 @@
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,35 @@
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,75 @@
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,19 @@
"use strict";
// Example code in typescript
// Based on /examples/js/fetch-from-many-exchanges-simultaneously.js
Object.defineProperty(exports, "__esModule", { value: true });
const ccxt = require("ccxt");
const log = require('ololog');
const symbol = 'BTC/USD';
const exchanges = ['coinbasepro', 'gemini', 'kraken'];
const fetchTickers = async (symbol) => {
const result = await Promise.all(exchanges.map(async (id) => {
const CCXT = ccxt; // Hack!
const exchange = new CCXT[id]({ 'enableRateLimit': true });
const ticker = await exchange.fetchTicker(symbol);
const exchangeExtended = exchange.extend({ 'exchange': id }, ticker);
return exchangeExtended;
}));
log(result);
};
fetchTickers(symbol);
@@ -0,0 +1,5 @@
"use strict";
module.exports = {
singleQuote: true,
trailingComma: 'es5',
};
@@ -0,0 +1,17 @@
// Example code in typescript
// Based on /examples/js/fetch-from-many-exchanges-simultaneously.js
import * as ccxt from 'ccxt';
const log = require('ololog');
const symbol = 'BTC/USD';
const exchanges = ['coinbasepro', 'gemini', 'kraken'];
const fetchTickers = async (symbol) => {
const result = await Promise.all(exchanges.map(async (id) => {
const CCXT = ccxt; // Hack!
const exchange = new CCXT[id]({ 'enableRateLimit': true });
const ticker = await exchange.fetchTicker(symbol);
const exchangeExtended = exchange.extend({ 'exchange': id }, ticker);
return exchangeExtended;
}));
log(result);
};
fetchTickers(symbol);
+43
View File
@@ -0,0 +1,43 @@
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 ();
+49
View File
@@ -0,0 +1,49 @@
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,49 @@
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)
}
}) ()
+74
View File
@@ -0,0 +1,74 @@
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,29 @@
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;
}
}
}) ()
+113
View File
@@ -0,0 +1,113 @@
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();
+61
View File
@@ -0,0 +1,61 @@
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,10 @@
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();
+71
View File
@@ -0,0 +1,71 @@
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,63 @@
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)
}
}) ()
+70
View File
@@ -0,0 +1,70 @@
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,98 @@
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,19 @@
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)
}) ()
+19
View File
@@ -0,0 +1,19 @@
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,13 @@
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,46 @@
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,31 @@
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,54 @@
// @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,33 @@
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,89 @@
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,38 @@
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 ()
+108
View File
@@ -0,0 +1,108 @@
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' ]))))
}
}) ()
+106
View File
@@ -0,0 +1,106 @@
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 ()
}) ()
+80
View File
@@ -0,0 +1,80 @@
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 ()
}) ()
+74
View File
@@ -0,0 +1,74 @@
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,41 @@
"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 ()

Some files were not shown because too many files have changed in this diff Show More