Author SHA1 Message Date
discountry 0d2aa84b84 feat: 更新 Lighter 适配器的账户快照逻辑,支持市场符号和市场 ID 过滤功能 2025-10-06 19:17:24 +08:00
discountry d2867ba98c feat: 更新订单协调器和 GRVT 适配器,添加触发类型支持,优化趋势引擎的损益计算逻辑 2025-10-06 19:06:49 +08:00
discountry e28240e799 feat: 更新订单协调器和 GRVT 适配器逻辑,添加止损单的 reduceOnly 和 closePosition 参数,修改默认价格触发器为 LAST 2025-10-06 18:44:16 +08:00
discountry cfd5f4309d feat: 添加 Paradex 适配器支持,更新环境变量配置和适配器构建逻辑 2025-10-06 18:06:23 +08:00
discountry ccc3a2bf89 feat: 增强 OffsetMakerEngine 订单处理逻辑,添加快速重价抑制机制以减少重复下单 2025-10-03 16:16:20 +08:00
discountry f8a87f4557 feat: 优化 Lighter 适配器的订单簿处理逻辑,添加排序和限制深度功能 2025-10-03 16:06:31 +08:00
discountry 263cbd7c21 feat: 增强 Lighter 适配器的账户更新逻辑,支持市场账户的实时更新和合并处理 2025-10-03 15:52:18 +08:00
discountry d328758074 feat: 添加止损单去抖机制,避免重复提交同价同向止损单 2025-10-03 15:40:17 +08:00
discountry 971a2a6adb feat: 优化 Lighter 适配器的订单过期逻辑,简化市场订单的即时过期处理 2025-10-03 15:35:45 +08:00
discountry fcb83bd16b commit 2025-10-03 15:28:16 +08:00
discountry d5c4b04746 feat: 更新订单处理逻辑,将价格类型改为字符串以避免精度问题,并添加价格格式化函数 2025-10-03 07:15:21 +08:00
discountry 65aaf26879 feat: 更新 Maker 刷新间隔配置,将间隔时间从 1500ms 修改为 500ms 2025-10-03 06:59:24 +08:00
947 changed files with 167674 additions and 257 deletions
+41 -2
View File
@@ -1,5 +1,5 @@
# Exchange selection
EXCHANGE=aster # Pick aster (default) or grvt
EXCHANGE=aster # Pick aster (default) or grvt/lighter/backpack/paradex
# Aster API credentials
ASTER_API_KEY=
@@ -33,7 +33,7 @@ MAX_CLOSE_SLIPPAGE_PCT=0.05 # Max allowed deviation vs mark when clo
MAKER_LOSS_LIMIT=0.05 # Maker loss cap (USDT). Defaults to LOSS_LIMIT if unset
MAKER_BID_OFFSET=0 # Bid quote offset from top bid (USDT)
MAKER_ASK_OFFSET=0 # Ask quote offset from top ask (USDT)
MAKER_REFRESH_INTERVAL_MS=1500 # Maker refresh cadence (ms)
MAKER_REFRESH_INTERVAL_MS=500 # Maker refresh cadence (ms)
MAKER_MAX_CLOSE_SLIPPAGE_PCT=0.05 # Maker close slippage guard (fallbacks to MAX_CLOSE_SLIPPAGE_PCT)
MAKER_PRICE_TICK=0.1 # Maker price tick size (defaults to PRICE_TICK)
@@ -61,3 +61,42 @@ LIGHTER_ENV=testnet # mainnet | testnet | staging | dev
# LIGHTER_MARKET_ID=1 # Prefer explicit market id when symbols differ
# LIGHTER_PRICE_DECIMALS=3 # Manual override for price decimals (optional)
# LIGHTER_SIZE_DECIMALS=3 # Manual override for size decimals (optional)
# Backpack exchange configuration
# Fill these with your Backpack API credentials and preferences
BACKPACK_API_KEY=
BACKPACK_API_SECRET=
BACKPACK_PASSWORD=
BACKPACK_SUBACCOUNT=
# Use sandbox environment: "true" to enable, otherwise leave as false
BACKPACK_SANDBOX=false
# Default trading symbol (falls back to TRADE_SYMBOL or BTCUSDC)
BACKPACK_SYMBOL=BTC_USD_PERP
# Enable verbose adapter logging: set to "1" or "true"
BACKPACK_DEBUG=false
# Paradex exchange configuration
# Provide the EVM private key & wallet address for onboarded accounts.
# When EXCHANGE=paradex these values are used automatically.
PARADEX_PRIVATE_KEY=
PARADEX_WALLET_ADDRESS=
# Symbol defaults to TRADE_SYMBOL if omitted. Use ccxt unified format like BTC-USD-PERP.
# PARADEX_SYMBOL=BTC-USD-PERP
# Enable testnet endpoints by setting to "true"; defaults to false (mainnet).
# PARADEX_SANDBOX=false
# Force disabling ccxt.pro websocket usage by setting to "false" (pro is preferred when installed).
# PARADEX_USE_PRO=true
# Optional reconnect delay override (milliseconds, e.g., 2000). Leave blank for default.
# PARADEX_RECONNECT_DELAY_MS=
# Enable verbose adapter logging: set to "1" or "true"
# PARADEX_DEBUG=false
File diff suppressed because one or more lines are too long
@@ -0,0 +1,51 @@
<!DOCTYPE HTML>
<html>
<head>
<title>CCXT Basic example for the browser</title>
<script type="text/javascript" src="https://unpkg.com/ccxt"></script>
<script>
document.addEventListener ("DOMContentLoaded", function () {
const pollTickerContinuously = async function (exchange, symbol) {
while (true) {
try {
const ticker = await exchange.watchTicker (symbol)
const text = [
exchange.id,
symbol,
JSON.stringify (ticker, undefined, '\n\t')
]
document.getElementById ('content').innerHTML = text.join (' ');
} catch (e) {
const text = [
e.constructor.name,
e.message,
]
document.getElementById ('content').innerHTML = text.join (' ');
}
}
}
const exchange = new ccxt.pro.binance ({ enableRateLimit: true })
const symbol = 'ETH/BTC'
pollTickerContinuously (exchange, symbol)
})
</script>
</head>
<body>
<h1>Hello, CCXT!</h1>
<p>This example uses websockets to watch changes in price of ETH/BTC</p>
<pre id="content"></pre>
</body>
</html>
@@ -0,0 +1,74 @@
'use strict';
import ccxt from '../../../js/ccxt.js';
// your version must be 0.7+
console.log ('CCXT Version:', ccxt.version)
function handle (exchange, symbol, ticker) {
console.log (new Date (), exchange.id, symbol, ticker)
}
async function loop (exchange, symbol) {
while (true) {
try {
const ticker = await exchange.watchMyTrades ()
handle (exchange, symbol, ticker)
sleep( 10000 )
} catch (e) {
console.log (symbol, e)
// do nothing and retry on next loop iteration
// throw e // uncomment to break all loops in case of an error in any one of them
// break // you can also break just this one loop if it fails
}
}
}
async function main () {
const exchange = new ccxt.pro.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': '',
},
}) // usd(s)-margined contracts
exchange.setSandboxMode(true)
//
// or
//
// const exchange = new ccxt.pro.binance () // spot markets
//
// WARNING: when using the spot markets mind subscription limits!
// don't attempt to subscribe to all of them
// the exchanges will not allow that in general
// instead, specify a shorter list of symbols to subscribe to
//
// or
//
// const exchange = new ccxt.pro.binancecoinm () // coin-margined contracts
if (exchange.has['watchTicker']) {
await exchange.loadMarkets ()
// many symbols
//await Promise.all (exchange.symbols.map (symbol => loop (exchange, symbol)))
//
// or
//
// const symbols = [ 'BTC/USDT', 'ETH/USDT' ] // specific symbols
// await Promise.all (symbols.map (symbol => loop (exchange, symbol)))
//
// or
//
await loop (exchange, ['BTC-USDT','ETH-USDT']) // one symbol
} else {
console.log (exchange.id, 'does not support watchTicker yet')
}
}
main ()
@@ -0,0 +1,55 @@
'use strict';
const ccxt = require ('../../../ccxt')
console.log ('CCXT Version:', ccxt.version)
// This example will run silent and will return your balance only when the balance is updated.
//
// 1. launch the example with your keys and keep it running
// 2. go to the trading section on the website
// 3. place a order on a spot market
// 4. see your balance updated in the example
//
// Warning! This example might produce a lot of output to your screen
async function watchBalance (exchange) {
let balance = await exchange.fetchBalance ()
console.log ('---------------------------------------------------------')
console.log (exchange.iso8601 (exchange.milliseconds ()))
console.log (balance, '\n')
while (true) {
try {
const update = await exchange.watchBalance ()
balance = exchange.deep_extend (balance, update)
// it will print the balance update when the balance changes
// if the balance remains unchanged the exchange will not send it
console.log ('---------------------------------------------------------')
console.log (exchange.iso8601 (exchange.milliseconds ()))
console.log (balance, '\n')
} catch (e) {
console.log (e.constructor.name, e.message)
break
}
}
}
async function main() {
const exchange = new ccxt.pro.binance ({
'apiKey': 'YOUR_API_KEY',
'secret': 'YOUR_SECRET',
})
await exchange.loadMarkets ()
// exchange.verbose = true // uncomment for debugging purposes if necessary
await watchBalance (exchange)
await exchange.close ()
}
main ()
@@ -0,0 +1,48 @@
'use strict';
const ccxt = require ('../../../ccxt')
console.log ('CCXT Version:', ccxt.version)
let HttpsProxyAgent = undefined
try {
HttpsProxyAgent = require ('https-proxy-agent')
} catch (e) {
console.log (e.constructor.name, e.message)
console.log ("\nCould not load the HTTPS proxy agent")
console.log ("\nPlease, run this command to make sure it's properly installed:")
console.log ("\nnpm install https-proxy-agent\n")
process.exit ()
}
async function main () {
console.log ('Using proxy server', httpsProxyUrl);
// adjust for your HTTPS proxy URL
const httpsProxyUrl = process.env.https_proxy || 'https://username:password@your-proxy.com'
, httpsAgent = new HttpsProxyAgent (httpsProxyUrl)
, exchange = new ccxt.binance ({
httpsAgent: httpsAgent, // ←--------------------- httpsAgent here
options: {
'ws': {
'options': { agent: httpsAgent }, // ←--- httpsAgent here
},
},
})
const symbol = 'BTC/USDT'
await exchange.loadMarkets ()
console.log ('Markets loaded')
while (true) {
try {
const orderbook = await exchange.watchOrderBook (symbol)
console.log (exchange.iso8601 (exchange.milliseconds()), symbol, orderbook['asks'][0], orderbook['bids'][0])
} catch (e) {
console.log (e.constructor.name, e.message)
}
}
}
main ()
@@ -0,0 +1,38 @@
"use strict";
const ccxt = require ('ccxt')
const ohlcvsBySymbol = {}
function handleAllOHLCVs (exchange, ohlcvs, symbol, timeframe) {
const now = exchange.iso8601 (exchange.milliseconds ())
const lastCandle = exchange.safeValue (ohlcvs, ohlcvs.length - 1)
const datetime = exchange.iso8601 (lastCandle[0])
console.log (now, datetime, symbol, timeframe, lastCandle.slice (1))
}
async function pollOHLCV (exchange, symbol, timeframe) {
await exchange.throttle (1000) // 1000ms delay between subscriptions
while (true) {
try {
const response = await exchange.watchOHLCV (symbol, timeframe)
ohlcvsBySymbol[symbol] = response
handleAllOHLCVs(exchange, response, symbol, timeframe)
} catch (e) {
console.log (e.constructor.name, e.message)
}
}
}
async function main () {
const exchange = new ccxt.pro.binance()
const markets = await exchange.loadMarkets ()
const timeframe = '5m'
const firstOneHundredSymbols = exchange.symbols.slice (0, 100)
await Promise.all (firstOneHundredSymbols.map (symbol => pollOHLCV (exchange, symbol, timeframe)))
}
main ()
@@ -0,0 +1,64 @@
'use strict';
const ccxt = require ('ccxt');
// your version must be 0.7+
console.log ('CCXT Version:', ccxt.version)
function handle (exchange, symbol, timeframe, candles) {
const lastCandle = candles[candles.length - 1]
const lastClosingPrice = lastCandle[4]
console.log (new Date (), exchange.id, timeframe, symbol, '\t', lastClosingPrice)
}
async function loop (exchange, symbol, timeframe) {
while (true) {
try {
const candles = await exchange.watchOHLCV (symbol, timeframe)
handle (exchange, symbol, timeframe, candles)
} catch (e) {
console.log (symbol, e)
// do nothing and retry on next loop iteration
// throw e // uncomment to break all loops in case of an error in any one of them
// break // you can also break just this one loop if it fails
}
}
}
async function main () {
const exchange = new ccxt.pro.binanceusdm () // usd(s)-margined contracts
//
// or
//
// const exchange = new ccxt.pro.binance () // spot markets
//
// WARNING: when using the spot markets mind subscription limits!
// don't attempt to subscribe to all of them
// the exchanges will not allow that in general
// instead, specify a shorter list of symbols to subscribe to
//
// or
//
// const exchange = new ccxt.pro.binancecoinm () // coin-margined contracts
if (exchange.has['watchOHLCV']) {
await exchange.loadMarkets ()
const timeframe = '15m'
// many symbols
await Promise.all (exchange.symbols.map (symbol => loop (exchange, symbol, timeframe)))
//
// or
//
// const symbols = [ 'BTC/USDT', 'ETH/USDT' ] // specific symbols
// await Promise.all (symbols.map (symbol => loop (exchange, symbol, timeframe)))
//
// or
//
// await loop (exchange, 'BTC/USDT', timeframe) // one symbol
} else {
console.log (exchange.id, 'does not support watchOHLCV yet')
}
}
main ()
@@ -0,0 +1,62 @@
'use strict';
const ccxt = require ('ccxt');
// your version must be 0.7+
console.log ('CCXT Version:', ccxt.version)
function handle (exchange, symbol, ticker) {
console.log (new Date (), exchange.id, symbol, ticker['last'])
}
async function loop (exchange, symbol) {
while (true) {
try {
const ticker = await exchange.watchTicker (symbol)
handle (exchange, symbol, ticker)
} catch (e) {
console.log (symbol, e)
// do nothing and retry on next loop iteration
// throw e // uncomment to break all loops in case of an error in any one of them
// break // you can also break just this one loop if it fails
}
}
}
async function main () {
const exchange = new ccxt.pro.binanceusdm () // usd(s)-margined contracts
//
// or
//
// const exchange = new ccxt.pro.binance () // spot markets
//
// WARNING: when using the spot markets mind subscription limits!
// don't attempt to subscribe to all of them
// the exchanges will not allow that in general
// instead, specify a shorter list of symbols to subscribe to
//
// or
//
// const exchange = new ccxt.pro.binancecoinm () // coin-margined contracts
if (exchange.has['watchTicker']) {
await exchange.loadMarkets ()
// many symbols
await Promise.all (exchange.symbols.map (symbol => loop (exchange, symbol)))
//
// or
//
// const symbols = [ 'BTC/USDT', 'ETH/USDT' ] // specific symbols
// await Promise.all (symbols.map (symbol => loop (exchange, symbol)))
//
// or
//
// await loop (exchange, 'BTC/USDT') // one symbol
} else {
console.log (exchange.id, 'does not support watchTicker yet')
}
}
main ()
@@ -0,0 +1,68 @@
'use strict';
const ccxt = require ('ccxt');
const asTable = require ('as-table').configure ({ delimiter: ' | ' })
console.log ('CCXT Version:', ccxt.version)
async function loop (exchange, symbol, timeframe, completeCandlesOnly = false) {
const durationInSeconds = exchange.parseTimeframe (timeframe)
const durationInMs = durationInSeconds * 1000
while (true) {
try {
const trades = await exchange.watchTrades (symbol)
if (trades.length > 0) {
const currentMinute = parseInt (exchange.milliseconds () / durationInMs)
let ohlcvc = exchange.buildOHLCVC (trades, timeframe)
if (completeCandlesOnly) {
ohlcvc = ohlcvc.filter (candle => parseInt (candle[0] / durationInMs) < currentMinute)
}
if (ohlcvc.length > 0) {
console.log("Symbol:", symbol, "timeframe:", timeframe);
console.log ('-----------------------------------------------------------')
console.log (asTable (ohlcvc))
console.log ('-----------------------------------------------------------')
}
}
} catch (e) {
console.log (symbol, e)
// do nothing and retry on next loop iteration
// throw e // uncomment to break all loops in case of an error in any one of them
// break // you can also break just this one loop if it fails
}
}
}
async function main () {
// select the exchange
const exchange = new ccxt.pro.ftx ()
if (exchange.has['watchTrades']) {
await exchange.loadMarkets ()
// Change this value accordingly
const timeframe = '1m'
const allSymbols = exchange.symbols;
// arbitrary n symbols
const limit = 5;
// const selectedSymbols = allSymbols.slice(0, limit);
// you can also specify the symbols manually
// example:
// const selectedSymbols = ['BTC/USDT', 'LTC/USDT']
console.log(selectedSymbols);
// Use this variable to choose if only complete candles
// should be considered
const completeCandlesOnly = true
await Promise.all (selectedSymbols.map (symbol => loop (exchange, symbol, timeframe, completeCandlesOnly)))
} else {
console.log (exchange.id, 'does not support watchTrades yet')
}
}
main ()
@@ -0,0 +1,82 @@
'use strict';
const ccxt = require ('../../../ccxt');
console.log ('CCXT Version:', ccxt.version)
let ohlcvs = {}
async function log (exchange, symbol, timeframe) {
const market = exchange.market (symbol)
const duration = exchange.parseTimeframe (timeframe) * 1000
console.log (exchange.iso8601 (exchange.milliseconds ()), 'Warming up, waiting for at least one trade...')
while (!Object.keys (ohlcvs).length) {
await exchange.throttle (1)
}
let now = exchange.milliseconds ()
const start = (parseInt (now / duration) + 1) * duration
console.log (exchange.iso8601 (exchange.milliseconds ()), 'Trades started arriving, waiting till', exchange.iso8601 (start))
await exchange.sleep (start - now)
console.log (exchange.iso8601 (exchange.milliseconds ()), 'Done warming up')
for (let i = 0;; i++) {
now = exchange.milliseconds ()
let candle = Object.values (ohlcvs)[0]
console.log ('')
console.log (exchange.iso8601 (now), '------------------------------------------------------')
console.log ('Datetime ', 'Timestamp ', ... [ 'Open', 'High', 'Low', 'Close', market['base'], market['quote'] ].map (x => x.toString ().padEnd (10, ' ')))
for (let j = start; j < now; j += duration) {
if (!(j in ohlcvs)) {
ohlcvs[j] = [ j, candle[4], candle[4], candle[4], candle[4], 0, 0 ]
}
candle = exchange.safeValue (ohlcvs, j);
console.log (exchange.iso8601 (j), ... candle.map (x => x.toString ().padEnd (10, ' ')))
}
ohlcvs = exchange.indexBy (Object.values (ohlcvs).slice (-1000), 0)
await exchange.sleep(1000)
}
}
async function watch (exchange, symbol, timeframe) {
console.log ('Starting', exchange.id, symbol)
const duration = exchange.parseTimeframe (timeframe) * 1000
while (true) {
try {
const trades = await exchange.watchTrades(symbol)
for (const trade of trades) {
const timestamp = parseInt(trade['timestamp'] / duration) * duration
let candle = exchange.safe_value(ohlcvs, timestamp)
if (candle) {
candle[2] = Math.max(trade['price'], candle[2])
candle[3] = Math.min(trade['price'], candle[3])
candle[4] = trade['price']
candle[5] = exchange.parseNumber(exchange.amountToPrecision(symbol, trade['amount'] + candle[5]))
candle[6] = exchange.parseNumber(exchange.costToPrecision(symbol, trade['cost'] + candle[6]))
} else {
candle = [
timestamp,
trade['price'],
trade['price'],
trade['price'],
trade['price'],
exchange.parseNumber(exchange.amountToPrecision(symbol, trade['amount'])),
exchange.parseNumber(exchange.costToPrecision(symbol, trade['cost'])),
]
}
ohlcvs[timestamp] = candle
}
} catch (e) {
console.log (e.constructor.name, e.message)
}
}
}
async function main() {
const symbol = 'BTC/USDT'
const exchange = new ccxt.pro.binance ({ 'newUpdates': true })
await exchange.loadMarkets ()
const timeframe = '1m'
await Promise.all ([ watch (exchange, symbol, timeframe), log (exchange, symbol, timeframe) ])
await exchange.close ()
}
main()
@@ -0,0 +1,59 @@
'use strict';
const ccxt = require ('../../../ccxt');
console.log ('CCXT Version:', ccxt.version)
async function main() {
let ohlcvs = {}
const symbol = 'BTC/USDT'
const exchange = new ccxt.pro.binance ({ 'newUpdates': true })
await exchange.loadMarkets ()
const market = exchange.market (symbol)
const timeframe = '1m'
const duration = exchange.parseTimeframe (timeframe) * 1000
console.log ('Starting', exchange.id, symbol)
while (true) {
try {
const trades = await exchange.watchTrades(symbol)
for (const trade of trades) {
const timestamp = parseInt(trade['timestamp'] / duration) * duration
let candle = exchange.safe_value(ohlcvs, timestamp)
if (candle) {
candle[2] = Math.max(trade['price'], candle[2])
candle[3] = Math.min(trade['price'], candle[3])
candle[4] = trade['price']
candle[5] = exchange.parseNumber(exchange.amountToPrecision(symbol, trade['amount'] + candle[5]))
candle[6] = exchange.parseNumber(exchange.costToPrecision(symbol, trade['cost'] + candle[6]))
} else {
candle = [
timestamp,
trade['price'],
trade['price'],
trade['price'],
trade['price'],
exchange.parseNumber(exchange.amountToPrecision(symbol, trade['amount'])),
exchange.parseNumber(exchange.costToPrecision(symbol, trade['cost'])),
]
}
ohlcvs[timestamp] = candle
}
console.log ('')
console.log (exchange.iso8601 (exchange.milliseconds ()), '------------------------------------------------------')
const values = Object.values (ohlcvs).slice (-1000)
ohlcvs = exchange.indexBy (values, 0)
console.log ('Datetime ', 'Timestamp ', ... [ 'Open', 'High', 'Low', 'Close', market['base'], market['quote'] ].map (x => x.toString ().padEnd (10, ' ')))
for (let i = 0; i < values.length; i++) {
const candle = values[i]
console.log (exchange.iso8601 (candle[0]), ... candle.map (x => x.toString ().padEnd (10, ' ')))
}
} catch (e) {
console.log (e.constructor.name, e.message)
}
}
await exchange.close ()
}
main()
@@ -0,0 +1,72 @@
"use strict";
/* ------------------------------------------------------------------------ */
const ccxt = require ('../../../ccxt.js').pro
, asTable = require ('as-table') // .configure ({ print: require ('string.ify').noPretty })
, log = require ('ololog').noLocate
, ansi = require ('ansicolor').nice
;(async function test () {
let total = 0
let missing = 0
let implemented = 0
let emulated = 0
const exchanges = ccxt.exchanges
.map (id => new ccxt[id]())
.filter (exchange => exchange.has.ws)
log (
asTable (
exchanges
.map (exchange => {
let result = {};
[
'ws',
'watchOrderBook',
'watchTicker',
'watchTrades',
'watchOHLCV',
'watchBalance',
'watchOrders',
'watchMyTrades',
].forEach (key => {
total += 1
let capability = (key in exchange.has) ?
exchange.has[key].toString () :
'undefined'
if (!exchange.has[key]) {
capability = exchange.id.red.dim
missing += 1
} else if (exchange.has[key] === 'emulated') {
capability = exchange.id.yellow
emulated += 1
} else {
capability = exchange.id.green
implemented += 1
}
result[key] = capability
})
return result
})
)
)
log ('Summary:',
exchanges.length.toString ().green, 'exchanges,',
implemented.toString ().green, 'methods implemented,',
emulated.toString ().yellow, 'emulated,',
missing.toString ().red, 'missing,',
total.toString (), 'total')
}) ()
@@ -0,0 +1,46 @@
'use strict';
const ccxt = require ('../../../ccxt')
console.log ("CCXT Pro Version:", ccxt.version)
const orderbooks = {}
let run = true
async function watchOrderBook (exchange, symbol) {
while (run) {
try {
const orderbook = await exchange.watchOrderBook (symbol)
orderbooks[symbol] = orderbook
console.log (exchange.iso8601 (exchange.milliseconds ()), orderbook['datetime'], orderbook['nonce'], symbol, orderbook['asks'][0], orderbook['bids'][0])
} catch (e) {
console.log (e.constructor.name, e.message)
}
}
}
async function stop (exchange) {
await exchange.sleep (10000)
run = false
await exchange.close ()
}
async function main () {
const exchange = new ccxt.pro.binance ()
await exchange.loadMarkets ()
exchange.verbose = true
const symbols = [
'BTC/USDT',
'ETH/USDT',
]
stop (exchange).then (() => {})
await Promise.all (symbols.map (symbol => watchOrderBook (exchange, symbol)))
console.log ('Sleeping for a moment...')
await exchange.sleep (10000)
console.log ('Done')
}
main ()
@@ -0,0 +1,30 @@
'use strict';
const ccxt = require ('ccxt')
console.log ("CCXT Pro Version:", ccxt.version)
async function loop (exchange, method, symbol) {
while (true) {
try {
const orderbook = await exchange[method] (symbol)
console.log (exchange.iso8601 (exchange.milliseconds ()), orderbook['datetime'], orderbook['nonce'], symbol, orderbook['asks'][0], orderbook['bids'][0])
} catch (e) {
console.log (e.constructor.name, e.message)
}
}
}
async function main () {
const exchange = new ccxt.pro.gateio ({
'options': {'defaultType':'swap'}
})
await exchange.loadMarkets ()
// exchange.verbose = true // uncomment for debugging purposes if necessary
const symbols = [
'ANC/USDT:USDT',
]
await Promise.all (symbols.map (symbol => loop (exchange, 'fetchOrderBook', symbol)))
}
main ()
@@ -0,0 +1,23 @@
const ccxt = require ('../../../ccxt')
console.log ('CCXT Pro version:', ccxt.version)
async function main () {
const exchange = new ccxt.pro.gateio ({
'apiKey': 'YOUR_API_KEY',
'secret': 'YOUR_SECRET',
})
await exchange.loadMarkets ()
exchange.verbose = true
while (true) {
try {
const response = await exchange.watchBalance ()
console.log (new Date (), response)
} catch (e) {
console.log (e.constructor.name, e.message)
await exchange.sleep (1000)
}
}
}
main ()
@@ -0,0 +1,71 @@
'use strict';
const ccxt = require ('ccxt')
console.log ("CCXT Pro Version:", ccxt.version)
const orderbooks = {}
async function watchAllSymbols (exchange, symbols) {
while (true) {
const keys = Object.keys (orderbooks);
if (symbols.length === keys.length) {
console.log ('\n\n\n\n\n')
console.log ('----------------------------------------------------')
console.log ('All orderbooks received at least one update:');
for (let i = 0; i < symbols.length; i++) {
const symbol = symbols[i]
const orderbook = orderbooks[symbol]
console.log (exchange.iso8601 (exchange.milliseconds ()), orderbook['datetime'], orderbook['nonce'], symbol, orderbook['asks'][0], orderbook['bids'][0])
}
console.log ('----------------------------------------------------')
console.log ('\n\n\n\n\n')
// process.exit () // stop here if you want
break
} else {
await exchange.sleep (1000);
}
}
}
async function watchOrderBook (exchange, symbol) {
while (true) {
try {
const orderbook = await exchange.watchOrderBook (symbol)
orderbooks[symbol] = orderbook
console.log (exchange.iso8601 (exchange.milliseconds ()), orderbook['datetime'], orderbook['nonce'], symbol, orderbook['asks'][0], orderbook['bids'][0])
} catch (e) {
console.log (e.constructor.name, e.message)
}
}
}
async function main () {
const exchange = new ccxt.pro.gateio ({
'options': {
'defaultType': 'swap',
},
})
await exchange.loadMarkets ()
// exchange.verbose = true // uncomment for debugging purposes if necessary
const symbols = [
// 'SOS/USDT:USDT',
// 'JASMY/USDT:USDT',
// 'SLP/USDT:USDT',
'ACH/USDT:USDT',
'MKISHU/USDT:USDT',
// 'GMT/USDT:USDT',
// 'ASTR/USDT:USDT',
'RAMP/USDT:USDT',
'RSR/USDT:USDT',
// 'RACA/USDT:USDT',
// 'ROOK/USDT:USDT',
// 'ROSE/USDT:USDT',
]
await Promise.all ([
watchAllSymbols (exchange, symbols),
... symbols.map (symbol => watchOrderBook (exchange, symbol))
])
}
main ()
@@ -0,0 +1,43 @@
'use strict';
const ccxt = require ('../../../ccxt');
let stop = false
async function shutdown (milliseconds) {
await ccxt.sleep (10000)
stop = true
}
async function watchOrderBook (exchangeId, symbol) {
const exchange = new ccxt.pro[exchangeId] ()
await exchange.loadMarkets ()
// exchange.verbose = true
while (!stop) {
try {
const orderbook = await exchange.watchOrderBook (symbol)
console.log (new Date (), exchange.id, symbol, orderbook['asks'][0], orderbook['bids'][0])
} catch (e) {
console.log (symbol, e)
stop = true
break
}
}
await exchange.close ()
}
async function main () {
const streams = {
'binance': 'BTC/USDT',
'ftx': 'BTC/USDT',
};
await Promise.all ([
shutdown (10000),
... Object.entries (streams).map (([ exchangeId, symbol ]) => watchOrderBook (exchangeId, symbol))
])
}
main()
@@ -0,0 +1,37 @@
'use strict';
const ccxt = require ('../../../ccxt');
(async () => {
const streams = {
'binance': 'BTC/USDT',
'bittrex': 'BTC/USDT',
'poloniex': 'BTC/USDT',
'bitfinex': 'BTC/USDT',
'hitbtc': 'BTC/USDT',
'upbit': 'BTC/USDT',
'coinbasepro': 'BTC/USD',
'ftx': 'BTC/USDT',
'okex': 'BTC/USDT',
'gateio': 'BTC/USDT',
};
await Promise.all (Object.keys (streams).map (exchangeId =>
(async () => {
const exchange = new ccxt.pro[exchangeId] ({ enableRateLimit: true })
const symbol = streams[exchangeId]
while (true) {
try {
const orderbook = await exchange.watchOrderBook (symbol)
console.log (new Date (), exchange.id, symbol, orderbook['asks'][0], orderbook['bids'][0])
} catch (e) {
console.log (symbol, e)
}
}
}) ())
)
}) ()
@@ -0,0 +1,48 @@
'use strict';
const ccxt = require ('ccxt')
, exchange = new ccxt.okex ({
apiKey: 'YOUR_API_KEY',
secret: 'YOUR_API_SECRET',
password: 'YOUR_API_PASSWORD',
enableRateLimit: true,
options: { defaultType: 'futures' },
})
, symbol = 'BTC/USDT:USDT-201225'
, amount = 1 // how may contracts
, price = undefined // or your limit price
, side = 'buy' // or 'sell'
, type = '1' // 1 open long, 2 open short, 3 close long, 4 close short for futures
, order_type = '4' // 0 = limit order, 4 = market order
console.log ('CCXT Pro Version: ', ccxt.version)
async function main () {
try {
await exchange.loadMarkets ()
// exchange.verbose = true // uncomment for debugging
// open long market price order
const order = await exchange.createOrder(symbol, 'market', side, amount, price, { type });
// --------------------------------------------------------------------
// open long market price order
// const order = await exchange.createOrder(symbol, type, side, amount, price, { order_type });
// --------------------------------------------------------------------
// close short market price order
// const order = await exchange.createOrder(symbol, 'market', side, amount, price, { type, order_type });
// --------------------------------------------------------------------
// close short market price order
// const order = await exchange.createOrder(symbol, '4', side, amount, price, { order_type });
// ...
console.log (order)
} catch (e) {
console.log (e.constructor.name, e.message)
}
}
main ()
@@ -0,0 +1,54 @@
const ccxt = require ('ccxt')
console.log ('Node.js:', process.version)
console.log ('CCXT Pro v' + ccxt.version)
const exchange = new ccxt.pro.okex ({
'apiKey': 'YOUR_API_KEY',
'secret': 'YOUR_API_SECRET',
'password': 'YOUR_API_PASWORD'
})
async function watchBalance (code) {
while (true) {
const balance = await exchange.watchBalance ({
'code': code,
})
console.log ('New', code, 'balance is: ', balance[code])
}
}
async function createOrder (symbol, type, side, amount, price = undefined, params = {}) {
console.log ('Creating', symbol, type, 'order')
const order = await exchange.createOrder (symbol, type, side, amount, price, params);
console.log (symbol, type, side, 'order created')
console.log (order)
}
;(async () => {
await exchange.loadMarkets ()
console.log (exchange.id, 'markets loaded')
const symbol = 'ETH/USDT'
const market = exchange.market (symbol)
const quote = market['quote']
// run in parallel without await
console.log ('Watching', quote, 'balance')
watchBalance (quote)
// wait a bit to allow it to subscribe
await exchange.sleep (3000)
const ticker = await exchange.watchTicker (symbol)
const type = 'market'
const side = 'buy'
const amount = 0.1
const price = ticker['bid']
await createOrder (symbol, type, side, amount, price)
}) ()
@@ -0,0 +1,31 @@
import ccxt from '../../../js/ccxt.js';
async function main() {
const exchange = new ccxt.pro.okx()
await exchange.loadMarkets()
// exchange.verbose = true
while (true) {
try {
// don't do this, specify a list of symbols to watch for watchTickers
// or a very large subscription message will crash your WS connection
// const tickers = await exchange.watchTickers ()
// do this instead
const symbols = [
'ETH/BTC',
'BTC/USDT',
'ETH/USDT',
// ...
]
const tickers = await exchange.watchTickers (symbols)
symbols = Object.keys(tickers)
console.log (new Date(), 'received', symbols.length, 'symbols', ... symbols.slice(0,5).join(', '), '...')
} catch (e) {
console.log (new Date(), e.constructor.name, e.message)
break
}
}
}
main()
@@ -0,0 +1,46 @@
'use strict';
const ccxt = require ('ccxt')
console.log ('CCXT Version:', ccxt.version)
async function watchOrders(exchange) {
while (true) {
try {
const orders = await exchange.watchOrders() // await here
console.log(orders)
} catch (e) {
console.log(e)
}
}
}
async function watchBalance(exchange) {
while (true) {
try {
const balance = await exchange.watchBalance() // await here
console.log(balance)
} catch (e) {
console.log(e)
}
}
}
async function main() {
const exchange = new ccxt.pro.binance({
'apiKey': 'YOUR_API_KEY',
'secret': 'YOUR_SECRET',
'password': 'IF NECESSARY',
// etc...
})
await exchange.loadMarkets () // await here
// exchange.verbose = true // uncomment for debugging purposes if necessary
watchOrders(exchange) // no await
watchBalance(exchange) // no await
await exchange.close()
}
main()
@@ -0,0 +1,26 @@
'use strict';
const ccxt = require ('ccxt');
(async () => {
const exchange = new ccxt.pro.binance ({ enableRateLimit: true })
const symbols = [ 'BTC/USDT', 'ETH/BTC', 'ETH/USDT' ]
const loop = async (symbol) => {
while (true) {
try {
const orderbook = await exchange.watchOrderBook (symbol)
console.log (new Date (), symbol, orderbook['asks'][0], orderbook['bids'][0])
} catch (e) {
console.log (symbol, e)
// do nothing and retry on next loop iteration
// throw e // uncomment to break all loops in case of an error in any one of them
// break // you can also break just this one loop if it fails
}
}
}
await Promise.all (symbols.map (symbol => loop (symbol)))
}) ()
@@ -0,0 +1,28 @@
'use strict';
const ccxt = require ('ccxt');
(async () => {
const exchange = new ccxt.pro.binance ({ enableRateLimit: true })
const symbols = [ 'BTC/USDT', 'ETH/BTC', 'ETH/USDT' ]
await Promise.all (symbols.map (symbol =>
(async () => {
while (true) {
try {
const orderbook = await exchange.watchOrderBook (symbol)
console.log (new Date (), symbol, orderbook['asks'][0], orderbook['bids'][0])
} catch (e) {
console.log (symbol, e)
// do nothing and retry on next loop iteration
// throw e // uncomment to break all loops in case of an error in any one of them
// break // you can also break just this one loop if it fails
}
}
}) ())
)
}) ()
@@ -0,0 +1,30 @@
'use strict';
const ccxt = require ('ccxt')
, SocksProxyAgent = require ('socks-proxy-agent')
, socks = 'socks://127.0.0.1:7000'
, socksAgent = new SocksProxyAgent (socks)
, exchange = new ccxt.binance ({
enableRatLimit: true,
httpsAgent: socksAgent, // ←--------------------- socksAgent here
options: {
'ws': {
'options': { agent: socksAgent }, // ←--- socksAgent here
},
},
})
;(async () => {
console.log (socks)
const symbol = 'BTC/USDT'
await exchange.loadMarkets ()
console.log ('Markets loaded')
while (true) {
try {
const orderbook = await exchange.watchOrderBook (symbol)
console.log (exchange.iso8601 (exchange.milliseconds()), symbol, orderbook['asks'][0], orderbook['bids'][0])
} catch (e) {
console.log (e.constructor.name, e.message)
}
}
}) ()
@@ -0,0 +1,40 @@
'use strict';
const ccxt = require ('../../../ccxt');
async function watchOrderBook (exchange, symbol) {
while (true) {
try {
const method = exchange.has.watchOrderBook ? 'watchOrderBook' : 'fetchOrderBook'
const orderbook = await exchange[method](symbol)
console.log (new Date (), exchange.id, symbol, orderbook['asks'][0], orderbook['bids'][0])
} catch (e) {
console.log (symbol, e)
process.exit ()
}
}
}
async function watchExchange (exchangeId, symbols) {
const exchange = new ccxt.pro[exchangeId] ()
await exchange.loadMarkets ()
await Promise.all (symbols.map (symbol => watchOrderBook (exchange, symbol)))
}
async function main () {
const streams = {
'ftx': [
'BTC/USDT',
'ETH/BTC',
],
'coinex': [
'BTC/USDT',
'ETH/BTC',
],
};
const entries = Object.entries (streams)
await Promise.all (entries.map (([ exchangeId, symbols ]) => watchExchange (exchangeId, symbols)))
}
main()
@@ -0,0 +1,38 @@
'use strict';
const ccxt = require ('../../../ccxt');
async function watchOrderBook (exchange, symbol) {
while (true) {
try {
const orderbook = await exchange.watchOrderBook (symbol)
console.log (new Date (), exchange.id, symbol, orderbook['asks'][0], orderbook['bids'][0])
} catch (e) {
console.log (symbol, e)
}
}
}
async function watchExchange (exchangeId, symbols) {
const exchange = new ccxt.pro[exchangeId] ()
await exchange.loadMarkets ()
await Promise.all (symbols.map (symbol => watchOrderBook (exchange, symbol)))
}
async function main () {
const streams = {
'binance': [
'BTC/USDT',
'ETH/BTC',
],
'ftx': [
'BTC/USDT',
'ETH/BTC',
],
};
const entries = Object.entries (streams)
await Promise.all (entries.map (([ exchangeId, symbols ]) => watchExchange (exchangeId, symbols)))
}
main()
@@ -0,0 +1,40 @@
'use strict';
const ccxt = require ('../../../ccxt');
console.log ('CCXT Version:', ccxt.version)
async function watchTickerLoop (exchange, symbol) {
// exchange.verbose = true // uncomment for debugging purposes if necessary
while (true) {
try {
const ticker = await exchange.watchTicker (symbol)
console.log (new Date (), exchange.id, symbol, ticker['last'])
} catch (e) {
console.log (symbol, e)
// do nothing and retry on next loop iteration
// throw e // uncomment to break all loops in case of an error in any one of them
// break // you can also break just this one loop if it fails
}
}
}
async function exchangeLoop (exchangeId, symbols) {
const exchange = new ccxt.pro[exchangeId]()
await exchange.loadMarkets ()
const loops = symbols.map (symbol => watchTickerLoop (exchange, symbol))
await Promise.all (loops)
await exchange.close ()
}
async function main () {
const exchanges = {
'binance': [ 'BTC/USDT', 'ETH/USDT' ],
'ftx': [ 'BTC/USD', 'ETH/USD' ],
}
const loops = Object.entries (exchanges).map (([ exchangeId, symbols ]) => exchangeLoop (exchangeId, symbols))
await Promise.all (loops)
}
main ()
@@ -0,0 +1,27 @@
'use strict';
const ccxt = require ('ccxt');
async function watchOrderBook (exchangeId, symbol) {
const exchange = new ccxt.pro[exchangeId] ()
while (true) {
try {
const orderbook = await exchange.watchOrderBook (symbol)
console.log (new Date (), exchange.id, symbol, orderbook['asks'][0], orderbook['bids'][0])
} catch (e) {
console.log (symbol, e)
}
}
}
async function main () {
const streams = {
'binance': 'BTC/USDT',
'ftx': 'BTC/USDT',
};
await Promise.all (Object.entries (streams).map (([ exchangeId, symbol ]) => watchOrderBook (exchangeId, symbol)))
}
main()
@@ -0,0 +1,43 @@
'use strict';
const ccxt = require ('../../../ccxt');
console.log ('CCXT Version:', ccxt.version);
async function watchExchange (exchangeId, symbol) {
const exchange = new ccxt.pro[exchangeId] ({
newUpdates: true,
})
await exchange.loadMarkets ();
// exchange.verbose = true // uncomment for debugging purposes if necessary
while (true) {
try {
const trades = await exchange.watchTrades (symbol)
for (let i = 0; i < trades.length; i++) {
const trade = trades[i]
console.log (exchange.iso8601 (exchange.milliseconds ()), exchange.id, trade['symbol'], trade['id'], trade['datetime'], trade['price'], trade['amount'])
}
} catch (e) {
console.log (symbol, e)
}
}
}
async function main () {
const streams = {
'binance': 'BTC/USDT',
'okex': 'BTC/USDT',
'kraken': 'BTC/USD',
};
const values = Object.entries (streams)
const promises = values.map (([ exchangeId, symbol ]) => watchExchange (exchangeId, symbol))
await Promise.all (promises)
}
main ()
@@ -0,0 +1,42 @@
'use strict';
const ccxt = require ('../../../ccxt');
(async () => {
const streams = {
'binance': 'BTC/USDT',
'okex': 'BTC/USDT'
};
await Promise.all (Object.keys (streams).map (exchangeId =>
(async () => {
const exchange = new ccxt.pro[exchangeId] ({
enableRateLimit: true,
options: {
tradesLimit: 100, // lower = better, 1000 by default
},
})
const symbol = streams[exchangeId]
let lastId = ''
while (true) {
console.log ('---')
try {
const trades = await exchange.watchTrades (symbol)
for (let i = 0; i < trades.length; i++) {
const trade = trades[i]
if (trade['id'] > lastId) {
console.log (exchange.iso8601 (exchange.milliseconds ()), exchange.id, trade['symbol'], trade['id'], trade['datetime'], trade['price'], trade['amount'])
lastId = trade['id']
}
}
} catch (e) {
console.log (symbol, e)
}
}
}) ())
)
}) ()
@@ -0,0 +1,29 @@
'use strict';
const ccxt = require ('ccxt');
console.log ('CCXT Version:', ccxt.version)
async function watchTrades (exchange, symbol) {
while (true) {
try {
const trades = await exchange.watchTrades (symbol)
console.log (new Date (), exchange.id, symbol, trades.length, 'trades')
} catch (e) {
console.log (symbol, e)
}
}
}
async function main () {
const symbols = [ 'USDT/THB', 'BTC/THB', 'ETH/THB' ]
const exchange = new ccxt.pro.zipmex({
'newUpdates': true
})
const markets = await exchange.loadMarkets ()
exchange.verbose = true
await Promise.all (symbols.map ((symbol) => watchTrades (exchange, symbol)))
}
main()
@@ -0,0 +1,29 @@
// see this issue for details
// https://github.com/ccxt/ccxt/issues/6659
const ccxt = require ('ccxt')
const exchange = new ccxt.pro.kraken ()
function yellow (s) {
return '\x1b[33m' + s + '\x1b[0m'
}
async function runWs () {
while (1) {
const book = await exchange.watchOrderBook ('ETH/BTC')
console.log (new Date (), 'WS ', book['datetime'], book['bids'][0][0], book['asks'][0][0])
}
}
async function runRest () {
while (1) {
const book = await exchange.fetchOrderBook ('ETH/BTC')
const timestamp = new Date (exchange.last_response_headers['Date']).getTime ()
const datetime = exchange.iso8601 (timestamp)
console.log (new Date (), 'REST', yellow (datetime), book['bids'][0][0], book['asks'][0][0])
}
}
runWs ()
runRest ()
@@ -0,0 +1,76 @@
<?php
error_reporting(E_ALL);
date_default_timezone_set('UTC');
$root = dirname(dirname(dirname(dirname(__FILE__))));
include $root . '/ccxt.php';
function create_exchange($exchange_id, $config) {
$keys = array(
'ids',
'markets',
'markets_by_id',
'currencies',
'currencies_by_id',
'base_currencies',
'quote_currencies',
'symbols',
);
$exchange_class = '\\ccxt\\pro\\' . $exchange_id;
$exchange = new $exchange_class($config);
$markets_on_disk = "./{$exchange_id}.markets.json";
$exchange->verbose = true; // this is a debug output to demonstrate which networking calls are being issued
if (file_exists($markets_on_disk)) {
$cache = json_decode(file_get_contents($markets_on_disk), true);
foreach ($keys as $key) {
$exchange->{$key} = $cache[$key];
}
} else {
$markets = yield $exchange->load_markets();
$cache = array();
foreach ($keys as $key) {
$cache[$key] = $exchange->{$key};
}
file_put_contents($markets_on_disk, json_encode($cache));
}
return $exchange;
}
$exchanges = array(
array('binance', array(
'id' => 'binance1',
'apiKey' => 'YOUR_API_KEY_HERE',
'secret' => 'YOUR_SECRET_HERE',
)),
array('binance', array(
'id' => 'binance2',
'apiKey' => 'YOUR_API_KEY_HERE',
'secret' => 'YOUR_SECRET_HERE',
)),
);
$loop = function($exchange_id, $config) {
$exchange = yield create_exchange($exchange_id, $config);
$exchange->verbose = true;
while (true) {
$response = yield $exchange->watch_balance();
print('--------------------------------------------------------------');
print($exchange->id);
print($response);
}
};
foreach ($exchanges as $exchange) {
\React\Async\coroutine($loop, $exchange[0], $exchange[1]);
}
@@ -0,0 +1,27 @@
<?php
$root = dirname(dirname(dirname(dirname(__FILE__))));
include $root . '/ccxt.php';
$config = array('enableRateLimit' => true);
$binance = new \ccxt\pro\binance($config);
$bittrex = new \ccxt\pro\bittrex($config);
$symbol = "BTC/USDT";
$loop = function($exchange, $symbol) {
echo 'got inside' . PHP_EOL;
for ($i = 0; $i < 5; $i++) {
$ticker = yield $exchange->watch_ticker($symbol);
print_ticker($ticker, $exchange->id, $symbol);
}
};
function print_ticker($ticker, $exchange_name, $symbol) {
$bid = $ticker['bid'];
$ask = $ticker['ask'];
echo "$exchange_name $symbol - bid: $bid <> ask: $ask" . PHP_EOL;
}
\React\Async\coroutine($loop, $bittrex, $symbol);
\React\Async\coroutine($loop, $binance, $symbol);
@@ -0,0 +1,30 @@
<?php
$root = dirname(dirname(dirname(dirname(__FILE__))));
include $root . '/ccxt.php';
$id = 'aax';
$exchange_class = '\\ccxt\\pro\\' . $id;
$exchange = new $exchange_class(array(
'enableRateLimit' => true,
));
$symbols = array('BTC/USDT', 'ETH/USDT', 'ETH/BTC');
function print_orderbook($orderbook, $symbol) {
$id = isset($orderbook['nonce']) ? $orderbook['nonce'] : $orderbook['datetime'];
echo $id, ' ', $symbol, ' ',
count($orderbook['asks']), ' asks ', json_encode($orderbook['asks'][0]), ' ',
count($orderbook['bids']), ' bids ', json_encode($orderbook['bids'][0]), "\n";
}
$loop = function($exchange, $symbol) {
while (true) {
$orderbook = yield $exchange->watch_order_book($symbol);
print_orderbook($orderbook, $symbol);
}
};
foreach ($symbols as $symbol) {
\React\Async\coroutine($loop, $exchange, $symbol);
}
@@ -0,0 +1,41 @@
<?php
error_reporting(E_ALL);
date_default_timezone_set('UTC');
include dirname(dirname(dirname(dirname(__FILE__)))). '/ccxt.php';
$binance_id = '\\ccxt\\pro\\binance';
$binance_exchange = new $binance_id( /*[ 'apiKey' => _YOUR_APIKEY_HERE_, 'secret' => _YOUR_SECRET_HERE_ ]*/ );
$ftx_id = '\\ccxt\\pro\\ftx';
$ftx_exchange = new $ftx_id( /*['apiKey' => _YOUR_APIKEY_HERE_, 'secret' => _YOUR_SECRET_HERE_]*/ );
$wrapper_func = function($exchange, $symbol, $method_name) {
if ($exchange->has[$method_name]) {
print ("Starting $method_name for $exchange->id -> $symbol\n");
while (true) {
try {
$orderbook = yield $exchange->$method_name($symbol);
print("$exchange->id -> $method_name -> $symbol : " . substr(json_encode($orderbook), 0 , 70) . "...\n");
} catch (\Exception $ex) {
print($ex->getMessage());
sleep(5);
}
}
} else {
print ($exchange->id . " API yet doesnt support $method_name");
}
};
function runAsync (...$args) {
\React\Async\coroutine(...$args);
}
// *** uncomment whichever methods you want to test ***
// runAsync($wrapper_func, ...[$exchange, 'ETH/USDT', 'watchOrderBook']);
// runAsync($wrapper_func, ...[$exchange, 'ETH/USDT', 'watchTicker']);
// runAsync($wrapper_func, ...[$exchange, 'ETH/USDT', 'watchOrders']);
// runAsync($wrapper_func, ...[$exchange, 'ETH/USDT', 'watchMyTrades']);
runAsync($wrapper_func, ...[$binance_exchange, 'SOL/USDT', 'watchTrades']);
runAsync($wrapper_func, ...[$ftx_exchange, 'ETH/USDT', 'watchTrades']);
@@ -0,0 +1,34 @@
import ccxt.pro
from pprint import pprint
from asyncio import run
print('CCXT Version:', ccxt.__version__)
async def main():
exchange = ccxt.pro.binance({
'apiKey': 'YOUR_API_KEY',
'secret': 'YOUR_SECRET',
})
markets = await exchange.load_markets()
# exchange.verbose = True # uncomment for debugging purposes if necessary
symbol = 'ETH/BTC'
type = 'limit' # or 'market'
side = 'sell' # or 'buy'
amount = 1.0
price = 0.060154 # or None
order = await exchange.create_order(symbol, type, side, amount, price)
canceled = await exchange.cancel_order(order['id'], order['symbol'])
pprint(canceled)
await exchange.close()
run(main())
@@ -0,0 +1,53 @@
# -*- coding: utf-8 -*-
import ccxt.pro
from asyncio import run
print('CCXT Version:', ccxt.__version__)
# This example will run silent and will return your balance only when the balance is updated.
#
# 1. launch the example with your keys and keep it running
# 2. go to the trading section on the website
# 3. place a order on a spot market
# 4. see your balance updated in the example
#
# Warning! This example might produce a lot of output to your screen
async def watch_balance(exchange):
await exchange.load_markets()
# exchange.verbose = True # uncomment for debugging purposes if necessary
balance = await exchange.fetch_balance()
print('---------------------------------------------------------')
print(exchange.iso8601(exchange.milliseconds()))
print(balance)
print('')
while True:
try:
update = await exchange.watch_balance()
balance = exchange.deep_extend(balance, update)
# it will print the balance update when the balance changes
# if the balance remains unchanged the exchange will not send it
print('---------------------------------------------------------')
print(exchange.iso8601(exchange.milliseconds()))
print(balance)
print('')
except Exception as e:
print('watch_balance() failed')
print(type(e).__name__, str(e))
break
async def main():
exchange = ccxt.pro.binance({
'apiKey': 'YOUR_API_KEY',
'secret': 'YOUR_SECRET',
})
await watch_balance(exchange)
await exchange.close()
run(main())
@@ -0,0 +1,39 @@
import ccxt
import ccxt.pro
import asyncio
from pprint import pprint
loop = asyncio.get_event_loop()
async def print_balance(exchange, market_type):
while True:
try:
balance = await exchange.watch_balance({'type': market_type})
pprint(balance)
print('balance of ' + market_type, balance)
print(exchange.options[market_type])
except ccxt.BaseError as e:
print(type(e), e)
except Exception as e:
print(type(e), e)
async def main():
exchange = ccxt.pro.binance({
"apiKey": "",
"secret": "",
'enableRateLimit': True,
'newUpdates': True,
})
# you must make an order a transfer first to the websocket to send updates
asyncio.ensure_future(print_balance(exchange, 'future'))
asyncio.ensure_future(print_balance(exchange, 'delivery')) # inverse futures settled in BTC
asyncio.ensure_future(print_balance(exchange, 'spot'))
asyncio.run(main())
asyncio.ensure_future(main())
loop.run_forever()
@@ -0,0 +1,22 @@
import ccxt.pro
from asyncio import run
async def main():
exchange = ccxt.pro.binance({
'options': {
'defaultType': 'future',
},
})
symbol = 'BTC/USDT'
while True:
try:
orderbook = await exchange.watch_order_book(symbol)
print(orderbook['bids'][0], orderbook['asks'][0])
except Exception as e:
print(type(e).__name__, str(e))
await exchange.close()
run(main())
@@ -0,0 +1,27 @@
import ccxt.pro as ccxt
from asyncio import run
print('CCXT Version:', ccxt.__version__)
async def main():
exchange = ccxt.pro.binance({
'options': {
'defaultType': 'future', # spot, margin, future, delivery
},
})
# or
# exchange = ccxt.pro.binanceusdm()
# or
# exchange = ccxt.pro.binancecoinm()
symbol = 'BTC/USDT'
while True:
try:
orderbook = await exchange.watch_order_book(symbol)
print(exchange.iso8601(exchange.milliseconds()), exchange.id, symbol, 'ask:', orderbook['asks'][0], 'bid:', orderbook['bids'][0])
except Exception as e:
print(type(e).__name__, str(e))
break
await exchange.close()
run(main())
@@ -0,0 +1,42 @@
import ccxt.pro
from asyncio import run, gather
print('CCXT Pro version', ccxt.pro.__version__)
async def watch_order_book(exchange, symbol):
while True:
try:
orderbook = await exchange.watch_order_book(symbol)
datetime = exchange.iso8601(exchange.milliseconds())
print(datetime, orderbook['nonce'], symbol, orderbook['asks'][0], orderbook['bids'][0])
except Exception as e:
print(type(e).__name__, str(e))
break
async def reload_markets(exchange, delay):
while True:
try:
await exchange.sleep(delay)
markets = await exchange.load_markets(True)
datetime = exchange.iso8601(exchange.milliseconds())
print(datetime, 'Markets reloaded')
except Exception as e:
print(type(e).__name__, str(e))
break
async def main():
exchange = ccxt.pro.binance()
await exchange.load_markets()
# exchange.verbose = True
symbol = 'BTC/USDT'
delay = 60000 # every minute = 60 seconds = 60000 milliseconds
loops = [watch_order_book(exchange, symbol), reload_markets(exchange, delay)]
await gather(*loops)
await exchange.close()
run(main())
@@ -0,0 +1,73 @@
# -*- coding: utf-8 -*-
import ccxt.pro
from asyncio import gather, run
orderbooks = {}
def handle_all_orderbooks(orderbooks):
print('We have the following orderbooks:')
for id, orderbooks_by_symbol in orderbooks.items():
for symbol in orderbooks_by_symbol.keys():
orderbook = orderbooks_by_symbol[symbol]
print(ccxt.pro.Exchange.iso8601(orderbook['timestamp']), id, symbol, orderbook['asks'][0], orderbook['bids'][0])
async def symbol_loop(exchange, id, symbol):
print('Starting', id, symbol)
while True:
try:
orderbook = await exchange.watch_order_book(symbol)
orderbooks[id] = orderbooks.get(id, {})
orderbooks[id][symbol] = orderbook
print('===========================================================')
#
# here you can do what you want
# with the most recent versions of each orderbook you have so far
#
# you can also wait until all of them are available
# by just looking into all the orderbooks and counting them
#
# we just print them here to keep this example simple
#
handle_all_orderbooks(orderbooks)
except Exception as e:
print(str(e))
# raise e # uncomment to break all loops in case of an error in any one of them
break # you can break just this one loop if it fails
async def exchange_loop(id, config):
print('Starting', id)
exchange = getattr(ccxt.pro, config['id'])({
'options': config['options'],
})
loops = [symbol_loop(exchange, id, symbol) for symbol in config['symbols']]
await gather(*loops)
await exchange.close()
async def main():
configs = {
'Exchange A (Binance spot)': {
'id': 'binance',
'symbols': ['BTC/USDT', 'ETH/BTC','ETH/USDT'],
'options': {
'defaultType': 'spot',
},
},
'Exchange B (Binance futures)': {
'id': 'binance',
'symbols': ['BTC/USDT', 'ETH/USDT'],
'options': {
'defaultType': 'future',
},
},
}
loops = [exchange_loop(id, config) for id, config in configs.items()]
await gather(*loops)
run(main())
@@ -0,0 +1,51 @@
import ccxt.pro as ccxt
import asyncio
orderbooks = {}
def when_orderbook_changed(exchange_spot, symbol, orderbook):
# this is a common handler function
# it is called when any of the orderbook is updated
# it has access to both the orderbook that was updated
# as well as the rest of the orderbooks
# ...................................................................
print('-------------------------------------------------------------')
print('Last updated:', exchange_spot.iso8601(exchange_spot.milliseconds()))
# ...................................................................
# print just one orderbook here
# print(orderbook['datetime'], symbol, orderbook['asks'][0], orderbook['bids'][0])
# ...................................................................
# or print all orderbooks that have been already subscribed-to
for symbol, orderbook in orderbooks.items():
print(orderbook['datetime'], symbol, orderbook['asks'][0], orderbook['bids'][0])
async def watch_one_orderbook(exchange_spot, symbol):
# a call cost of 1 in the queue of subscriptions
# means one subscription per exchange.rateLimit milliseconds
your_delay = 1
await exchange_spot.throttle(your_delay)
while True:
try:
orderbook = await exchange_spot.watch_order_book(symbol)
orderbooks[symbol] = orderbook
when_orderbook_changed(exchange_spot, symbol, orderbook)
except Exception as e:
print(type(e).__name__, str(e))
async def watch_some_orderbooks(exchange_spot, symbol_list):
loops = [watch_one_orderbook(exchange_spot, symbol) for symbol in symbol_list]
# let them run, don't for all tasks cause they execute asynchronously
# don't print here
await asyncio.gather(*loops)
async def main():
exchange_spot = ccxt.binance()
await exchange_spot.load_markets()
await watch_some_orderbooks(exchange_spot, ['ZEN/USDT', 'RUNE/USDT', 'AAVE/USDT', 'SNX/USDT'])
await exchange_spot.close()
asyncio.run(main())
@@ -0,0 +1,40 @@
# -*- coding: utf-8 -*-
from asyncio import run
import ccxt.pro as ccxt
from pprint import pprint
# This example will run silent and will return your balance only when the balance is updated.
# 1. launch the example with your keys and keep it running
# 2. go to the margin trading on the website
# 3. place a margin order on a spot market
# 4. see your balance updated in the example
async def main():
exchange = ccxt.pro.binance({
'apiKey': 'YOUR_API_KEY',
'secret': 'YOUR_SECRET',
'options': {
'defaultType': 'margin',
},
# comment it out if you don't want debug output
# this is for the demo purpose only (to show the communication)
'verbose': True,
})
while True:
try:
balance = await exchange.watch_balance()
# it will print the balance update when the balance changes
# if the balance remains unchanged the exchange will not send it
pprint(balance)
except Exception as e:
print('watch_balance() failed')
print(e)
break
await exchange.close()
run(main())
@@ -0,0 +1,43 @@
import ccxt.pro
from asyncio import run
print('CCXT Pro version', ccxt.pro.__version__)
def table(values):
first = values[0]
keys = list(first.keys()) if isinstance(first, dict) else range(0, len(first))
widths = [max([len(str(v[k])) for v in values]) for k in keys]
string = ' | '.join(['{:<' + str(w) + '}' for w in widths])
return "\n".join([string.format(*[str(v[k]) for k in keys]) for v in values])
async def main():
exchange = ccxt.pro.binance({
# 'options': {
# 'OHLCVLimit': 1000, # how many candles to store in memory by default
# },
})
symbol = 'ETH/USDT' # or BNB/USDT, etc...
timeframe = '1m' # 5m, 1h, 1d
limit = 10 # how many candles to return max
method = 'watchOHLCV'
if (method in exchange.has) and exchange.has[method]:
max_iterations = 100000 # how many times to repeat the loop before exiting
for i in range(0, max_iterations):
try:
ohlcvs = await exchange.watch_ohlcv(symbol, timeframe, None, limit)
now = exchange.milliseconds()
print('\n===============================================================================')
print('Loop iteration:', i, 'current time:', exchange.iso8601(now), symbol, timeframe)
print('-------------------------------------------------------------------------------')
print(table([[exchange.iso8601(o[0])] + o[1:] for o in ohlcvs]))
except Exception as e:
print(type(e).__name__, str(e))
break
await exchange.close()
else:
print(exchange.id, method, 'is not supported or not implemented yet')
run(main())
@@ -0,0 +1,34 @@
# -*- coding: utf-8 -*-
from asyncio import run
import ccxt.pro as ccxt
class MyBinance(ccxt.binance):
def handle_order_book_message(self, client, message, orderbook):
asks = self.safe_value(message, 'a', [])
bids = self.safe_value(message, 'b', [])
# printing high-frequency updates is a resource-heavy task
# this print statement is here just to demonstrate the work of it
# replace it with you logic for processing individual updates
print('Updates:', {
'asks': asks,
'bids': bids,
})
return super(MyBinance, self).handle_order_book_message(client, message, orderbook);
async def main():
exchange = MyBinance()
symbol = 'BTC/USDT'
print('Watching', exchange.id, symbol)
while True:
try:
orderbook = await exchange.watch_order_book(symbol)
except Exception as e:
print(str(e))
# raise e # uncomment to break all loops in case of an error in any one of them
# break # you can also break just this one loop if it fails
await exchange.close()
run(main())
@@ -0,0 +1,63 @@
import ccxt.pro
from asyncio import run, gather
data = {
'orderbook': None,
'balance': None,
}
def common_handler(exchange, symbol):
market = exchange.market(symbol)
base = market['base']
quote = market['quote']
balance = data['balance']
orderbook = data['orderbook']
if balance and orderbook:
total = balance['total']
tip = [ orderbook['asks'][0], orderbook['bids'][0] ]
print(exchange.iso8601(exchange.milliseconds()), symbol, 'orderbook:', tip, 'balance:', total)
async def watch_order_book(exchange, symbol):
while True:
try:
data['orderbook'] = await exchange.watch_order_book(symbol)
common_handler(exchange, symbol)
except Exception as e:
print(type(e).__name__, str(e))
break # break this loop
async def watch_balance(exchange, symbol):
while True:
try:
data['balance'] = await exchange.watch_balance()
common_handler(exchange, symbol)
except Exception as e:
print(type(e).__name__, str(e))
break # break this loop
async def main():
exchange = ccxt.pro.binance({
'apiKey': 'YOUR_API_KEY',
'secret': 'YOUR_SECRET',
})
await exchange.load_markets()
symbol = 'BTC/USDT'
while True:
try:
loops = [
watch_order_book(exchange, symbol),
watch_balance(exchange, symbol)
]
await gather(*loops)
except Exception as e:
print(type(e).__name__, str(e))
break
await exchange.close()
run(main())
@@ -0,0 +1,59 @@
# Python
import ccxt.pro
from asyncio import run, gather
from pprint import pprint
async def place_delayed_order(exchange, symbol, amount, price):
try:
await exchange.sleep(5000) # wait a bit
order = await exchange.create_limit_buy_order(symbol, amount, price)
print(exchange.iso8601(exchange.milliseconds()), 'place_delayed_order')
pprint(order)
print('---------------------------------------------------------------')
except Exception as e:
# break
print(e)
async def watch_orders_loop(exchange, symbol):
while True:
try:
orders = await exchange.watch_orders(symbol)
print(exchange.iso8601(exchange.milliseconds()), 'watch_orders_loop', len(orders), ' last orders cached')
print('---------------------------------------------------------------')
except Exception as e:
# break
print(e)
async def watch_balance_loop(exchange):
while True:
try:
balance = await exchange.watch_balance()
print(exchange.iso8601(exchange.milliseconds()), 'watch_balance_loop')
pprint(balance)
print('---------------------------------------------------------------')
except Exception as e:
# break
print(e)
async def main():
exchange = ccxt.pro.binanceusdm({
'apiKey': 'YOUR_API_KEY',
'secret': 'YOUR_SECRET',
})
symbol = 'BTC/USDT'
amount = 0.001
price = 11111
loops = [
watch_orders_loop(exchange, symbol),
watch_balance_loop(exchange),
place_delayed_order(exchange, symbol, amount, price)
]
await gather(*loops)
await exchange.close()
run(main())
@@ -0,0 +1,48 @@
# -*- coding: utf-8 -*-
from asyncio import run, gather
import os
import sys
root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
sys.path.append(root + '/python')
import ccxt.pro # noqa: E402
print('CCXT Version:', ccxt.__version__)
async def print_balance_continuously(exchange):
while True:
try:
print('-----------------------------------------------------------')
await exchange.load_markets()
balance = await exchange.watch_balance()
print(exchange.iso8601(exchange.milliseconds()), exchange.id)
for currency, value in balance['total'].items():
print(value, currency)
except Exception as e:
print('-----------------------------------------------------------')
print(exchange.iso8601(exchange.milliseconds()), exchange.id, type(e), e)
await exchange.sleep(300000) # sleep 5 minutes and retry
async def main():
config = {
'apiKey': 'YOUR_API_KEY',
'secret': 'YOUR_SECRET',
}
exchange_ids = [
'binance',
'binanceusdm',
'binancecoinm',
]
exchanges = [getattr(ccxt.pro, exchange_id)(config) for exchange_id in exchange_ids]
printing_loops = [print_balance_continuously(exchange) for exchange in exchanges]
await gather(*printing_loops)
closing_tasks = [exchange.close() for exchange in exchanges]
await gather(*closing_tasks)
run(main())
@@ -0,0 +1,41 @@
import ccxt.pro
from asyncio import run
def table(values):
first = values[0]
keys = list(first.keys()) if isinstance(first, dict) else range(0, len(first))
widths = [max([len(str(v[k])) for v in values]) for k in keys]
string = ' | '.join(['{:<' + str(w) + '}' for w in widths])
return "\n".join([string.format(*[str(v[k]) for k in keys]) for v in values])
async def main():
exchange = ccxt.pro.bitmex({
# 'options': {
# 'OHLCVLimit': 1000, # how many candles to store in memory by default
# },
})
symbol = 'BTC/USD'
timeframe = '1m' # 5m, 1h, 1d
limit = 10 # how many candles to return max
method = 'watchOHLCV'
if (method in exchange.has) and exchange.has[method]:
max_iterations = 100 # how many times to repeat the loop before exiting
for i in range(0, max_iterations):
try:
ohlcvs = await exchange.watch_ohlcv(symbol, timeframe, None, limit)
now = exchange.milliseconds()
print('\n===============================================================================')
print('Loop iteration:', i, 'current time:', exchange.iso8601(now), symbol, timeframe)
print('-------------------------------------------------------------------------------')
print(table([[exchange.iso8601(o[0])] + o[1:] for o in ohlcvs]))
except Exception as e:
print(type(e).__name__, str(e))
break
await exchange.close()
else:
print(exchange.id, method, 'is not supported or not implemented yet')
run(main())
@@ -0,0 +1,73 @@
import ccxt.pro
from asyncio import run, gather
def table(values):
first = values[0]
keys = list(first.keys()) if isinstance(first, dict) else range(0, len(first))
widths = [max([len(str(v[k])) for v in values]) for k in keys]
string = ' | '.join(['{:<' + str(w) + '}' for w in widths])
return "\n".join([string.format(*[str(v[k]) for k in keys]) for v in values])
async def watch_ticker(color, duration, exchange, symbol):
method = 'watchTicker'
if (method in exchange.has) and exchange.has[method]:
start = exchange.milliseconds()
i = 1
while True:
ticker = await exchange.watch_ticker(symbol)
now = exchange.milliseconds()
# start color code
print(color, 'Ticker ========================================================================')
print(exchange.iso8601(now), symbol, 'iteration:', i, 'last price:', ticker['last'])
print('-------------------------------------------------------------------------------')
# pprint.pprint(ticker) # uncomment for a lengthy complete printout
print('\x1b[0m') # stop color code
i += 1
if (start + duration) < now:
break
else:
raise Exception(exchange.id + ' ' + method + ' is not supported or not implemented yet')
async def watch_ohlcv(color, duration, exchange, symbol, timeframe, limit):
method = 'watchOHLCV'
if (method in exchange.has) and exchange.has[method]:
start = exchange.milliseconds()
i = 1
while True:
ohlcvs = await exchange.watch_ohlcv(symbol, timeframe, None, limit)
now = exchange.milliseconds()
# start color code
print(color, 'OHLCV =========================================================================')
print(exchange.iso8601(now), symbol, timeframe, 'iteration:', i)
print('-------------------------------------------------------------------------------')
print(table([[exchange.iso8601(o[0])] + o[1:] for o in ohlcvs]))
print('\x1b[0m') # stop color code
i += 1
if (start + duration) < now:
break
else:
raise Exception(exchange.id + ' ' + method + ' is not supported or not implemented yet')
# =============================================================================
async def main():
exchange = ccxt.pro.bitmex()
await exchange.load_markets()
duration = 1200000 # run 20 minutes = 1200000 milliseconds
symbol = 'BTC/USD'
limit = 10
loops = [
watch_ticker('\033[35m', duration, exchange, symbol), # magenta
watch_ohlcv('\x1b[33m', duration, exchange, symbol, '1m', limit), # yellow
watch_ohlcv('\x1b[32m', duration, exchange, symbol, '5m', limit), # green
]
await gather(*loops)
await exchange.close()
run(main())
@@ -0,0 +1,23 @@
import ccxt.pro
from asyncio import run
print('CCXT Pro version', ccxt.pro.__version__)
async def main():
exchange = ccxt.pro.bitvavo()
await exchange.load_markets()
exchange.verbose = True
symbol = 'BTC/EUR'
while True:
try:
orderbook = await exchange.watch_order_book(symbol)
print(orderbook['nonce'], symbol, orderbook['asks'][0], orderbook['bids'][0])
except Exception as e:
print(type(e).__name__, str(e))
break
await exchange.close()
run(main())
@@ -0,0 +1,53 @@
# -*- coding: utf-8 -*-
import asyncio
import ccxt.pro
print('CCXT Version:', ccxt.__version__)
async def loop(exchange, symbol, timeframe, complete_candles_only=False):
duration_in_seconds = exchange.parse_timeframe(timeframe)
duration_in_ms = duration_in_seconds * 1000
while True:
try:
trades = await exchange.watch_trades(symbol)
if len(trades) > 0:
current_minute = int(exchange.milliseconds() / duration_in_ms)
ohlcvc = exchange.build_ohlcvc(trades, timeframe)
if complete_candles_only:
ohlcvc = [candle for candle in ohlcvc if int(candle[0] / duration_in_ms) < current_minute]
if len(ohlcvc) > 0:
print('-----------------------------------------------------------')
print("Symbol:", symbol, "timeframe:", timeframe)
print(ohlcvc)
except Exception as e:
print(f"{type(e).__name__}: {(str(e))}")
# raise type(e)(str(e)) # uncomment to break all loops in case of an error in any one of them
# break # you can also break just this one loop if it fails
async def main():
# select the exchange
exchange = ccxt.pro.binance()
if exchange.has['watchTrades']:
markets = await exchange.load_markets()
# Change this value accordingly
timeframe = '1m'
limit = 5
selected_symbols = list(markets.values())[:limit]
# you can also specify the symbols manually
# selected_symbols = ['BTC/USDT', 'ETH/USDT']
# Use this variable to choose if only complete candles
# should be considered
complete_candles_only = True
await asyncio.gather(*[loop(exchange, symbol['symbol'], timeframe, complete_candles_only)
for symbol in selected_symbols])
await exchange.close()
else:
print(exchange.id, 'does not support watchTrades yet')
asyncio.run(main())
@@ -0,0 +1,30 @@
# -*- coding: utf-8 -*-
import ccxt.pro
from asyncio import run
async def main():
exchange = ccxt.pro.coinbase()
method = 'watchTrades'
print('CCXT Pro version', ccxt.pro.__version__)
if exchange.has[method]:
last_id = ''
while True:
try:
trades = await exchange.watch_trades('BTC/USD')
for trade in trades:
if trade['id'] > last_id:
print(exchange.iso8601(exchange.milliseconds()), trade['symbol'], trade['datetime'], trade['price'], trade['amount'])
last_id = trade['id']
except Exception as e:
# stop
await exchange.close()
raise e
# or retry
# pass
else:
raise Exception(exchange.id + ' ' + method + ' is not supported or not implemented yet')
run(main())
@@ -0,0 +1,27 @@
# -*- coding: utf-8 -*-
import ccxt.pro
from asyncio import run
async def main():
exchange = ccxt.pro.coinbase()
method = 'watchTrades'
print('CCXT Pro version', ccxt.pro.__version__)
if exchange.has[method]:
while True:
try:
trades = await exchange.watch_trades('BTC/USD')
num_trades = len(trades)
trade = trades[-1]
print(exchange.iso8601(exchange.milliseconds()), trade['symbol'], trade['datetime'], trade['price'], trade['amount'], 'stored', num_trades, 'trades in cache')
except Exception as e:
# stop
await exchange.close()
raise e
# or retry
# pass
else:
raise Exception(exchange.id + ' ' + method + ' is not supported or not implemented yet')
run(main())
@@ -0,0 +1,22 @@
import ccxt.pro
from asyncio import run
async def consume_all_trades(exchange, symbol):
await exchange.load_markets()
while True:
try:
trades = await exchange.watch_trades(symbol)
print('----------------------------------------------------------------------')
print(exchange.iso8601(exchange.milliseconds()), 'received', len(trades), 'new', symbol, 'trades:')
for trade in trades:
print(exchange.id, symbol, trade['id'], trade['datetime'], trade['amount'], trade['price'])
exchange.trades[symbol].clear()
except Exception as e:
print(type(e).__name__, str(e))
await exchange.close()
exchange = ccxt.pro.bitmex()
symbol = 'BTC/USD'
run(consume_all_trades(exchange, symbol))
@@ -0,0 +1,25 @@
# -*- coding: utf-8 -*-
import asyncio
import ccxt.pro
from datetime import datetime
async def loop(exchange, symbol):
since = datetime.utcnow()
timestamp = int(since.timestamp() * 1000)
while True:
trades = await exchange.watch_trades(symbol, since=timestamp)
print('--------------------------------------------------------------')
print('Received', len(trades), 'after', exchange.iso8601 (timestamp))
print('waiting for next update...')
async def main():
exchange = ccxt.pro.gateio()
await loop(exchange, 'BTC/USDT')
await exchange.close()
if __name__ == '__main__':
asyncio.run(main())
@@ -0,0 +1,31 @@
# -*- coding: utf-8 -*-
from asyncio import run
import ccxt.pro
from pprint import pprint
class MyBinance(ccxt.pro.binance):
def handle_ohlcv(self, client, message):
# add your handling of the original message here
print('intercepted', message)
return super(MyBinance, self).handle_ohlcv(client, message)
async def main():
exchange = MyBinance()
symbol = 'BTC/USDT'
print('Watching', exchange.id, symbol)
while True:
try:
ohlcv = await exchange.watch_ohlcv(symbol, '1m')
except Exception as e:
print(str(e))
# raise e # uncomment to break all loops in case of an error in any one of them
# break # you can also break just this one loop if it fails
await exchange.close()
if __name__ == "__main__":
print('CCXT Version:', ccxt.__version__)
run(main())
@@ -0,0 +1,31 @@
# -*- coding: utf-8 -*-
import ccxt.pro
from asyncio import gather, run
async def symbol_loop(exchange, symbol):
print('Starting the', exchange.id, 'symbol loop with', symbol)
while True:
try:
orderbook = await exchange.watch_order_book(symbol)
now = exchange.milliseconds()
print(exchange.iso8601(now), exchange.id, symbol, orderbook['asks'][0], orderbook['bids'][0])
except Exception as e:
print(str(e))
# raise e # uncomment to break all loops in case of an error in any one of them
break # you can break just this one loop if it fails
async def main():
exchange = ccxt.pro.kucoin({
"apiKey": "YOUR_API_KEY",
"secret": "YOUR_API_SECRET",
"password": "YOUR_API_PASSWORD",
})
symbols = ['KDA/USDT', 'KDA/BTC', 'BTC/USDT']
loops = [symbol_loop(exchange, symbol) for symbol in symbols]
await gather(*loops)
await exchange.close()
run(main())
@@ -0,0 +1,56 @@
# -*- coding: utf-8 -*-
import ccxt.pro
from asyncio import gather, run
async def symbol_loop(exchange, method, symbol):
print('Starting', exchange.id, method, symbol)
while True:
try:
response = await getattr(exchange, method)(symbol)
now = exchange.milliseconds()
iso8601 = exchange.iso8601(now)
if method == 'watchOrderBook':
print(iso8601, exchange.id, method, symbol, response['asks'][0], response['bids'][0])
elif method == 'watchTicker':
print(iso8601, exchange.id, method, symbol, response['high'], response['low'], response['bid'], response['ask'])
elif method == 'watchTrades':
print(iso8601, exchange.id, method, symbol, len(response), 'trades')
except Exception as e:
print(str(e))
# raise e # uncomment to break all loops in case of an error in any one of them
break # you can break just this one loop if it fails
async def method_loop(exchange, method, symbols):
print('Starting', exchange.id, method, symbols)
loops = [symbol_loop(exchange, method, symbol) for symbol in symbols]
await gather(*loops)
async def exchange_loop(exchange_id, methods):
print('Starting', exchange_id, methods)
exchange = getattr(ccxt.pro, exchange_id)()
loops = [method_loop(exchange, method, symbols) for method, symbols in methods.items()]
await gather(*loops)
await exchange.close()
async def main():
exchanges = {
'okex': {
'watchOrderBook': ['BTC/USDT', 'ETH/BTC', 'ETH/USDT'],
'watchTicker': ['BTC/USDT'],
},
'binance': {
'watchOrderBook': ['BTC/USDT', 'ETH/BTC'],
'watchTrades': [ 'ETH/BTC' ],
},
}
loops = [exchange_loop(exchange_id, methods) for exchange_id, methods in exchanges.items()]
await gather(*loops)
run(main())
@@ -0,0 +1,59 @@
# -*- coding: utf-8 -*-
import asyncio
import ccxt.pro
orderbooks = {}
def handle_all_orderbooks(orderbooks):
print('We have the following orderbooks:')
for exchange_id, orderbooks_by_symbol in orderbooks.items():
for symbol in orderbooks_by_symbol.keys():
orderbook = orderbooks_by_symbol[symbol]
print(ccxt.pro.Exchange.iso8601(orderbook['timestamp']), exchange_id, symbol, orderbook['asks'][0], orderbook['bids'][0])
async def symbol_loop(exchange, symbol):
while True:
try:
orderbook = await exchange.watch_order_book(symbol)
orderbooks[exchange.id] = orderbooks.get(exchange.id, {})
orderbooks[exchange.id][symbol] = orderbook
print('===========================================================')
#
# here you can do what you want
# with the most recent versions of each orderbook you have so far
#
# you can also wait until all of them are available
# by just looking into all the orderbooks and counting them
#
# we just print them here to keep this example simple
#
handle_all_orderbooks(orderbooks)
except Exception as e:
print(str(e))
# raise e # uncomment to break all loops in case of an error in any one of them
break # you can break just this one loop if it fails
async def exchange_loop(exchange_id, symbols):
exchange = getattr(ccxt.pro, exchange_id)()
loops = [symbol_loop(exchange, symbol) for symbol in symbols]
await asyncio.gather(*loops)
await exchange.close()
async def main():
symbols = ['BTC/USDT', 'ETH/BTC']
# symbols = []
exchanges = {
'okex': symbols + ['ETH/USDT'],
'binance': symbols,
}
loops = [exchange_loop(exchange_id, symbols) for exchange_id, symbols in exchanges.items()]
await asyncio.gather(*loops)
asyncio.run(main())
@@ -0,0 +1,56 @@
# -*- coding: utf-8 -*-
import ccxt.pro
from asyncio import run, gather, sleep
orderbooks = {}
def handle_all_orderbooks(orderbooks):
print('We have the following orderbooks:')
for exchange_id, orderbooks_by_symbol in orderbooks.items():
for symbol in orderbooks_by_symbol.keys():
orderbook = orderbooks_by_symbol[symbol]
print(ccxt.pro.Exchange.iso8601(orderbook['timestamp']), exchange_id, symbol, orderbook['asks'][0], orderbook['bids'][0])
async def handling_loop(orderbooks):
delay = 5
while True:
await sleep(delay)
handle_all_orderbooks(orderbooks)
async def symbol_loop(exchange, symbol):
while True:
try:
orderbook = await exchange.watch_order_book(symbol)
orderbooks[exchange.id] = orderbooks.get(exchange.id, {})
orderbooks[exchange.id][symbol] = orderbook
except Exception as e:
print(str(e))
# raise e # uncomment to break all loops in case of an error in any one of them
break # you can break just this one loop if it fails
async def exchange_loop(exchange_id, symbols):
exchange = getattr(ccxt.pro, exchange_id)()
loops = [symbol_loop(exchange, symbol) for symbol in symbols]
await gather(*loops)
await exchange.close()
async def main():
symbols = ['BTC/USDT', 'ETH/BTC']
# symbols = []
exchanges = {
'okex': symbols + ['ETH/USDT'],
'binance': symbols,
}
loops = [exchange_loop(exchange_id, symbols) for exchange_id, symbols in exchanges.items()]
loops += [handling_loop(orderbooks)]
await gather(*loops)
run(main())
@@ -0,0 +1,83 @@
# -*- coding: utf-8 -*-
import ccxt.pro
from asyncio import gather, run
async def symbol_loop(exchange, method, symbol):
print('Starting', exchange.id, method, symbol)
while True:
try:
response = await getattr(exchange, method)(symbol)
now = exchange.milliseconds()
iso8601 = exchange.iso8601(now)
if method == 'watchOrderBook':
print(iso8601, exchange.id, method, symbol, response['asks'][0], response['bids'][0])
elif method == 'watchTicker':
print(iso8601, exchange.id, method, symbol, response['high'], response['low'], response['bid'], response['ask'])
elif method == 'watchTrades':
print(iso8601, exchange.id, method, symbol, len(response), 'trades')
except Exception as e:
print(str(e))
# raise e # uncomment to break all loops in case of an error in any one of them
break # you can break just this one loop if it fails
async def symbols_method_loop(exchange, method, symbols):
print('Starting', exchange.id, method, symbols)
loops = [symbol_loop(exchange, method, symbol) for symbol in symbols]
await gather(*loops)
async def method_loop(exchange, method):
print('Starting', exchange.id, method)
while True:
try:
response = await getattr(exchange, method)()
now = exchange.milliseconds()
iso8601 = exchange.iso8601(now)
print(iso8601, exchange.id, method, response)
except Exception as e:
print(str(e))
# raise e # uncomment to break all loops in case of an error in any one of them
break # you can break just this one loop if it fails
async def exchange_loop(exchange_id, methods, config={}):
print('Starting', exchange_id, methods)
exchange = getattr(ccxt.pro, exchange_id)()
for attr, value in config.items():
setattr(exchange, attr, value)
loops = [symbols_method_loop(exchange, method, symbols) if len(symbols) else method_loop(exchange, method) for method, symbols in methods.items()]
await gather(*loops)
await exchange.close()
async def main():
keys = {
'okex': {
'apiKey': 'YOUR_API_KEY',
'secret': 'YOUR_SECRET',
},
'binance': {
'apiKey': 'YOUR_API_KEY',
'secret': 'YOUR_SECRET',
},
}
exchanges = {
'okex': {
'watchOrderBook': ['BTC/USDT', 'ETH/BTC', 'ETH/USDT'],
'watchTicker': ['BTC/USDT'],
'watchBalance': [],
},
'binance': {
'watchOrderBook': ['BTC/USDT', 'ETH/BTC'],
'watchTrades': [ 'ETH/BTC' ],
'watchBalance': [],
},
}
loops = [exchange_loop(exchange_id, methods, keys.get(exchange_id, {})) for exchange_id, methods in exchanges.items()]
await gather(*loops)
run(main())
@@ -0,0 +1,36 @@
# -*- coding: utf-8 -*-
import ccxt.pro
from asyncio import gather, run
async def symbol_loop(exchange, symbol):
print('Starting the', exchange.id, 'symbol loop with', symbol)
while True:
try:
orderbook = await exchange.watch_order_book(symbol)
now = exchange.milliseconds()
print(exchange.iso8601(now), exchange.id, symbol, orderbook['asks'][0], orderbook['bids'][0])
except Exception as e:
print(str(e))
# raise e # uncomment to break all loops in case of an error in any one of them
break # you can break just this one loop if it fails
async def exchange_loop(exchange_id, symbols):
print('Starting the', exchange_id, 'exchange loop with', symbols)
exchange = getattr(ccxt.pro, exchange_id)()
loops = [symbol_loop(exchange, symbol) for symbol in symbols]
await gather(*loops)
await exchange.close()
async def main():
exchanges = {
'okex': ['BTC/USDT', 'ETH/BTC', 'ETH/USDT'],
'binance': ['BTC/USDT', 'ETH/BTC'],
}
loops = [exchange_loop(exchange_id, symbols) for exchange_id, symbols in exchanges.items()]
await gather(*loops)
run(main())
@@ -0,0 +1,39 @@
# -*- coding: utf-8 -*-
import ccxt.pro
from asyncio import gather, run
async def symbol_loop(exchange, symbol):
print('Starting the', exchange.id, 'symbol loop with', symbol)
while True:
try:
trades = await exchange.watch_trades(symbol)
now = exchange.milliseconds()
print(exchange.iso8601(now), exchange.id, symbol, len(trades), trades[-1]['price'])
except Exception as e:
print(str(e))
# raise e # uncomment to break all loops in case of an error in any one of them
break # you can break just this one loop if it fails
async def exchange_loop(exchange_id, symbols):
print('Starting the', exchange_id, 'exchange loop with', symbols)
exchange = getattr(ccxt.pro, exchange_id)({
'newUpdates': True, # https://github.com/ccxt/ccxt/wiki/ccxt.pro.manual#incremental-data-structures
})
loops = [symbol_loop(exchange, symbol) for symbol in symbols]
await gather(*loops)
await exchange.close()
async def main():
exchanges = {
'okex': ['BTC/USDT', 'ETH/BTC', 'ETH/USDT'],
'binance': ['BTC/USDT', 'ETH/BTC'],
}
loops = [exchange_loop(exchange_id, symbols) for exchange_id, symbols in exchanges.items()]
await gather(*loops)
run(main())
@@ -0,0 +1,30 @@
# -*- coding: utf-8 -*-
import asyncio
import ccxt.pro
async def loop(exchange_id, symbol):
exchange = getattr(ccxt.pro, exchange_id)()
while True:
try:
orderbook = await exchange.watch_order_book(symbol)
now = exchange.milliseconds()
print(exchange.iso8601(now), exchange.id, symbol, orderbook['asks'][0], orderbook['bids'][0])
except Exception as e:
print(str(e))
# raise e # uncomment to break all loops in case of an error in any one of them
break # you can break just this one loop if it fails
await exchange.close()
async def main():
symbols = {
'kraken': 'BTC/USDT',
'binance': 'BTC/USDT',
'bitmex': 'XBT_USDT',
}
await asyncio.gather(*[loop(exchange_id, symbol) for exchange_id, symbol in symbols.items()])
asyncio.run(main())
@@ -0,0 +1,34 @@
import ccxt.pro
import asyncio
import time
async def watch_book(exchange, ticker):
last = None
while True:
try:
orderbook = await exchange.watch_order_book(ticker)
# TODO add timeout within a minute
# TODO add last
top_bid = orderbook['bids'][0][0]
if last != top_bid:
print(f'{int(time.time() * 1000)} top bid for celo on {exchange.name} is {top_bid}')
last = top_bid
except Exception as e:
print(f'{exchange.name} failed {type(e)} {e}')
async def main():
exchange_ids = ['coinbasepro', 'okcoin', 'bittrex']
exchanges = [getattr(ccxt.pro, exchange_id)() for exchange_id in exchange_ids]
try:
done, pending = await asyncio.wait({watch_book(exchange, 'CELO/USD') for exchange in exchanges}, return_when=asyncio.FIRST_EXCEPTION)
for completed in done:
# trigger the exception here
completed.result()
except Exception as e:
print(f'closing all exchanges because of exception {type(e)} {e}')
await asyncio.gather(*[exchange.close() for exchange in exchanges])
asyncio.run(main())
@@ -0,0 +1,50 @@
# -*- coding: utf-8 -*-
from asyncio import run
import ccxt.pro
print('CCXT Pro Version: ', ccxt.pro.__version__)
exchange = ccxt.pro.okex({
'apiKey': 'YOUR_API_KEY',
'secret': 'YOUR_API_SECRET',
'password': 'YOUR_API_PASSWORD',
'options': { 'defaultType': 'swap' },
})
async def main():
await exchange.load_markets()
# exchange.verbose = True # uncomment for debugging
# https://github.com/ccxt/ccxt/wiki/Manual#overriding-unified-params
# https://www.okex.com/docs/en/#swap-swap---orders
symbol = 'BTC/USDT:USDT'
amount = 1 # how may contracts
price = None # or your limit price
side = 'buy' # or 'sell'
future_type = '1' # 1 open long, 2 open short, 3 close long, 4 close short for futures
order_type = '4' # 0 = limit order, 4 = market order
try:
# open long market price order
order = await exchange.create_order(symbol, 'market', side, amount, price, {'type': future_type})
# --------------------------------------------------------------------
# open long market price order
# const order = await exchange.create_order(symbol, type, side, amount, price, {'order_type': order_type})
# --------------------------------------------------------------------
# close short market price order
# const order = await exchange.create_order(symbol, 'market', side, amount, price, {'type': future_type, 'order_type': order_type})
# --------------------------------------------------------------------
# close short market price order
# const order = await exchange.create_order(symbol, '4', side, amount, price, {'order_type': order_type})
# ...
print(order)
except Exception as e:
print(type(e).__name__, str(e))
await exchange.close()
run(main())
@@ -0,0 +1,35 @@
# -*- coding: utf-8 -*-
import asyncio
import ccxt.pro as ccxt
from pprint import pprint
async def main():
exchange = ccxt.pro.okex({
'apiKey': 'YOUR_API_KEY',
'secret': 'YOUR_SECRET',
# okex requires this: https://github.com/ccxt/ccxt/wiki/Manual#authentication
'password': 'YOUR_API_PASSWORD',
# comment it out if you don't want debug output
# this is for the demo purpose only (to show the communication)
'verbose': True,
})
while True:
try:
balance = await exchange.watch_balance({
# okex watch_balance requires a symbol or an instrument_id
'symbol': 'BTC/USDT',
'type': 'margin',
})
# it will print the balance update when the balance changes
# if the balance remains unchanged the exchange will not send it
pprint(balance)
except Exception as e:
print('watch_balance() failed')
print(e)
break
await exchange.close()
asyncio.run(main())
@@ -0,0 +1,37 @@
# -*- coding: utf-8 -*-
import asyncio
import ccxt.pro as ccxt
from pprint import pprint
async def main():
exchange = ccxt.pro.okex({
'apiKey': 'YOUR_API_KEY',
'secret': 'YOUR_SECRET',
# okex requires this: https://github.com/ccxt/ccxt/wiki/Manual#authentication
'password': 'YOUR_API_PASSWORD',
'options': {
'watchBalance': 'margin',
},
# comment it out if you don't want debug output
# this is for the demo purpose only (to show the communication)
'verbose': True,
})
while True:
try:
balance = await exchange.watch_balance({
# okex watch_balance requires a symbol or an instrument_id
'symbol': 'BTC/USDT',
})
# it will print the balance update when the balance changes
# if the balance remains unchanged the exchange will not send it
pprint(balance)
except Exception as e:
print('watch_balance() failed')
print(e)
break
await exchange.close()
asyncio.run(main())
@@ -0,0 +1,36 @@
import ccxt.pro
from asyncio import run
print('CCXT Pro version', ccxt.pro.__version__)
async def main():
exchange = ccxt.pro.okx({
'options': {
'watchOrderBook': {
'depth': 'bbo-tbt', # tick-by-tick best bidask
},
},
})
markets = await exchange.load_markets()
# exchange.verbose = True # uncomment for debugging purposes if necessary
symbol = 'BTC/USDT'
while True:
try:
# -----------------------------------------------------------------
# use this:
# orderbook = await exchange.watch_order_book(symbol)
# print(orderbook['datetime'], symbol, orderbook['asks'][0], orderbook['bids'][0])
# -----------------------------------------------------------------
# or this:
ticker = await exchange.watch_ticker(symbol)
print(ticker['datetime'], symbol, [ticker['ask'], ticker['askVolume']], [ticker['bid'], ticker['bidVolume']])
# -----------------------------------------------------------------
except Exception as e:
print(type(e).__name__, str(e))
break
await exchange.close()
run(main())
@@ -0,0 +1,55 @@
import ccxt.pro
from asyncio import run, ensure_future
from pprint import pprint
print('CCXT Version:', ccxt.__version__)
# on_connected() is called when a client connection is established
# note that the exchange will reuse the same client connection
# some exchanges might require two or more public/private connections
# therefore on_connected() may be called more than once
class MyBinance(ccxt.pro.binance):
def on_connected(self, client, message=None):
print('Connected to', client.url)
ensure_future(create_order(self))
async def create_order(exchange):
symbol = 'BTC/USDT'
type = 'limit'
side = 'buy'
amount = 123.45 # change for your values
price = 54.321 # change for your values
params = {}
try:
order = await exchange.create_order(symbol, type, side, amount, price, params)
print('--------------------------------------------------------------')
print('create_order():')
pprint(order)
except Exception as e:
print(type(e).__name__, str(e))
async def watch_orders(exchange):
while True:
try:
orders = await exchange.watch_orders()
print('--------------------------------------------------------------')
print('watch_orders():')
pprint(orders)
except Exception as e:
print(type(e).__name__, str(e))
break
await exchange.close()
exchange = MyBinance({
'apiKey': 'YOUR_API_KEY',
'secret': 'YOUR_SECRET',
})
run(watch_orders(exchange))
@@ -0,0 +1,35 @@
import ccxt.pro
import asyncio
async def watch_order_book(exchange, symbol):
while True:
orderbook = await exchange.watch_order_book(symbol)
print(orderbook['datetime'], symbol, orderbook['asks'][0], orderbook['bids'][0])
async def watch_trades(exchange, symbol):
while True:
trades = await exchange.watch_trades(symbol)
last = trades[-1]
print(last['datetime'], last['price'], last['amount'])
async def main():
exchange = ccxt.pro.bitstamp()
await exchange.load_markets()
symbol = 'BTC/USD'
while True:
try:
loops = [
watch_order_book(exchange, symbol),
watch_trades(exchange, symbol)
]
await asyncio.gather(*loops)
except Exception as e:
print(type(e).__name__, str(e))
break
await exchange.close()
asyncio.run(main())
@@ -0,0 +1,25 @@
# -*- coding: utf-8 -*-
from asyncio import run
import ccxt.pro
async def loop(exchange, symbol):
await exchange.throttle(10)
while True:
try:
orderbook = await exchange.watch_order_book(symbol)
now = exchange.milliseconds()
print(exchange.iso8601(now), symbol, orderbook['asks'][0], orderbook['bids'][0])
except Exception as e:
print(str(e))
# raise e # uncomment to break all loops in case of an error in any one of them
# break # you can also break just this one loop if it fails
async def main():
exchange = ccxt.pro.ftx()
symbols = ['BTC/USDT', 'ETH/USDT', 'ETH/BTC']
await asyncio.gather(*[loop(exchange, symbol) for symbol in symbols])
await exchange.close()
run(main())
@@ -0,0 +1,23 @@
import ccxt.pro
from asyncio import run
from pprint import pprint
print('CCXT Version:', ccxt.__version__)
async def main():
exchange = ccxt.pro.phemex({
'apiKey': 'YOUR_API_KEY',
'secret': 'YOUR_SECRET',
})
markets = await exchange.load_markets()
# exchange.verbose = True # uncomment for debugging purposes if necessary
try:
symbol = 'UNI/USDT'
response = await exchange.cancel_all_orders(symbol)
pprint(response)
except Exception as e:
print(type(e).__name__, str(e))
await exchange.close()
run(main())
@@ -0,0 +1,66 @@
# -*- coding: utf-8 -*-
import asyncio
import sys
import os
# ------------------------------------------------------------------------------
root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))))
sys.path.append(root + '/python')
# ------------------------------------------------------------------------------
import ccxt.pro
print('CCXT Version:', ccxt.pro.__version__)
orderbooks = {}
def handle_all_orderbooks(exchange, orderbooks, spot, future):
if spot in orderbooks and future in orderbooks:
spot_order_book = orderbooks[spot]
future_order_book = orderbooks[future]
timestamp = exchange.milliseconds()
spot_lag = abs(timestamp - spot_order_book['timestamp']) if spot_order_book['timestamp'] else 10000
future_lag = abs(timestamp - future_order_book['timestamp']) if future_order_book['timestamp'] else 10000
if spot_lag >= 10000 or future_lag >= 10000:
print('Lag > 10 seconds')
async def symbol_loop(exchange, symbol, spot, future):
while True:
try:
orderbook = await exchange.watch_order_book(symbol)
orderbooks[symbol] = orderbook
print(exchange.id, '{:13s}'.format(symbol), orderbook['datetime'], orderbook['asks'][0], orderbook['bids'][0])
#
# here you can do what you want
# with the most recent versions of each orderbook you have so far
#
# you can also wait until all of them are available
# by just looking into all the orderbooks and counting them
#
# we just print them here to keep this example simple
#
handle_all_orderbooks(exchange, orderbooks, spot, future)
except Exception as e:
print(str(e))
# raise e # uncomment to break all loops in case of an error in any one of them
break # you can break just this one loop if it fails
async def main():
spot = 'BTC/USDT'
future = 'BTC/USDT:USDT'
symbols = [ spot, future ]
exchange = ccxt.pro.bitmart()
loops = [
symbol_loop(exchange, spot, spot, future),
symbol_loop(exchange, future, spot, future),
]
await asyncio.gather(*loops)
await exchange.close()
asyncio.run(main())
@@ -0,0 +1,35 @@
# -*- coding: utf-8 -*-
import asyncio
import ccxt.pro
async def loop(exchange, symbol, n):
i = 0
while True:
try:
orderbook = await exchange.watch_order_book(symbol)
# print every 100th bidask to avoid wasting CPU cycles on printing
if not i % 100:
# i = how many updates there were in total
# n = the number of the pair to count subscriptions
now = exchange.milliseconds()
print(exchange.iso8601(now), n, symbol, i, orderbook['asks'][0], orderbook['bids'][0])
i += 1
except Exception as e:
print(str(e))
# raise e # uncomment to break all loops in case of an error in any one of them
# break # you can also break just this one loop if it fails
async def main():
exchange = ccxt.pro.kraken()
await exchange.load_markets()
markets = list(exchange.markets.values())
symbols = [market['symbol'] for market in markets if not market['darkpool']]
await asyncio.gather(*[loop(exchange, symbol, n) for n, symbol in enumerate(symbols)])
await exchange.close()
asyncio.run(main())
@@ -0,0 +1,45 @@
import asyncio
import ccxt.pro
class MyBinance(ccxt.pro.binance):
def handle_mini_ticker(self, client, message):
market_id = self.safe_string_lower(message, 's')
message_hash = market_id + '@miniTicker'
client.resolve(message, message_hash)
def handle_message(self, client, message):
handlers = {
'24hrMiniTicker': self.handle_mini_ticker,
# add other custom handlers here
}
e = self.safe_string(message, 'e')
method = self.safe_value(handlers, e)
if method:
return method(client, message)
else:
return super(MyBinance, self).handle_message(client, message)
async def main():
exchange = MyBinance({
'enableRateLimit': False,
'options': {
'defaultType': 'future'
}
})
await exchange.load_markets()
# exchange.verbose = True # uncomment for debugging purposes
market = exchange.market('BTC/USDT')
message_hash = market['lowercaseId'] + '@miniTicker'
while True:
try:
print(await exchange.watch_public(message_hash))
except Exception as e:
print(type(e).__name__, str(e))
await exchange.close()
if __name__ == '__main__':
asyncio.run(main())
@@ -0,0 +1,39 @@
# -*- coding: utf-8 -*-
from asyncio import run, gather
import ccxt.pro
print('CCXT Version:', ccxt.__version__)
async def exchange_loop(exchange_id, symbols):
exchange = getattr(ccxt.pro, exchange_id)()
markets = await exchange.load_markets()
await gather(*[watch_ticker_loop(exchange, symbol) for symbol in symbols])
await exchange.close()
async def watch_ticker_loop(exchange, symbol):
# exchange.verbose = True # uncomment for debugging purposes if necessary
while True:
try:
ticker = await exchange.watch_ticker(symbol)
now = exchange.milliseconds()
print(exchange.iso8601(now), exchange.id, symbol, 'bid:', ticker['bid'], 'ask:', ticker['ask'], 'last:', ticker['last'], 'on', ticker['datetime'])
except Exception as e:
print(str(e))
# raise e # uncomment to break all loops in case of an error in any one of them
break # you can break just this one loop if it fails
async def main():
exchanges = {
'binance': [ 'BTC/USDT', 'ETH/USDT' ],
'ftx': [ 'BTC/USD', 'ETH/USD' ],
}
loops = [exchange_loop(exchange_id, symbols) for exchange_id, symbols in exchanges.items()]
await gather(*loops)
run(main())
@@ -0,0 +1,45 @@
# -*- coding: utf-8 -*-
from asyncio import gather, run
import ccxt.pro
from pprint import pprint
async def watch_ticker_continuously(exchange, symbol):
filename = exchange.id + '-' + symbol.replace('/', '-') + '.csv'
print('Watching', exchange.id, symbol, filename)
keys = ['index', 'exchange', 'symbol', 'timestamp', 'open', 'high', 'low', 'close', 'baseVolume']
with open(filename, 'w') as file:
file.write(','.join(keys) + "\n")
index = 0
while True:
try:
ticker = await exchange.watch_ticker(symbol)
values = [str(index), exchange.id] + [str(ticker[key]) for key in keys[2:]]
print(*values)
with open(filename, 'a') as file:
file.write(','.join(values) + "\n")
index += 1
except Exception as e:
print(e)
async def watch_tickers_continuously(exchange_id, overrides, symbols):
exchange_class = getattr(ccxt.pro, exchange_id)
exchange = exchange_class(overrides)
coroutines = [watch_ticker_continuously(exchange, symbol) for symbol in symbols]
await gather(*coroutines)
await exchange.close()
async def main():
exchanges = {
'binance': {'options': {'defaultType': 'future'}},
'huobipro': {}
}
symbols = ['BTC/USDT', 'ETH/USDT', 'LTC/USDT', 'XRP/USDT', 'BCH/USDT']
coroutines = [watch_tickers_continuously(exchange_id, exchanges[exchange_id], symbols) for exchange_id in exchanges.keys()]
return await gather(*coroutines)
run(main())
@@ -0,0 +1,46 @@
<!DOCTYPE HTML>
<html>
<head>
<title>CCXT Basic example for the browser</title>
<script type="text/javascript" src="https://unpkg.com/ccxt"></script>
<script>
document.addEventListener ("DOMContentLoaded", function () {
alert ('ccxt version ' + ccxt.version);
const exchange = new ccxt.bittrex ({
'proxyUrl': 'https://cors-anywhere.herokuapp.com/'
})
const symbol = 'BTC/USDT'
exchange.fetchTicker (symbol).then (ticker => {
const text = [
exchange.id,
symbol,
JSON.stringify (ticker, undefined, '\n\t')
]
document.getElementById ('content').innerHTML = text.join (' ')
}).catch (e => {
const text = [
e.constructor.name,
e.message,
]
document.getElementById ('content').innerHTML = text.join (' ')
})
})
</script>
</head>
<body>
<h1>Hello, CCXT!</h1>
<pre id="content"></pre>
</body>
</html>
@@ -0,0 +1,47 @@
<!DOCTYPE HTML>
<html>
<head>
<title>CCXT Basic example for the browser</title>
<script type="text/javascript" src="https://unpkg.com/ccxt"></script>
<style type="text/css">
#contentA { background-color: #ccccff; }
#contentB { background-color: #ffcccc; }
</style>
<script>'use strict'
class MyExchange extends ccxt.coinbasepro {
async fetchTicker (symbol, params = {}) {
alert ("I'm about to call the parent method from the overrided class, woohooo!")
// just call the parent method and that's it
return super.fetchTicker (symbol, params);
}
}
document.addEventListener ("DOMContentLoaded", function () {
const exchange = new MyExchange ()
const symbol = 'ETH/BTC'
const showFetchedTicker = function (ticker, elementId) {
const text = [
exchange.id,
symbol,
JSON.stringify (ticker, undefined, '\n\t')
]
document.getElementById (elementId).innerHTML = text.join (' ')
}
exchange.fetchTicker (symbol).then (ticker => showFetchedTicker (ticker, 'content'))
})
</script>
</head>
<body>
<h1>Hello, CCXT!</h1>
<pre id="content"></pre>
</body>
</html>
+52
View File
@@ -0,0 +1,52 @@
<!DOCTYPE HTML>
<html>
<head>
<title>CCXT Basic example for the browser</title>
<script type="text/javascript" src="https://unpkg.com/ccxt"></script>
<script>
document.addEventListener ("DOMContentLoaded", function () {
alert ('ccxt version ' + ccxt.version + ' supporting ');
const pollTickerContinuously = async function (exchange, symbol) {
while (true) {
try {
const ticker = await exchange.fetchTicker (symbol)
const text = [
exchange.id,
symbol,
JSON.stringify (ticker, undefined, '\n\t')
]
document.getElementById ('content').innerHTML = text.join (' ');
} catch (e) {
const text = [
e.constructor.name,
e.message,
]
document.getElementById ('content').innerHTML = text.join (' ');
}
}
}
const exchange = new ccxt.binance ({ enableRateLimit: true })
const symbol = 'ETH/BTC'
pollTickerContinuously (exchange, symbol)
})
</script>
</head>
<body>
<h1>Hello, CCXT!</h1>
<pre id="content"></pre>
</body>
</html>
@@ -0,0 +1,49 @@
<!DOCTYPE HTML>
<html>
<head>
<title>CCXT Basic example for the browser</title>
<script type="text/javascript" src="https://unpkg.com/ccxt"></script>
<script>
document.addEventListener ("DOMContentLoaded", async function () {
alert ('ccxt version ' + ccxt.version);
const enableRateLimit = true
const exchange = new ccxt.poloniex ({ enableRateLimit })
const symbol = 'ETH/BTC'
while (true) {
let text = []
try {
const ticker = await exchange.fetchTicker (symbol)
text = [
exchange.id,
symbol,
JSON.stringify (exchange.omit (ticker, 'info'), undefined, '\t')
]
} catch (e) {
text = [
e.constructor.name,
e.message,
]
}
document.getElementById ('content').innerHTML = text.join (' ')
}
})
</script>
</head>
<body>
<h1>Hello, CCXT!</h1>
<pre id="content"></pre>
</body>
</html>
+43
View File
@@ -0,0 +1,43 @@
<!DOCTYPE HTML>
<html>
<head>
<title>CCXT Basic example for the browser</title>
<script type="text/javascript" src="https://unpkg.com/ccxt"></script>
<script>
document.addEventListener ("DOMContentLoaded", function () {
alert ('CCXT' + (ccxt.isBrowser ? ' browser' : '') + ' version ' + ccxt.version);
const exchange = new ccxt.coinbasepro ({ enableRateLimit: true })
const symbol = 'ETH/BTC'
exchange.fetchTicker (symbol).then (ticker => {
const text = [
exchange.id,
symbol,
JSON.stringify (ticker, undefined, '\n\t')
]
document.getElementById ('content').innerHTML = text.join (' ')
}).catch (e => {
const text = [
e.constructor.name,
e.message,
]
document.getElementById ('content').innerHTML = text.join (' ')
})
})
</script>
</head>
<body>
<h1>Hello, CCXT!</h1>
<pre id="content"></pre>
</body>
</html>
@@ -0,0 +1,28 @@
<!DOCTYPE HTML>
<html>
<head>
<title>CCXT Basic example for the browser</title>
<script type="text/javascript" src="https://unpkg.com/ccxt"></script>
<script>
document.addEventListener ("DOMContentLoaded", function () {
async function main () {
const exchange = new ccxt.binance ({
'apiKey': 'YOUR_API_KEY',
'secret': 'YOUR_API_SECRET',
'proxyUrl': 'https://cors-anywhere.herokuapp.com/',
})
const response = await exchange.fetchBalance ()
console.log (response)
}
main ()
})
</script>
</head>
<body>
<h1>Hello, CCXT!</h1>
<pre id="content"></pre>
</body>
</html>
@@ -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
const 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')
+46
View File
@@ -0,0 +1,46 @@
<!DOCTYPE HTML>
<html>
<head>
<title>CCXT Basic example for the browser</title>
<script type="text/javascript" src="https://unpkg.com/ccxt"></script>
<script>
document.addEventListener ("DOMContentLoaded", function () {
alert ('ccxt version ' + ccxt.version);
const exchange = new ccxt.bitmex ({
'proxyUrl': 'http://127.0.0.1:8080/',
})
const symbol = 'BTC/USDT'
exchange.fetchTicker (symbol).then (ticker => {
const text = [
exchange.id,
symbol,
JSON.stringify (ticker, undefined, '\n\t')
]
document.getElementById ('content').innerHTML = text.join (' ')
}).catch (e => {
const text = [
e.constructor.name,
e.message,
]
document.getElementById ('content').innerHTML = text.join (' ')
})
})
</script>
</head>
<body>
<h1>Hello, CCXT!</h1>
<pre id="content"></pre>
</body>
</html>
@@ -0,0 +1,61 @@
<!DOCTYPE HTML>
<html>
<head>
<title>CCXT Basic example for the browser</title>
<script type="text/javascript" src="https://unpkg.com/ccxt"></script>
<script type="text/javascript" src="https://unpkg.com/lightweight-charts@3.4.0/dist/lightweight-charts.standalone.production.js"></script>
<script>
document.addEventListener ("DOMContentLoaded", async function () {
try {
const exchange = new ccxt.coinbasepro ({ enableRateLimit: true });
const symbol = 'ETH/BTC';
const timeframe = '1d';
const since = undefined;
const limit = 600;
const config = {
width: 600,
height: 300,
priceScale: {
position: 'left',
mode: 1,
autoScale: true,
invertScale: false,
},
timeScale: {
fixLeftEdge: true,
lockVisibleTimeRangeOnResize: true,
rightBarStaysOnScroll: true,
visible: true,
timeVisible: true,
secondsVisible: true,
},
crosshair: {
mode: window.LightweightCharts.CrosshairMode.Normal,
},
};
const chart = window.LightweightCharts.createChart(document.body, config);
const candleSeries = chart.addCandlestickSeries();
while (true) {
try {
const response = await exchange.fetchOHLCV(symbol, timeframe, since, limit);
const last = response[response.length - 1]
const [ timestamp, open, high, low, close ] = last;
const data = response.map (([ timestamp, open, high, low, close ]) => ({ time: exchange.iso8601 (timestamp), open, high, low, close }));
candleSeries.setData(data);
} catch (e) {
console.log (e.constructor.name, e.message);
}
await exchange.sleep (1000);
}
} catch (e) {
alert (e.constructor.name + ' ' + e.message);
}
})
</script>
</head>
<body>
</body>
</html>
@@ -0,0 +1,97 @@
<!DOCTYPE html>
<html>
<body>
<h2>CCXT running on a Webworker example</h2>
<p>This example uses a web worker to continuously call <b>fetchTicker</b> on a user-defined exchange, symbol and interval. Then, the web worker reaches back with the results.</p>
<h3>Parameters</h3>
<label for="exchange">Exchange:</label>
<input type="text" id="exchange" name="exchange" ><br><br>
<label for="symbol">Symbol: </label>
<input type="text" id="symbol" name="symbol"><br><br>
<label for="interval">Interval (ms): </label>
<input type="text" id="interval" name="interval"><br><br>
<button onclick="startWorker()">Start CCXT worker</button>
<button onclick="stopWorker()">Stop CCXT worker</button>
<h3> Received Results:</h3>
<output id="result"></output>
<table id="resultsTable" style="left:300px;width:400px; border:1px solid black;" >
<thead>
<tr>
<th>Symbol</th>
<th>Last Price</th>
<th>Base Volume</th>
<th>Exchange Ts</th>
<th>Local Ts</th>
</tr>
</thead>
<tbody id="tbody">
</tbody>
</table>
</body>
<script>
// fill in default values
document.addEventListener('DOMContentLoaded', function(event) {
document.getElementById('exchange').value = 'coinbasepro';
document.getElementById('symbol').value = 'BTC/USDT';
document.getElementById('interval').value = '1000';
});
var ccxtWorker;
function startWorker() {
if (typeof(Worker) !== "undefined") {
// if the worker does not exist yet, creates it
if (typeof(ccxtWorker) == "undefined") {
ccxtWorker = new Worker("worker.js");
}
// reads user-defined parameters
var exchange = document.getElementById('exchange').value
var symbol = document.getElementById('symbol').value
var interval = document.getElementById('interval').value
// send a message with those values
ccxtWorker.postMessage([exchange,symbol, interval]);
ccxtWorker.onmessage = function(event) {
// every time the ccxtworker posts a message
// this handler will be invoked
handleReceivedData(event.data)
};
} else {
document.getElementById("result").innerHTML = "Sorry! No Web Worker support.";
}
}
function handleReceivedData(data) {
var [symbol, last, baseVolume, timestamp, ourTimestamp] = data;
var tableRef = document.getElementById('resultsTable');
var tbody = document.getElementById('tbody');
row = tbody.insertRow(0);
cellSymbol = row.insertCell();
cellSymbol.innerHTML = symbol;
cellPrice = row.insertCell();
cellPrice.innerHTML = last;
cellPrice = row.insertCell();
cellPrice.innerHTML = baseVolume;
cellTimestamp = row.insertCell();
cellTimestamp.innerHTML = timestamp;
cellOurtimestamp = row.insertCell();
cellOurtimestamp.innerHTML = ourTimestamp;
}
function stopWorker() {
if (ccxtWorker !== undefined) {
ccxtWorker.terminate();
ccxtWorker = undefined;
}
}
</script>
</body>
</html>
@@ -0,0 +1,43 @@
self.importScripts('https://unpkg.com/ccxt@1.79.2/dist/ccxt.browser.js');
console.log("Loaded ccxt version:", self.ccxt.version);
var exchangeInstance = undefined;
// handler of received messages
self.onmessage = async function handler(msg) {
await handleMessageFromMain(msg)
}
// get messages from the main script
async function handleMessageFromMain(msg) {
console.log(msg.data);
var [exchange, symbol, interval] = msg.data;
console.log('Worker received:', symbol,exchange, interval)
interval = parseInt(interval)
await processTicker(symbol, exchange)
// schedule process ticker execution
setInterval (async () => {
await processTicker(symbol, exchange)
}, interval)
}
async function processTicker(symbol, exchangeId) {
if (exchangeInstance === undefined) {
exchangeInstance = new ccxt[exchangeId]
}
var result = await fetchTicker(symbol)
var symbol = result['symbol']
var last = result['last']
var timestamp = result['timestamp']
var baseVolume = result['baseVolume']
var ourTimestamp = Date.now()
// send the data back to the main script
postMessage([symbol, last, baseVolume, timestamp, ourTimestamp]);
}
async function fetchTicker(symbol){
// use ccxt to fetch ticker info
var result = await exchangeInstance.fetchTicker(symbol)
return result;
}
+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 ()
}) ()

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