mirror of
https://github.com/discountry/ritmex-bot.git
synced 2026-09-11 01:08:07 +00:00
commit
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
<style>ul { margin-bottom: -10px; }</style>
|
||||
|
||||
# [<-](Examples?id=typescript)
|
||||
|
||||
- [Benchmark](./examples/ts/benchmark.md)
|
||||
|
||||
- [Build Ohlcv Bars](./examples/ts/build-ohlcv-bars.md)
|
||||
|
||||
- [Compare Two Exchanges Capabilities](./examples/ts/compare-two-exchanges-capabilities.md)
|
||||
|
||||
- [Create Order Position With Takeprofit Stoploss](./examples/ts/create-order-position-with-takeprofit-stoploss.md)
|
||||
|
||||
- [Create Order Ws Example](./examples/ts/create-order-ws-example.md)
|
||||
|
||||
- [Create Orders Example](./examples/ts/create-orders-example.md)
|
||||
|
||||
- [Create Trailing Amount Order](./examples/ts/create-trailing-amount-order.md)
|
||||
|
||||
- [Create Trailing Percent Order](./examples/ts/create-trailing-percent-order.md)
|
||||
|
||||
- [Custom Proxy Agent For Js](./examples/ts/custom-proxy-agent-for-js.md)
|
||||
|
||||
- [Fetch First Ohlcv Timestamp](./examples/ts/fetch-first-ohlcv-timestamp.md)
|
||||
|
||||
- [📂 Fetch Futures](https://github.com/ccxt/ccxt/tree/master/./examples/ts/fetch-futures)
|
||||
|
||||
- [Fetch Ohlcv Many Exchanges Continuosly](./examples/ts/fetch-ohlcv-many-exchanges-continuosly.md)
|
||||
|
||||
- [Fetch Ohlcv](./examples/ts/fetch-ohlcv.md)
|
||||
|
||||
- [📂 Fetch Tickers](https://github.com/ccxt/ccxt/tree/master/./examples/ts/fetch-tickers)
|
||||
|
||||
- [Hibachi Example](./examples/ts/hibachi-example.md)
|
||||
|
||||
- [How To Import One Exchange Esm](./examples/ts/how-to-import-one-exchange-esm.md)
|
||||
|
||||
- [Kraken Create And Close Position](./examples/ts/kraken-create-and-close-position.md)
|
||||
|
||||
- [Margin Loan Borrow Buy Sell Repay](./examples/ts/margin-loan-borrow-buy-sell-repay.md)
|
||||
|
||||
- [📂 Nextjs Page Router](https://github.com/ccxt/ccxt/tree/master/./examples/ts/nextjs-page-router)
|
||||
|
||||
- [Phemex Create Order Position With Takeprofit Stoploss](./examples/ts/phemex-create-order-position-with-takeprofit-stoploss.md)
|
||||
|
||||
- [Proxy Usage](./examples/ts/proxy-usage.md)
|
||||
|
||||
- [Sample Local Proxy Server With Cors](./examples/ts/sample-local-proxy-server-with-cors.md)
|
||||
|
||||
- [Watch Ohlcv For Symbols](./examples/ts/watch-OHLCV-For-Symbols.md)
|
||||
|
||||
- [Watch Ohlcv](./examples/ts/watch-OHLCV.md)
|
||||
|
||||
- [Watch Orderbook For Symbols](./examples/ts/watch-OrderBook-For-Symbols.md)
|
||||
|
||||
- [Watch Trades For Symbols](./examples/ts/watch-Trades-For-Symbols.md)
|
||||
|
||||
- [Watch Tickers](./examples/ts/watch-tickers.md)
|
||||
|
||||
- [Watchpositions Many Exchanges Continuosly](./examples/ts/watchPositions-many-exchanges-continuosly.md)
|
||||
|
||||
- [Watchpositions](./examples/ts/watchPositions.md)
|
||||
|
||||
- [Watchpositionsforsymbols](./examples/ts/watchPositionsForSymbols.md)
|
||||
|
||||
@@ -0,0 +1,140 @@
|
||||
- [Benchmark](./examples/ts/)
|
||||
|
||||
|
||||
```javascript
|
||||
import { spawn } from 'child_process';
|
||||
import asTable from 'as-table';
|
||||
import ccxt, { version } from '../../js/ccxt.js';
|
||||
|
||||
interface Stats {
|
||||
min: number;
|
||||
average: number;
|
||||
max: number;
|
||||
median: number;
|
||||
iterations: number;
|
||||
}
|
||||
|
||||
interface Test {
|
||||
language: string;
|
||||
method: string;
|
||||
command: string;
|
||||
}
|
||||
|
||||
interface Benchmark extends Omit<Test, 'command'>, Stats { }
|
||||
|
||||
const stats = (times: number[]): Stats => {
|
||||
// calculate statistics
|
||||
const sum = times.reduce ((a, b) => a + b, 0);
|
||||
const avg = Math.round (sum / times.length);
|
||||
const min = Math.min (...times);
|
||||
const max = Math.max (...times);
|
||||
times.sort ((a, b) => a - b);
|
||||
const median = times.length % 2 === 0 ? (times[times.length / 2 - 1] + times[times.length / 2]) / 2 : times[Math.floor (times.length / 2)];
|
||||
return { min, 'average': avg, max, median, 'iterations': times.length };
|
||||
};
|
||||
|
||||
async function benchmark (exchangeId, method, args, verbose = false, minIterations = 10, argsv = '') {
|
||||
const exchange = new ccxt.pro[exchangeId] ({});
|
||||
const languages = [ 'js', 'py', 'php', 'cs' ];
|
||||
const commands: Test[] = languages.map ((language) => ({
|
||||
'language': language,
|
||||
'method': method,
|
||||
'command': `npm run cli.${language} ${exchangeId} ${method} ${args.join (' ')} -- ${argsv} --poll`,
|
||||
}));
|
||||
const wsMethod = method + 'Ws';
|
||||
if (exchange.has[wsMethod]) {
|
||||
const wsCommands: Test[] = languages.map ((language) => ({
|
||||
'language': language,
|
||||
'method': wsMethod,
|
||||
'command': `npm run cli.${language} ${exchangeId} ${wsMethod} ${args.join (' ')} -- ${argsv} --poll`,
|
||||
}));
|
||||
commands.push (...wsCommands);
|
||||
}
|
||||
const regex = /iteration (\d+) passed in (\d+) ms/g;
|
||||
|
||||
async function runCommand (command: string) {
|
||||
if (verbose) {
|
||||
console.log (exchange.iso8601 (new Date ().getTime ()), ' running command:', command);
|
||||
}
|
||||
return new Promise<{ times: number[] }> ((resolve, reject) => {
|
||||
const [ cmd, ...args ] = command.split (' ');
|
||||
|
||||
const child = spawn (cmd, args);
|
||||
const matches = [];
|
||||
const language = command.slice (8, 15);
|
||||
child.stdout.on ('data', (data: Buffer) => {
|
||||
const message = data.toString ();
|
||||
matches.push (...Array.from (message.matchAll (regex)));
|
||||
const match = matches[matches.length - 1];
|
||||
|
||||
if (match && match[1] && match[2]) {
|
||||
const iteration = parseInt (match[1]);
|
||||
const time = parseInt (match[2]);
|
||||
|
||||
if (iteration <= minIterations) {
|
||||
if (verbose) {
|
||||
console.log (exchange.iso8601 (new Date ().getTime ()), `${language} iteration ${iteration} passed in ${time} ms`);
|
||||
}
|
||||
} else {
|
||||
const times = matches.map ((m) => parseInt (m[2]));
|
||||
child.kill ();
|
||||
if (verbose) {
|
||||
console.log (exchange.iso8601 (new Date ().getTime ()), `killed process - ${language} iteration ${iteration} passed in ${time} ms`);
|
||||
}
|
||||
resolve ({ times });
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
child.stderr.on ('data', (data: Buffer) => {
|
||||
const message = data.toString ();
|
||||
console.error (exchange.iso8601 (new Date ().getTime ()), `command ${command} failed. stderr: ${message}`);
|
||||
const times = matches.map ((m) => parseInt (m[2]));
|
||||
resolve ({ times });
|
||||
});
|
||||
|
||||
child.on ('close', (code: number) => {
|
||||
const times = matches.map ((m) => parseInt (m[2]));
|
||||
resolve ({ times });
|
||||
console.log (exchange.iso8601 (new Date ().getTime ()), `${language} child process exited with code ${code}`);
|
||||
});
|
||||
|
||||
child.on ('error', (err) => {
|
||||
console.error (exchange.iso8601 (new Date ().getTime ()), `command ${command} failed. error: ${err}`);
|
||||
reject (err);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
const benchmarks: Benchmark[] = [];
|
||||
const results = await Promise.all (commands.map ((c) => runCommand (c.command)));
|
||||
for (let i = 0; i < results.length; i++) {
|
||||
const result = results[i];
|
||||
benchmarks.push ({ 'language': commands[i].language, 'method': commands[i].method, ...stats (result.times) });
|
||||
}
|
||||
if (verbose) {
|
||||
const rawResults = results.map ((r, i) => ({ 'language': commands[i].language, 'method': commands[i].method, ...stats (r.times), 'times': r.times }));
|
||||
console.log (rawResults);
|
||||
}
|
||||
console.log (asTable (benchmarks));
|
||||
}
|
||||
|
||||
const [ _, , exchangeId, methodName, ...params ] = process.argv.filter ((x) => !x.startsWith ('--'));
|
||||
const verbose = process.argv.includes ('--verbose');
|
||||
const minIterationsString = process.argv.find ((x) => x.startsWith ('--min-iterations='))?.slice (18);
|
||||
const minIterations = minIterationsString ? parseInt (minIterationsString) : 10;
|
||||
const argsv = process.argv.filter ((x) => x.startsWith ('--') && !x.startsWith ('--min-iterations')).join (' ');
|
||||
|
||||
|
||||
console.log ((new Date ()).toISOString ());
|
||||
console.log ('Node.js:', process.version);
|
||||
console.log ('CCXT v' + version);
|
||||
|
||||
const start = new Date ().getTime ();
|
||||
await benchmark (exchangeId, methodName, params, verbose, minIterations, argsv);
|
||||
const end = new Date ().getTime ();
|
||||
|
||||
console.log ((new Date ().toISOString ()), 'Total time:', end - start, 'ms');
|
||||
process.exit (0);
|
||||
|
||||
```
|
||||
@@ -0,0 +1,59 @@
|
||||
- [Build Ohlcv Bars](./examples/ts/)
|
||||
|
||||
|
||||
```javascript
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
|
||||
// AUTO-TRANSPILE //
|
||||
|
||||
// Bulding OHLCV array from trades (executions) data is a bit tricky. For example, if you want to build 100 ohlcv bars of 1-minute timeframe, then you have to fetch the 100 minutes of trading data. So, higher timeframe bars require more trading data (i.e. building 100 bars of 1-day timeframe OHLCV would require massive amount of trading data, which might not be desirable for user, because of data-usage rate limits)
|
||||
|
||||
async function example_with_fetch_trades () {
|
||||
const exch = new ccxt.binance ({});
|
||||
const timeframe = '1m';
|
||||
const symbol = 'OGN/USDT';
|
||||
const since = exch.milliseconds () - 1000 * 60 * 30; // last 30 mins
|
||||
const limit = 1000;
|
||||
const trades = await exch.fetchTrades (symbol, since, limit);
|
||||
const generatedBars = exch.buildOHLCVC (trades, timeframe, since, limit);
|
||||
// you can ignore 6th index ("count" field) from ohlcv entries, which is not part of OHLCV standard structure and is just added internally by `buildOHLCVC` method
|
||||
console.log ('[REST] Constructed', generatedBars.length, 'bars from trades: ', generatedBars);
|
||||
}
|
||||
|
||||
async function example_with_watch_trades () {
|
||||
const exch = new ccxt.pro.binance ({});
|
||||
const timeframe = '1m';
|
||||
const symbol = 'DOGE/USDT';
|
||||
const limit = 1000;
|
||||
const since = exch.milliseconds () - 10 * 60 * 1000 * 1000; // last 10 hrs
|
||||
let collectedTrades = [];
|
||||
const collectedBars = [];
|
||||
while (true) {
|
||||
const wsTrades = await exch.watchTrades (symbol, since, limit, {});
|
||||
collectedTrades = collectedTrades.concat (wsTrades);
|
||||
const generatedBars = exch.buildOHLCVC (collectedTrades, timeframe, since, limit);
|
||||
// Note: first bar would be partially constructed bar and its 'open' & 'high' & 'low' prices (except 'close' price) would probably have different values compared to real bar on chart, because the first obtained trade timestamp might be somewhere in the middle of timeframe period, so the pre-period would be missing because we would not have trades data. To fix that, you can get older data with `fetchTrades` to fill up bars till start bar.
|
||||
for (let i = 0; i < generatedBars.length; i++) {
|
||||
const bar = generatedBars[i];
|
||||
const barTimestamp = bar[0];
|
||||
const collectedBarsLength = collectedBars.length;
|
||||
const lastCollectedBarTimestamp = collectedBarsLength > 0 ? collectedBars[collectedBarsLength - 1][0] : 0;
|
||||
if (barTimestamp === lastCollectedBarTimestamp) {
|
||||
// if timestamps are same, just updarte the last bar
|
||||
collectedBars[collectedBarsLength - 1] = bar;
|
||||
} else if (barTimestamp > lastCollectedBarTimestamp) {
|
||||
collectedBars.push (bar);
|
||||
// remove the trades from saved array, which were till last collected bar's open timestamp
|
||||
collectedTrades = exch.filterBySinceLimit (collectedTrades, barTimestamp);
|
||||
}
|
||||
}
|
||||
// Note: first bar would carry incomplete values, please read comment in "buildOHLCVCFromWatchTrades" method definition for further explanation
|
||||
console.log ('[WS] Constructed', collectedBars.length, 'bars from', symbol, 'trades: ', collectedBars);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
await example_with_fetch_trades ();
|
||||
await example_with_watch_trades ();
|
||||
|
||||
```
|
||||
@@ -0,0 +1,42 @@
|
||||
- [Compare Two Exchanges Capabilities](./examples/ts/)
|
||||
|
||||
|
||||
```javascript
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
|
||||
// AUTO-TRANSPILE //
|
||||
|
||||
async function example () {
|
||||
const prefix = '-';
|
||||
const exchange_1 = new ccxt.okx ();
|
||||
const exchange_2 = new ccxt.htx ();
|
||||
const keys_1 = Object.keys (exchange_1.has);
|
||||
const keys_2 = Object.keys (exchange_2.has);
|
||||
// check missing from exchange-1
|
||||
console.log ('### checking missing functionalities from exchange-1:', exchange_1.id);
|
||||
for (let i = 0; i < keys_2.length; i++) {
|
||||
const key = keys_2[i];
|
||||
if (exchange_2.has[key]) {
|
||||
if (!keys_1.includes (key)) {
|
||||
console.log (prefix, key, 'does not exist in', exchange_1.id, 'as opposed to', exchange_2.id);
|
||||
} else if (exchange_2.has[key] !== exchange_1.has[key]) {
|
||||
console.log (prefix, key, '> ', exchange_1.id, ':', exchange_1.has[key], ',', exchange_2.id, ':', exchange_2.has[key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
// check missing from exchange-2
|
||||
console.log ('### checking missing functionalities from exchange-2:', exchange_2.id);
|
||||
for (let i = 0; i < keys_1.length; i++) {
|
||||
const key = keys_1[i];
|
||||
if (exchange_1.has[key]) {
|
||||
if (!keys_2.includes (key)) {
|
||||
console.log (prefix, key, 'does not exist in', exchange_2.id, 'as opposed to', exchange_1.id);
|
||||
} else if (exchange_1.has[key] !== exchange_2.has[key]) {
|
||||
console.log (prefix, key, '> ', exchange_2.id, ':', exchange_2.has[key], ',', exchange_1.id, ':', exchange_1.has[key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
await example ();
|
||||
|
||||
```
|
||||
@@ -0,0 +1,95 @@
|
||||
- [Create Order Position With Takeprofit Stoploss](./examples/ts/)
|
||||
|
||||
|
||||
```javascript
|
||||
// @ts-nocheck
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
|
||||
// AUTO-TRANSPILE //
|
||||
|
||||
console.log ('CCXT Version:', ccxt.version);
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
|
||||
async function example () {
|
||||
// at this moment, only OKX support embedded stop-loss & take-profit orders in unified manner. other exchanges are being added actively and will be available soon.
|
||||
const exchange = new ccxt.okx ({
|
||||
"apiKey": "YOUR_API_KEY",
|
||||
"secret": "YOUR_API_SECRET",
|
||||
"password": "YOUR_API_PASSWORD", // if exchange does not require password, comment out this line
|
||||
});
|
||||
|
||||
const symbol = 'DOGE/USDT:USDT';
|
||||
const side = 'buy'; // 'buy' | 'sell'
|
||||
const order_type = 'limit'; // 'market' | 'limit'
|
||||
const amount = 1; // how many contracts (see `market(symbol).contractSize` to find out coin portion per one contract)
|
||||
|
||||
await exchange.loadMarkets ();
|
||||
const market = exchange.market (symbol);
|
||||
|
||||
const ticker = await exchange.fetchTicker (symbol);
|
||||
|
||||
const last_price = ticker['last'];
|
||||
const ask_price = ticker['ask'];
|
||||
const bid_price = ticker['bid'];
|
||||
|
||||
// if order_type is 'market', then price is not needed
|
||||
let price = undefined;
|
||||
// if order_type is 'limit', then set a price at your desired level
|
||||
if (order_type === 'limit') {
|
||||
price = (side === 'buy') ? bid_price * 0.95 : ask_price * 1.05; // i.e. 5% from current price
|
||||
}
|
||||
|
||||
// set trigger price for stop-loss/take-profit to 2% from current price
|
||||
// (note, across different exchanges "trigger" price can be also mentioned with different synonyms, like "activation price", "stop price", "conditional price", etc. )
|
||||
const stop_loss_trigger_price = (order_type === 'market' ? last_price : price) * (side === 'buy' ? 0.98 : 1.02);
|
||||
const take_profit_trigger_price = (order_type === 'market' ? last_price : price) * (side === 'buy' ? 1.02 : 0.98);
|
||||
|
||||
// when symbol's price reaches your predefined "trigger price", stop-loss order would be activated as a "market order". but if you want it to be activated as a "limit order", then set a 'price' parameter for it
|
||||
const params = {
|
||||
'stopLoss': {
|
||||
'triggerPrice': stop_loss_trigger_price,
|
||||
// set a 'price' to act as limit order, otherwise remove it for a market order
|
||||
'price': stop_loss_trigger_price * 0.98,
|
||||
},
|
||||
'takeProfit': {
|
||||
'triggerPrice': take_profit_trigger_price,
|
||||
// set a 'price' to act as limit order, otherwise remove it for a market order
|
||||
'price': take_profit_trigger_price * 0.98,
|
||||
},
|
||||
// note that some exchanges might require some exchange specific parameter when opening a position, i.e.:
|
||||
// 'posSide': 'long', // for phemex hedge-mode api
|
||||
};
|
||||
|
||||
const position_amount = market['contractSize'] * amount;
|
||||
const position_value = position_amount * last_price;
|
||||
// log
|
||||
console.log ('Going to open a position', 'for', amount, 'contracts worth', position_amount, market['base'], '~', position_value, market['settle'], 'using', side, order_type, 'order (', (order_type === 'limit' ? exchange.priceToPrecision (symbol, price) : ''), '), using the following params:');
|
||||
console.log (params);
|
||||
console.log ('-----------------------------------------------------------------------');
|
||||
|
||||
// exchange.verbose = True // uncomment for debugging purposes if necessary
|
||||
|
||||
try {
|
||||
const created_order = await exchange.createOrder (symbol, order_type, side, amount, price, params);
|
||||
console.log ("Created an order", created_order);
|
||||
|
||||
// Fetch all your open orders for this symbol
|
||||
// - use 'fetchOpenOrders' or 'fetchOrders' and filter with 'open' status
|
||||
// - note, that some exchanges might return one order object with embedded stoploss/takeprofit fields, while other exchanges might have separate stoploss/takeprofit order objects
|
||||
const all_open_orders = await exchange.fetchOpenOrders (symbol);
|
||||
console.log ("Fetched all your orders for this symbol", all_open_orders);
|
||||
|
||||
// To cancel a limit order, use "exchange.cancel_order(created_order['id'], symbol)""
|
||||
} catch (e) {
|
||||
console.log (e.toString ());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
await example ();
|
||||
|
||||
// NOTES:
|
||||
// - Sometimes you might experience, when their stop-loss/take-profit order might not become activated, even though on chart the price had crossed that "trigger-price" order was not executed . That happens because some exchange might be using mark-price (instead of last-price) as a reference-price, so that mark-price might reach your trigger-price and it would activate your SL/TP order (even though on your symbol's chart you are viewing the "last-price" by default, which could have different movements than the mark-price).
|
||||
|
||||
```
|
||||
@@ -0,0 +1,39 @@
|
||||
- [Create Order Ws Example](./examples/ts/)
|
||||
|
||||
|
||||
```javascript
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
|
||||
// AUTO-TRANSPILE //
|
||||
|
||||
async function example () {
|
||||
const exchange = new ccxt.pro.binance ({
|
||||
'apiKey': 'MY_API_KEY',
|
||||
'secret': 'MY_SECRET',
|
||||
});
|
||||
exchange.setSandboxMode (true);
|
||||
exchange.verbose = true; // uncomment for debugging purposes if necessary
|
||||
// load markets
|
||||
await exchange.loadMarkets ();
|
||||
const symbol = 'ETH/USDT';
|
||||
const type = 'limit';
|
||||
const side = 'buy';
|
||||
const amount = 0.01;
|
||||
let price = 1000;
|
||||
let orders = [];
|
||||
for (let i=1; i<5; i++) {
|
||||
const response = await exchange.createOrderWs (
|
||||
symbol,
|
||||
type,
|
||||
side,
|
||||
amount,
|
||||
price
|
||||
);
|
||||
price += i;
|
||||
orders.push (response);
|
||||
}
|
||||
console.log (orders);
|
||||
}
|
||||
await example ();
|
||||
|
||||
```
|
||||
@@ -0,0 +1,27 @@
|
||||
- [Create Orders Example](./examples/ts/)
|
||||
|
||||
|
||||
```javascript
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
|
||||
// AUTO-TRANSPILE //
|
||||
|
||||
async function example () {
|
||||
const exchange = new ccxt.binance ({
|
||||
'apiKey': 'MY_API_KEY',
|
||||
'secret': 'MY_SECRET',
|
||||
});
|
||||
exchange.setSandboxMode (true);
|
||||
await exchange.loadMarkets ();
|
||||
exchange.verbose = true; // uncomment for debugging purposes if necessary
|
||||
const orders = await exchange.createOrders (
|
||||
[
|
||||
{ 'symbol': 'LTC/USDT:USDT', 'type': 'limit', 'side': 'buy', 'amount': 10, 'price': 55 },
|
||||
{ 'symbol': 'ETH/USDT:USDT', 'type': 'market', 'side': 'buy', 'amount': 0.5 },
|
||||
]
|
||||
);
|
||||
console.log (orders);
|
||||
}
|
||||
await example ();
|
||||
|
||||
```
|
||||
@@ -0,0 +1,43 @@
|
||||
- [Create Trailing Amount Order](./examples/ts/)
|
||||
|
||||
|
||||
```javascript
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
|
||||
// AUTO-TRANSPILE //
|
||||
|
||||
async function example () {
|
||||
const exchange = new ccxt.bingx ({
|
||||
'apiKey': 'MY_API_KEY',
|
||||
'secret': 'MY_SECRET',
|
||||
});
|
||||
// exchange.setSandboxMode (true);
|
||||
// exchange.verbose = true; // uncomment for debugging purposes if necessary
|
||||
await exchange.loadMarkets ();
|
||||
const symbol = 'BTC/USDT:USDT';
|
||||
const order_type = 'market';
|
||||
const side = 'sell';
|
||||
const amount = 0.0001;
|
||||
const price = undefined;
|
||||
const reduceOnly = true;
|
||||
const trailingAmount = 100;
|
||||
// const trailingTriggerPrice = undefined; // not supported on all exchanges
|
||||
const params = {
|
||||
'reduceOnly': reduceOnly,
|
||||
'trailingAmount': trailingAmount,
|
||||
// 'trailingTriggerPrice': trailingTriggerPrice,
|
||||
};
|
||||
try {
|
||||
const create_order = await exchange.createOrder (symbol, order_type, side, amount, price, params);
|
||||
// Alternatively use the createTrailingAmountOrder method:
|
||||
// const create_order = await exchange.createTrailingAmountOrder (symbol, order_type, side, amount, price, trailingAmount, trailingTriggerPrice, {
|
||||
// 'reduceOnly': reduceOnly,
|
||||
// });
|
||||
console.log (create_order);
|
||||
} catch (e) {
|
||||
console.log (e.toString ());
|
||||
}
|
||||
}
|
||||
await example ();
|
||||
|
||||
```
|
||||
@@ -0,0 +1,43 @@
|
||||
- [Create Trailing Percent Order](./examples/ts/)
|
||||
|
||||
|
||||
```javascript
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
|
||||
// AUTO-TRANSPILE //
|
||||
|
||||
async function example () {
|
||||
const exchange = new ccxt.bingx ({
|
||||
'apiKey': 'MY_API_KEY',
|
||||
'secret': 'MY_SECRET',
|
||||
});
|
||||
// exchange.setSandboxMode (true);
|
||||
// exchange.verbose = true; // uncomment for debugging purposes if necessary
|
||||
await exchange.loadMarkets ();
|
||||
const symbol = 'BTC/USDT:USDT';
|
||||
const order_type = 'market';
|
||||
const side = 'sell';
|
||||
const amount = 0.0001;
|
||||
const price = undefined;
|
||||
const reduceOnly = true;
|
||||
const trailingPercent = 10;
|
||||
// const trailingTriggerPrice = undefined; // not supported on all exchanges
|
||||
const params = {
|
||||
'reduceOnly': reduceOnly,
|
||||
'trailingPercent': trailingPercent,
|
||||
// 'trailingTriggerPrice': trailingTriggerPrice,
|
||||
};
|
||||
try {
|
||||
const create_order = await exchange.createOrder (symbol, order_type, side, amount, price, params);
|
||||
// Alternatively use the createTrailingAmountOrder method:
|
||||
// const create_order = await exchange.createTrailingPercentOrder (symbol, order_type, side, amount, price, trailingPercent, trailingTriggerPrice, {
|
||||
// 'reduceOnly': reduceOnly,
|
||||
// });
|
||||
console.log (create_order);
|
||||
} catch (e) {
|
||||
console.log (e.toString ());
|
||||
}
|
||||
}
|
||||
await example ();
|
||||
|
||||
```
|
||||
@@ -0,0 +1,18 @@
|
||||
- [Custom Proxy Agent For Js](./examples/ts/)
|
||||
|
||||
|
||||
```javascript
|
||||
// @ts-nocheck
|
||||
// to set custom "proxy-agent" for ccxt
|
||||
import ccxt from 'ccxt';
|
||||
import HttpProxyAgent from 'http-proxy-agent';
|
||||
import HttpsProxyAgent from 'https-proxy-agent';
|
||||
const proxy = 'http://1.2.3.4:5678';
|
||||
const httpAgent = new HttpProxyAgent (proxy);
|
||||
const httpsAgent = new HttpsProxyAgent (proxy);
|
||||
// then pass it through constructor
|
||||
const kraken = new ccxt.kraken ({ agent: httpAgent /* or httpsAgent */ });
|
||||
// or set it later
|
||||
kraken.agent = agent;
|
||||
|
||||
```
|
||||
@@ -0,0 +1,94 @@
|
||||
- [Fetch First Ohlcv Timestamp](./examples/ts/)
|
||||
|
||||
|
||||
```javascript
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
|
||||
// AUTO-TRANSPILE //
|
||||
|
||||
|
||||
// ###### Description ######
|
||||
//
|
||||
// This function tries to fetch the "listing time" of a symbol by fetching the earliest available bar in daily resolution.
|
||||
// Top-tier exchanges also support fetching smaller timeframes (eg. 1 minute) even several years back, so for those exchanges you can also use `useMinuteTimeframe = true` argument to get the timestamp rounded to the earliest minute bar (instead of daily bar timestamp).
|
||||
// See usage in the end of this file
|
||||
|
||||
|
||||
async function fetchFirstBarTimestamp (exchange:any, symbol: string, useMinuteTimeframe = false) {
|
||||
// set some constants
|
||||
const millisecondsPerDay = 86400000;
|
||||
const minutesPerDay = 1440;
|
||||
const minimumTimestamp = 1230768000000; // 2009-01-01 (bitcoin created year)
|
||||
// get market features
|
||||
const market = exchange.market (symbol);
|
||||
const marketType = exchange.safeString (market, 'type');
|
||||
let features = exchange.safeDict (exchange.features, marketType, {});
|
||||
if (market['subType'] !== undefined) {
|
||||
features = exchange.safeDict (features, market['subType'], {});
|
||||
}
|
||||
const ohlcv = exchange.safeDict (features, 'fetchOHLCV');
|
||||
if (ohlcv === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
const limit = exchange.safeInteger (ohlcv, 'limit');
|
||||
const fetchParams = { 'maxRetriesOnFailure': 3 };
|
||||
// start loop
|
||||
let currentSince = exchange.milliseconds () - millisecondsPerDay * (limit - 1);
|
||||
let foundStartTime = 0;
|
||||
// eslint-disable-next-line
|
||||
while (true) {
|
||||
currentSince = Math.max (currentSince, minimumTimestamp);
|
||||
const dailyBars = await exchange.fetchOHLCV (symbol, '1d', currentSince, limit, fetchParams);
|
||||
if (dailyBars.length <= 0) {
|
||||
break; // if no days returned, then probably start date was passed
|
||||
}
|
||||
const firstTs = dailyBars[0][0];
|
||||
if (firstTs === foundStartTime) {
|
||||
// if the first timestamp is equal to the last-fetched timestamp, then break here, because some exchanges still return initial bar even if since is much ahead to listing time
|
||||
break;
|
||||
}
|
||||
foundStartTime = firstTs;
|
||||
currentSince = foundStartTime - millisecondsPerDay * (limit - 1); // shift 'since' one step back
|
||||
if (dailyBars.length === 1) {
|
||||
// in some cases, some exchanges might still return first bar of chart when endtime overlaps previous day
|
||||
break;
|
||||
}
|
||||
}
|
||||
// if minute resolution needed
|
||||
if (useMinuteTimeframe) {
|
||||
const maxIteration = Math.ceil (minutesPerDay / limit) * 2;
|
||||
const allPromises: any[] = [];
|
||||
for (let i = 0; i < maxIteration; i++) {
|
||||
currentSince = foundStartTime - millisecondsPerDay + i * limit * 60 * 1000; // shift one-duration back for more accuracy for different kind of exchanges, like OKX, where first daily bar is offset by one day, but minute bars present
|
||||
allPromises.push (exchange.fetchOHLCV (symbol, '1m', currentSince, limit, fetchParams));
|
||||
}
|
||||
const allResponses = await Promise.all (allPromises);
|
||||
// find earliest bar
|
||||
for (let i = 0; i < allResponses.length; i++) {
|
||||
const response = allResponses[i];
|
||||
if (response.length > 0) {
|
||||
foundStartTime = response[0][0];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return foundStartTime;
|
||||
}
|
||||
|
||||
// ###### Usage ######
|
||||
|
||||
const runExample = false; // set to true to run example
|
||||
if (runExample) {
|
||||
const myEx = new ccxt.binance ();
|
||||
await myEx.loadMarkets ();
|
||||
const symbol = 'TRUMP/USDT';
|
||||
const earliest_timestamp = await fetchFirstBarTimestamp (myEx, symbol, true);
|
||||
console.log ('- Earliest bar timestamp:', earliest_timestamp, ', readable: ', myEx.iso8601 (earliest_timestamp));
|
||||
console.log ('- market.created value:', myEx.market (symbol)['created']);
|
||||
}
|
||||
|
||||
|
||||
export default fetchFirstBarTimestamp;
|
||||
|
||||
```
|
||||
@@ -0,0 +1,50 @@
|
||||
- [Fetch Ohlcv Many Exchanges Continuosly](./examples/ts/)
|
||||
|
||||
|
||||
```javascript
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
|
||||
// AUTO-TRANSPILE //
|
||||
|
||||
// fetch and handle constinuosly
|
||||
async function fetchOHLCVContinuously (exchange, symbol) {
|
||||
while (true) {
|
||||
try {
|
||||
const ohlcv = await exchange.fetchOHLCV (symbol);
|
||||
const ohlcvLength = ohlcv.length;
|
||||
console.log ('Fetched ', exchange.id, ' - ', symbol, ' candles. last candle: ', ohlcv[ohlcvLength - 1]);
|
||||
} catch (e) {
|
||||
console.log (e);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// start exchanges and fetch OHLCV loop
|
||||
async function startExchange (exchangeName, symbols) {
|
||||
const ex = new ccxt[exchangeName] ({});
|
||||
const promises = [];
|
||||
for (let i = 0; i < symbols.length; i++) {
|
||||
const symbol = symbols[i];
|
||||
promises.push (fetchOHLCVContinuously (ex, symbol));
|
||||
}
|
||||
await Promise.all (promises);
|
||||
await ex.close ();
|
||||
}
|
||||
|
||||
// main function
|
||||
async function example () {
|
||||
const exchanges = [ 'binance', 'okx', 'kraken' ];
|
||||
const symbols = [ 'BTC/USDT', 'ETH/USDT' ];
|
||||
const promises = [];
|
||||
for (let i = 0; i < exchanges.length; i++) {
|
||||
const exchangeName = exchanges[i];
|
||||
promises.push (startExchange (exchangeName, symbols));
|
||||
}
|
||||
await Promise.all (promises);
|
||||
}
|
||||
|
||||
|
||||
await example ();
|
||||
|
||||
```
|
||||
@@ -0,0 +1,23 @@
|
||||
- [Fetch Ohlcv](./examples/ts/)
|
||||
|
||||
|
||||
```javascript
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
|
||||
// AUTO-TRANSPILE //
|
||||
|
||||
async function example () {
|
||||
const myex = new ccxt.okx ({});
|
||||
const fromTimestamp = myex.milliseconds () - 86400 * 1000;// last 24 hrs
|
||||
const ohlcv = await myex.fetchOHLCV ('BTC/USDT', '1m', fromTimestamp, 3, { 'whatever': 123 });
|
||||
const length = ohlcv.length;
|
||||
if (length > 0) {
|
||||
const lastPrice = ohlcv[length - 1][4];
|
||||
console.log ('Fetched ', length, ' candles for ', myex.id, ': last close ', lastPrice);
|
||||
} else {
|
||||
console.log ('No candles have been fetched');
|
||||
}
|
||||
}
|
||||
await example ();
|
||||
|
||||
```
|
||||
@@ -0,0 +1,143 @@
|
||||
- [Hibachi Example](./examples/ts/)
|
||||
|
||||
|
||||
```javascript
|
||||
import { hibachi } from '../../js/ccxt.js';
|
||||
import fs from 'fs';
|
||||
|
||||
/*
|
||||
In order to run the examples, you need to setup keys.local.json file like this:
|
||||
```
|
||||
{
|
||||
"hibachi": {
|
||||
"accountId": 111,
|
||||
"apiKey": "1111111111111111111111111111111111111111111=",
|
||||
"privateKey": "0x1111111111111111111111111111111111111111111111111111111111111111",
|
||||
"publicKey": "0x11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111",
|
||||
"withdrawAddress": "0x1111111111111111111111111111111111111111"
|
||||
}
|
||||
}
|
||||
```
|
||||
You can get the accountId, apiKey and privateKey from Hibachi App by creating an API key
|
||||
After that you can view the API key, it will show the publicKey (only for trustless account, you can ignore it for exchange managed account)
|
||||
Note: if you are using exchange managed account, the privateKey's length will be 44 instead
|
||||
The withdrawAddress can be any ethereum wallet address, that is used to receive funds for withdraw tests
|
||||
*/
|
||||
async function example () {
|
||||
const keys = JSON.parse(fs.readFileSync('keys.local.json', 'utf-8'));
|
||||
const exchange = new hibachi (keys.hibachi);
|
||||
exchange.verbose = true;
|
||||
|
||||
const markets = await exchange.fetchMarkets();
|
||||
console.log ('fetchMarkets', markets.length, markets[0]);
|
||||
|
||||
const currencies = await exchange.fetchCurrencies();
|
||||
console.dir (currencies, { depth: null, colors: true });
|
||||
|
||||
const trades = await exchange.fetchTrades("BTC/USDT:USDT");
|
||||
console.log('fetchTrades', trades.length, trades[0]);
|
||||
|
||||
const tenMinutes = 10 * 60 * 1000;
|
||||
const until = Date.now();
|
||||
const since = until - tenMinutes;
|
||||
const ohlcv = await exchange.fetchOHLCV('BTC/USDT:USDT', '5min', since, 100, {until});
|
||||
console.log ('fetchOHLCV', ohlcv.length, ohlcv[0]);
|
||||
|
||||
const balance = await exchange.fetchBalance();
|
||||
console.dir (balance, { depth: null, colors: true });
|
||||
|
||||
const ticker = await exchange.fetchTicker('BTC/USDT:USDT');
|
||||
console.log ('fetchTicker', ticker);
|
||||
|
||||
// createOrder, editOrder and cancelOrder
|
||||
const order1 = await exchange.createOrder('BTC/USDT:USDT', 'market', 'buy', 0.00002);
|
||||
const order2 = await exchange.createOrder('BTC/USDT:USDT', 'market', 'sell', 0.00002);
|
||||
console.log('create market order', order1.id, order2.id);
|
||||
const order3 = await exchange.createOrder('ETH/USDT:USDT', 'limit', 'buy', 1.234, 1.234);
|
||||
const order4 = await exchange.editOrder(order3.id, 'ETH/USDT:USDT', 'limit', 'buy', 0.987, 1.123);
|
||||
const order5 = await exchange.cancelOrder(order3.id);
|
||||
console.log('create, edit and cancel limit order', order3.id, order4.id, order5.id);
|
||||
|
||||
// advanced order parameters
|
||||
const postOnlyOrder = await exchange.createOrder('BTC/USDT:USDT', 'limit', 'buy', 2.0, 2.0, {'timeInForce': 'PO'});
|
||||
await exchange.cancelOrder(postOnlyOrder.id);
|
||||
const iocOrder = await exchange.createOrder('BTC/USDT:USDT', 'limit', 'buy', 2.0, 2.0, {'timeInForce': 'IOC'});
|
||||
await exchange.createOrder('BTC/USDT:USDT', 'market', 'buy', 0.00002);
|
||||
const reduceOnlyOrder = await exchange.createOrder('BTC/USDT:USDT', 'market', 'sell', 0.00002, undefined, {'reduceOnly': true});
|
||||
const triggerOrder = await exchange.createOrder('BTC/USDT:USDT', 'limit', 'sell', 2.0, 2.0, {'triggerPrice': '2.0'});
|
||||
await exchange.cancelOrder(triggerOrder.id);
|
||||
console.log('postOnly, IOC, reduceOnly, trigger order', postOnlyOrder.id, iocOrder.id, reduceOnlyOrder.id, triggerOrder.id);
|
||||
|
||||
const order1_info = await exchange.fetchOrder (order1.id, 'BTC/USDT:USDT');
|
||||
console.log ('fetchOrder', order1_info);
|
||||
|
||||
const orderbook = await exchange.fetchOrderBook ('BTC/USDT:USDT');
|
||||
console.log ('fetchOrderBook', orderbook);
|
||||
const withdrawResponse = await exchange.withdraw('USDT', 0.02, keys.hibachi.withdrawAddress);
|
||||
console.log(withdrawResponse);
|
||||
|
||||
const myTrades = await exchange.fetchMyTrades('BTC/USDT:USDT', undefined, 1);
|
||||
console.log('fetchMyTrades', myTrades);
|
||||
|
||||
const tradingFees = await exchange.fetchTradingFees ();
|
||||
console.log ('fetchTradingFees', tradingFees);
|
||||
|
||||
const openOrders = await exchange.fetchOpenOrders ();
|
||||
console.log ('fetchOpenOrders', openOrders);
|
||||
const openOrdersWithLimit = await exchange.fetchOpenOrders (undefined, undefined, 1);
|
||||
console.log ('fetchOpenOrdersWithLimit', openOrdersWithLimit);
|
||||
const openOrdersBTC = await exchange.fetchOpenOrders ('BTC/USDT:USDT');
|
||||
console.log ('fetchOpenOrdersBTC', openOrdersBTC);
|
||||
const openOrdersSince = await exchange.fetchOpenOrders (undefined, 1752552000000); // 7/15/2025 00:00 UTC
|
||||
console.log ('fetchOpenOrdersSince', openOrdersSince);
|
||||
|
||||
if (keys.hibachi.publicKey !== undefined) {
|
||||
const depositAddress = await exchange.fetchDepositAddress ('USDT', {'publicKey': keys.hibachi.publicKey});
|
||||
console.log ('fetchDepositAddress', depositAddress);
|
||||
}
|
||||
|
||||
const ledger = await exchange.fetchLedger('USDT', undefined, 2);
|
||||
console.log('fetchLedger', ledger);
|
||||
|
||||
const deposits = await exchange.fetchDeposits ();
|
||||
console.log ('fetchDeposits', deposits);
|
||||
|
||||
const withdrawals = await exchange.fetchWithdrawals ();
|
||||
console.log ('fetchWithdrawals', withdrawals);
|
||||
|
||||
const timestamp = await exchange.fetchTime();
|
||||
console.log('fetchTime', timestamp)
|
||||
|
||||
const openInterest = await exchange.fetchOpenInterest('BTC/USDT:USDT');
|
||||
console.log('fetchOpenInterest', openInterest);
|
||||
|
||||
const fundingRate = await exchange.fetchFundingRate('BTC/USDT:USDT');
|
||||
console.log('fetchFundingRate', fundingRate);
|
||||
|
||||
const fundingRateHistory = await exchange.fetchFundingRateHistory('BTC/USDT:USDT', undefined, 2);
|
||||
console.log('fetchFundingRateHistory', fundingRateHistory);
|
||||
|
||||
// Batch orders
|
||||
const createOrders = await exchange.createOrders([
|
||||
{'symbol': 'ETH/USDT:USDT', 'type': 'limit', 'side': 'buy', 'amount': 1.234, 'price': 1.234},
|
||||
{'symbol': 'BTC/USDT:USDT', 'type': 'limit', 'side': 'buy', 'amount': 1.001, 'price': 1.001},
|
||||
{'symbol': 'ETH/USDT:USDT', 'type': 'limit', 'side': 'buy', 'amount': 1.002, 'price': 1.002},
|
||||
{'symbol': 'ETH/USDT:USDT', 'type': 'limit', 'side': 'buy', 'amount': 1.003, 'price': 1.003},
|
||||
]);
|
||||
console.log('createOrders', createOrders);
|
||||
const editOrders = await exchange.editOrders([
|
||||
// @ts-expect-error OrderRequest lacks `id` but we expects it for editing
|
||||
{'id': createOrders[0].id, 'symbol': 'ETH/USDT:USDT', 'type': 'limit', 'side': 'buy', 'amount': 1.111, 'price': 0.999},
|
||||
// @ts-expect-error OrderRequest lacks `id` but we expects it for editing
|
||||
{'id': createOrders[1].id, 'symbol': 'BTC/USDT:USDT', 'type': 'limit', 'side': 'buy', 'amount': 1.112, 'price': 0.998},
|
||||
]);
|
||||
console.log('editOrders', editOrders);
|
||||
const cancelOrders = await exchange.cancelOrders([createOrders[0].id, createOrders[1].id]);
|
||||
console.log('cancelOrders', cancelOrders);
|
||||
const cancelAll = await exchange.cancelAllOrders('ETH/USDT:USDT');
|
||||
console.log(cancelAll);
|
||||
|
||||
}
|
||||
example ();
|
||||
|
||||
```
|
||||
@@ -0,0 +1,17 @@
|
||||
- [How To Import One Exchange Esm](./examples/ts/)
|
||||
|
||||
|
||||
```javascript
|
||||
import { binance } from '../../js/ccxt.js';
|
||||
|
||||
async function example () {
|
||||
const exchange = new binance ({});
|
||||
const ob = await exchange.fetchOrderBook ('BTC/USDT', 3);
|
||||
const asks = ob['asks'];
|
||||
const bids = ob['bids'];
|
||||
console.log (asks);
|
||||
console.log (bids);
|
||||
}
|
||||
example ();
|
||||
|
||||
```
|
||||
@@ -0,0 +1,75 @@
|
||||
- [Kraken Create And Close Position](./examples/ts/)
|
||||
|
||||
|
||||
```javascript
|
||||
// @ts-nocheck
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
|
||||
// AUTO-TRANSPILE //
|
||||
|
||||
console.log ('CCXT Version:', ccxt.version);
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
|
||||
async function example () {
|
||||
const exchange = new ccxt.kraken ({
|
||||
"apiKey": "YOUR_API_KEY",
|
||||
"secret": "YOUR_API_SECRET",
|
||||
});
|
||||
|
||||
const symbol = 'UNI/USD';
|
||||
let side = 'buy'; // set it to 'buy' for a long position, 'sell' for a short position
|
||||
const order_type = 'market'; // set it to 'market' or 'limit'
|
||||
const amount = 1;
|
||||
const leverage = 2;
|
||||
|
||||
await exchange.loadMarkets ();
|
||||
const market = exchange.market (symbol);
|
||||
|
||||
// if order_type is 'market', then price is not needed
|
||||
let price = undefined;
|
||||
// if order_type is 'limit', then set a price at your desired level
|
||||
// you can fetch the ticker and update price
|
||||
// const ticker = await exchange.fetchTicker (symbol);
|
||||
// const last_price = ticker['last'];
|
||||
// const ask_price = ticker['ask'];
|
||||
// const bid_price = ticker['bid'];
|
||||
// if (order_type === 'limit') {
|
||||
// price = (side === 'buy') ? bid_price * 0.95 : ask_price * 1.05; // i.e. 5% from current price
|
||||
// }
|
||||
|
||||
const params = {
|
||||
'leverage': leverage,
|
||||
};
|
||||
|
||||
// log
|
||||
console.log ('Going to open a position', 'for', amount, 'worth', amount, market['base'], '~', market['settle'], 'using', side, order_type, 'order (', (order_type === 'limit' ? exchange.priceToPrecision (symbol, price) : ''), '), using the following params:');
|
||||
console.log (params);
|
||||
console.log ('-----------------------------------------------------------------------');
|
||||
|
||||
// exchange.verbose = True // uncomment for debugging purposes if necessary
|
||||
|
||||
try {
|
||||
const created_order = await exchange.createOrder (symbol, order_type, side, amount, price, params);
|
||||
console.log ("Created an order", created_order);
|
||||
|
||||
// Fetch all your closed orders for this symbol (because we used market order)
|
||||
// - use 'fetchClosedOrders' or 'fetchOrders' and filter with 'closed' status
|
||||
const all_closed_orders = await exchange.fetchClosedOrders (symbol);
|
||||
console.log ("Fetched all your closed orders for this symbol", all_closed_orders);
|
||||
|
||||
const all_open_positions = await exchange.fetchPositions (symbol);
|
||||
console.log ("Fetched all your positions for this symbol", all_open_positions);
|
||||
|
||||
// To close a position:
|
||||
// - long position (buy), you can create a sell order: exchange.createOrder (symbol, order_type, 'sell', amount, price, params);
|
||||
// - short position (sell), you can create a buy order: exchange.createOrder (symbol, order_type, 'buy', amount, price, params);
|
||||
} catch (e) {
|
||||
console.log (e.toString ());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
await example ();
|
||||
|
||||
```
|
||||
@@ -0,0 +1,78 @@
|
||||
- [Margin Loan Borrow Buy Sell Repay](./examples/ts/)
|
||||
|
||||
|
||||
```javascript
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
|
||||
// AUTO-TRANSPILE //
|
||||
|
||||
// Note, this is just an example and might not yet work on other exchanges, which are being still unified.
|
||||
|
||||
async function example () {
|
||||
// ########## user inputs ##########
|
||||
const exchange = new ccxt['binance'] ({ 'apiKey': 'xxx', 'secret': 'xxx' });
|
||||
const symbol = 'BUSD/USDT'; // set target symbol
|
||||
const marginMode = 'isolated'; // margin mode (cross or isolated)
|
||||
const collateral_coin = 'USDT'; // which asset you want to use for margin-borrow collateral
|
||||
const borrow_coin = 'BUSD'; // which coin to borrow
|
||||
const order_side: any = 'sell'; // which side to trade
|
||||
const amount_to_trade = 14; // how many coins to sell
|
||||
const order_type = 'limit'; // order type (can be market, limit or etc)
|
||||
const limit_price: any = 0.99; // price to sell at (set undefined/null/None if market-order)
|
||||
const margin_magnitude = 5; // target margin (aka 'leverage'). This might also be obtainable using other unified methods, but for example purposes, we set here manually
|
||||
// ########## end of user-inputs ##########
|
||||
//
|
||||
// for example purposes, let's also check available balance at first
|
||||
const balance_margin = await exchange.fetchBalance ({ 'defaultType': 'margin', 'marginMode': marginMode }); // use `defaultType` because of temporary bug, otherwise, after several days, you can use `type` too.
|
||||
// if we don't have enought coins, then we have to borrow at first
|
||||
let needed_amount_to_borrow: any = undefined; // will be auto-set below
|
||||
if (amount_to_trade > balance_margin[symbol][borrow_coin]['free']) {
|
||||
needed_amount_to_borrow = amount_to_trade - balance_margin[symbol][borrow_coin]['free'];
|
||||
console.log ('hmm, I have only ', balance_margin[symbol][borrow_coin]['free'], ' ', borrow_coin, ' in margin balance, and still need additional ', needed_amount_to_borrow, ' to make an order. Lets borrow it.');
|
||||
// To initate a borrow, at first, check if we have enough collateral (for this example, as we make a sell-short, we need '-1' to keep for collateral currency)
|
||||
const needed_collateral_amount = needed_amount_to_borrow / (margin_magnitude - 1);
|
||||
// Check if we have any collateral to get permission for borrow
|
||||
if (balance_margin[symbol][collateral_coin]['free'] < needed_collateral_amount) {
|
||||
// If we don't have enough collateral, then let's try to transfer collateral-asset from spot-balance to margin-balance
|
||||
console.log ('hmm, I have only ', balance_margin[symbol][collateral_coin]['free'], ' in balance, but ', needed_collateral_amount, ' collateral is needed. I should transfer ', needed_collateral_amount, ' from spot');
|
||||
// let's check if we have spot balance at all
|
||||
const balance_spot = await exchange.fetchBalance ({ 'type': 'spot' });
|
||||
if (exchange.parseNumber (balance_spot[collateral_coin]['free']) < needed_collateral_amount) {
|
||||
console.log ('hmm, I neither do have enough balance on spot - only ', balance_spot[collateral_coin]['free'], '. Script can not continue...');
|
||||
return;
|
||||
} else {
|
||||
console.log ('Transferring ', needed_collateral_amount, ' to margin account');
|
||||
await exchange.transfer (collateral_coin, needed_collateral_amount, 'spot', marginMode, { 'symbol': symbol });
|
||||
}
|
||||
}
|
||||
// now, as we have enough margin collateral, initiate borrow
|
||||
console.log ('Initiating margin borrow of ', needed_amount_to_borrow, ' ', borrow_coin);
|
||||
const borrowResult = await exchange.borrowMargin (borrow_coin, needed_amount_to_borrow, symbol, { 'marginMode': marginMode });
|
||||
}
|
||||
console.log ('Submitting order.');
|
||||
const order = await exchange.createOrder (symbol, order_type, order_side, amount_to_trade, limit_price, { 'marginMode': marginMode });
|
||||
console.log ('Order was submitted !', order['id']);
|
||||
//
|
||||
//
|
||||
// ...
|
||||
// ...
|
||||
// some time later, if you want to repay the loan back (like 'close the position')...
|
||||
// ...
|
||||
// ...
|
||||
//
|
||||
//
|
||||
// set the "repay-back" amount (for this example snippet, this will be same amount that we borrowed above)
|
||||
if (needed_amount_to_borrow !== undefined) {
|
||||
const amount_to_repay_back = needed_amount_to_borrow;
|
||||
// At first, you need to get back the borrowed coin, by making an opposide trade
|
||||
console.log ('Making purchase back of ', amount_to_repay_back, ' ', borrow_coin, ' to repay it back.');
|
||||
const purchase_back_price: any = 1.01;
|
||||
const order_back = await exchange.createOrder (symbol, order_type, (order_side === 'buy' ? 'sell' : 'buy'), amount_to_repay_back, purchase_back_price, { 'marginMode': marginMode });
|
||||
console.log ('Now, repaying the loan.');
|
||||
const repayResult = await exchange.repayMargin (borrow_coin, amount_to_repay_back, symbol, { 'marginMode': marginMode });
|
||||
console.log ('finished.');
|
||||
}
|
||||
}
|
||||
await example ();
|
||||
|
||||
```
|
||||
@@ -0,0 +1,68 @@
|
||||
- [Phemex Create Order Position With Takeprofit Stoploss](./examples/ts/)
|
||||
|
||||
|
||||
```javascript
|
||||
// @ts-nocheck
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
|
||||
// AUTO-TRANSPILE //
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
|
||||
async function example () {
|
||||
const exchange = new ccxt.phemex ({
|
||||
'apiKey': 'YOUR_API_KEY',
|
||||
'secret': 'YOUR_API_SECRET',
|
||||
});
|
||||
|
||||
const symbol = 'XRP/USDT:USDT';
|
||||
const side = 'buy'; // set it to 'buy' for a long position, 'sell' for a short position
|
||||
const order_type = 'limit'; // set it to 'market' or 'limit'
|
||||
const amount = 1; // how many contracts
|
||||
const price = 0.5; // set a price at your desired level
|
||||
|
||||
// take profit and stop loss prices and types
|
||||
const take_profit_trigger_price = 0.6;
|
||||
const stop_loss_trigger_price = 0.4;
|
||||
const take_profit_limit_price = 0.7;
|
||||
const stop_loss_limit_price = 0.3;
|
||||
|
||||
await exchange.loadMarkets ();
|
||||
|
||||
// when symbol's price reaches your predefined "trigger price", stop-loss order would be activated as a "market order". but if you want it to be activated as a "limit order", then set a 'price' parameter for it
|
||||
const params = {
|
||||
'posSide': 'Long', // "Long" / "Short" for hedge mode
|
||||
'stopLoss': {
|
||||
'triggerPrice': stop_loss_trigger_price,
|
||||
'type': 'limit',
|
||||
'price': stop_loss_limit_price,
|
||||
},
|
||||
'takeProfit': {
|
||||
'triggerPrice': take_profit_trigger_price,
|
||||
'type': 'limit',
|
||||
'price': take_profit_limit_price,
|
||||
},
|
||||
};
|
||||
|
||||
console.log ('-----------------------------------------------------------------------');
|
||||
|
||||
// exchange.verbose = True // uncomment for debugging purposes if necessary
|
||||
|
||||
try {
|
||||
const created_order = await exchange.createOrder (symbol, order_type, side, amount, price, params);
|
||||
console.log ('Created an order', created_order);
|
||||
|
||||
// Fetch all your open orders for this symbol
|
||||
const all_open_orders = await exchange.fetchOpenOrders (symbol);
|
||||
console.log ('Fetched all your orders for this symbol', all_open_orders);
|
||||
|
||||
// To cancel a limit order, use "exchange.cancel_order(created_order['id'], symbol)""
|
||||
} catch (e) {
|
||||
console.log (e.toString ());
|
||||
}
|
||||
}
|
||||
|
||||
await example ();
|
||||
|
||||
|
||||
```
|
||||
@@ -0,0 +1,55 @@
|
||||
- [Proxy Usage](./examples/ts/)
|
||||
|
||||
|
||||
```javascript
|
||||
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
|
||||
// AUTO-TRANSPILE //
|
||||
|
||||
// 1) ABOUT CCXT PROXIES, READ MORE AT: https://docs.ccxt.com/#/README?id=proxy
|
||||
// 2) in python, uncomment the below:
|
||||
// if sys.platform == 'win32':
|
||||
// asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
|
||||
|
||||
async function example_proxyUrl () {
|
||||
const myEx = new ccxt.kucoin ();
|
||||
myEx.proxyUrl = 'http://188.245.226.105:8090/proxy_url.php?caller=https://ccxt.com&url=';
|
||||
console.log (await myEx.fetch ('https://api.ipify.org/'));
|
||||
}
|
||||
|
||||
async function example_httpProxy () {
|
||||
const myEx = new ccxt.kucoin ();
|
||||
myEx.httpProxy = 'http://188.245.226.105:8911'; // "httpProxy" or "httpsProxy" (depending on your proxy protocol)
|
||||
console.log (await myEx.fetch ('https://api.ipify.org/'));
|
||||
}
|
||||
|
||||
async function example_socksProxy () {
|
||||
const myEx = new ccxt.kucoin ();
|
||||
myEx.socksProxy = 'socks5://127.0.0.1:1080'; // from protocols: socks, socks5, socks5h
|
||||
console.log (await myEx.fetch ('https://api.ipify.org/'));
|
||||
}
|
||||
|
||||
async function example_webSockets () {
|
||||
const myEx = new ccxt.pro.kucoin ();
|
||||
myEx.httpProxy = 'http://188.245.226.105:8911'; // even though you are using WebSockets, you might also need to set up proxy for the exchange's REST requests
|
||||
myEx.wsProxy = 'http://188.245.226.105:8911'; // "wsProxy" or "wssProxy" or "wsSocksProxy" (depending on your proxy protocol)
|
||||
await myEx.loadMarkets ();
|
||||
//
|
||||
// To ensure your WS proxy works, uncomment below code and watch the log
|
||||
//
|
||||
// myEx.verbose = true;
|
||||
// await myEx.loadHttpProxyAgent ();
|
||||
// await myEx.watch ('ws://188.245.226.105:9876/', 'myip'); // in the incoming logs, confirm that you see the proxy IP in "hello" message
|
||||
//
|
||||
console.log (await myEx.watchTicker ('BTC/USDT'));
|
||||
await myEx.close ();
|
||||
}
|
||||
|
||||
|
||||
// await example_proxyUrl ();
|
||||
await example_httpProxy ();
|
||||
// await example_socksProxy ();
|
||||
// await example_webSockets ();
|
||||
|
||||
```
|
||||
@@ -0,0 +1,21 @@
|
||||
- [Sample Local Proxy Server With Cors](./examples/ts/)
|
||||
|
||||
|
||||
```javascript
|
||||
// @ts-nocheck
|
||||
// JavaScript sample Proxy with CORS support
|
||||
|
||||
// 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)
|
||||
|
||||
import cors from 'cors-anywhere'; // npm install cors-anywhere
|
||||
|
||||
const port = (process.argv.length > 2) ? parseInt (process.argv[2]) : 8080; // if not provided from cli, default to 8080
|
||||
cors.createServer ({
|
||||
// you can set origin, if needed by exchange
|
||||
// setHeaders: { 'origin': 'https://www.bitmex.com' }
|
||||
}).listen (port, 'localhost');
|
||||
console.log ('Running CORS Anywhere on localhost:' + port);
|
||||
|
||||
```
|
||||
@@ -0,0 +1,23 @@
|
||||
- [Watch Ohlcv For Symbols](./examples/ts/)
|
||||
|
||||
|
||||
```javascript
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
|
||||
// AUTO-TRANSPILE //
|
||||
|
||||
async function example () {
|
||||
const binance = new ccxt.pro.binance ({});
|
||||
const subscriptions = [
|
||||
[ 'BTC/USDT', '5m' ],
|
||||
[ 'ETH/USDT', '5m' ],
|
||||
[ 'BTC/USDT', '1h' ],
|
||||
];
|
||||
while (true) {
|
||||
const ohlcv = await binance.watchOHLCVForSymbols (subscriptions);
|
||||
console.log (ohlcv);
|
||||
}
|
||||
}
|
||||
await example ();
|
||||
|
||||
```
|
||||
@@ -0,0 +1,20 @@
|
||||
- [Watch Ohlcv](./examples/ts/)
|
||||
|
||||
|
||||
```javascript
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
|
||||
// AUTO-TRANSPILE //
|
||||
|
||||
async function example () {
|
||||
const binance = new ccxt.pro.binance ({});
|
||||
const symbol = 'BTC/USDT';
|
||||
const timeframe = '1m';
|
||||
while (true) {
|
||||
const ohlcv = await binance.watchOHLCV (symbol, timeframe);
|
||||
console.log (ohlcv);
|
||||
}
|
||||
}
|
||||
await example ();
|
||||
|
||||
```
|
||||
@@ -0,0 +1,19 @@
|
||||
- [Watch Orderbook For Symbols](./examples/ts/)
|
||||
|
||||
|
||||
```javascript
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
|
||||
// AUTO-TRANSPILE //
|
||||
|
||||
async function example () {
|
||||
const binance = new ccxt.pro.binance ({});
|
||||
const symbols = [ 'BTC/USDT', 'ETH/USDT', 'DOGE/USDT' ];
|
||||
while (true) {
|
||||
const orderbook = await binance.watchOrderBookForSymbols (symbols);
|
||||
console.log (orderbook['symbol'], orderbook['asks'][0], orderbook['bids'][0]);
|
||||
}
|
||||
}
|
||||
await example ();
|
||||
|
||||
```
|
||||
@@ -0,0 +1,19 @@
|
||||
- [Watch Trades For Symbols](./examples/ts/)
|
||||
|
||||
|
||||
```javascript
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
|
||||
// AUTO-TRANSPILE //
|
||||
|
||||
async function example () {
|
||||
const binance = new ccxt.pro.binance ({});
|
||||
const symbols = [ 'BTC/USDT', 'ETH/USDT', 'DOGE/USDT' ];
|
||||
while (true) {
|
||||
const trades = await binance.watchTradesForSymbols (symbols);
|
||||
console.log (trades);
|
||||
}
|
||||
}
|
||||
await example ();
|
||||
|
||||
```
|
||||
@@ -0,0 +1,19 @@
|
||||
- [Watch Tickers](./examples/ts/)
|
||||
|
||||
|
||||
```javascript
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
|
||||
// AUTO-TRANSPILE //
|
||||
|
||||
async function example () {
|
||||
const binance = new ccxt.pro.binance ({});
|
||||
const symbols = [ 'BTC/USDT', 'ETH/USDT', 'DOGE/USDT' ];
|
||||
while (true) {
|
||||
const tickers = await binance.watchTickers (symbols);
|
||||
console.log (tickers['BTC/USDT'], tickers['ETH/USDT'], tickers['DOGE/USDT']);
|
||||
}
|
||||
}
|
||||
await example ();
|
||||
|
||||
```
|
||||
@@ -0,0 +1,59 @@
|
||||
- [Watchpositions Many Exchanges Continuosly](./examples/ts/)
|
||||
|
||||
|
||||
```javascript
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
|
||||
// AUTO-TRANSPILE //
|
||||
|
||||
// watch and handle constinuosly
|
||||
async function watchPositionsContinuously (exchange) {
|
||||
while (true) {
|
||||
try {
|
||||
const positions = await exchange.watchPositions ();
|
||||
console.log ('Fetched ', exchange.id, ' - Positions: ', positions);
|
||||
} catch (e) {
|
||||
console.log (e);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// start exchanges and fetch OHLCV loop
|
||||
async function startExchange (exchangeName, config) {
|
||||
const ex = new ccxt[exchangeName] (config);
|
||||
const promises = [];
|
||||
promises.push (watchPositionsContinuously (ex));
|
||||
await Promise.all (promises);
|
||||
await ex.close ();
|
||||
}
|
||||
|
||||
// main function
|
||||
async function example () {
|
||||
const exchanges = {
|
||||
'binanceusdm': {
|
||||
'apiKey': 'YOUR_API_KEY',
|
||||
'secret': 'YOUR_API_SECRET',
|
||||
},
|
||||
'okx': {
|
||||
'apiKey': 'YOUR_API_KEY',
|
||||
'secret': 'YOUR_API_SECRET',
|
||||
},
|
||||
'huobi':{
|
||||
'apiKey': 'YOUR_API_KEY',
|
||||
'secret': 'YOUR_API_SECRET',
|
||||
},
|
||||
};
|
||||
const promises = [];
|
||||
const exchangeIds = Object.keys (exchanges);
|
||||
for (let i = 0; i < exchangeIds.length; i++) {
|
||||
const exchangeName = exchangeIds[i];
|
||||
const config = exchanges[exchangeName];
|
||||
promises.push (startExchange (exchangeName, config));
|
||||
}
|
||||
await Promise.all (promises);
|
||||
}
|
||||
|
||||
await example ();
|
||||
|
||||
```
|
||||
@@ -0,0 +1,21 @@
|
||||
- [Watchpositions](./examples/ts/)
|
||||
|
||||
|
||||
```javascript
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
|
||||
// AUTO-TRANSPILE //
|
||||
|
||||
async function example () {
|
||||
const exchange = new ccxt.pro.binanceusdm ({
|
||||
'apiKey': 'YOUR_API_KEY',
|
||||
'secret': 'YOUR_API_SECRET'
|
||||
});
|
||||
while (true) {
|
||||
const trades = await exchange.watchPositions ();
|
||||
console.log (trades);
|
||||
}
|
||||
}
|
||||
await example ();
|
||||
|
||||
```
|
||||
@@ -0,0 +1,22 @@
|
||||
- [Watchpositionsforsymbols](./examples/ts/)
|
||||
|
||||
|
||||
```javascript
|
||||
import ccxt from '../../js/ccxt.js';
|
||||
|
||||
// AUTO-TRANSPILE //
|
||||
|
||||
async function example () {
|
||||
const exchange = new ccxt.pro.binanceusdm ({
|
||||
'apiKey': 'YOUR_API_KEY',
|
||||
'secret': 'Your_API_SECRET'
|
||||
});
|
||||
const symbols = [ 'BTC/USDT:USDT', 'ETH/USDT:USDT', 'DOGE/USDT:USDT' ];
|
||||
while (true) {
|
||||
const trades = await exchange.watchPositions (symbols);
|
||||
console.log (trades);
|
||||
}
|
||||
}
|
||||
await example ();
|
||||
|
||||
```
|
||||
Reference in New Issue
Block a user