PyAlgoEngine 0.8.0a17__tar.gz → 0.8.0.post2__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.8.0a17 → pyalgoengine-0.8.0.post2}/PKG-INFO +1 -1
- {pyalgoengine-0.8.0a17 → pyalgoengine-0.8.0.post2}/PyAlgoEngine.egg-info/PKG-INFO +1 -1
- {pyalgoengine-0.8.0a17 → pyalgoengine-0.8.0.post2}/PyAlgoEngine.egg-info/SOURCES.txt +1 -0
- {pyalgoengine-0.8.0a17 → pyalgoengine-0.8.0.post2}/algo_engine/__init__.py +1 -1
- {pyalgoengine-0.8.0a17 → pyalgoengine-0.8.0.post2}/algo_engine/apps/backtest/tester.py +11 -9
- {pyalgoengine-0.8.0a17 → pyalgoengine-0.8.0.post2}/algo_engine/backtest/__init__.py +2 -2
- {pyalgoengine-0.8.0a17 → pyalgoengine-0.8.0.post2}/algo_engine/backtest/replay.py +119 -23
- {pyalgoengine-0.8.0a17 → pyalgoengine-0.8.0.post2}/algo_engine/base/__init__.py +5 -0
- {pyalgoengine-0.8.0a17 → pyalgoengine-0.8.0.post2}/algo_engine/base/market_data.pyi +3 -0
- {pyalgoengine-0.8.0a17 → pyalgoengine-0.8.0.post2}/algo_engine/base/market_data_buffer.pyi +12 -2
- pyalgoengine-0.8.0.post2/algo_engine/base/trade_utils_native.py +693 -0
- pyalgoengine-0.8.0.post2/algo_engine/profile/__init__.py +236 -0
- {pyalgoengine-0.8.0a17 → pyalgoengine-0.8.0.post2}/algo_engine/strategy/strategy_engine.py +6 -5
- pyalgoengine-0.8.0a17/algo_engine/profile/__init__.py +0 -121
- {pyalgoengine-0.8.0a17 → pyalgoengine-0.8.0.post2}/LICENSE +0 -0
- {pyalgoengine-0.8.0a17 → pyalgoengine-0.8.0.post2}/PyAlgoEngine.egg-info/dependency_links.txt +0 -0
- {pyalgoengine-0.8.0a17 → pyalgoengine-0.8.0.post2}/PyAlgoEngine.egg-info/requires.txt +0 -0
- {pyalgoengine-0.8.0a17 → pyalgoengine-0.8.0.post2}/PyAlgoEngine.egg-info/top_level.txt +0 -0
- {pyalgoengine-0.8.0a17 → pyalgoengine-0.8.0.post2}/README.md +0 -0
- {pyalgoengine-0.8.0a17 → pyalgoengine-0.8.0.post2}/algo_engine/apps/__init__.py +0 -0
- {pyalgoengine-0.8.0a17 → pyalgoengine-0.8.0.post2}/algo_engine/apps/backtest/__init__.py +0 -0
- {pyalgoengine-0.8.0a17 → pyalgoengine-0.8.0.post2}/algo_engine/apps/backtest/doc_server.py +0 -0
- {pyalgoengine-0.8.0a17 → pyalgoengine-0.8.0.post2}/algo_engine/apps/backtest/web_app.py +0 -0
- {pyalgoengine-0.8.0a17 → pyalgoengine-0.8.0.post2}/algo_engine/apps/bokeh_server.py +0 -0
- {pyalgoengine-0.8.0a17 → pyalgoengine-0.8.0.post2}/algo_engine/apps/demo/__init__.py +0 -0
- {pyalgoengine-0.8.0a17 → pyalgoengine-0.8.0.post2}/algo_engine/apps/demo/test.py +0 -0
- {pyalgoengine-0.8.0a17 → pyalgoengine-0.8.0.post2}/algo_engine/apps/sim_input/__init__.py +0 -0
- {pyalgoengine-0.8.0a17 → pyalgoengine-0.8.0.post2}/algo_engine/apps/sim_input/client.py +0 -0
- {pyalgoengine-0.8.0a17 → pyalgoengine-0.8.0.post2}/algo_engine/apps/sim_input/sim_keyboard.py +0 -0
- {pyalgoengine-0.8.0a17 → pyalgoengine-0.8.0.post2}/algo_engine/apps/sim_input/sim_mouse.py +0 -0
- {pyalgoengine-0.8.0a17 → pyalgoengine-0.8.0.post2}/algo_engine/apps/sim_input/window.py +0 -0
- {pyalgoengine-0.8.0a17 → pyalgoengine-0.8.0.post2}/algo_engine/backtest/__main__.py +0 -0
- {pyalgoengine-0.8.0a17 → pyalgoengine-0.8.0.post2}/algo_engine/backtest/metrics.py +0 -0
- {pyalgoengine-0.8.0a17 → pyalgoengine-0.8.0.post2}/algo_engine/backtest/sim_match.py +0 -0
- {pyalgoengine-0.8.0a17 → pyalgoengine-0.8.0.post2}/algo_engine/base/candlestick.pyi +0 -0
- {pyalgoengine-0.8.0a17 → pyalgoengine-0.8.0.post2}/algo_engine/base/console_utils.py +0 -0
- {pyalgoengine-0.8.0a17 → pyalgoengine-0.8.0.post2}/algo_engine/base/finance_decimal.py +0 -0
- {pyalgoengine-0.8.0a17 → pyalgoengine-0.8.0.post2}/algo_engine/base/market_utils_nt.py +0 -0
- {pyalgoengine-0.8.0a17 → pyalgoengine-0.8.0.post2}/algo_engine/base/market_utils_posix.py +0 -0
- {pyalgoengine-0.8.0a17 → pyalgoengine-0.8.0.post2}/algo_engine/base/technical_analysis.py +0 -0
- {pyalgoengine-0.8.0a17 → pyalgoengine-0.8.0.post2}/algo_engine/base/telemetrics.py +0 -0
- {pyalgoengine-0.8.0a17 → pyalgoengine-0.8.0.post2}/algo_engine/base/tick.pyi +0 -0
- {pyalgoengine-0.8.0a17 → pyalgoengine-0.8.0.post2}/algo_engine/base/trade_utils.pyi +0 -0
- {pyalgoengine-0.8.0a17 → pyalgoengine-0.8.0.post2}/algo_engine/base/transaction.pyi +0 -0
- {pyalgoengine-0.8.0a17 → pyalgoengine-0.8.0.post2}/algo_engine/engine/__init__.py +0 -0
- {pyalgoengine-0.8.0a17 → pyalgoengine-0.8.0.post2}/algo_engine/engine/algo_engine.py +0 -0
- {pyalgoengine-0.8.0a17 → pyalgoengine-0.8.0.post2}/algo_engine/engine/event_engine.py +0 -0
- {pyalgoengine-0.8.0a17 → pyalgoengine-0.8.0.post2}/algo_engine/engine/market_engine.py +0 -0
- {pyalgoengine-0.8.0a17 → pyalgoengine-0.8.0.post2}/algo_engine/engine/trade_engine.py +0 -0
- {pyalgoengine-0.8.0a17 → pyalgoengine-0.8.0.post2}/algo_engine/monitor/__init__.py +0 -0
- {pyalgoengine-0.8.0a17 → pyalgoengine-0.8.0.post2}/algo_engine/monitor/advanced_data_interface.py +0 -0
- {pyalgoengine-0.8.0a17 → pyalgoengine-0.8.0.post2}/algo_engine/profile/cn.py +0 -0
- {pyalgoengine-0.8.0a17 → pyalgoengine-0.8.0.post2}/algo_engine/strategy/__init__.py +0 -0
- {pyalgoengine-0.8.0a17 → pyalgoengine-0.8.0.post2}/algo_engine/utils/__init__.py +0 -0
- {pyalgoengine-0.8.0a17 → pyalgoengine-0.8.0.post2}/algo_engine/utils/commit_regularizer.py +0 -0
- {pyalgoengine-0.8.0a17 → pyalgoengine-0.8.0.post2}/algo_engine/utils/data_utils.py +0 -0
- {pyalgoengine-0.8.0a17 → pyalgoengine-0.8.0.post2}/setup.cfg +0 -0
- {pyalgoengine-0.8.0a17 → pyalgoengine-0.8.0.post2}/setup.py +0 -0
|
@@ -37,6 +37,7 @@ algo_engine/base/technical_analysis.py
|
|
|
37
37
|
algo_engine/base/telemetrics.py
|
|
38
38
|
algo_engine/base/tick.pyi
|
|
39
39
|
algo_engine/base/trade_utils.pyi
|
|
40
|
+
algo_engine/base/trade_utils_native.py
|
|
40
41
|
algo_engine/base/transaction.pyi
|
|
41
42
|
algo_engine/engine/__init__.py
|
|
42
43
|
algo_engine/engine/algo_engine.py
|
|
@@ -8,7 +8,7 @@ import numpy as np
|
|
|
8
8
|
from algo_engine.backtest.metrics import TradeMetrics
|
|
9
9
|
from . import LOGGER
|
|
10
10
|
from .web_app import WebApp
|
|
11
|
-
from ...backtest import SimMatch,
|
|
11
|
+
from ...backtest import SimMatch, ProgressReplay
|
|
12
12
|
from ...base import MarketData, TradeReport, TradeInstruction
|
|
13
13
|
from ...profile import Profile, PROFILE
|
|
14
14
|
|
|
@@ -109,17 +109,18 @@ class Tester(object, metaclass=abc.ABCMeta):
|
|
|
109
109
|
pass
|
|
110
110
|
|
|
111
111
|
def run(self, **kwargs):
|
|
112
|
-
replay =
|
|
112
|
+
replay = ProgressReplay(
|
|
113
113
|
loader=self.load_data,
|
|
114
|
-
tickers=list(self.subscription),
|
|
115
|
-
dtype=['TickData', 'TradeData'],
|
|
116
114
|
start_date=self.start_date,
|
|
117
115
|
end_date=self.end_date,
|
|
118
116
|
bod=self.bod,
|
|
119
117
|
eod=self.eod,
|
|
120
|
-
tick_size=kwargs.get('progress_tick_size', 0.001),
|
|
121
118
|
)
|
|
122
119
|
|
|
120
|
+
for ticker in self.subscription:
|
|
121
|
+
replay.add_subscription(ticker, dtype='TickData')
|
|
122
|
+
replay.add_subscription(ticker, dtype='TradeData')
|
|
123
|
+
|
|
123
124
|
_start_ts = time.time()
|
|
124
125
|
|
|
125
126
|
for market_data in replay:
|
|
@@ -222,17 +223,18 @@ class StrategyTester(Tester):
|
|
|
222
223
|
if not self.event_engine.active:
|
|
223
224
|
self.event_engine.start()
|
|
224
225
|
|
|
225
|
-
replay =
|
|
226
|
+
replay = ProgressReplay(
|
|
226
227
|
loader=self.load_data,
|
|
227
|
-
tickers=list(self.subscription),
|
|
228
|
-
dtype=['TickData', 'TradeData'],
|
|
229
228
|
start_date=self.start_date,
|
|
230
229
|
end_date=self.end_date,
|
|
231
230
|
bod=self.bod,
|
|
232
231
|
eod=self.eod,
|
|
233
|
-
tick_size=kwargs.get('progress_tick_size', 0.001),
|
|
234
232
|
)
|
|
235
233
|
|
|
234
|
+
for ticker in self.subscription:
|
|
235
|
+
replay.add_subscription(ticker, dtype='TickData')
|
|
236
|
+
replay.add_subscription(ticker, dtype='TradeData')
|
|
237
|
+
|
|
236
238
|
_start_ts = time.time()
|
|
237
239
|
|
|
238
240
|
for market_data in replay:
|
|
@@ -13,7 +13,7 @@ def set_logger(logger: logging.Logger):
|
|
|
13
13
|
sim_match.LOGGER = LOGGER.getChild('SimMatch')
|
|
14
14
|
|
|
15
15
|
|
|
16
|
-
from .replay import PyDataScope, MarketDateCallable, MarketDataLoader, MarketDataBulkLoader, Replay, SimpleReplay, ProgressReplay
|
|
16
|
+
from .replay import PyDataScope, MarketDateCallable, MarketDataLoader, MarketDataBulkLoader, Replay, SimpleReplay, ProgressReplay
|
|
17
17
|
from .sim_match import SimMatch
|
|
18
18
|
|
|
19
|
-
__all__ = ['PyDataScope', 'MarketDateCallable', 'MarketDataLoader', 'MarketDataBulkLoader', 'Replay', 'SimpleReplay', 'ProgressReplay', '
|
|
19
|
+
__all__ = ['PyDataScope', 'MarketDateCallable', 'MarketDataLoader', 'MarketDataBulkLoader', 'Replay', 'SimpleReplay', 'ProgressReplay', 'SimMatch']
|
|
@@ -2,6 +2,7 @@ import abc
|
|
|
2
2
|
import datetime
|
|
3
3
|
import enum
|
|
4
4
|
import inspect
|
|
5
|
+
import logging
|
|
5
6
|
import operator
|
|
6
7
|
import warnings
|
|
7
8
|
from collections.abc import Sequence, Mapping, Iterable, Callable
|
|
@@ -244,7 +245,7 @@ class SimpleReplay(Replay):
|
|
|
244
245
|
|
|
245
246
|
def __iter__(self):
|
|
246
247
|
self._calendar = self.calendar or [self.start_date + datetime.timedelta(days=i) for i in range((self.end_date - self.start_date).days + 1)]
|
|
247
|
-
self._market_date =
|
|
248
|
+
self._market_date = sorted(_ for _ in self._calendar if _ >= self.market_date)[0]
|
|
248
249
|
self._status = {market_date: 'skipped' if market_date < self.market_date else 'idle' for market_date in self._calendar}
|
|
249
250
|
self._idx_buffer = 0
|
|
250
251
|
self._idx_date = sum([1 for _ in self._calendar if _ < self.market_date])
|
|
@@ -353,7 +354,7 @@ class SimpleReplay(Replay):
|
|
|
353
354
|
if not hasattr(self, '_buffer'):
|
|
354
355
|
raise RuntimeError(f'{self.__class__.__name__} not started yet.')
|
|
355
356
|
|
|
356
|
-
return (self._idx_date +
|
|
357
|
+
return (self._idx_date + self._idx_buffer / self._buffer_size) / len(self._calendar)
|
|
357
358
|
|
|
358
359
|
@property
|
|
359
360
|
def tickers(self) -> list[str]:
|
|
@@ -387,7 +388,7 @@ class ProgressReplay(SimpleReplay):
|
|
|
387
388
|
calendar: Sequence[datetime.date] = None,
|
|
388
389
|
bod: MarketDateCallable = None,
|
|
389
390
|
eod: MarketDateCallable = None,
|
|
390
|
-
**
|
|
391
|
+
**pbar_config
|
|
391
392
|
):
|
|
392
393
|
super().__init__(
|
|
393
394
|
loader=loader,
|
|
@@ -399,40 +400,135 @@ class ProgressReplay(SimpleReplay):
|
|
|
399
400
|
eod=eod
|
|
400
401
|
)
|
|
401
402
|
|
|
402
|
-
self.
|
|
403
|
-
'
|
|
404
|
-
'
|
|
405
|
-
'unit': 'percent',
|
|
406
|
-
'mininterval': 0.1,
|
|
407
|
-
'miniters': 0.001,
|
|
408
|
-
**tqdm_kwargs
|
|
403
|
+
self.pbar_config = {
|
|
404
|
+
'backend': pbar_config.pop('backend', 'tqdm'), # tqdm or native
|
|
405
|
+
'config': pbar_config,
|
|
409
406
|
}
|
|
410
407
|
self._pbar = None
|
|
411
|
-
self.add_bod(self.
|
|
408
|
+
self.add_bod(self._update_pbar_prefix, priority=0)
|
|
409
|
+
|
|
410
|
+
def _init_pbar(self):
|
|
411
|
+
pbar_backend = self.pbar_config['backend']
|
|
412
|
+
match pbar_backend:
|
|
413
|
+
case 'tqdm':
|
|
414
|
+
from tqdm.auto import tqdm
|
|
415
|
+
from tqdm.std import tqdm as tqdm_std
|
|
416
|
+
from tqdm.contrib.logging import _TqdmLoggingHandler, _get_first_found_console_logging_handler, _is_console_logging_handler
|
|
417
|
+
|
|
418
|
+
tqdm_secondary_config = {
|
|
419
|
+
'total': 1,
|
|
420
|
+
'unit_scale': True,
|
|
421
|
+
'unit': 'percent',
|
|
422
|
+
'mininterval': 0.1,
|
|
423
|
+
'miniters': 0.001,
|
|
424
|
+
**self.pbar_config['config'],
|
|
425
|
+
}
|
|
426
|
+
self._pbar_secondary = tqdm(**tqdm_secondary_config)
|
|
427
|
+
|
|
428
|
+
tqdm_config = {
|
|
429
|
+
'total': 1,
|
|
430
|
+
'unit_scale': True,
|
|
431
|
+
'unit': 'percent',
|
|
432
|
+
'mininterval': 0.1,
|
|
433
|
+
'miniters': 0.001,
|
|
434
|
+
**self.pbar_config['config'],
|
|
435
|
+
}
|
|
436
|
+
self._pbar = tqdm(**tqdm_config)
|
|
437
|
+
|
|
438
|
+
self._update_pbar_progress = self._update_tqdm_progress
|
|
439
|
+
self.pbar_config['loggers'] = loggers = [LOGGER.root] + [_ for _ in LOGGER.root.manager.loggerDict.values() if isinstance(_, logging.Logger) and _.handlers]
|
|
440
|
+
self.pbar_config['original_handlers_list'] = [logger.handlers for logger in loggers]
|
|
441
|
+
for logger in loggers:
|
|
442
|
+
tqdm_handler = _TqdmLoggingHandler(tqdm_std)
|
|
443
|
+
orig_handler = _get_first_found_console_logging_handler(logger.handlers)
|
|
444
|
+
if orig_handler is not None:
|
|
445
|
+
tqdm_handler.setFormatter(orig_handler.formatter)
|
|
446
|
+
tqdm_handler.stream = orig_handler.stream
|
|
447
|
+
logger.handlers = [handler for handler in logger.handlers if not _is_console_logging_handler(handler)] + [tqdm_handler]
|
|
448
|
+
case 'native':
|
|
449
|
+
from ..base import Progress
|
|
450
|
+
|
|
451
|
+
progress_config = dict(
|
|
452
|
+
tasks=1,
|
|
453
|
+
tick_size=0.001,
|
|
454
|
+
**self.pbar_config['config'],
|
|
455
|
+
)
|
|
456
|
+
|
|
457
|
+
self._pbar = Progress(**progress_config)
|
|
458
|
+
self._update_pbar_progress = self._update_native_progress
|
|
459
|
+
case _:
|
|
460
|
+
raise NotImplementedError(f'Invalid pbar backend {pbar_backend}')
|
|
461
|
+
|
|
462
|
+
def _update_pbar_prefix(self, market_date: datetime.date):
|
|
463
|
+
pbar_backend = self.pbar_config['backend']
|
|
464
|
+
match pbar_backend:
|
|
465
|
+
case 'tqdm':
|
|
466
|
+
prompt = f'Progress Total ({self._idx_date + 1} / {len(self._calendar)})'
|
|
467
|
+
prompt_secondary = f'Progress [{market_date:%Y-%m-%d}]'
|
|
468
|
+
prompt_length = max(len(prompt), len(prompt_secondary))
|
|
469
|
+
self._pbar.set_description(prompt.ljust(prompt_length))
|
|
470
|
+
self._pbar.refresh()
|
|
471
|
+
self._pbar_secondary.n = 0
|
|
472
|
+
self._pbar_secondary.set_description(prompt_secondary.ljust(prompt_length))
|
|
473
|
+
self._pbar_secondary.refresh()
|
|
474
|
+
case 'native':
|
|
475
|
+
self._pbar.prompt = f'Replay {market_date:%Y-%m-%d} ({self._idx_date + 1} / {len(self._calendar)}):'
|
|
476
|
+
self._pbar.output()
|
|
477
|
+
case _:
|
|
478
|
+
raise NotImplementedError(f'Invalid pbar backend {pbar_backend}')
|
|
479
|
+
|
|
480
|
+
def _close_pbar(self):
|
|
481
|
+
pbar_backend = self.pbar_config['backend']
|
|
482
|
+
match pbar_backend:
|
|
483
|
+
case 'tqdm':
|
|
484
|
+
for logger, original_handlers in zip(self.pbar_config['loggers'], self.pbar_config['original_handlers_list']):
|
|
485
|
+
logger.handlers = original_handlers
|
|
486
|
+
|
|
487
|
+
self._pbar_secondary.n = 1
|
|
488
|
+
# self._pbar_secondary.refresh()
|
|
489
|
+
self._pbar_secondary.close()
|
|
490
|
+
self._pbar_secondary = None
|
|
491
|
+
|
|
492
|
+
self._pbar.n = 1
|
|
493
|
+
# self._pbar.refresh()
|
|
494
|
+
self._pbar.close()
|
|
495
|
+
self._pbar = None
|
|
496
|
+
case 'native':
|
|
497
|
+
self._pbar.done_tasks = 1
|
|
498
|
+
self._pbar.output()
|
|
499
|
+
case _:
|
|
500
|
+
raise NotImplementedError(f'Invalid pbar backend {pbar_backend}')
|
|
501
|
+
|
|
502
|
+
def _update_tqdm_progress(self):
|
|
503
|
+
self._pbar.n = self.progress
|
|
504
|
+
self._pbar.update(0)
|
|
505
|
+
|
|
506
|
+
self._pbar_secondary.n = self._idx_buffer / self._buffer_size
|
|
507
|
+
self._pbar_secondary.update(0)
|
|
508
|
+
|
|
509
|
+
def _update_native_progress(self):
|
|
510
|
+
self._pbar.done_tasks = self.progress
|
|
511
|
+
|
|
512
|
+
if (not self._pbar.tick_size) \
|
|
513
|
+
or self._pbar.progress >= self._pbar.tick_size + self._pbar.last_output \
|
|
514
|
+
or self._pbar.is_done:
|
|
515
|
+
self._pbar.output()
|
|
412
516
|
|
|
413
517
|
def __iter__(self):
|
|
414
|
-
|
|
415
|
-
self._pbar = tqdm(**self._tqdm_kwargs)
|
|
518
|
+
self._init_pbar()
|
|
416
519
|
return super().__iter__()
|
|
417
520
|
|
|
418
521
|
def __next__(self) -> MarketData:
|
|
419
522
|
try:
|
|
420
523
|
result = super().__next__()
|
|
421
|
-
if self._pbar:
|
|
422
|
-
self.
|
|
423
|
-
self._pbar.refresh()
|
|
524
|
+
if self._pbar is not None:
|
|
525
|
+
self._update_pbar_progress()
|
|
424
526
|
return result
|
|
425
527
|
except StopIteration:
|
|
426
528
|
if self._pbar is not None:
|
|
427
|
-
self.
|
|
428
|
-
self._pbar = None
|
|
529
|
+
self._close_pbar()
|
|
429
530
|
raise
|
|
430
531
|
|
|
431
|
-
def _update_progress_bar(self, market_date: datetime.date):
|
|
432
|
-
if self._pbar:
|
|
433
|
-
self._pbar.set_description(f'Replay {market_date:%Y-%m-%d} ({self._idx_date + 1} / {len(self._calendar)})')
|
|
434
|
-
self._pbar.refresh()
|
|
435
|
-
|
|
436
532
|
|
|
437
533
|
class ProgressiveReplay(SimpleReplay):
|
|
438
534
|
"""
|
|
@@ -5,6 +5,8 @@ import pathlib
|
|
|
5
5
|
from .telemetrics import LOGGER
|
|
6
6
|
from ..profile import PROFILE
|
|
7
7
|
|
|
8
|
+
USE_CYTHON = True
|
|
9
|
+
|
|
8
10
|
|
|
9
11
|
def set_logger(logger: logging.Logger):
|
|
10
12
|
global LOGGER
|
|
@@ -15,6 +17,9 @@ def set_logger(logger: logging.Logger):
|
|
|
15
17
|
|
|
16
18
|
|
|
17
19
|
def check_cython_module(cython_module) -> bool:
|
|
20
|
+
if not USE_CYTHON:
|
|
21
|
+
return False
|
|
22
|
+
|
|
18
23
|
for name in cython_module:
|
|
19
24
|
cython_ext = '.pyd' if os.name == 'nt' else '.so'
|
|
20
25
|
for file in pathlib.Path(__file__).parent.glob(f'*{cython_ext}'):
|
|
@@ -31,7 +31,7 @@ class MarketDataBuffer:
|
|
|
31
31
|
|
|
32
32
|
def to_bytes(self) -> bytes: ...
|
|
33
33
|
|
|
34
|
-
def update(self, dtype: int, **kwargs:
|
|
34
|
+
def update(self, dtype: int, **kwargs: Any) -> None: ...
|
|
35
35
|
|
|
36
36
|
def __getitem__(self, idx: int) -> MarketData | TransactionData | OrderData | TickDataLite | TickData | BarData: ...
|
|
37
37
|
|
|
@@ -79,6 +79,10 @@ class MarketDataConcurrentBuffer:
|
|
|
79
79
|
capacity: int = ...
|
|
80
80
|
) -> None: ...
|
|
81
81
|
|
|
82
|
+
def get_head(self, worker_id: int) -> int: ...
|
|
83
|
+
|
|
84
|
+
def min_head(self) -> int: ...
|
|
85
|
+
|
|
82
86
|
def is_empty(self, worker_id: int) -> bool: ...
|
|
83
87
|
|
|
84
88
|
def is_empty_all(self) -> bool: ...
|
|
@@ -89,4 +93,10 @@ class MarketDataConcurrentBuffer:
|
|
|
89
93
|
|
|
90
94
|
def get(self, idx: int) -> MarketData | TransactionData | OrderData | TickDataLite | TickData | BarData: ...
|
|
91
95
|
|
|
92
|
-
def listen(self, worker_id: int, timeout: float = ...) -> MarketData | TransactionData | OrderData | TickDataLite | TickData | BarData: ...
|
|
96
|
+
def listen(self, worker_id: int, block: bool = True, timeout: float = ...) -> MarketData | TransactionData | OrderData | TickDataLite | TickData | BarData: ...
|
|
97
|
+
|
|
98
|
+
@property
|
|
99
|
+
def head(self) -> list[int]: ...
|
|
100
|
+
|
|
101
|
+
@property
|
|
102
|
+
def tail(self) -> int: ...
|