OrderHistory HOW
Example from file: examples/demos/lowlevel/01_general_operations.go¶
The
OrderHistory()method is used to get historical orders (executed, cancelled, expired) for a selected time period. It does not return open positions — only completed operations.
🧩 Code example¶
fmt.Println("\n5.4. OrderHistory() - Get historical orders")
// Set time range (last 30 days) - must use timestamppb.Timestamp
now := time.Now()
fromTimestamp := timestamppb.New(now.AddDate(0, 0, -30))
toTimestamp := timestamppb.New(now)
orderHistoryReq := &pb.OrderHistoryRequest{
InputFromUtc: fromTimestamp, // time.Now() is UTC-based: use the *Utc fields
InputToUtc: toTimestamp,
InputSortMode: pb.BMT5_ENUM_ORDER_HISTORY_SORT_TYPE_BMT5_SORT_BY_OPEN_TIME_ASC,
PageNumber: 0, // 0 = page-number paging not used (all items)
ItemsPerPage: 0, // 0 = page-number paging not used (all items)
}
orderHistoryData, err := account.OrderHistory(ctx, orderHistoryReq)
if err != nil {
helpers.PrintShortError(err, "OrderHistory failed")
} else {
fmt.Printf(" Historical orders (last 30d): %d\n", len(orderHistoryData.HistoryData))
maxShow := 2
if len(orderHistoryData.HistoryData) < maxShow {
maxShow = len(orderHistoryData.HistoryData)
}
for i := 0; i < maxShow; i++ {
item := orderHistoryData.HistoryData[i]
if item.HistoryOrder != nil {
order := item.HistoryOrder
fmt.Printf("\n Order #%d:\n", i+1)
fmt.Printf(" Ticket: %d\n", order.Ticket)
fmt.Printf(" Symbol: %s\n", order.Symbol)
fmt.Printf(" Type: %v\n", order.Type)
fmt.Printf(" Volume: %.2f\n", order.VolumeInitial)
fmt.Printf(" Price Open: %.5f\n", order.PriceOpen)
}
}
}
🟢 Detailed Code Explanation¶
now := time.Now()
fromTimestamp := timestamppb.New(now.AddDate(0, 0, -30))
toTimestamp := timestamppb.New(now)
A date range is formed — the last 30 days.
MetaTrader requires fields of type timestamppb.Timestamp, so conversion from time.Time is used.
orderHistoryReq := &pb.OrderHistoryRequest{
InputFromUtc: fromTimestamp,
InputToUtc: toTimestamp,
InputSortMode: pb.BMT5_ENUM_ORDER_HISTORY_SORT_TYPE_BMT5_SORT_BY_OPEN_TIME_ASC,
PageNumber: 0,
ItemsPerPage: 0,
}
A request is created to get orders for the period between InputFromUtc and InputToUtc.
Request Parameters:
InputFrom/InputFromUtc- start time of history range (required):InputFromis in the broker server's time zone,InputFromUtcin UTC; send one of them, not bothInputTo/InputToUtc- end time of history range (required), same ruleInputSortMode- sort mode (optional):BMT5_SORT_BY_OPEN_TIME_ASC(0) /BMT5_SORT_BY_OPEN_TIME_DESC(1) - sort by open timeBMT5_SORT_BY_CLOSE_TIME_ASC(2) /BMT5_SORT_BY_CLOSE_TIME_DESC(3) - sort by close timeBMT5_SORT_BY_ORDER_TICKET_ID_ASC(4) /BMT5_SORT_BY_ORDER_TICKET_ID_DESC(5) - sort by ticket IDPageNumber- page number for legacy page-number paging (1-based, needsItemsPerPage; 0 = not used, all items)ItemsPerPage- rows per page for legacy page-number paging (0 = not used)PageToken/PageSize- cursor paging (preferred); cannot be combined withPageNumber/ItemsPerPage
A gRPC call OrderHistory() is sent.
In response, an array of HistoryData structures is received, each describing one completed order.
The total number of historical orders found for the specified period is displayed.
if item.HistoryOrder != nil {
order := item.HistoryOrder
fmt.Printf("\n Order #%d:\n", i+1)
fmt.Printf(" Ticket: %d\n", order.Ticket)
fmt.Printf(" Symbol: %s\n", order.Symbol)
fmt.Printf(" Type: %v\n", order.Type)
fmt.Printf(" Volume: %.2f\n", order.VolumeInitial)
fmt.Printf(" Price Open: %.5f\n", order.PriceOpen)
}
The loop outputs the main fields for each order:
- Ticket — unique order number;
- Symbol — instrument for which it was placed;
- Type — order type (
BUY,SELL,BUY_LIMIT, etc.); - VolumeInitial — initial volume;
- PriceOpen — order opening price.
📦 What the Server Returns¶
message OrdersHistoryData {
int32 arrayTotal = 1;
int32 pageNumber = 2;
int32 itemsPerPage = 3;
repeated HistoryData history_data = 4;
string next_page_token = 5; // cursor paging: token of the next page
}
message HistoryData {
uint32 index = 1;
OrderHistoryData history_order = 2;
DealHistoryData history_deal = 3;
}
message OrderHistoryData {
uint64 ticket = 1;
google.protobuf.Timestamp setup_time = 2;
google.protobuf.Timestamp done_time = 3;
BMT5_ENUM_ORDER_STATE state = 4;
double price_current = 5;
double price_open = 6;
double stop_limit = 7;
double stop_loss = 8;
double take_profit = 9;
double volume_current = 10;
double volume_initial = 11;
int64 magic_number = 12;
BMT5_ENUM_ORDER_TYPE type = 13;
google.protobuf.Timestamp time_expiration = 14;
BMT5_ENUM_ORDER_TYPE_FILLING type_filling = 15;
BMT5_ENUM_ORDER_TYPE_TIME type_time = 16;
uint64 position_id = 17;
string symbol = 18;
string external_id = 19;
string comment = 20;
int64 account_login = 21;
}
💡 Example Output¶
Historical orders (last 30d): 2
Order #1:
Ticket: 128007201
Symbol: EURUSD
Type: BMT5_ORDER_TYPE_BUY
Volume: 0.01
Price Open: 0.00000
Order #2:
Ticket: 128009723
Symbol: EURUSD
Type: BMT5_ORDER_TYPE_BUY
Volume: 0.01
Price Open: 0.00000
⚠️ Why Price Open Equals 0.00000¶
If you see that the PriceOpen = 0.00000 field, this is not a code error. Possible reasons:
-
Historical orders were not executed (Pending Orders) If an order was cancelled by the user or expired by time, the server stores it in history but without an opening price.
-
Market orders are filled at the market price A market order may be stored with
PriceOpen= 0; the actual execution price is in the matching deal (HistoryDeal.Price). -
Historical data limited by server Some brokers store only basic order attributes, and if an order was closed long ago or was not executed, some fields may be zeroed.
-
MetaTrader demo server On demo servers (especially test clusters), trade history is sometimes incomplete —
PriceOpenmay not be filled.
🧠 What It's Used For¶
The OrderHistory() method is used:
- for analyzing trading for a specific period (PnL, trade frequency, instruments);
- for restoring history after restarting a trading robot;
- for forming reports and trade journals;
- in analytical modules that build charts or statistics on trades.
💬 In Simple Terms¶
OrderHistory()allows you to get history of completed orders for a specified period. If the opening price is zero, it means the order was not executed or data is incomplete on the server side. This is a normal situation when working with demo or inactive orders.