---
id: mooncmd-protocol-description
title: "MoonCDM Protocol Description"
section: documentation
category: "Additional materials / MoonCMD Remote Control Protocol"
url: https://moonbot.eu/en/documentation/mooncmd-remote-control-protocol/mooncmd-protocol-description
locale: en
status: published
updated_at: 2026-07-04T11:07:48+00:00
---

# 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:001.0 = 31 December 1899 00:000.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.

### Header

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).
