/arbitrage-algorithms-framework

Arbitrage Algorithms Framework (working) Prototype for making trading bots on top of CCXT, with simple lifecycle. In TypeScript.

Primary LanguageTypeScriptOtherNOASSERTION

Arbitrage Algorithms Framework Prototype

For making trading bots on top of CCXT, with simple lifecycle. In TypeScript.

example

Feel free to contribute.

Configuration

{
    keys: {
        [key: string /* exchange */]: {
            apiKey: string;
            secret: string;
        }
    };
    exchangesToWatch: string[];
    orderBookLimit: number;
    exchangeOptions: {
        [key: string /* exchange */]: any
    };
    defaultExchangeOptions: any;
    currenciesToWatch: string[];

    makeOrders: boolean;
    parallelOrders: boolean;

    profile: boolean;
    logDetails: boolean;
    logAdditionalDetails: boolean;
    logWarnings: boolean;
    logAdditionalWarnings: boolean;
    logError: boolean;
    logErrorDetails: boolean;

    // ccxt calculate_fees correction
    feesRate: number;
    zeroesFeesCorrection: boolean;
    correctAllFees: boolean;
    feesRoundType: 'ceil' | 'floor' |'round';

    orderOptionsByExchange: {
        [key: string /* exchange */]: any
    };
    defaultOrderOptions: any;

    enableProxy: boolean;
    changeProxyAfterEveryOrder: boolean;
    changeProxyAfterAnyNetworkError: boolean;
    proxies: string[];

    telegram?: {
      token: string;
      startPhrase: string;
      stopPhrase: string;
      chats: string[];
      logErrors: boolean;
    }
}

Usage

import Bot from "arbitrage-algorithms-framework";
import { config, errorLogTemplate, log } from "arbitrage-algorithms-framework";

const bot = new Bot(config(require("path/to/config.local.json")));
const toIterate = [];
bot.init().then(
    () => {
        bot.printProfileTime();
        bot.cycle(
            toIterate, 
            (params) => {
                // class extending Algorithm base class to be used in cycle
                return new CustomAlgorithm(params)
            }, iteratedElement => ({
                // function for element adaptation
                ...iteratedElement
            } as CustomAlgorithmParams),
            () => {
                log('Algorithm cycle stared');      
                bot.printProfileTime();  
                bot.telegram.sendMessage('Algorithm cycle stared');
            }
        );
    },
    err => log(errorLogTemplate(err))
);

Check src/example.ts for more details.

Todo

  • "fluid" fees (depends on fees.currency, other than default)
  • use prepared error handler
  • bot method for placing orders with retries
  • WS adapter class compatible with ccxt (for updating iterating elements in rl time, making orders, use with proxy?)
  • limits, precisions exceptions (per exchange, coin, exchange + coin and order side)
  • make triangle orders at once via proxy or one by one
  • fill order at once or chunk (depends on balance and/or agresivness)
  • ArbitrageBetweenExchanges
  • ArbitrageTriangularBetweenExchanges
  • handle fees in BNB on binance
  • handle other ordersand fees types (eg. oco, precision rounding types)
  • ignore (exchange, market, coin) lists
  • readme, docs

Proxy

To start proxy on another server:

npm i arbitrage-algorithms-framework
npm i -g cors-anywhere
node node_modules/arbitrage-algorithms-framework/misc/proxy.js PORT HOST

Then add HOST:PORT in config proxies list.

ArbitrageTriangleWithinExchange

MARKET: BASE/QUOTE

	     M0				 
         /\				 
        /  \			 
   D0 |/_   \_
      /     |\      	 
    _/        \			 
    /|        _\| D1	 
   /            \ 		 
  /____\____/____\	
 M2    /    \    M1		 

D - DIRECTION,			 
M - MARKET, 
C - COIN 	

M0 C0_C1
M1 C1_C2
M2 C0_C2

Direction 0:
M0 BUY (C0 for C1)  | +C0 -C1
M1 BUY (C1 for C2)  | +C1 -C2
M2 SELL (C0 for C2) | -C0 +C2

