Discussing the article: "High frequency arbitrage trading system in Python using MetaTrader 5"

 

Check out the new article: High frequency arbitrage trading system in Python using MetaTrader 5.

In this article, we will create an arbitration system that remains legal in the eyes of brokers, creates thousands of synthetic prices on the Forex market, analyzes them, and successfully trades for profit.

Foreign exchange market. Algorithmic strategies. Python and MetaTrader 5. This came together when I started working on an arbitrage trading system. The idea was simple - create a high-frequency system to find price imbalances. What did all this lead to in the end?

I used MetaTrader 5 API most often during this period. I decided to calculate synthetic cross rates. I decided not to limit myself to ten or a hundred. The number has exceeded one thousand.

Risk management was a separate task. System architecture, algorithms, decision making - we will analyze everything here. I will show the results of backtesting and live trading. And of course, I will share ideas for the future. Who knows, maybe one of you would like to develop this topic further? I hope that my work will be in demand. I would like to believe that it will contribute to the development of algorithmic trading. Maybe someone will take it as a basis and create something even more effective in the world of high-frequency arbitrage. After all, that is the essence of science - moving forward based on the experience of predecessors. Let's get straight to the point.


Author: Yevgeniy Koshtenko

 
метку Toxic Order Flow ставят не столько из-за поглощения ликвидности из рынка в моменте, сколько из-за высоких нагрузок на обслуживание такого потока ордеров.
Toxic is a profitable trade. There is no order spam problem.
 

Misunderstood. Usually arbitrage involves trading at least two instruments in the direction of each other. Here, it seems that one order is generated for each arbitrage situation, i.e. the hope is that the real instrument will pull up to the synthetic, but not vice versa. The probability of this is fifty-fifty, imho.

Also, for some reason the bid price is taken for purchases and ask for sales:

price = symbol_info.bid if direction == "BUY" else symbol_info.ask

If the idea is to "bend" the broker on the spread - the 8 points in the signal condition:

arbitrage_opportunities = pd.DataFrame(spreads) > 0.00008

then in the properties of the order there is a slippage of 30 ("deviation": 30), which gives him the opportunity to execute with much greater losses than the planned profit.

And I didn't see positions closing exactly on the condition of successful arbitrage triggering, and waiting for closing on kilometre take profit or stop loss is like guessing at coffee grounds for an arbitrage strategy (which catches millimetre imbalances), imho.

 

Please explain what this is about:

А теперь следующий шаг — список pairs. Это наши валютные пары, которые мы будем использовать для синтеза. Дальше начинается еще один процесс. Мы запускаем цикл по всем парам. Для каждой пары мы рассчитываем синтетическую цену двумя способами:

Делим bid первой пары на ask второй.
Делим bid первой пары на bid второй.
И каждый раз мы увеличиваем наш method_count. В итоге у нас получается не 1000, не 1500, а целых 2000 синтетических цен!

Here are the pairs:

pairs = [('AUDUSD', 'USDCHF'), ('AUDUSD', 'NZDUSD'), ('AUDUSD', 'USDJPY'),
             ('USDCHF', 'USDCAD'), ('USDCHF', 'NZDCHF'), ('USDCHF', 'CHFJPY'),
             ('USDJPY', 'USDCAD'), ('USDJPY', 'NZDJPY'), ('USDJPY', 'GBPJPY'),
             ('NZDUSD', 'NZDCAD'), ('NZDUSD', 'NZDCHF'), ('NZDUSD', 'NZDJPY'),
             ('GBPUSD', 'GBPCAD'), ('GBPUSD', 'GBPCHF'), ('GBPUSD', 'GBPJPY'),
             ('EURUSD', 'EURCAD'), ('EURUSD', 'EURCHF'), ('EURUSD', 'EURJPY'),
             ('CADCHF', 'CADJPY'), ('CADCHF', 'GBPCAD'), ('CADCHF', 'EURCAD'),
             ('CHFJPY', 'GBPCHF'), ('CHFJPY', 'EURCHF'), ('CHFJPY', 'NZDCHF'),
             ('NZDCAD', 'NZDJPY'), ('NZDCAD', 'GBPNZD'), ('NZDCAD', 'EURNZD'),
             ('NZDCHF', 'NZDJPY'), ('NZDCHF', 'GBPNZD'), ('NZDCHF', 'EURNZD'),
             ('NZDJPY', 'GBPNZD'), ('NZDJPY', 'EURNZD')]

What is the Bid of the first pair ? The first pair is:

('AUDUSD', 'USDCHF')
 
pivomoe #:

What is the Bid of the first pair ? The first pair is:

AUDUSD is also a pair. AUD to USD.

 
pivomoe #:

Please explain what this is about:

Here are the pairs:

What is the Bid of the first pair ? The first pair is:

This is how synthetics builds. Not through difference, but division. And not simple - but... read.....
 
ticks = mt5.copy_ticks_from(symbol, utc_from, count, mt5.COPY_TICKS_ALL)

All installed. This is what comes up in ticks:

array([b'', b'', b'', b'', b'', b'', b'', b'', b'', b'', b'', b'', b'', b'', b'',

...

b'', b'', b'', b'', b'', b'', b'', b'', b'', b'', b'', b'', b'', b'', b'',

b'', b'', b'', b'', b'', b'', b'', b'', b'', b'', b'', b'', b'', b'', b'',

b'', b'', b'', b'', b'', b'', b'', b'', b'', b'', b'', b'', b'', b''],

dtype='|V0')


And here we already get an exit on time:

ticks_frame['time'] = pd.to_datetime(ticks_frame['time'], unit='s')
 

The code from the example https://www.mql5.com/ru/docs/python_metatrader5/mt5copyticksfrom_py doesn't work either

>>>  timezone = pytz.timezone("Etc/UTC")
>>>  utc_from = datetime(2020, 1, 10, tzinfo=timezone)
>>>  ticks = mt5.copy_ticks_from("EURUSD", utc_from, 100000, mt5.COPY_TICKS_ALL)
>>>
>>> print("Received ticks:",len(ticks))
Получено тиков: 100000
>>> print("Let's take the resulting ticks as they are.")
Выведем полученные тики как есть
>>>  count = 0
>>> for tick in ticks:
...     count+=1
...     print(tick)
...     if count >= 100:
...         break
...
b''
b''
b''
b''

Anyway, what is python like? How to prepare it? It's unclear...

Документация по MQL5: Python интеграция / copy_ticks_from
Документация по MQL5: Python интеграция / copy_ticks_from
  • www.mql5.com
Получает тики из терминала MetaTrader 5, начиная с указанной даты. Параметры symbol [in]  Имя финансового инструмента, например, ...
 
Does this really work? It's not supported by regular brokers