PyAlgoEngine 0.7.7a3__tar.gz → 0.7.7a5__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.7.7a3 → pyalgoengine-0.7.7a5}/PKG-INFO +1 -1
- {pyalgoengine-0.7.7a3 → pyalgoengine-0.7.7a5}/PyAlgoEngine.egg-info/PKG-INFO +1 -1
- {pyalgoengine-0.7.7a3 → pyalgoengine-0.7.7a5}/algo_engine/__init__.py +1 -1
- {pyalgoengine-0.7.7a3 → pyalgoengine-0.7.7a5}/algo_engine/apps/sim_input/client.py +25 -7
- {pyalgoengine-0.7.7a3 → pyalgoengine-0.7.7a5}/algo_engine/backtest/replay.py +17 -4
- {pyalgoengine-0.7.7a3 → pyalgoengine-0.7.7a5}/LICENSE +0 -0
- {pyalgoengine-0.7.7a3 → pyalgoengine-0.7.7a5}/PyAlgoEngine.egg-info/SOURCES.txt +0 -0
- {pyalgoengine-0.7.7a3 → pyalgoengine-0.7.7a5}/PyAlgoEngine.egg-info/dependency_links.txt +0 -0
- {pyalgoengine-0.7.7a3 → pyalgoengine-0.7.7a5}/PyAlgoEngine.egg-info/requires.txt +0 -0
- {pyalgoengine-0.7.7a3 → pyalgoengine-0.7.7a5}/PyAlgoEngine.egg-info/top_level.txt +0 -0
- {pyalgoengine-0.7.7a3 → pyalgoengine-0.7.7a5}/README.md +0 -0
- {pyalgoengine-0.7.7a3 → pyalgoengine-0.7.7a5}/algo_engine/apps/__init__.py +0 -0
- {pyalgoengine-0.7.7a3 → pyalgoengine-0.7.7a5}/algo_engine/apps/backtest/__init__.py +0 -0
- {pyalgoengine-0.7.7a3 → pyalgoengine-0.7.7a5}/algo_engine/apps/backtest/doc_server.py +0 -0
- {pyalgoengine-0.7.7a3 → pyalgoengine-0.7.7a5}/algo_engine/apps/backtest/tester.py +0 -0
- {pyalgoengine-0.7.7a3 → pyalgoengine-0.7.7a5}/algo_engine/apps/backtest/web_app.py +0 -0
- {pyalgoengine-0.7.7a3 → pyalgoengine-0.7.7a5}/algo_engine/apps/bokeh_server.py +0 -0
- {pyalgoengine-0.7.7a3 → pyalgoengine-0.7.7a5}/algo_engine/apps/demo/__init__.py +0 -0
- {pyalgoengine-0.7.7a3 → pyalgoengine-0.7.7a5}/algo_engine/apps/demo/test.py +0 -0
- {pyalgoengine-0.7.7a3 → pyalgoengine-0.7.7a5}/algo_engine/apps/sim_input/__init__.py +0 -0
- {pyalgoengine-0.7.7a3 → pyalgoengine-0.7.7a5}/algo_engine/apps/sim_input/sim_keyboard.py +0 -0
- {pyalgoengine-0.7.7a3 → pyalgoengine-0.7.7a5}/algo_engine/apps/sim_input/sim_mouse.py +0 -0
- {pyalgoengine-0.7.7a3 → pyalgoengine-0.7.7a5}/algo_engine/apps/sim_input/window.py +0 -0
- {pyalgoengine-0.7.7a3 → pyalgoengine-0.7.7a5}/algo_engine/backtest/__init__.py +0 -0
- {pyalgoengine-0.7.7a3 → pyalgoengine-0.7.7a5}/algo_engine/backtest/__main__.py +0 -0
- {pyalgoengine-0.7.7a3 → pyalgoengine-0.7.7a5}/algo_engine/backtest/metrics.py +0 -0
- {pyalgoengine-0.7.7a3 → pyalgoengine-0.7.7a5}/algo_engine/backtest/sim_match.py +0 -0
- {pyalgoengine-0.7.7a3 → pyalgoengine-0.7.7a5}/algo_engine/base/__init__.py +0 -0
- {pyalgoengine-0.7.7a3 → pyalgoengine-0.7.7a5}/algo_engine/base/console_utils.py +0 -0
- {pyalgoengine-0.7.7a3 → pyalgoengine-0.7.7a5}/algo_engine/base/finance_decimal.py +0 -0
- {pyalgoengine-0.7.7a3 → pyalgoengine-0.7.7a5}/algo_engine/base/market_buffer.py +0 -0
- {pyalgoengine-0.7.7a3 → pyalgoengine-0.7.7a5}/algo_engine/base/market_utils.py +0 -0
- {pyalgoengine-0.7.7a3 → pyalgoengine-0.7.7a5}/algo_engine/base/market_utils_nt.py +0 -0
- {pyalgoengine-0.7.7a3 → pyalgoengine-0.7.7a5}/algo_engine/base/market_utils_posix.py +0 -0
- {pyalgoengine-0.7.7a3 → pyalgoengine-0.7.7a5}/algo_engine/base/technical_analysis.py +0 -0
- {pyalgoengine-0.7.7a3 → pyalgoengine-0.7.7a5}/algo_engine/base/telemetrics.py +0 -0
- {pyalgoengine-0.7.7a3 → pyalgoengine-0.7.7a5}/algo_engine/base/trade_utils.py +0 -0
- {pyalgoengine-0.7.7a3 → pyalgoengine-0.7.7a5}/algo_engine/engine/__init__.py +0 -0
- {pyalgoengine-0.7.7a3 → pyalgoengine-0.7.7a5}/algo_engine/engine/algo_engine.py +0 -0
- {pyalgoengine-0.7.7a3 → pyalgoengine-0.7.7a5}/algo_engine/engine/event_engine.py +0 -0
- {pyalgoengine-0.7.7a3 → pyalgoengine-0.7.7a5}/algo_engine/engine/market_engine.py +0 -0
- {pyalgoengine-0.7.7a3 → pyalgoengine-0.7.7a5}/algo_engine/engine/trade_engine.py +0 -0
- {pyalgoengine-0.7.7a3 → pyalgoengine-0.7.7a5}/algo_engine/monitor/__init__.py +0 -0
- {pyalgoengine-0.7.7a3 → pyalgoengine-0.7.7a5}/algo_engine/monitor/advanced_data_interface.py +0 -0
- {pyalgoengine-0.7.7a3 → pyalgoengine-0.7.7a5}/algo_engine/profile/__init__.py +0 -0
- {pyalgoengine-0.7.7a3 → pyalgoengine-0.7.7a5}/algo_engine/profile/cn.py +0 -0
- {pyalgoengine-0.7.7a3 → pyalgoengine-0.7.7a5}/algo_engine/strategy/__init__.py +0 -0
- {pyalgoengine-0.7.7a3 → pyalgoengine-0.7.7a5}/algo_engine/strategy/strategy_engine.py +0 -0
- {pyalgoengine-0.7.7a3 → pyalgoengine-0.7.7a5}/algo_engine/utils/__init__.py +0 -0
- {pyalgoengine-0.7.7a3 → pyalgoengine-0.7.7a5}/algo_engine/utils/commit_regularizer.py +0 -0
- {pyalgoengine-0.7.7a3 → pyalgoengine-0.7.7a5}/algo_engine/utils/data_utils.py +0 -0
- {pyalgoengine-0.7.7a3 → pyalgoengine-0.7.7a5}/setup.cfg +0 -0
- {pyalgoengine-0.7.7a3 → pyalgoengine-0.7.7a5}/setup.py +0 -0
|
@@ -25,7 +25,7 @@ class Action(object):
|
|
|
25
25
|
self.name = name
|
|
26
26
|
self.steps: list[Action.Step] = []
|
|
27
27
|
|
|
28
|
-
def append(self, name: str, action: Callable
|
|
28
|
+
def append(self, name: str, action: Callable, args=None, kwargs=None, comments: str = None) -> None:
|
|
29
29
|
step = Action.Step(name=name, procedure=action)
|
|
30
30
|
|
|
31
31
|
if args is not None:
|
|
@@ -172,6 +172,9 @@ class AutoWorkClient(object, metaclass=abc.ABCMeta):
|
|
|
172
172
|
# Simulate delay between steps
|
|
173
173
|
|
|
174
174
|
# Wait 3 seconds, then close the test ground and restore the client window
|
|
175
|
+
input_history.insert("end", "-" * 50)
|
|
176
|
+
input_history.insert("active", f"Mocking {action.name} Completed! Exiting in {timeout} seconds...")
|
|
177
|
+
|
|
175
178
|
time.sleep(timeout)
|
|
176
179
|
testground.destroy()
|
|
177
180
|
self.root.deiconify()
|
|
@@ -179,13 +182,27 @@ class AutoWorkClient(object, metaclass=abc.ABCMeta):
|
|
|
179
182
|
def toggle_auto_work(self):
|
|
180
183
|
"""Toggle the daemon thread to start or stop auto work."""
|
|
181
184
|
if not self.running:
|
|
182
|
-
self.
|
|
183
|
-
self.layout['button_takeover'].config(text="Release Control")
|
|
184
|
-
self.worker_thread = Thread(target=self.auto_work, daemon=True)
|
|
185
|
-
self.worker_thread.start()
|
|
185
|
+
self.takeover_control()
|
|
186
186
|
else:
|
|
187
|
-
self.
|
|
188
|
-
|
|
187
|
+
self.release_control()
|
|
188
|
+
|
|
189
|
+
def takeover_control(self):
|
|
190
|
+
if self.running:
|
|
191
|
+
LOGGER.info('Autoworker already running!')
|
|
192
|
+
return
|
|
193
|
+
|
|
194
|
+
self.running = True
|
|
195
|
+
self.layout['button_takeover'].config(text="Release Control")
|
|
196
|
+
self.worker_thread = Thread(target=self.auto_work, daemon=True)
|
|
197
|
+
self.worker_thread.start()
|
|
198
|
+
|
|
199
|
+
def release_control(self):
|
|
200
|
+
if not self.running:
|
|
201
|
+
LOGGER.info('Autoworker already stopped!')
|
|
202
|
+
return
|
|
203
|
+
|
|
204
|
+
self.running = False
|
|
205
|
+
self.layout['button_takeover'].config(text="Takeover Input")
|
|
189
206
|
|
|
190
207
|
def toggle_mock(self):
|
|
191
208
|
"""Mock the action selected in the dropdown."""
|
|
@@ -342,6 +359,7 @@ class AutoWorkClient(object, metaclass=abc.ABCMeta):
|
|
|
342
359
|
|
|
343
360
|
testground.bind("<Escape>", exit_record)
|
|
344
361
|
|
|
362
|
+
|
|
345
363
|
class ExampleClient(AutoWorkClient):
|
|
346
364
|
"""An example implementation of the AutoWorkClient."""
|
|
347
365
|
dummy_signal = 0
|
|
@@ -107,6 +107,7 @@ class ProgressiveReplay(Replay):
|
|
|
107
107
|
**kwargs
|
|
108
108
|
):
|
|
109
109
|
self.loader = loader
|
|
110
|
+
self.market_date: datetime.date | None = kwargs.pop('market_date', None)
|
|
110
111
|
self.start_date: datetime.date | None = kwargs.pop('start_date', None)
|
|
111
112
|
self.end_date: datetime.date | None = kwargs.pop('end_date', None)
|
|
112
113
|
self.calendar: list[datetime.date] | None = kwargs.pop('calendar', None)
|
|
@@ -117,6 +118,7 @@ class ProgressiveReplay(Replay):
|
|
|
117
118
|
self.replay_subscription = {}
|
|
118
119
|
self.replay_calendar = []
|
|
119
120
|
self.replay_task = []
|
|
121
|
+
self.replay_status = {}
|
|
120
122
|
|
|
121
123
|
self.date_progress = 0
|
|
122
124
|
self.task_progress = 0
|
|
@@ -182,8 +184,16 @@ class ProgressiveReplay(Replay):
|
|
|
182
184
|
else:
|
|
183
185
|
self.replay_calendar = self.calendar
|
|
184
186
|
|
|
187
|
+
if self.market_date is None:
|
|
188
|
+
self.market_date = self.replay_calendar[0] if self.replay_calendar else self.start_date
|
|
189
|
+
else:
|
|
190
|
+
date_to_replay = [_ for _ in self.replay_calendar if _ >= self.market_date]
|
|
191
|
+
self.market_date = date_to_replay[0] if date_to_replay else self.end_date
|
|
192
|
+
|
|
193
|
+
self.replay_status = {market_date: 'skipped' if market_date < self.market_date else 'idle' for market_date in self.replay_calendar}
|
|
194
|
+
|
|
185
195
|
self.task_progress = 0
|
|
186
|
-
self.date_progress = sum([1 for _ in self.replay_calendar if _ < self.
|
|
196
|
+
self.date_progress = sum([1 for _ in self.replay_calendar if _ < self.market_date])
|
|
187
197
|
self.progress.reset()
|
|
188
198
|
|
|
189
199
|
if self.date_progress:
|
|
@@ -191,7 +201,8 @@ class ProgressiveReplay(Replay):
|
|
|
191
201
|
|
|
192
202
|
def next_trade_day(self):
|
|
193
203
|
if self.date_progress < len(self.replay_calendar):
|
|
194
|
-
market_date = self.replay_calendar[self.date_progress]
|
|
204
|
+
market_date = self.market_date = self.replay_calendar[self.date_progress]
|
|
205
|
+
self.replay_status[market_date] = 'started'
|
|
195
206
|
self.progress.prompt = f'Replay {market_date:%Y-%m-%d} ({self.date_progress + 1} / {len(self.replay_calendar)}):'
|
|
196
207
|
for topic in self.replay_subscription:
|
|
197
208
|
ticker, dtype = self.replay_subscription[topic]
|
|
@@ -214,8 +225,9 @@ class ProgressiveReplay(Replay):
|
|
|
214
225
|
data = self.replay_task[self.task_progress]
|
|
215
226
|
self.task_progress += 1
|
|
216
227
|
else:
|
|
217
|
-
if self.eod is not None and self.
|
|
218
|
-
self.eod(market_date=self.
|
|
228
|
+
if self.eod is not None and self.replay_status[self.market_date] == 'started':
|
|
229
|
+
self.eod(market_date=self.market_date, replay=self)
|
|
230
|
+
self.replay_status[self.market_date] = 'done'
|
|
219
231
|
|
|
220
232
|
self.replay_task.clear()
|
|
221
233
|
self.task_progress = 0
|
|
@@ -223,6 +235,7 @@ class ProgressiveReplay(Replay):
|
|
|
223
235
|
if self.bod is not None and self.date_progress < len(self.replay_calendar):
|
|
224
236
|
self.bod(market_date=self.replay_calendar[self.date_progress], replay=self)
|
|
225
237
|
|
|
238
|
+
# this is by designed, to load the new data after the bod is done.
|
|
226
239
|
self.next_trade_day()
|
|
227
240
|
|
|
228
241
|
# the bod process should be moved here!
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pyalgoengine-0.7.7a3 → pyalgoengine-0.7.7a5}/algo_engine/monitor/advanced_data_interface.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|