✅ On Position Profit¶
Request: subscribe to periodic position P/L updates. Server‑streaming RPC that emits batches of new/updated/deleted positions plus an account P/L snapshot.
Source files (SDK):
MetaRpcMT5/mt5_account.py
— methodon_position_profit(...)
MetaRpcMT5/mt5_term_api_subscriptions_pb2.py
—OnPositionProfit*
messages and payloadsMetaRpcMT5/mt5_term_api_subscriptions_pb2_grpc.py
— service stubSubscriptionServiceStub
RPC¶
- Service:
mt5_term_api.SubscriptionService
- Method:
OnPositionProfit(OnPositionProfitRequest) → stream OnPositionProfitReply
- Low‑level client:
SubscriptionServiceStub.OnPositionProfit(request, metadata, timeout)
(server‑streaming iterator) - SDK wrapper:
MT5Account.on_position_profit(interval_ms, ignore_empty, cancellation_event=None) → async stream of OnPositionProfitData
🔗 Code Example¶
# Minimal: stream profit updates every 1s, skip empty batches
async for ev in acct.on_position_profit(interval_ms=1000, ignore_empty=True):
# ev: OnPositionProfitData
total = sum(p.profit for p in (getattr(ev, 'updated_positions', []) or []))
print("updated:", len(getattr(ev, 'updated_positions', []) or []), "total pnl:", total)
# With cooperative cancellation after first non‑empty event
import asyncio
cancel = asyncio.Event()
async for ev in acct.on_position_profit(500, True, cancellation_event=cancel):
if (getattr(ev, 'new_positions', None) or getattr(ev, 'updated_positions', None) or getattr(ev, 'deleted_positions', None)):
print("non‑empty batch; equity:", getattr(ev, 'account_info', None).equity)
cancel.set()
Method Signature¶
async def on_position_profit(
self,
interval_ms: int,
ignore_empty: bool,
cancellation_event: asyncio.Event | None = None,
) -> AsyncIterator[subscription_pb2.OnPositionProfitData]
💬 Just about the main thing¶
- What it is. Timed profit snapshots for positions with deltas (new/updated/deleted) and an account P/L frame.
- Why. Keep dashboards, badges, and risk widgets fresh without polling multiple services.
-
Be careful.
-
interval_ms
controls server timer; don’t spam with tiny intervals unless you really need it. ignore_empty=True
suppresses empty frames (no position changes) to reduce UI churn.
🔽 Input¶
Parameter | Type | Description | |
---|---|---|---|
interval_ms |
int (required) |
Sampling period in milliseconds (server timer). | |
ignore_empty |
bool (required) |
Skip frames with no changes (positions lists empty). | |
cancellation_event |
`asyncio.Event | None` | Cooperative stop for the streaming RPC. |
Request message:
OnPositionProfitRequest { timerPeriodMilliseconds: int32, ignoreEmptyData: bool }
⬆️ Output¶
Stream payload: OnPositionProfitData
¶
Field | Proto Type | Description |
---|---|---|
type |
MT5_SUB_ENUM_EVENT_GROUP_TYPE |
Event group marker (e.g., OrderProfit ). |
new_positions |
repeated OnPositionProfitPositionInfo |
Positions that appeared since last frame. |
updated_positions |
repeated OnPositionProfitPositionInfo |
Positions with profit change/update. |
deleted_positions |
repeated OnPositionProfitPositionInfo |
Positions that disappeared (closed). |
account_info |
OnEventAccountInfo |
Account snapshot (balance/equity/margins). |
terminal_instance_guid_id |
string |
Source terminal GUID. |
OnPositionProfitPositionInfo
¶
# | Field | Type | Notes |
---|---|---|---|
1 | index |
int32 | Ordering index inside the batch. |
2 | ticket |
int64 | Position ticket. |
3 | profit |
double | Position profit at this snapshot. |
4 | position_symbol |
string | Symbol of the position. |
OnEventAccountInfo
¶
# | Field | Type |
---|---|---|
1 | balance |
double |
2 | credit |
double |
3 | equity |
double |
4 | margin |
double |
5 | free_margin |
double |
6 | profit |
double |
7 | margin_level |
double |
8 | login |
int64 |
Wire stream:
OnPositionProfitReply { data: OnPositionProfitData, error?: Error }
SDK wrapper yieldsOnPositionProfitData
objects one by one.
Enum: MT5_SUB_ENUM_EVENT_GROUP_TYPE
¶
Number | Value |
---|---|
0 | OrderProfit |
1 | OrderUpdate |
🎯 Purpose¶
- Drive P/L tickers and summary tiles in UI.
- Alert on unusual profit swings per position.
- Lightweight input for risk dashboards and telemetry.
🧩 Notes & Tips¶
- For orders/positions life‑cycle deltas (beyond profit), see
OnTrade
. - For low-level transaction auditing (request/result), see
OnTradeTransaction
. - Use
symbol_info_*
calls to enrich rows with digits/format if you render money values.
See also: opened_orders.md, positions_history.md, on_trade.md
Usage Examples¶
1) Running sum of current P/L¶
async for ev in acct.on_position_profit(1000, True):
pnl = sum(p.profit for p in (ev.updated_positions or []))
print("P/L:", pnl)
2) Only show non-empty frames¶
async for ev in acct.on_position_profit(500, True):
if not (ev.new_positions or ev.updated_positions or ev.deleted_positions):
continue
print("changed:", len(ev.new_positions), len(ev.updated_positions), len(ev.deleted_positions))
3) Stop the stream after 5 seconds¶
import asyncio
stop = asyncio.Event()
async def guard():
await asyncio.sleep(5)
stop.set()
asyncio.create_task(guard())
async for ev in acct.on_position_profit(200, False, cancellation_event=stop):
print(ev.account_info.equity)