Дополнительные материалы

Быстрый поиск по статье

Экспорт на UDP порт

Терминал Moonbot может передавать рыночные данные (5-минутные свечи и все сделки по всем маркетам) на локальный UDP-порт с IP-адресом 127.0.0.1. Данные обновляются только по активным парам (BTC, USDT или ETH — в зависимости от выбранной конфигурации терминала).


Также терминал может принимать торговые сигналы на покупку через UDP-порт.


Для включения этой функции зайдите в Настройки Специальные System и установите галочку UDP Export.


Передача данных осуществляется в двоичном формате пакетами, содержащими несколько элементов. В параметрах UDP необходимо указать порт 2000 и размер буфера 65000.


Массив свечей передаётся полностью при каждом обновлении (раз в 5 минут). Данные по сделкам передаются только новые, однако в одном пакете может содержаться несколько трейдов.


Приём сигналов осуществляется терминалом на порту 1999 в текстовом формате. Полученные сигналы обрабатываются стратегией типа UDP (см. рисунок ниже):



Пример сигнала: ‘Key=Test1 Coin=NEO Order=buy BuyPrice=0.0071’.


Расшифровка параметров:


  • Key = ключ, по которому будет выбрана стратегия в терминале с соответствующим полем ChannelKey (в примере на рис. выше это Test1).

  • Coin = монета

  • Order =

    • buy - команда на покупку

    • sell - активация продажи на ранее купленной в терминале монете (купленной по любой стратегии, не обязательно UDP)

  • BuyPrice = цена, на которую будет выставлен Buy ордер. Если не задана, то будет использована настройка стратегии.


Пример кода, поясняющий приём и обработку данных (скачать архив с исходным кодом и готовым примером можно по ссылке 🔗https://moonbot.eu/files/udpTest.zip):


// structures


TOrderType = (O_SELL,O_BUY,O_BuyStop);


TUpdateKind = (UK_Candles, UK_Trades);


TUpdateHeader = packed record


Version: byte; // 1 byte - packet version, currently 1


TimeStamp: dword; // 4 bytes - Unix timestamp


Kind: TUpdateKind; // 1 byte - candles (0) or trades (1) inside


Coin: string[7]; // 7 bytes - coin ticker name


Count: word; // 2 bytes - elements count in the data array


reserved1: dword; // 4 bytes currently unused


reserved2: dword; // 4 bytes currently unused


end;


TTradeOrder = record // 8-bytes aligned


ID: integer;


Time: TDateTime;


Price: double;


Quantity: double;


BuyerID: integer;


reserved: integer;


OrderType: TOrderType;


FillType: byte; // 0 - PARTIAL, 1 - FULL


end;


TCandle = record


OpenP,CloseP,MaxP,MinP: double;


Vol: double;


Time: TDateTime;


end;


TTrades = array of TTradeOrder;


TCandles = array of TCandle;


// Data reading and handling


procedure TfrmUDPTest.IdUDPServer1UDPRead(AThread: TIdUDPListenerThread;


const AData: TIdBytes; ABinding: TIdSocketHandle);


var


hdr: TUpdateHeader;


Trades: TTrades;


Candles: TCandles;


begin


move(AData[0], hdr, SizeOf(hdr));


If hdr.Kind = UK_Trades then begin


SetLength(Trades, hdr.Count);


move(AData[SizeOf(hdr)], Trades[0], hdr.Count * SizeOf(TTradeOrder));


If SelectedCoin = hdr.Coin


then lPrice.Caption:=hdr.Coin + ‘ Last: ‘ + FloatToStr(Trades[hdr.Count - 1].Price);


end;


If hdr.Kind = UK_Candles then begin


SetLength(Candles, hdr.Count);


move(AData[SizeOf(hdr)], Candles[0], hdr.Count * SizeOf(TCandle));


lLastCandle.Caption:=’ Last candle: ‘ + hdr.Coin + ‘ 5m vol: ‘ + FloatToStr(Candles[hdr.Count - 1].Vol);


end;


lLastTrade.Caption:=Format(‘Last update: %s time: %d’, [hdr.Coin, hdr.TimeStamp]);


end;