@@ -22,8 +22,7 @@ includes sending commands to, and receiving events from, the trading venue
22
22
endpoints via its registered execution clients.
23
23
24
24
The engine employs a simple fan-in fan-out messaging pattern to execute
25
- `TradingCommand` messages, and process `AccountState` or `OrderEvent` type
26
- messages.
25
+ `TradingCommand` messages and `OrderEvent` messages.
27
26
28
27
Alternative implementations can be written on top of the generic engine - which
29
28
just need to override the `execute` and `process` methods.
@@ -48,7 +47,6 @@ from nautilus_trader.common.component cimport RECV
48
47
from nautilus_trader.common.component cimport Clock
49
48
from nautilus_trader.common.component cimport Component
50
49
from nautilus_trader.common.component cimport LogColor
51
- from nautilus_trader.common.component cimport Logger
52
50
from nautilus_trader.common.component cimport MessageBus
53
51
from nautilus_trader.common.component cimport TimeEvent
54
52
from nautilus_trader.common.generators cimport PositionIdGenerator
@@ -57,12 +55,9 @@ from nautilus_trader.core.fsm cimport InvalidStateTrigger
57
55
from nautilus_trader.core.rust.core cimport secs_to_nanos
58
56
from nautilus_trader.core.rust.model cimport ContingencyType
59
57
from nautilus_trader.core.rust.model cimport OmsType
60
- from nautilus_trader.core.rust.model cimport OrderStatus
61
- from nautilus_trader.core.rust.model cimport OrderType
58
+ from nautilus_trader.core.rust.model cimport OrderSide
62
59
from nautilus_trader.core.rust.model cimport PositionSide
63
- from nautilus_trader.core.rust.model cimport TimeInForce
64
60
from nautilus_trader.core.uuid cimport UUID4
65
- from nautilus_trader.execution.algorithm cimport ExecAlgorithm
66
61
from nautilus_trader.execution.client cimport ExecutionClient
67
62
from nautilus_trader.execution.messages cimport BatchCancelOrders
68
63
from nautilus_trader.execution.messages cimport CancelAllOrders
@@ -91,11 +86,11 @@ from nautilus_trader.model.identifiers cimport PositionId
91
86
from nautilus_trader.model.identifiers cimport StrategyId
92
87
from nautilus_trader.model.identifiers cimport Venue
93
88
from nautilus_trader.model.instruments.base cimport Instrument
94
- from nautilus_trader.model.instruments.currency_pair cimport CurrencyPair
95
89
from nautilus_trader.model.objects cimport Money
96
90
from nautilus_trader.model.objects cimport Price
97
91
from nautilus_trader.model.objects cimport Quantity
98
92
from nautilus_trader.model.orders.base cimport Order
93
+ from nautilus_trader.trading.strategy cimport Strategy
99
94
100
95
101
96
cdef class ExecutionEngine(Component):
@@ -151,6 +146,8 @@ cdef class ExecutionEngine(Component):
151
146
clock = clock,
152
147
)
153
148
149
+ self._pending_position_events = []
150
+
154
151
# Configuration
155
152
self.debug: bool = config.debug
156
153
self.manage_own_order_books = config.manage_own_order_books
@@ -1050,6 +1047,25 @@ cdef class ExecutionEngine(Component):
1050
1047
else :
1051
1048
self ._apply_event_to_order(order, event)
1052
1049
1050
+ # Publish events
1051
+ self ._msgbus.publish_c(
1052
+ topic = f" events.order.{event.strategy_id}" ,
1053
+ msg = event,
1054
+ )
1055
+ if self .snapshot_orders:
1056
+ self ._create_order_state_snapshot(order)
1057
+
1058
+ for pos_event in self ._pending_position_events:
1059
+ self ._msgbus.publish_c(
1060
+ topic = f" events.position.{pos_event.strategy_id}" ,
1061
+ msg = pos_event,
1062
+ )
1063
+ if self .snapshot_positions:
1064
+ position = self .cache.position(pos_event.position_id)
1065
+ self ._create_position_state_snapshot(position, open_only = isinstance (pos_event, PositionOpened))
1066
+
1067
+ self ._pending_position_events.clear()
1068
+
1053
1069
cpdef OmsType _determine_oms_type(self , OrderFilled fill):
1054
1070
cdef ExecutionClient client
1055
1071
# Check for strategy OMS override
@@ -1171,13 +1187,6 @@ cdef class ExecutionEngine(Component):
1171
1187
1172
1188
self ._cache.update_order(order)
1173
1189
1174
- self ._msgbus.publish_c(
1175
- topic = f" events.order.{event.strategy_id}" ,
1176
- msg = event,
1177
- )
1178
- if self .snapshot_orders:
1179
- self ._create_order_state_snapshot(order)
1180
-
1181
1190
cpdef void _handle_order_fill(self , Order order, OrderFilled fill, OmsType oms_type):
1182
1191
cdef Instrument instrument = self ._cache.load_instrument(fill.instrument_id)
1183
1192
if instrument is None :
@@ -1222,8 +1231,6 @@ cdef class ExecutionEngine(Component):
1222
1231
if position is None :
1223
1232
position = Position(instrument, fill)
1224
1233
self ._cache.add_position(position, oms_type)
1225
- if self .snapshot_positions:
1226
- self ._create_position_state_snapshot(position, open_only = True )
1227
1234
else :
1228
1235
try :
1229
1236
# Always snapshot opening positions to handle NETTING OMS
@@ -1242,10 +1249,7 @@ cdef class ExecutionEngine(Component):
1242
1249
ts_init = self ._clock.timestamp_ns(),
1243
1250
)
1244
1251
1245
- self ._msgbus.publish_c(
1246
- topic = f" events.position.{event.strategy_id}" ,
1247
- msg = event,
1248
- )
1252
+ self ._pending_position_events.append(event)
1249
1253
1250
1254
return position
1251
1255
@@ -1258,8 +1262,6 @@ cdef class ExecutionEngine(Component):
1258
1262
return # Not re-raising to avoid crashing engine
1259
1263
1260
1264
self ._cache.update_position(position)
1261
- if self .snapshot_positions:
1262
- self ._create_position_state_snapshot(position, open_only = False )
1263
1265
1264
1266
cdef PositionEvent event
1265
1267
if position.is_closed_c():
@@ -1277,10 +1279,7 @@ cdef class ExecutionEngine(Component):
1277
1279
ts_init = self ._clock.timestamp_ns(),
1278
1280
)
1279
1281
1280
- self ._msgbus.publish_c(
1281
- topic = f" events.position.{event.strategy_id}" ,
1282
- msg = event,
1283
- )
1282
+ self ._pending_position_events.append(event)
1284
1283
1285
1284
cpdef bint _will_flip_position(self , Position position, OrderFilled fill):
1286
1285
return (
0 commit comments