Direction 1:
M0 SELL (C0 for C1) | -C0 +C1
M1 SELL (C1 for C2) | -C1 +C2
M2 BUY (C0 for C2)  | +C0 -C2

Temporary assumptions:

  • don't use BNB for fees on Binance
  • every exchange has limit orders

Known issues:

  • handle minimum fees on Bleutrade

ArbitrageBetweenExchanges

TBD

BUY C0 FOR C1 -> TRANSFER C0 -> SELL C0 FOR C1 -> TRANSFER C1 SELL C0 FOR C1 -> TRANSFER C1 -> BUY C0 FOR C1 -> TRANSFER C0

ArbitrageTriangularBetweenExchanges

TBD

MARKET: BASE/QUOTE

	    M0E0			 
         /\				 
        /  \			 
      |/_   \_
      /     |\      	 
    _/        \			 
    /|        _\| 		 
   /            \ 		 
  /____\____/____\		 
M2E1   /    \	 M1E0	 

D - DIRECTION,			 
M - MARKET, 
C - COIN, 	 
E - EXCHANGE 			 
						 		 	 
M0 C0_C1
M1 C1_C2
M2 C0_C2

Direction 0:
M0E0 BUY (C0 for C1)  | +C0 -C1 | E0
M2E0 SELL (C0 for C2) | -C0 +C2 | E0
TRANSFER C2 FROM E0 TO E1       | -E0 +E1
M2E1 BUY (C0 for C2)  | +C0 -C2 | E1
TRANSFER C0 FROM E1 TO E0 		 | -E1 +E0

Direction 1:
M0E0 SELL (C0 for C1) | -C0 +C1 | E0
M1E0 BUY (C2 for C1)  | +C2 -C1 | E0
TRANSFER C2 FROM E0 TO E1       | -E0 +E1
M2E1 BUY (C0 for C2)  | +C0 -C2 | E1
TRANSFER C0 FROM E1 TO E0 		 | -E1 +E0

Direction 2:
M0E0 BUY (C0 for C1)  | +C0 -C1 | E0
TRANSFER C0 FROM E0 TO E1       | -E0 +E1
M2E1 SELL (C0 for C2) | -C0 +C2 | E1
M2E1 BUY (C0 for C2)  | +C0 -C2 | E1
TRANSFER C0 FROM E1 TO E0 		 | -E1 +E0

Direction 3:
M0E0 SELL (C0 for C1) | -C0 +C1 | E0
TRANSFER C1 FROM E0 TO E1       | -E0 +E1
M1E1 BUY (C2 for C1)  | +C2 -C1 | E1
M2E1 BUY (C0 for C2)  | +C0 -C2 | E1
TRANSFER C0 FROM E1 TO E0 		 | -E1 +E0

Direction 4:
M0E0 BUY (C0 for C1)  | +C0 -C1 | E0
TRANSFER C0 FROM E0 TO E1       | -E0 +E1
M2E1 SELL (C0 for C2) | -C0 +C2 | E1
M2E1 BUY (C0 for C2)  | +C0 -C2 | E1
TRANSFER C0 FROM E1 TO E0 		 | -E1 +E0

Direction 5:
M0E0 SELL (C0 for C1) | -C0 +C1 | E0
TRANSFER C1 FROM E0 TO E1       | -E0 +E1
M1E1 BUY (C2 for C1)  | +C2 -C1 | E1
M2E1 BUY (C0 for C2)  | +C0 -C2 | E1
TRANSFER C0 FROM E1 TO E0 		 | -E1 +E0

Direction 0 is exemplary. Transfers can be between any cone, cones can be vary within three markets (not every occures in every direction).

m	m	m	t	t
m	t	t	m	m
t	m	m	m	t
m	m	t	t	m
t	t	m	m	m *

@TODO: GET EVERY POSSIBLE DIRECTION (* take into account bids/asks variation)