Há cerca de 7 anos, tive experiência em escrever um terminal para a Bolsa de Moscou. Parte da equipe gostava de negociação algorítmica, inclusive eu. No entanto, ele nunca percebeu esse negócio como uma fonte real de renda, embora houvesse pouco sucesso nisso. É claro que para competir com bancos e vários fundos, com suas equipes de matemáticos e programadores, é difícil e fácil de implementar em outras áreas.
Agora, as criptomoedas são ouvidas, um grande número de trocas apareceu. Com base no pressuposto de que é possível ganhar dinheiro com a diferença nas taxas de câmbio em diferentes bolsas, decidi estudar a possibilidade de criar um robô de arbitragem. Mas basicamente, para começar a aprender python com um exemplo real. Então, vamos começar.
Antes de tudo, é necessário detectar pares de moedas para os quais é possível negociar arbitragem. Precisamos de pares que, em uma primeira aproximação, estejam negociando ativamente, e os preços em diferentes trocas divergam e convergam.
De antemão, o plano de trabalho deve ser assim:
- Criação de um banco de dados onde os preços dos pares de moedas serão armazenados.
- Um servidor que salvará dados no banco de dados.
- Análise primária.
As fontes estão disponíveis em
arb_analysis .
Criação de banco de dados
Para armazenar dados, você precisa de 3 tabelas.
Esta tabela irá armazenar uma lista de trocas.
CREATE TABLE `exchange` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(50) NOT NULL, PRIMARY KEY (id) ) ENGINE=MyISAM;
Lista de pares de criptomoedas.
CREATE TABLE `market` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` char(50) NOT NULL, `id_exchange` int(11) NOT NULL, PRIMARY KEY (id) ) ENGINE=MyISAM; CREATE INDEX id_exchange ON market (id_exchange);
Uma tabela com transações, informações também serão armazenadas aqui, de acordo com dados do vidro da bolsa de valores.
CREATE TABLE `ticker` ( `id` int(11) NOT NULL AUTO_INCREMENT, `id_market` int(5) NOT NULL, `local_time` int(9) NOT NULL, `timestamp` int(9) NOT NULL, `last` DECIMAL (11,11) NOT NULL, `low` DECIMAL (11,11), `high` DECIMAL (11,11), `bid` DECIMAL (11,11), `ask` DECIMAL (11,11), PRIMARY KEY (id) ) ENGINE=MyISAM; CREATE INDEX id_market ON ticker (id_market);
Obtendo dados de trocas
Para acesso conveniente às trocas, existe um projeto de código aberto ccxt. Com a ajuda da qual é possível aplicar a diferentes trocas em um único estilo. No entanto, verificou-se que nem tudo era tão otimista; para várias trocas, não foi possível obter informações e alguns métodos não funcionaram.
No arquivo create_markets.py, a inicialização ocorre, obtemos uma lista de pares de criptomoedas por troca. Nesse caso, é usado o método load_markets (), que retorna uma lista de pares para a troca.
name_exchange = ["acx", "binance", "bitfinex", "bitfinex2", "wex"] def create_exchange_and_market_in_db(): exchanges = {} for id in name_exchange: exchange = getattr(ccxt, id) exchanges[id] = exchange() id_exchage = db_helper.insert_exchage_to_db(exchanges[id],cnx,cursor) markets = exchanges[id].load_markets() for mark in markets: id_market = db_helper.insert_market_to_db( id_exchage, mark, cnx,cursor)
Em seguida, no arquivo ex_data_saver.py, começamos a salvar a alteração nos preços dos pares:
def save(): markets = db_helper.get_data_exch() exchanges = {} for id in name_exchange: exchange = getattr(ccxt, id)
O recebimento assíncrono de ticks para um par específico ocorre usando o método ccxt fetchTickers ().
async def fetch_ticker(exchanges, name): item = exchanges[name] try: ticker = await item.fetchTickers() return {name:ticker}
Análise preliminar de dados
Antes de tudo, é interessante em quais trocas e em quais pares a negociação mais ativa ocorre, estamos interessados em pares líquidos. Para fazer isso, você precisa calcular o número de transações agrupadas por trocas e pares específicos. Como resultado, obtemos pares que estão negociando ativamente.
SELECT ex.name as exchange_name, m.name as market_name, count(*) as count_deals FROM exchange ex LEFT JOIN market m ON m.id_exchange = ex.id LEFT JOIN ticker t ON t.id_market =m.id GROUP BY ex.id, t.id_market ORDER BY m.name HAVING count_deals > 10000;
Usando consultas SQL, é possível encontrar vários padrões e filtrar dados; no entanto, para uma análise detalhada, é necessário criar um robô de teste que funcione com os dados acumulados de várias trocas.
O próximo artigo será dedicado à criação deste robô. E o servidor de teste - emulando o trabalho de uma troca real.Eu quero colocar os seguintes pontos no servidor de teste:
- Atrasos.
- Deslizamento.
- Comissões.