Back to Ccxt

Arbitrage Pairs

wiki/examples/py/arbitrage-pairs.md

4.5.523.4 KB
Original Source
python
# -*- coding: utf-8 -*-

import os
import sys

import ccxt  # noqa: E402


def style(s, style):
   return style + s + '\033[0m'


def green(s):
   return style(s, '\033[92m')


def blue(s):
   return style(s, '\033[94m')


def yellow(s):
   return style(s, '\033[93m')


def red(s):
   return style(s, '\033[91m')


def pink(s):
   return style(s, '\033[95m')


def bold(s):
   return style(s, '\033[1m')


def underline(s):
   return style(s, '\033[4m')


def dump(*args):
   print(' '.join([str(arg) for arg in args]))


def print_exchanges():
   dump('Supported exchanges:', ', '.join(ccxt.exchanges))


def print_usage():
   dump("Usage: python " + sys.argv[0], green('id1'), yellow('id2'), blue('id3'), '...')


proxies = [
   '',  # no proxy by default
   'https://crossorigin.me/',
   'https://cors-anywhere.herokuapp.com/',
]

if len(sys.argv) > 2:
   ids = list(sys.argv[1:])
   exchanges = {}
   dump(ids)
   dump(yellow(' '.join(ids)))
   for id in ids:  # load all markets from all exchange exchanges

       # instantiate the exchange by id
       exchange = getattr(ccxt, id)()

       # save it in a dictionary under its id for future use
       exchanges[id] = exchange

       # load all markets from the exchange
       markets = exchange.load_markets()

       # basic round-robin proxy scheduler
       currentProxy = -1
       maxRetries = len(proxies)

       for numRetries in range(0, maxRetries):

           # try proxies in round-robin fashion
           currentProxy = (currentProxy + 1) % len(proxies)

           try:  # try to load exchange markets using current proxy

               exchange.proxy = proxies[currentProxy]
               exchange.load_markets()

           except ccxt.DDoSProtection as e:
               dump(yellow(type(e).__name__), e.args)
           except ccxt.RequestTimeout as e:
               dump(yellow(type(e).__name__), e.args)
           except ccxt.AuthenticationError as e:
               dump(yellow(type(e).__name__), e.args)
           except ccxt.ExchangeNotAvailable as e:
               dump(yellow(type(e).__name__), e.args)
           except ccxt.ExchangeError as e:
               dump(yellow(type(e).__name__), e.args)
           except ccxt.NetworkError as e:
               dump(yellow(type(e).__name__), e.args)
           except Exception as e:  # reraise all other exceptions
               raise

       dump(green(id), 'loaded', green(str(len(exchange.symbols))), 'markets')

   dump(green('Loaded all markets'))

   allSymbols = [symbol for id in ids for symbol in exchanges[id].symbols]

   # get all unique symbols
   uniqueSymbols = list(set(allSymbols))

   # filter out symbols that are not present on at least two exchanges
   arbitrableSymbols = sorted([symbol for symbol in uniqueSymbols if allSymbols.count(symbol) > 1])

   # print a table of arbitrable symbols
   table = []
   dump(green(' symbol          | ' + ''.join([' {:<15} | '.format(id) for id in ids])))
   dump(green(''.join(['-----------------+-' for x in range(0, len(ids) + 1)])))

   for symbol in arbitrableSymbols:
       string = ' {:<15} | '.format(symbol)
       row = {}
       for id in ids:
           # if a symbol is present on a exchange print that exchange's id in the row
           string += ' {:<15} | '.format(id if symbol in exchanges[id].symbols else '')
       dump(string)

else:
   print_usage()