tradx 0.8.3__tar.gz → 0.9__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {tradx-0.8.3 → tradx-0.9}/PKG-INFO +1 -1
- {tradx-0.8.3 → tradx-0.9}/examples/example1.py +1 -1
- {tradx-0.8.3 → tradx-0.9}/examples/example2.py +26 -19
- {tradx-0.8.3 → tradx-0.9}/pyproject.toml +1 -1
- tradx-0.9/src/tradx/algoContainer.py +170 -0
- {tradx-0.8.3 → tradx-0.9}/src/tradx/baseClass/baseAlgo.py +24 -9
- {tradx-0.8.3/src/tradx/baseClass → tradx-0.9/src/tradx/baseClass/interactive}/order.py +6 -0
- {tradx-0.8.3/src/tradx/baseClass → tradx-0.9/src/tradx/baseClass/interactive}/orderEvent.py +3 -1
- {tradx-0.8.3/src/tradx/baseClass → tradx-0.9/src/tradx/baseClass/interactive}/position.py +8 -1
- {tradx-0.8.3 → tradx-0.9}/src/tradx/interactiveEngine.py +197 -58
- {tradx-0.8.3 → tradx-0.9}/src/tradx/marketDataEngine.py +254 -76
- tradx-0.8.3/src/tradx/algoContainer.py +0 -90
- {tradx-0.8.3 → tradx-0.9}/.gitignore +0 -0
- {tradx-0.8.3 → tradx-0.9}/.vscode/settings.json +0 -0
- {tradx-0.8.3 → tradx-0.9}/README.md +0 -0
- {tradx-0.8.3 → tradx-0.9}/examples/example1.log +0 -0
- {tradx-0.8.3 → tradx-0.9}/examples/example2.log +0 -0
- {tradx-0.8.3 → tradx-0.9}/src/tradx/__init__.py +0 -0
- {tradx-0.8.3/src/tradx/baseClass → tradx-0.9/src/tradx/baseClass/interactive}/positionEvent.py +0 -0
- {tradx-0.8.3/src/tradx/baseClass → tradx-0.9/src/tradx/baseClass/interactive}/tradeConversionEvent.py +0 -0
- {tradx-0.8.3/src/tradx/baseClass → tradx-0.9/src/tradx/baseClass/interactive}/tradeEvent.py +0 -0
- {tradx-0.8.3/src/tradx/baseClass → tradx-0.9/src/tradx/baseClass/market}/candleData.py +0 -0
- {tradx-0.8.3/src/tradx/baseClass → tradx-0.9/src/tradx/baseClass/market}/cmInstrument.py +0 -0
- {tradx-0.8.3/src/tradx/baseClass → tradx-0.9/src/tradx/baseClass/market}/futureInstrument.py +0 -0
- {tradx-0.8.3/src/tradx/baseClass → tradx-0.9/src/tradx/baseClass/market}/index.py +0 -0
- {tradx-0.8.3/src/tradx/baseClass → tradx-0.9/src/tradx/baseClass/market}/instrumentPropertyChangeData.py +0 -0
- {tradx-0.8.3/src/tradx/baseClass → tradx-0.9/src/tradx/baseClass/market}/ltpData.py +0 -0
- {tradx-0.8.3/src/tradx/baseClass → tradx-0.9/src/tradx/baseClass/market}/ltpPartialData.py +0 -0
- {tradx-0.8.3/src/tradx/baseClass → tradx-0.9/src/tradx/baseClass/market}/marketDepthData.py +0 -0
- {tradx-0.8.3/src/tradx/baseClass → tradx-0.9/src/tradx/baseClass/market}/marketStatusData.py +0 -0
- {tradx-0.8.3/src/tradx/baseClass → tradx-0.9/src/tradx/baseClass/market}/openInterestData.py +0 -0
- {tradx-0.8.3/src/tradx/baseClass → tradx-0.9/src/tradx/baseClass/market}/openInterestPartialData.py +0 -0
- {tradx-0.8.3/src/tradx/baseClass → tradx-0.9/src/tradx/baseClass/market}/optionsInstrument.py +0 -0
- {tradx-0.8.3/src/tradx/baseClass → tradx-0.9/src/tradx/baseClass/market}/touchLineData.py +0 -0
- {tradx-0.8.3/src/tradx/baseClass → tradx-0.9/src/tradx/baseClass/market}/touchLinePartialData.py +0 -0
- {tradx-0.8.3 → tradx-0.9}/src/tradx/constants/holidays.py +0 -0
- {tradx-0.8.3 → tradx-0.9}/src/tradx/dualHashMap.py +0 -0
- {tradx-0.8.3 → tradx-0.9}/src/tradx/logger/logger.py +0 -0
- {tradx-0.8.3 → tradx-0.9}/src/tradx/logger/logger2.py +0 -0
- {tradx-0.8.3 → tradx-0.9}/src/tradx/py.typed +0 -0
- {tradx-0.8.3 → tradx-0.9}/test/test_candleData.py +0 -0
- {tradx-0.8.3 → tradx-0.9}/test/test_interactiveEngine.log +0 -0
- {tradx-0.8.3 → tradx-0.9}/test/test_interactiveEngine.py +0 -0
- {tradx-0.8.3 → tradx-0.9}/test/test_logger.log +0 -0
- {tradx-0.8.3 → tradx-0.9}/test/test_logger.py +0 -0
- {tradx-0.8.3 → tradx-0.9}/test/test_ltpData.py +0 -0
- {tradx-0.8.3 → tradx-0.9}/test/test_ltpPartailData.py +0 -0
- {tradx-0.8.3 → tradx-0.9}/test/test_marketDataEngine.log +0 -0
- {tradx-0.8.3 → tradx-0.9}/test/test_marketDataEngine.py +0 -0
- {tradx-0.8.3 → tradx-0.9}/test/test_marketDepthData.py +0 -0
- {tradx-0.8.3 → tradx-0.9}/test/test_marketStatusData.py +0 -0
- {tradx-0.8.3 → tradx-0.9}/test/test_openInterestData.py +0 -0
- {tradx-0.8.3 → tradx-0.9}/test/test_openInterestPartialData.py +0 -0
- {tradx-0.8.3 → tradx-0.9}/test/test_option.py +0 -0
- {tradx-0.8.3 → tradx-0.9}/test/test_orderEvent.py +0 -0
- {tradx-0.8.3 → tradx-0.9}/test/test_positionEvent.py +0 -0
- {tradx-0.8.3 → tradx-0.9}/test/test_touchLineData.py +0 -0
- {tradx-0.8.3 → tradx-0.9}/test/test_tradeConversionEvent.py +0 -0
- {tradx-0.8.3 → tradx-0.9}/test/test_tradeEvent.py +0 -0
@@ -1,7 +1,7 @@
|
|
1
1
|
from tradx.marketDataEngine import marketDataEngine
|
2
2
|
from tradx.interactiveEngine import interactiveEngine
|
3
3
|
from tradx.baseClass.baseAlgo import BaseAlgo
|
4
|
-
from tradx.baseClass.candleData import CandleData
|
4
|
+
from tradx.baseClass.market.candleData import CandleData
|
5
5
|
from tradx.logger.logger import setup_user_logger
|
6
6
|
import asyncio
|
7
7
|
import os
|
@@ -1,15 +1,17 @@
|
|
1
|
+
# Importing modules from tradx
|
1
2
|
from tradx.marketDataEngine import marketDataEngine
|
2
3
|
from tradx.interactiveEngine import interactiveEngine
|
3
4
|
from tradx.baseClass.baseAlgo import BaseAlgo
|
4
|
-
from tradx.baseClass.candleData import CandleData
|
5
|
-
from tradx.baseClass.orderEvent import OrderEvent
|
6
|
-
from tradx.baseClass.tradeEvent import TradeEvent
|
7
|
-
from tradx.baseClass.order import Order
|
8
|
-
from tradx.baseClass.position import Position
|
5
|
+
from tradx.baseClass.market.candleData import CandleData
|
6
|
+
from tradx.baseClass.interactive.orderEvent import OrderEvent
|
7
|
+
from tradx.baseClass.interactive.tradeEvent import TradeEvent
|
8
|
+
from tradx.baseClass.interactive.order import Order
|
9
|
+
from tradx.baseClass.interactive.position import Position
|
9
10
|
from tradx.logger.logger import setup_user_logger
|
11
|
+
|
12
|
+
# Importing other necessary modules
|
10
13
|
import asyncio
|
11
14
|
import os
|
12
|
-
from dotenv import load_dotenv
|
13
15
|
from apscheduler.schedulers.asyncio import AsyncIOScheduler
|
14
16
|
from datetime import datetime, timedelta
|
15
17
|
|
@@ -47,6 +49,7 @@ Dependencies:
|
|
47
49
|
To run the script, execute it as a standalone Python file.
|
48
50
|
"""
|
49
51
|
|
52
|
+
|
50
53
|
class Example1(BaseAlgo):
|
51
54
|
def __init__(
|
52
55
|
self, marketDataEngine: marketDataEngine, interactiveEngine: interactiveEngine
|
@@ -72,12 +75,14 @@ class Example1(BaseAlgo):
|
|
72
75
|
|
73
76
|
async def on_orderEvent(self, order: OrderEvent):
|
74
77
|
self.interactiveEngine.user_logger.info(
|
75
|
-
f"Received order event: {order}",
|
78
|
+
f"Received order event: {order}",
|
79
|
+
caller=f"{self.__class__.__name__}.on_orderEvent",
|
76
80
|
)
|
77
81
|
|
78
82
|
async def on_tradeEvent(self, trade: TradeEvent):
|
79
83
|
self.interactiveEngine.user_logger.info(
|
80
|
-
f"Received trade event: {trade}",
|
84
|
+
f"Received trade event: {trade}",
|
85
|
+
caller=f"{self.__class__.__name__}.on_tradeEvent",
|
81
86
|
)
|
82
87
|
|
83
88
|
async def subscribe(self): ...
|
@@ -109,12 +114,14 @@ class Example2(BaseAlgo):
|
|
109
114
|
|
110
115
|
async def on_orderEvent(self, order: OrderEvent):
|
111
116
|
self.interactiveEngine.user_logger.info(
|
112
|
-
f"Received order event: {order}",
|
117
|
+
f"Received order event: {order}",
|
118
|
+
caller=f"{self.__class__.__name__}.on_orderEvent",
|
113
119
|
)
|
114
120
|
|
115
121
|
async def on_tradeEvent(self, trade: TradeEvent):
|
116
122
|
self.interactiveEngine.user_logger.info(
|
117
|
-
f"Received trade event: {trade}",
|
123
|
+
f"Received trade event: {trade}",
|
124
|
+
caller=f"{self.__class__.__name__}.on_tradeEvent",
|
118
125
|
)
|
119
126
|
|
120
127
|
async def subscribe(self): ...
|
@@ -123,7 +130,6 @@ class Example2(BaseAlgo):
|
|
123
130
|
|
124
131
|
|
125
132
|
async def main():
|
126
|
-
load_dotenv()
|
127
133
|
log_file_path = os.path.join(os.path.dirname(__file__), "TEST.log")
|
128
134
|
if os.path.exists(log_file_path):
|
129
135
|
os.remove(log_file_path)
|
@@ -131,22 +137,23 @@ async def main():
|
|
131
137
|
scheduler = AsyncIOScheduler()
|
132
138
|
scheduler.start()
|
133
139
|
tradeObject = marketDataEngine(
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
140
|
+
"MARKETDATA_API_KEY",
|
141
|
+
"MARKETDATA_API_SECRET",
|
142
|
+
"SOURCE",
|
143
|
+
"ROOT",
|
138
144
|
user_logger,
|
139
145
|
)
|
140
146
|
|
141
147
|
interactiveObj = interactiveEngine(
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
148
|
+
"INTERACTIVE_API_KEY",
|
149
|
+
"INTERACTIVE_API_SECRET",
|
150
|
+
"SOURCE",
|
151
|
+
"ROOT",
|
146
152
|
user_logger,
|
147
153
|
)
|
148
154
|
|
149
155
|
await interactiveObj.initialize()
|
156
|
+
await tradeObject.loadMaster()
|
150
157
|
algo1 = Example1(tradeObject, interactiveObj)
|
151
158
|
algo2 = Example2(tradeObject, interactiveObj)
|
152
159
|
scheduler.add_job(
|
@@ -0,0 +1,170 @@
|
|
1
|
+
from typing import Dict, Set, Any
|
2
|
+
from tradx.baseClass.baseAlgo import BaseAlgo
|
3
|
+
from tradx.baseClass.market.candleData import CandleData
|
4
|
+
from tradx.baseClass.market.touchLineData import TouchLineData
|
5
|
+
import asyncio
|
6
|
+
|
7
|
+
|
8
|
+
class AlgoContainer:
|
9
|
+
"""
|
10
|
+
AlgoContainer is a container class that maps algorithms to their subscriptions and allows broadcasting messages.
|
11
|
+
Attributes:
|
12
|
+
subscriptions (Dict[int, Set[BaseAlgo]]): A dictionary mapping subscription keys to sets of algorithm instances.
|
13
|
+
Methods:
|
14
|
+
__init__():
|
15
|
+
Initializes the AlgoContainer with an empty subscription map.
|
16
|
+
subscribe(key: int, algo: BaseAlgo):
|
17
|
+
Subscribes an algorithm to a specific key.
|
18
|
+
key (int): The subscription key.
|
19
|
+
algo (BaseAlgo): The algorithm instance subscribing.
|
20
|
+
unsubscribe(key: int, algo: BaseAlgo):
|
21
|
+
Unsubscribes an algorithm from a specific key.
|
22
|
+
key (int): The subscription key.
|
23
|
+
algo (BaseAlgo): The algorithm instance unsubscribing.
|
24
|
+
broadcast(key: int, message: str, dataType: str):
|
25
|
+
Broadcasts a message to all algorithms subscribed to a given key.
|
26
|
+
key (int): The key to broadcast the message for.
|
27
|
+
dataType (str): The type of data being broadcasted (e.g., "bar").
|
28
|
+
"""
|
29
|
+
|
30
|
+
def __init__(self) -> None:
|
31
|
+
"""
|
32
|
+
Initializes the algoContainer instance.
|
33
|
+
|
34
|
+
Attributes:
|
35
|
+
subscriptions (Dict[int, Set[BaseAlgo]]):
|
36
|
+
A dictionary mapping an integer key (e.g., a topic or identifier)
|
37
|
+
to a set of algorithm instances (BaseAlgo).
|
38
|
+
"""
|
39
|
+
self.subscriptions: Dict[int, Set[BaseAlgo]] = {}
|
40
|
+
|
41
|
+
def subscribe(self, key, algo: BaseAlgo) -> None:
|
42
|
+
"""
|
43
|
+
Subscribes an algorithm to a given key.
|
44
|
+
Args:
|
45
|
+
key: The key to subscribe the algorithm to.
|
46
|
+
algo (BaseAlgo): The algorithm to be subscribed.
|
47
|
+
Raises:
|
48
|
+
None
|
49
|
+
Returns:
|
50
|
+
None
|
51
|
+
"""
|
52
|
+
|
53
|
+
if key not in self.subscriptions:
|
54
|
+
self.subscriptions[key] = set()
|
55
|
+
self.subscriptions[key].add(algo)
|
56
|
+
|
57
|
+
def unsubscribe(self, key, algo: BaseAlgo) -> None:
|
58
|
+
"""
|
59
|
+
Unsubscribe an algorithm from a given key.
|
60
|
+
This method removes the specified algorithm from the list of
|
61
|
+
subscriptions associated with the given key. If no more algorithms
|
62
|
+
are subscribed to the key after removal, the key is deleted from
|
63
|
+
the subscriptions.
|
64
|
+
Args:
|
65
|
+
key: The key from which the algorithm should be unsubscribed.
|
66
|
+
algo (BaseAlgo): The algorithm instance to be unsubscribed.
|
67
|
+
"""
|
68
|
+
|
69
|
+
if key in self.subscriptions and algo in self.subscriptions[key]:
|
70
|
+
self.subscriptions[key].remove(algo)
|
71
|
+
|
72
|
+
# Remove the key if no more algorithms are subscribed
|
73
|
+
if not self.subscriptions[key]:
|
74
|
+
del self.subscriptions[key]
|
75
|
+
|
76
|
+
async def broadcast(self, message: Any) -> None:
|
77
|
+
"""
|
78
|
+
Broadcast a message to all algorithms subscribed to a given key.
|
79
|
+
|
80
|
+
Args:
|
81
|
+
key (str): The key to broadcast the message for.
|
82
|
+
message (str): The message to broadcast.
|
83
|
+
"""
|
84
|
+
if message.ExchangeInstrumentID in self.subscriptions:
|
85
|
+
if isinstance(message, CandleData):
|
86
|
+
for algo in self.subscriptions[message.ExchangeInstrumentID]:
|
87
|
+
asyncio.ensure_future(algo.on_barData(message))
|
88
|
+
if isinstance(message, TouchLineData):
|
89
|
+
for algo in self.subscriptions[message.ExchangeInstrumentID]:
|
90
|
+
asyncio.ensure_future(algo.on_touchLineData(message))
|
91
|
+
|
92
|
+
|
93
|
+
class SubcribeContainer:
|
94
|
+
"""
|
95
|
+
AlgoContainer is a container class that maps algorithms to their subscriptions and allows broadcasting messages.
|
96
|
+
Attributes:
|
97
|
+
subscriptions (Dict[int, Set[BaseAlgo]]): A dictionary mapping subscription keys to sets of algorithm instances.
|
98
|
+
Methods:
|
99
|
+
__init__():
|
100
|
+
Initializes the AlgoContainer with an empty subscription map.
|
101
|
+
subscribe(key: int, algo: BaseAlgo):
|
102
|
+
Subscribes an algorithm to a specific key.
|
103
|
+
key (int): The subscription key.
|
104
|
+
algo (BaseAlgo): The algorithm instance subscribing.
|
105
|
+
unsubscribe(key: int, algo: BaseAlgo):
|
106
|
+
Unsubscribes an algorithm from a specific key.
|
107
|
+
key (int): The subscription key.
|
108
|
+
algo (BaseAlgo): The algorithm instance unsubscribing.
|
109
|
+
broadcast(key: int, message: str, dataType: str):
|
110
|
+
Broadcasts a message to all algorithms subscribed to a given key.
|
111
|
+
key (int): The key to broadcast the message for.
|
112
|
+
dataType (str): The type of data being broadcasted (e.g., "bar").
|
113
|
+
"""
|
114
|
+
|
115
|
+
def __init__(self) -> None:
|
116
|
+
"""
|
117
|
+
Initializes the algoContainer instance.
|
118
|
+
|
119
|
+
Attributes:
|
120
|
+
subscriptions (Dict[int, Set[BaseAlgo]]):
|
121
|
+
A dictionary mapping an integer key (e.g., a topic or identifier)
|
122
|
+
to a set of algorithm instances (BaseAlgo).
|
123
|
+
"""
|
124
|
+
self.subscriptions: Dict[int, Set[str]] = {}
|
125
|
+
|
126
|
+
def subscribe(self, exchangeInstrumentID, xtsMessageCode, uuid: str) -> None:
|
127
|
+
"""
|
128
|
+
Subscribes an algorithm to a given key.
|
129
|
+
Args:
|
130
|
+
key: The key to subscribe the algorithm to.
|
131
|
+
algo (BaseAlgo): The algorithm to be subscribed.
|
132
|
+
Raises:
|
133
|
+
None
|
134
|
+
Returns:
|
135
|
+
None
|
136
|
+
"""
|
137
|
+
key = (exchangeInstrumentID, xtsMessageCode)
|
138
|
+
if key not in self.subscriptions:
|
139
|
+
self.subscriptions[key] = set()
|
140
|
+
self.subscriptions[key].add(uuid)
|
141
|
+
|
142
|
+
def unsubscribe(self, exchangeInstrumentID, xtsMessageCode, uuid: str) -> None:
|
143
|
+
"""
|
144
|
+
Unsubscribe an algorithm from a given key.
|
145
|
+
This method removes the specified algorithm from the list of
|
146
|
+
subscriptions associated with the given key. If no more algorithms
|
147
|
+
are subscribed to the key after removal, the key is deleted from
|
148
|
+
the subscriptions.
|
149
|
+
Args:
|
150
|
+
key: The key from which the algorithm should be unsubscribed.
|
151
|
+
algo (BaseAlgo): The algorithm instance to be unsubscribed.
|
152
|
+
"""
|
153
|
+
key = (exchangeInstrumentID, xtsMessageCode)
|
154
|
+
if key in self.subscriptions and uuid in self.subscriptions[key]:
|
155
|
+
self.subscriptions[key].remove(uuid)
|
156
|
+
|
157
|
+
# Remove the key if no more algorithms are subscribed
|
158
|
+
if not self.subscriptions[key]:
|
159
|
+
del self.subscriptions[key]
|
160
|
+
|
161
|
+
def ifExists(self, exchangeInstrumentID, xtsMessageCode) -> bool:
|
162
|
+
"""
|
163
|
+
Check if a subscription exists for the given exchangeInstrumentID and xtsMessageCode.
|
164
|
+
Args:
|
165
|
+
exchangeInstrumentID: The exchange instrument ID to check.
|
166
|
+
xtsMessageCode: The XTS message code to check.
|
167
|
+
Returns:
|
168
|
+
bool: True if the subscription exists, False otherwise.
|
169
|
+
"""
|
170
|
+
return (exchangeInstrumentID, xtsMessageCode) in self.subscriptions
|
@@ -1,9 +1,9 @@
|
|
1
1
|
from abc import ABC, abstractmethod
|
2
2
|
import shortuuid
|
3
|
-
from typing import Any, TYPE_CHECKING, List, Dict
|
3
|
+
from typing import Any, TYPE_CHECKING, List, Dict, Set
|
4
4
|
from decimal import Decimal
|
5
|
-
from tradx.baseClass.order import Order
|
6
|
-
from tradx.baseClass.position import Position
|
5
|
+
from tradx.baseClass.interactive.order import Order
|
6
|
+
from tradx.baseClass.interactive.position import Position
|
7
7
|
|
8
8
|
import asyncio
|
9
9
|
|
@@ -11,10 +11,10 @@ import asyncio
|
|
11
11
|
if TYPE_CHECKING:
|
12
12
|
from tradx.marketDataEngine import marketDataEngine
|
13
13
|
from tradx.interactiveEngine import interactiveEngine
|
14
|
-
from tradx.baseClass.touchLineData import TouchLineData
|
15
|
-
from tradx.baseClass.orderEvent import OrderEvent
|
16
|
-
from tradx.baseClass.tradeEvent import TradeEvent
|
17
|
-
from tradx.baseClass.candleData import CandleData
|
14
|
+
from tradx.baseClass.market.touchLineData import TouchLineData
|
15
|
+
from tradx.baseClass.interactive.orderEvent import OrderEvent
|
16
|
+
from tradx.baseClass.interactive.tradeEvent import TradeEvent
|
17
|
+
from tradx.baseClass.market.candleData import CandleData
|
18
18
|
|
19
19
|
|
20
20
|
class BaseAlgo(ABC):
|
@@ -74,6 +74,7 @@ class BaseAlgo(ABC):
|
|
74
74
|
self.order_nos = shortuuid
|
75
75
|
self.position_diary: List[Position] = []
|
76
76
|
self.order_diary: List[Order] = []
|
77
|
+
self.uuids = set()
|
77
78
|
# Registering inside interactive engine
|
78
79
|
self.name = interactiveEngine.shortuuid.ShortUUID().random(length=4)
|
79
80
|
self.interactiveEngine.strategy_to_id[self.name] = self
|
@@ -127,7 +128,13 @@ class BaseAlgo(ABC):
|
|
127
128
|
Returns:
|
128
129
|
str: An 8-digit unique order identifier.
|
129
130
|
"""
|
130
|
-
|
131
|
+
# Generate a unique 4-character key not present in self.uuids
|
132
|
+
while True:
|
133
|
+
ids = self.order_nos.ShortUUID().random(length=4)
|
134
|
+
if ids not in self.uuids:
|
135
|
+
self.uuids.add(ids)
|
136
|
+
break
|
137
|
+
return f"{self.name}{ids}"
|
131
138
|
|
132
139
|
async def order_(self, order: "OrderEvent") -> None:
|
133
140
|
"""
|
@@ -152,6 +159,14 @@ class BaseAlgo(ABC):
|
|
152
159
|
# Update the status of the existing order
|
153
160
|
existing_order.OrderStatus = order.OrderStatus
|
154
161
|
existing_order.OrderPrice = order.OrderAverageTradedPriceAPI
|
162
|
+
if existing_order.AppOrderID != order.AppOrderID:
|
163
|
+
|
164
|
+
if self.interactiveEngine.user_logger:
|
165
|
+
self.interactiveEngine.user_logger.info(
|
166
|
+
f"Updated order {order.OrderUniqueIdentifier} App order id from {existing_order.AppOrderID} to {order.AppOrderID}",
|
167
|
+
caller=f"{self.__class__.__name__}.order_",
|
168
|
+
)
|
169
|
+
existing_order.AppOrderID = order.AppOrderID
|
155
170
|
if self.interactiveEngine.user_logger:
|
156
171
|
self.interactiveEngine.user_logger.info(
|
157
172
|
f"Updated order {order.OrderUniqueIdentifier} status to {order.OrderStatus}",
|
@@ -289,7 +304,7 @@ class BaseAlgo(ABC):
|
|
289
304
|
)
|
290
305
|
|
291
306
|
for order in self.order_diary:
|
292
|
-
if order.OrderStatus in ["PendingNew", "New"]:
|
307
|
+
if order.OrderStatus in ["PendingNew", "New", "Replaced", "PendingReplace"]:
|
293
308
|
asyncio.ensure_future(
|
294
309
|
self.interactiveEngine.cancel_order(
|
295
310
|
order.AppOrderID, order.OrderUniqueIdentifier
|
@@ -1,5 +1,6 @@
|
|
1
1
|
from pydantic import BaseModel
|
2
2
|
from decimal import Decimal
|
3
|
+
import json
|
3
4
|
|
4
5
|
|
5
6
|
class Order(BaseModel):
|
@@ -53,3 +54,8 @@ class Order(BaseModel):
|
|
53
54
|
OrderSide=OrderSide,
|
54
55
|
TimeInForce=TimeInForce,
|
55
56
|
)
|
57
|
+
|
58
|
+
@classmethod
|
59
|
+
def from_str(cls, message: str):
|
60
|
+
data = json.loads(message)
|
61
|
+
return cls(**data)
|
@@ -34,7 +34,9 @@ def parse_datetime(value) -> Any:
|
|
34
34
|
return datetime(1980, 1, 1) + timedelta(seconds=value)
|
35
35
|
return value
|
36
36
|
class OrderEvent(BaseModel):
|
37
|
-
|
37
|
+
"""
|
38
|
+
Order Event class representing an order event in the system.
|
39
|
+
"""
|
38
40
|
|
39
41
|
LoginID: str
|
40
42
|
ClientID: str = "*****"
|
@@ -1,4 +1,5 @@
|
|
1
1
|
from pydantic import BaseModel
|
2
|
+
import json
|
2
3
|
|
3
4
|
|
4
5
|
class Position(BaseModel):
|
@@ -20,8 +21,9 @@ class Position(BaseModel):
|
|
20
21
|
Constructs all the necessary attributes for the Position object.
|
21
22
|
"""
|
22
23
|
|
23
|
-
ExchangeSegment: str
|
24
24
|
ExchangeInstrumentID: int
|
25
|
+
ExchangeSegment: str
|
26
|
+
|
25
27
|
ProductType: str
|
26
28
|
Quantity: int
|
27
29
|
|
@@ -44,3 +46,8 @@ class Position(BaseModel):
|
|
44
46
|
ProductType=ProductType,
|
45
47
|
Quantity=Quantity,
|
46
48
|
)
|
49
|
+
|
50
|
+
@classmethod
|
51
|
+
def from_str(cls, message: str):
|
52
|
+
data = json.loads(message)
|
53
|
+
return cls(**data)
|