PyAlgoEngine 0.5.4.post10__tar.gz → 0.7.4__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.
- {pyalgoengine-0.5.4.post10 → pyalgoengine-0.7.4}/PKG-INFO +1 -1
- {pyalgoengine-0.5.4.post10 → pyalgoengine-0.7.4}/PyAlgoEngine.egg-info/PKG-INFO +1 -1
- {pyalgoengine-0.5.4.post10 → pyalgoengine-0.7.4}/PyAlgoEngine.egg-info/SOURCES.txt +3 -0
- {pyalgoengine-0.5.4.post10 → pyalgoengine-0.7.4}/algo_engine/__init__.py +1 -1
- {pyalgoengine-0.5.4.post10 → pyalgoengine-0.7.4}/algo_engine/apps/backtest/doc_server.py +24 -20
- {pyalgoengine-0.5.4.post10 → pyalgoengine-0.7.4}/algo_engine/apps/bokeh_server.py +57 -14
- {pyalgoengine-0.5.4.post10 → pyalgoengine-0.7.4}/algo_engine/backtest/replay.py +5 -2
- pyalgoengine-0.7.4/algo_engine/base/__init__.py +40 -0
- pyalgoengine-0.7.4/algo_engine/base/market_buffer.py +571 -0
- pyalgoengine-0.7.4/algo_engine/base/market_utils.py +3092 -0
- pyalgoengine-0.7.4/algo_engine/base/market_utils_nt.py +188 -0
- pyalgoengine-0.7.4/algo_engine/base/market_utils_posix.py +3004 -0
- {pyalgoengine-0.5.4.post10 → pyalgoengine-0.7.4}/algo_engine/engine/algo_engine.py +1 -1
- {pyalgoengine-0.5.4.post10 → pyalgoengine-0.7.4}/algo_engine/engine/trade_engine.py +1 -1
- {pyalgoengine-0.5.4.post10 → pyalgoengine-0.7.4}/algo_engine/utils/data_utils.py +2 -2
- {pyalgoengine-0.5.4.post10 → pyalgoengine-0.7.4}/setup.py +15 -2
- pyalgoengine-0.5.4.post10/algo_engine/base/__init__.py +0 -28
- pyalgoengine-0.5.4.post10/algo_engine/base/market_utils.py +0 -1686
- {pyalgoengine-0.5.4.post10 → pyalgoengine-0.7.4}/LICENSE +0 -0
- {pyalgoengine-0.5.4.post10 → pyalgoengine-0.7.4}/PyAlgoEngine.egg-info/dependency_links.txt +0 -0
- {pyalgoengine-0.5.4.post10 → pyalgoengine-0.7.4}/PyAlgoEngine.egg-info/requires.txt +0 -0
- {pyalgoengine-0.5.4.post10 → pyalgoengine-0.7.4}/PyAlgoEngine.egg-info/top_level.txt +0 -0
- {pyalgoengine-0.5.4.post10 → pyalgoengine-0.7.4}/README.md +0 -0
- {pyalgoengine-0.5.4.post10 → pyalgoengine-0.7.4}/algo_engine/apps/__init__.py +0 -0
- {pyalgoengine-0.5.4.post10 → pyalgoengine-0.7.4}/algo_engine/apps/backtest/__init__.py +0 -0
- {pyalgoengine-0.5.4.post10 → pyalgoengine-0.7.4}/algo_engine/apps/backtest/tester.py +0 -0
- {pyalgoengine-0.5.4.post10 → pyalgoengine-0.7.4}/algo_engine/apps/backtest/web_app.py +0 -0
- {pyalgoengine-0.5.4.post10 → pyalgoengine-0.7.4}/algo_engine/apps/demo/__init__.py +0 -0
- {pyalgoengine-0.5.4.post10 → pyalgoengine-0.7.4}/algo_engine/apps/demo/test.py +0 -0
- {pyalgoengine-0.5.4.post10 → pyalgoengine-0.7.4}/algo_engine/backtest/__init__.py +0 -0
- {pyalgoengine-0.5.4.post10 → pyalgoengine-0.7.4}/algo_engine/backtest/__main__.py +0 -0
- {pyalgoengine-0.5.4.post10 → pyalgoengine-0.7.4}/algo_engine/backtest/metrics.py +0 -0
- {pyalgoengine-0.5.4.post10 → pyalgoengine-0.7.4}/algo_engine/backtest/sim_match.py +0 -0
- {pyalgoengine-0.5.4.post10 → pyalgoengine-0.7.4}/algo_engine/base/console_utils.py +0 -0
- {pyalgoengine-0.5.4.post10 → pyalgoengine-0.7.4}/algo_engine/base/finance_decimal.py +0 -0
- {pyalgoengine-0.5.4.post10 → pyalgoengine-0.7.4}/algo_engine/base/technical_analysis.py +0 -0
- {pyalgoengine-0.5.4.post10 → pyalgoengine-0.7.4}/algo_engine/base/telemetrics.py +0 -0
- {pyalgoengine-0.5.4.post10 → pyalgoengine-0.7.4}/algo_engine/base/trade_utils.py +0 -0
- {pyalgoengine-0.5.4.post10 → pyalgoengine-0.7.4}/algo_engine/engine/__init__.py +0 -0
- {pyalgoengine-0.5.4.post10 → pyalgoengine-0.7.4}/algo_engine/engine/event_engine.py +0 -0
- {pyalgoengine-0.5.4.post10 → pyalgoengine-0.7.4}/algo_engine/engine/market_engine.py +0 -0
- {pyalgoengine-0.5.4.post10 → pyalgoengine-0.7.4}/algo_engine/monitor/__init__.py +0 -0
- {pyalgoengine-0.5.4.post10 → pyalgoengine-0.7.4}/algo_engine/monitor/advanced_data_interface.py +0 -0
- {pyalgoengine-0.5.4.post10 → pyalgoengine-0.7.4}/algo_engine/profile/__init__.py +0 -0
- {pyalgoengine-0.5.4.post10 → pyalgoengine-0.7.4}/algo_engine/profile/cn.py +0 -0
- {pyalgoengine-0.5.4.post10 → pyalgoengine-0.7.4}/algo_engine/strategy/__init__.py +0 -0
- {pyalgoengine-0.5.4.post10 → pyalgoengine-0.7.4}/algo_engine/strategy/strategy_engine.py +0 -0
- {pyalgoengine-0.5.4.post10 → pyalgoengine-0.7.4}/algo_engine/utils/__init__.py +0 -0
- {pyalgoengine-0.5.4.post10 → pyalgoengine-0.7.4}/algo_engine/utils/commit_regularizer.py +0 -0
- {pyalgoengine-0.5.4.post10 → pyalgoengine-0.7.4}/setup.cfg +0 -0
|
@@ -23,7 +23,10 @@ algo_engine/backtest/sim_match.py
|
|
|
23
23
|
algo_engine/base/__init__.py
|
|
24
24
|
algo_engine/base/console_utils.py
|
|
25
25
|
algo_engine/base/finance_decimal.py
|
|
26
|
+
algo_engine/base/market_buffer.py
|
|
26
27
|
algo_engine/base/market_utils.py
|
|
28
|
+
algo_engine/base/market_utils_nt.py
|
|
29
|
+
algo_engine/base/market_utils_posix.py
|
|
27
30
|
algo_engine/base/technical_analysis.py
|
|
28
31
|
algo_engine/base/telemetrics.py
|
|
29
32
|
algo_engine/base/trade_utils.py
|
|
@@ -71,18 +71,18 @@ class CandleStick(DocServer):
|
|
|
71
71
|
self.theme = StickTheme(profile=self.profile) if self.theme is None else self.theme
|
|
72
72
|
self.timestamp: float = 0.
|
|
73
73
|
self.active_bar_data: CandleStick.ActiveBarData | None = None
|
|
74
|
-
self.
|
|
75
|
-
index
|
|
76
|
-
market_time
|
|
77
|
-
open_price
|
|
78
|
-
high_price
|
|
79
|
-
low_price
|
|
80
|
-
close_price
|
|
81
|
-
volume
|
|
82
|
-
_max_price
|
|
83
|
-
_min_price
|
|
84
|
-
stick_color
|
|
85
|
-
|
|
74
|
+
self._data = {
|
|
75
|
+
'index': [],
|
|
76
|
+
'market_time': [],
|
|
77
|
+
'open_price': [],
|
|
78
|
+
'cs.high_price': [],
|
|
79
|
+
'cs.low_price': [],
|
|
80
|
+
'close_price': [],
|
|
81
|
+
'volume': [],
|
|
82
|
+
'_max_price': [],
|
|
83
|
+
'_min_price': [],
|
|
84
|
+
'stick_color': []
|
|
85
|
+
}
|
|
86
86
|
|
|
87
87
|
def ts_indices(self) -> list[float]:
|
|
88
88
|
"""generate integer indices
|
|
@@ -187,7 +187,7 @@ class CandleStick(DocServer):
|
|
|
187
187
|
|
|
188
188
|
for doc_id in list(self.bokeh_documents):
|
|
189
189
|
doc = self.bokeh_documents[doc_id]
|
|
190
|
-
new_data = self.
|
|
190
|
+
new_data = self.bokeh_data_pipe[doc_id]
|
|
191
191
|
|
|
192
192
|
self.pipe(sequence=new_data)
|
|
193
193
|
|
|
@@ -209,8 +209,8 @@ class CandleStick(DocServer):
|
|
|
209
209
|
sequence['market_time'].append(datetime.datetime.fromtimestamp(self.active_bar_data['ts_start'], tz=self.profile.time_zone))
|
|
210
210
|
sequence['open_price'].append(self.active_bar_data['open_price'])
|
|
211
211
|
sequence['close_price'].append(self.active_bar_data['close_price'])
|
|
212
|
-
sequence['high_price'].append(self.active_bar_data['high_price'])
|
|
213
|
-
sequence['low_price'].append(self.active_bar_data['low_price'])
|
|
212
|
+
sequence['cs.high_price'].append(self.active_bar_data['high_price'])
|
|
213
|
+
sequence['cs.low_price'].append(self.active_bar_data['low_price'])
|
|
214
214
|
sequence['volume'].append(self.active_bar_data['volume'])
|
|
215
215
|
sequence['_max_price'].append(max(self.active_bar_data['open_price'], self.active_bar_data['close_price']))
|
|
216
216
|
sequence['_min_price'].append(min(self.active_bar_data['open_price'], self.active_bar_data['close_price']))
|
|
@@ -224,7 +224,7 @@ class CandleStick(DocServer):
|
|
|
224
224
|
from bokeh.plotting import figure, gridplot
|
|
225
225
|
|
|
226
226
|
doc = self.bokeh_documents[doc_id]
|
|
227
|
-
source = self.
|
|
227
|
+
source = self.bokeh_data_source[doc_id]
|
|
228
228
|
|
|
229
229
|
tools = [
|
|
230
230
|
PanTool(dimensions="width", syncable=False),
|
|
@@ -242,8 +242,8 @@ class CandleStick(DocServer):
|
|
|
242
242
|
("market_time", "@market_time{%H:%M:%S}"),
|
|
243
243
|
("close_price", "@close_price"),
|
|
244
244
|
("open_price", "@open_price"),
|
|
245
|
-
("high_price", "@high_price"),
|
|
246
|
-
("low_price", "@low_price"),
|
|
245
|
+
("high_price", "@{cs.high_price}"),
|
|
246
|
+
("low_price", "@{cs.low_price}"),
|
|
247
247
|
]
|
|
248
248
|
|
|
249
249
|
plot = figure(
|
|
@@ -261,8 +261,8 @@ class CandleStick(DocServer):
|
|
|
261
261
|
name='candlestick.shade',
|
|
262
262
|
x0='index',
|
|
263
263
|
x1='index',
|
|
264
|
-
y0='low_price',
|
|
265
|
-
y1='high_price',
|
|
264
|
+
y0='cs.low_price',
|
|
265
|
+
y1='cs.high_price',
|
|
266
266
|
line_width=1,
|
|
267
267
|
color="black",
|
|
268
268
|
alpha=0.8,
|
|
@@ -325,3 +325,7 @@ class CandleStick(DocServer):
|
|
|
325
325
|
df = pd.DataFrame(self.data).set_index(keys='market_time')
|
|
326
326
|
df = df[['open_price', 'high_price', 'low_price', 'close_price', 'volume']]
|
|
327
327
|
df.to_csv(filename)
|
|
328
|
+
|
|
329
|
+
@property
|
|
330
|
+
def data(self) -> dict[str, list]:
|
|
331
|
+
return self._data
|
|
@@ -24,9 +24,10 @@ class DocServer(object, metaclass=abc.ABCMeta):
|
|
|
24
24
|
self.lock = Lock() if lock is None else lock
|
|
25
25
|
|
|
26
26
|
self.bokeh_documents: dict[int, Document] = {}
|
|
27
|
-
self.bokeh_source: dict[int, ColumnDataSource] = {}
|
|
28
|
-
self.
|
|
29
|
-
self.
|
|
27
|
+
# self.bokeh_source: dict[int, ColumnDataSource] = {}
|
|
28
|
+
self.bokeh_data_pipe: dict[int, dict[str, list[...]]] = {}
|
|
29
|
+
self.bokeh_data_patch: dict[int, dict[str, list[tuple[int, ...]]]] = {}
|
|
30
|
+
self.bokeh_data_source: dict[int, ColumnDataSource] = {}
|
|
30
31
|
|
|
31
32
|
def __str__(self):
|
|
32
33
|
return f'<{self.__class__.__name__}>(id={id(self.__class__)})'
|
|
@@ -63,15 +64,31 @@ class DocServer(object, metaclass=abc.ABCMeta):
|
|
|
63
64
|
self.stream(doc_id=doc_id)
|
|
64
65
|
return
|
|
65
66
|
|
|
66
|
-
doc = self.bokeh_documents[doc_id]
|
|
67
|
-
|
|
68
|
-
source = self.
|
|
67
|
+
# doc = self.bokeh_documents[doc_id]
|
|
68
|
+
data_pipe = self.bokeh_data_pipe[doc_id]
|
|
69
|
+
source = self.bokeh_data_source[doc_id]
|
|
69
70
|
|
|
70
|
-
source.stream(new_data=deepcopy(
|
|
71
|
-
for key, seq in
|
|
71
|
+
source.stream(new_data=deepcopy(data_pipe), rollover=self.max_size)
|
|
72
|
+
for key, seq in data_pipe.items():
|
|
72
73
|
seq.clear()
|
|
73
74
|
|
|
74
|
-
LOGGER.debug(f'{self.__class__} stream updated!')
|
|
75
|
+
LOGGER.debug(f'{self.__class__} <stream> updated!')
|
|
76
|
+
|
|
77
|
+
def patch(self, doc_id: int = None):
|
|
78
|
+
if doc_id is None:
|
|
79
|
+
for doc_id in list(self.bokeh_documents):
|
|
80
|
+
self.patch(doc_id=doc_id)
|
|
81
|
+
return
|
|
82
|
+
|
|
83
|
+
# doc = self.bokeh_documents[doc_id]
|
|
84
|
+
data_patch = self.bokeh_data_patch[doc_id]
|
|
85
|
+
source = self.bokeh_data_source[doc_id]
|
|
86
|
+
|
|
87
|
+
source.patch(patches=deepcopy(data_patch))
|
|
88
|
+
for key, seq in data_patch.items():
|
|
89
|
+
seq.clear()
|
|
90
|
+
|
|
91
|
+
LOGGER.debug(f'{self.__class__} <patch> updated!')
|
|
75
92
|
|
|
76
93
|
def register_document(self, doc):
|
|
77
94
|
from bokeh.models import ColumnDataSource
|
|
@@ -80,14 +97,17 @@ class DocServer(object, metaclass=abc.ABCMeta):
|
|
|
80
97
|
|
|
81
98
|
doc_id = uuid.uuid4().int
|
|
82
99
|
|
|
100
|
+
data = deepcopy(self.data)
|
|
83
101
|
self.bokeh_documents[doc_id] = doc
|
|
84
|
-
self.
|
|
85
|
-
self.
|
|
102
|
+
self.bokeh_data_pipe[doc_id] = {key: [] for key in data}
|
|
103
|
+
self.bokeh_data_patch[doc_id] = {key: [] for key in data}
|
|
104
|
+
self.bokeh_data_source[doc_id] = ColumnDataSource(data=data)
|
|
86
105
|
|
|
87
106
|
self.layout(doc_id=doc_id)
|
|
88
107
|
|
|
89
108
|
if self.update_interval:
|
|
90
109
|
doc.add_periodic_callback(callback=partial(self.stream, doc_id=doc_id), period_milliseconds=int(self.update_interval * 1000))
|
|
110
|
+
doc.add_periodic_callback(callback=partial(self.patch, doc_id=doc_id), period_milliseconds=int(self.update_interval * 1000))
|
|
91
111
|
|
|
92
112
|
doc.on_session_destroyed(partial(self._unregister_document, doc_id=doc_id))
|
|
93
113
|
|
|
@@ -99,10 +119,19 @@ class DocServer(object, metaclass=abc.ABCMeta):
|
|
|
99
119
|
LOGGER.info(f'Session {doc_id} disconnected!')
|
|
100
120
|
|
|
101
121
|
self.bokeh_documents.pop(doc_id)
|
|
102
|
-
self.
|
|
103
|
-
self.
|
|
122
|
+
self.bokeh_data_pipe.pop(doc_id)
|
|
123
|
+
self.bokeh_data_patch.pop(doc_id)
|
|
124
|
+
self.bokeh_data_source.pop(doc_id)
|
|
104
125
|
self.lock.release()
|
|
105
126
|
|
|
127
|
+
@property
|
|
128
|
+
@abc.abstractmethod
|
|
129
|
+
def data(self) -> dict[str, list]:
|
|
130
|
+
"""
|
|
131
|
+
the data used to provide initial values for new bokeh.ColumnDataSource.
|
|
132
|
+
"""
|
|
133
|
+
...
|
|
134
|
+
|
|
106
135
|
|
|
107
136
|
class DocManager(object):
|
|
108
137
|
def __init__(self, host: str = 'localhost', port: int = 21543, **kwargs):
|
|
@@ -136,13 +165,27 @@ class DocManager(object):
|
|
|
136
165
|
|
|
137
166
|
def serve_bokeh(self):
|
|
138
167
|
from bokeh.server.server import Server
|
|
168
|
+
import psutil
|
|
169
|
+
import socket
|
|
170
|
+
|
|
171
|
+
# Get all network interfaces and their IP addresses
|
|
172
|
+
addrs = psutil.net_if_addrs()
|
|
173
|
+
websocket_origin = [
|
|
174
|
+
f"{self.host}:{self.port}"
|
|
175
|
+
]
|
|
176
|
+
|
|
177
|
+
for interface, addr_info in addrs.items():
|
|
178
|
+
for addr in addr_info:
|
|
179
|
+
if addr.family == socket.AF_INET: # Filter only IPv4 addresses
|
|
180
|
+
LOGGER.info(f"Binding network interface: {interface}, IP Address: {addr.address}")
|
|
181
|
+
websocket_origin.append(f"{addr.address}:{self.port}")
|
|
139
182
|
|
|
140
183
|
server = Server(
|
|
141
184
|
applications=self.doc_server,
|
|
142
185
|
address=self.bokeh_host,
|
|
143
186
|
port=self.bokeh_port,
|
|
144
187
|
check_unused_sessions_milliseconds=(self.bokeh_check_unused_sessions * 1000),
|
|
145
|
-
allow_websocket_origin=[f"{self.bokeh_host}:{self.bokeh_port}"
|
|
188
|
+
allow_websocket_origin=[f"{self.bokeh_host}:{self.bokeh_port}"] + websocket_origin,
|
|
146
189
|
# num_procs=1
|
|
147
190
|
)
|
|
148
191
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import abc
|
|
2
2
|
import datetime
|
|
3
3
|
import inspect
|
|
4
|
+
import operator
|
|
4
5
|
from typing import Iterable
|
|
5
6
|
|
|
6
7
|
from . import LOGGER
|
|
@@ -196,17 +197,17 @@ class ProgressiveReplay(Replay):
|
|
|
196
197
|
ticker, dtype = self.replay_subscription[topic]
|
|
197
198
|
LOGGER.info(f'{self} loading {market_date} {ticker} {dtype}')
|
|
198
199
|
data = self.loader(market_date=market_date, ticker=ticker, dtype=dtype)
|
|
199
|
-
|
|
200
200
|
if isinstance(data, dict):
|
|
201
201
|
self.replay_task.extend(list(data.values()))
|
|
202
202
|
elif isinstance(data, (list, tuple)):
|
|
203
203
|
self.replay_task.extend(data)
|
|
204
204
|
|
|
205
|
+
LOGGER.info(f'{market_date} data loaded! {len(self.replay_task):,} entries.')
|
|
205
206
|
self.date_progress += 1
|
|
206
207
|
else:
|
|
207
208
|
raise StopIteration()
|
|
208
209
|
|
|
209
|
-
self.replay_task.sort(key=
|
|
210
|
+
self.replay_task.sort(key=operator.attrgetter('timestamp', 'ticker', '__class__.__name__'))
|
|
210
211
|
|
|
211
212
|
def next_task(self):
|
|
212
213
|
if self.task_progress < len(self.replay_task):
|
|
@@ -224,6 +225,8 @@ class ProgressiveReplay(Replay):
|
|
|
224
225
|
|
|
225
226
|
self.next_trade_day()
|
|
226
227
|
|
|
228
|
+
# the bod process should be moved here!
|
|
229
|
+
|
|
227
230
|
data = self.next_task()
|
|
228
231
|
|
|
229
232
|
if self.replay_task and self.replay_calendar:
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
import os
|
|
3
|
+
|
|
4
|
+
from .telemetrics import LOGGER
|
|
5
|
+
from ..profile import PROFILE
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def set_logger(logger: logging.Logger):
|
|
9
|
+
global LOGGER
|
|
10
|
+
LOGGER = logger
|
|
11
|
+
|
|
12
|
+
market_utils.LOGGER = logger.getChild('MarketUtils')
|
|
13
|
+
trade_utils.LOGGER = logger.getChild('TradeUtils')
|
|
14
|
+
technical_analysis.LOGGER = logger.getChild('TA')
|
|
15
|
+
console_utils.LOGGER = logger.getChild('Console')
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
from .finance_decimal import FinancialDecimal
|
|
19
|
+
|
|
20
|
+
if os.name == 'nt':
|
|
21
|
+
from .market_utils_nt import TransactionSide, OrderType, MarketData, OrderBook, BarData, DailyBar, CandleStick, TickData, TransactionData, TradeData, OrderData, MarketDataBuffer, MarketDataRingBuffer
|
|
22
|
+
else:
|
|
23
|
+
from .market_utils_posix import TransactionSide, OrderType, MarketData, OrderBook, BarData, DailyBar, CandleStick, TickData, TransactionData, TradeData, OrderData, MarketDataBuffer, MarketDataRingBuffer
|
|
24
|
+
|
|
25
|
+
# from .market_utils_posix import OrderType
|
|
26
|
+
# from .market_utils import TransactionSide, MarketData, OrderBook, BarData, DailyBar, CandleStick, TickData, TransactionData, TradeData
|
|
27
|
+
# from .market_buffer import MarketDataPointer, MarketDataMemoryBuffer, OrderBookPointer, OrderBookBuffer, BarDataPointer, BarDataBuffer, TickDataPointer, TickDataBuffer, TransactionDataPointer, TransactionDataBuffer
|
|
28
|
+
|
|
29
|
+
from .technical_analysis import TechnicalAnalysis
|
|
30
|
+
from .trade_utils import OrderState, TradeInstruction, TradeReport
|
|
31
|
+
from .console_utils import Progress, GetInput, GetArgs, count_ordinal, TerminalStyle, InteractiveShell, ShellTransfer
|
|
32
|
+
|
|
33
|
+
__all__ = ['PROFILE',
|
|
34
|
+
'FinancialDecimal',
|
|
35
|
+
'TransactionSide', 'OrderType', 'MarketData', 'OrderBook', 'BarData', 'DailyBar', 'CandleStick', 'TickData', 'TransactionData', 'TradeData', 'OrderData', 'MarketDataBuffer', 'MarketDataRingBuffer',
|
|
36
|
+
# 'MarketDataMemoryBuffer', 'OrderBookBuffer', 'BarDataBuffer', 'TickDataBuffer', 'TransactionDataBuffer',
|
|
37
|
+
# 'MarketDataPointer', 'OrderBookPointer', 'BarDataPointer', 'TickDataPointer', 'TransactionDataPointer',
|
|
38
|
+
'TechnicalAnalysis',
|
|
39
|
+
'OrderState', 'TradeInstruction', 'TradeReport',
|
|
40
|
+
'Progress', 'GetInput', 'GetArgs', 'count_ordinal', 'TerminalStyle', 'InteractiveShell', 'ShellTransfer']
|