MoonCMD Remote Control Protocol

Quick article search

MoonCDM Protocol Description

Basic Types


Byte order: little-endian for all numeric types.


Types:


  • word – 2 bytes (UInt16);

  • integer – 4 bytes (Int32);

  • single – 4 bytes (float);

  • boolean – 1 byte (0 = false, 1 = true);

  • TDateTime – 8 bytes (double), number of days since 30 December 1899:
    0.0 = 30 December 1899 00:00
    1.0 = 31 December 1899 00:00
    0.5 = 30 December 1899 12:00, etc.


Short string (Delphi ShortString):


- string[40] = 41 bytes:
1 byte for the length Len (0..40), followed by Len bytes of characters (ANSI / single-byte encoding).


UTF-8 strings (WriteStringToStreamUtf8):
- 2 bytes: word L – the length of the string data in bytes
- L bytes: UTF-8 without BOM.



Reading sequence:


  1. Read the ‘ver’ word (2 bytes) – the format version.

  2. Read 4 lines in UTF-8:

    1. MarketName: - word L - L bytes of UTF-8;

    2. MarketCurrency: - word L - L bytes UTF-8;

    3. PumpChannel (cfg.PumpChannel): - word L- L bytes UTF-8;

    4. bnMarketName: - word L- L bytes UTF-8.


Time Interval


Reading procedure:


  1. Read StartTime (8-byte double, TDateTime);

  2. Read EndTime (8-byte double, TDateTime).


Historical Price Line (HistoryPrice)


THistoricalPrice element (correction):


Used in the stream as a pair (Time, Price), both of type double.


Element type:


  • 8 bytes: double Time;

  • 4 bytes: single Price.


Reading order:


  1. Read an integer N (4 bytes) – the number of elements;

  2. If N > 0, read N elements in sequence:
    for i = 0..N-1:

    1. 8 bytes: Time[i];

    2. 8 bytes: Price[i].


pData ORDERS (if written)


In the stream, this looks like this:


Reading order:


  1. Read integer N (4 bytes):

    1. if pData = nil when written, then N = 0 (no further orders);

    2. if pData ≠ nil, then N = 2 (exactly two orders).

  2. If N > 0, read N = 2 times: Buy Order and Sell Order:

    1. OrderID: TOrderUID = string[40]:
      - 1 byte: Len (0..40)
      - Len bytes: identifier data (single-byte characters) (if you wish to strictly replicate Delphi ShortString, you can always read 41 bytes, but for parsing, the following is sufficient: 1 byte for length + Len bytes of data)

    2. MeanPrice:
      - 8 bytes: double

    3. CreateTime:
      - 8 bytes: double (TDateTime)

    4. OpenTime:
      - 8 bytes: double (TDateTime)

    5. CloseTime:
      - 8 bytes: double (TDateTime).



Trades on the Chart (crosses, OrdersH)


THPackedHOrder element:


  • 8 bytes: double Time (TDateTime)

  • 4 bytes: single Price (for sell orders, the price is recorded with a ‘−’ sign).


Reading order:


  1. Read integer N (4 bytes) – the number of trades.

  2. If N > 0, read N elements in sequence:
    for j = 0..N-1:
    - 8 bytes: Time[j]
    - 4 bytes: Price[j].


Delta/Volume Block (two variants)


  • Last1mDelta – 8 bytes

  • Last5mDelta – 8 bytes

  • Last1hDelta – 8 bytes

  • Last3hDelta – 8 bytes

  • Last24hDelta – 8 bytes

  • PumpDelta1h – 8 bytes

  • DumpDelta1h – 8 bytes

  • hvol – 8 bytes

  • hvolFast – 8 bytes

  • TestPriceDown – 8 bytes

  • TestPriceUp – 8 bytes

  • IsMoonShot – 1 byte

  • SessionProfit – 8 bytes.


Average Price Line for Trades (ClosestPrices)


Elements of the same format as the THistoricalPrice records above:
(Time, Price), both double.


Element type:


  • 8 bytes: double Time;

  • 8 bytes: double Price.


Reading order


  1. 1) Read integer N (4 bytes) – the number of points.

  2. 2) If N > 0, read N elements in sequence:
    for k = 0..N-1:
    - 8 bytes: Time[k]
    - 8 bytes: Price[k]
    (In the code, N=0 is written first, then the elements themselves, then the code returns and rewrites N.
    What matters to the reader is the final form: the number and N elements).


Mini Candles (SCandles)


TMiniCandle structure:


  • 8 bytes: Time – TDateTime (double)

  • 4 bytes: Cnt – integer (Int32)

  • 8 bytes: MinPrice – double

  • 8 bytes: MaxPrice – double

  • 8 bytes: BuyVol – double

  • 8 bytes: SellVol – double.


Size of a single TMiniCandle element = 44 bytes.


Reading order


  1. 1) Read integer N (4 bytes) – the number of mini-candles.

  2. 2) If N > 0, for each candle (i = 0..N-1) read:

    1. Time – 8 bytes (double, TDateTime);

    2. Cnt – 4 bytes (integer);

    3. MinPrice – 8 bytes (double);

    4. MaxPrice – 8 bytes (double);

    5. BuyVol – 8 bytes (double);

    6. SellVol – 8 bytes (double).


Final File Read Order


  1. word ver;

  2. UTF-8 string MarketName;

  3. UTF-8 string MarketCurrency;

  4. UTF-8 string PumpChannel;

  5. UTF-8 string bnMarketName;

  6. TDateTime StartTime (double);

  7. TDateTime EndTime (double);

  8. integer N_History;

  9. N_History * (Time, Price) as double,double;

  10. integer N_Orders;

  11. N_Orders * (OrderID string[40], MeanPrice, CreateTime, OpenTime, CloseTime);

  12. integer N_Trades;

  13. N_Trades * (Time, Price) as double,double;

  14. Delta/Volume block;

  15. double SessionProfit;

  16. integer N_ClosestPrices;

  17. N_ClosestPrices * (Time, Price) as double,double;

  18. integer N_SCandles;

  19. N_SCandles * TMiniCandle (Time, Cnt, MinPrice, MaxPrice, BuyVol, SellVol).