✅ Sending an Order¶
Request: place a market or pending order on a given symbol. Wrapper around the TradingHelper RPC that accepts volume, optional price (for pending), SL/TP, slippage, comment, magic, and expiration.
Source files (SDK):
MetaRpcMT4/mt4_account.py— methodorder_send(...)MetaRpcMT4/mt4_term_api_trading_helper_pb2.py—OrderSend*messages,OrderSendOperationTypeenum
RPC¶
- Service:
mt4_term_api.TradingHelper - Method:
OrderSend(OrderSendRequest) → OrderSendReply - Low‑level client:
TradingHelperStub.OrderSend(request, metadata, timeout) - SDK wrapper:
MT4Account.order_send(
symbol: str,
operation_type: trading_helper_pb2.OrderSendOperationType,
volume: float,
price: float | None = None,
slippage: int | None = None,
stoploss: float | None = None,
takeprofit: float | None = None,
comment: str | None = None,
magic_number: int | None = None,
expiration: datetime | None = None,
deadline: datetime | None = None,
cancellation_event: asyncio.Event | None = None,
) -> trading_helper_pb2.OrderSendData
Request message: OrderSendRequest { symbol, operation_type, volume, price?, slippage?, stoploss?, takeprofit?, comment?, magic_number?, expiration? }
Reply message: OrderSendReply { data: OrderSendData }
🔗 Code Examples¶
from MetaRpcMT4 import mt4_term_api_trading_helper_pb2 as trade_pb
# 1) Market BUY 0.10 with SL/TP
await acct.order_send(
symbol="EURUSD",
operation_type=trade_pb.OrderSendOperationType.OC_OP_BUY, # BUY
volume=0.10,
stoploss=1.0820,
takeprofit=1.0870,
slippage=20, # points
comment="bot v1",
magic_number=12345,
)
# 2) Pending SELL LIMIT with expiration
from datetime import datetime, timedelta, timezone
await acct.order_send(
symbol="XAUUSD",
operation_type=trade_pb.OrderSendOperationType.OC_OP_SELLLIMIT,
volume=0.50,
price=2365.0,
stoploss=2378.0,
takeprofit=2325.0,
expiration=datetime.now(timezone.utc) + timedelta(hours=6),
comment="grid#7",
)
Method Signature¶
async def order_send(
self,
symbol: str,
operation_type: trading_helper_pb2.OrderSendOperationType,
volume: float,
price: float | None = None,
slippage: int | None = None,
stoploss: float | None = None,
takeprofit: float | None = None,
comment: str | None = None,
magic_number: int | None = None,
expiration: datetime | None = None,
deadline: datetime | None = None,
cancellation_event: asyncio.Event | None = None,
) -> trading_helper_pb2.OrderSendData
💬 Just the essentials¶
- What it is. A single call to place market or pending orders.
- Why. Primary entry‑point for strategy execution / manual actions.
- Validation. Always combine with
symbol_params_many(...)to respectVolumeMin/Max/Step,StopsLevel/FreezeLevel, and withquote(...)for price sanity.
🔽 Input¶
| Parameter | Type | Description | |
|---|---|---|---|
symbol |
str |
Target symbol (e.g., EURUSD). |
|
operation_type |
OrderSendOperationType |
BUY / SELL / BUYLIMIT / SELLLIMIT / BUYSTOP / SELLSTOP. | |
volume |
float |
Lots to trade (see VolumeMin/Max/Step). |
|
price |
float | None |
Entry price for pending orders; None for market. |
|
slippage |
int | None |
Max slippage in points for market orders. | |
stoploss |
float | None |
Initial SL. | |
takeprofit |
float | None |
Initial TP. | |
comment |
str | None |
User/system comment. | |
magic_number |
int | None |
EA magic for robots. | |
expiration |
datetime | None |
Expiration for pending orders. | |
deadline |
datetime | None |
Absolute per‑call deadline. | |
cancellation_event |
asyncio.Event | None |
Cooperative cancel for retry wrapper. |
Price/SL/TP are raw prices; convert from points/pips with
Pointfromsymbol_params_many(...).
⬆️ Output¶
Payload: OrderSendData¶
| Field | Proto Type | Description |
|---|---|---|
ticket |
int32 |
Ticket assigned to the newly created order/position. |
volume |
double |
Volume (lots) of the order. |
price |
double |
Executed/placed price (market or pending). |
open_time |
google.protobuf.Timestamp |
Server timestamp of order opening. |
On error, the wrapper raises per
error_selectorinexecute_with_reconnect(...).
🧱 Related enums (from pb)¶
OrderSendOperationType¶
OC_OP_BUY = 0— Market buy orderOC_OP_SELL = 1— Market sell orderOC_OP_BUYLIMIT = 2— Buy limit pending orderOC_OP_SELLLIMIT = 3— Sell limit pending orderOC_OP_BUYSTOP = 4— Buy stop pending orderOC_OP_SELLSTOP = 5— Sell stop pending order
🎯 Purpose¶
Use this method to:
- Place entries from strategies or UI.
- Create bracket orders with initial SL/TP.
- Populate audit logs with ticket/price outcomes.
🧩 Notes & Tips¶
- Respect StopsLevel/FreezeLevel: ensure
abs(entry - SL/TP) >= min_points * Point. - Volume snapping: clamp and snap to
[VolumeMin, VolumeMax]byVolumeStep. - Prefer absolute UTC times for
expiration. Ensure it’s in the future relative to server time. - For market orders, omit
price; the server will fill at best available withinslippage.
See also:
order_modify(...) — update SL/TP/expiration/price for pending.
order_close_delete(...) — close market positions / delete pendings.
order_close_by(...) — close one position by another (hedge accounts).
Usage Snippets¶
1) Snap & validate volume¶
p = (await acct.symbol_params_many("EURUSD")).params_info[0]
def snap_volume(vol, p):
vol = max(p.VolumeMin, min(p.VolumeMax, vol))
steps = round((vol - p.VolumeMin) / p.VolumeStep)
return p.VolumeMin + steps * p.VolumeStep
v = snap_volume(0.27, p)
2) Ensure SL/TP distances¶
q = await acct.quote("EURUSD")
p = (await acct.symbol_params_many("EURUSD")).params_info[0]
min_pts = max(p.StopsLevel, p.FreezeLevel)
min_delta = min_pts * p.Point
# Example for BUY pending
entry = q.ask - 10 * p.Point
sl = entry - 20 * p.Point
assert (entry - sl) >= min_delta
3) Market buy with tight slippage and comment¶
from MetaRpcMT4 import mt4_term_api_trading_helper_pb2 as trade_pb
await acct.order_send(
symbol="GBPUSD",
operation_type=trade_pb.OrderSendOperationType.OC_OP_BUY,
volume=0.20,
slippage=10,
comment="scalp#42",
)