PyAlgoEngine 0.4.1__tar.gz → 0.4.2__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.
Files changed (33) hide show
  1. {PyAlgoEngine-0.4.1 → PyAlgoEngine-0.4.2}/PKG-INFO +1 -1
  2. {PyAlgoEngine-0.4.1 → PyAlgoEngine-0.4.2}/PyAlgoEngine.egg-info/PKG-INFO +1 -1
  3. {PyAlgoEngine-0.4.1 → PyAlgoEngine-0.4.2}/algo_engine/__init__.py +1 -1
  4. {PyAlgoEngine-0.4.1 → PyAlgoEngine-0.4.2}/algo_engine/back_test/sim_match.py +1 -1
  5. {PyAlgoEngine-0.4.1 → PyAlgoEngine-0.4.2}/algo_engine/base/market_utils.py +3 -3
  6. {PyAlgoEngine-0.4.1 → PyAlgoEngine-0.4.2}/algo_engine/base/trade_utils.py +6 -6
  7. {PyAlgoEngine-0.4.1 → PyAlgoEngine-0.4.2}/algo_engine/engine/algo_engine.py +2 -2
  8. {PyAlgoEngine-0.4.1 → PyAlgoEngine-0.4.2}/algo_engine/engine/market_engine.py +4 -7
  9. {PyAlgoEngine-0.4.1 → PyAlgoEngine-0.4.2}/algo_engine/profile/__init__.py +12 -5
  10. {PyAlgoEngine-0.4.1 → PyAlgoEngine-0.4.2}/algo_engine/profile/cn.py +18 -23
  11. {PyAlgoEngine-0.4.1 → PyAlgoEngine-0.4.2}/LICENSE +0 -0
  12. {PyAlgoEngine-0.4.1 → PyAlgoEngine-0.4.2}/PyAlgoEngine.egg-info/SOURCES.txt +0 -0
  13. {PyAlgoEngine-0.4.1 → PyAlgoEngine-0.4.2}/PyAlgoEngine.egg-info/dependency_links.txt +0 -0
  14. {PyAlgoEngine-0.4.1 → PyAlgoEngine-0.4.2}/PyAlgoEngine.egg-info/requires.txt +0 -0
  15. {PyAlgoEngine-0.4.1 → PyAlgoEngine-0.4.2}/PyAlgoEngine.egg-info/top_level.txt +0 -0
  16. {PyAlgoEngine-0.4.1 → PyAlgoEngine-0.4.2}/README.md +0 -0
  17. {PyAlgoEngine-0.4.1 → PyAlgoEngine-0.4.2}/algo_engine/back_test/__init__.py +0 -0
  18. {PyAlgoEngine-0.4.1 → PyAlgoEngine-0.4.2}/algo_engine/back_test/__main__.py +0 -0
  19. {PyAlgoEngine-0.4.1 → PyAlgoEngine-0.4.2}/algo_engine/back_test/replay.py +0 -0
  20. {PyAlgoEngine-0.4.1 → PyAlgoEngine-0.4.2}/algo_engine/base/__init__.py +0 -0
  21. {PyAlgoEngine-0.4.1 → PyAlgoEngine-0.4.2}/algo_engine/base/console_utils.py +0 -0
  22. {PyAlgoEngine-0.4.1 → PyAlgoEngine-0.4.2}/algo_engine/base/finance_decimal.py +0 -0
  23. {PyAlgoEngine-0.4.1 → PyAlgoEngine-0.4.2}/algo_engine/base/technical_analysis.py +0 -0
  24. {PyAlgoEngine-0.4.1 → PyAlgoEngine-0.4.2}/algo_engine/base/telemetrics.py +0 -0
  25. {PyAlgoEngine-0.4.1 → PyAlgoEngine-0.4.2}/algo_engine/engine/__init__.py +0 -0
  26. {PyAlgoEngine-0.4.1 → PyAlgoEngine-0.4.2}/algo_engine/engine/event_engine.py +0 -0
  27. {PyAlgoEngine-0.4.1 → PyAlgoEngine-0.4.2}/algo_engine/engine/trade_engine.py +0 -0
  28. {PyAlgoEngine-0.4.1 → PyAlgoEngine-0.4.2}/algo_engine/monitor/__init__.py +0 -0
  29. {PyAlgoEngine-0.4.1 → PyAlgoEngine-0.4.2}/algo_engine/monitor/advanced_data_interface.py +0 -0
  30. {PyAlgoEngine-0.4.1 → PyAlgoEngine-0.4.2}/algo_engine/strategy/__init__.py +0 -0
  31. {PyAlgoEngine-0.4.1 → PyAlgoEngine-0.4.2}/algo_engine/strategy/strategy_engine.py +0 -0
  32. {PyAlgoEngine-0.4.1 → PyAlgoEngine-0.4.2}/setup.cfg +0 -0
  33. {PyAlgoEngine-0.4.1 → PyAlgoEngine-0.4.2}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: PyAlgoEngine
3
- Version: 0.4.1
3
+ Version: 0.4.2
4
4
  Summary: Basic algo engine
5
5
  Home-page: https://github.com/BolunHan/PyAlgoEngine
6
6
  Author: Bolun.Han
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: PyAlgoEngine
3
- Version: 0.4.1
3
+ Version: 0.4.2
4
4
  Summary: Basic algo engine
5
5
  Home-page: https://github.com/BolunHan/PyAlgoEngine
6
6
  Author: Bolun.Han
@@ -1,4 +1,4 @@
1
- __version__ = "0.4.1"
1
+ __version__ = "0.4.2"
2
2
 
3
3
  import logging
4
4
  import os
@@ -292,4 +292,4 @@ class SimMatch(object):
292
292
 
293
293
  @property
294
294
  def market_time(self) -> datetime.datetime:
295
- return datetime.datetime.fromtimestamp(self.timestamp, tz=PROFILE.timezone)
295
+ return datetime.datetime.fromtimestamp(self.timestamp, tz=PROFILE.time_zone)
@@ -269,7 +269,7 @@ class MarketData(dict, metaclass=abc.ABCMeta):
269
269
 
270
270
  @property
271
271
  def market_time(self) -> datetime.datetime | datetime.date:
272
- return datetime.datetime.fromtimestamp(self.timestamp, tz=PROFILE.timezone)
272
+ return datetime.datetime.fromtimestamp(self.timestamp, tz=PROFILE.time_zone)
273
273
 
274
274
  @property
275
275
  @abc.abstractmethod
@@ -823,9 +823,9 @@ class BarData(MarketData):
823
823
  @property
824
824
  def bar_start_time(self) -> datetime.datetime:
825
825
  if 'start_timestamp' in self:
826
- return datetime.datetime.fromtimestamp(self['start_timestamp'], tz=PROFILE.timezone)
826
+ return datetime.datetime.fromtimestamp(self['start_timestamp'], tz=PROFILE.time_zone)
827
827
  else:
828
- return datetime.datetime.fromtimestamp(self['timestamp'] - self['bar_span'], tz=PROFILE.timezone)
828
+ return datetime.datetime.fromtimestamp(self['timestamp'] - self['bar_span'], tz=PROFILE.time_zone)
829
829
 
830
830
  @property
831
831
  def vwap(self) -> float:
@@ -152,7 +152,7 @@ class TradeBaseClass(dict, metaclass=abc.ABCMeta):
152
152
 
153
153
  @property
154
154
  def market_time(self) -> datetime.datetime | datetime.date:
155
- return datetime.datetime.fromtimestamp(self.timestamp, tz=PROFILE.timezone)
155
+ return datetime.datetime.fromtimestamp(self.timestamp, tz=PROFILE.time_zone)
156
156
 
157
157
 
158
158
  class TradeReport(TradeBaseClass):
@@ -377,7 +377,7 @@ class TradeReport(TradeBaseClass):
377
377
 
378
378
  @property
379
379
  def trade_time(self) -> datetime.datetime:
380
- return datetime.datetime.fromtimestamp(self.timestamp, tz=PROFILE.timezone)
380
+ return datetime.datetime.fromtimestamp(self.timestamp, tz=PROFILE.time_zone)
381
381
 
382
382
 
383
383
  class TradeInstruction(TradeBaseClass):
@@ -681,26 +681,26 @@ class TradeInstruction(TradeBaseClass):
681
681
 
682
682
  @property
683
683
  def start_time(self) -> datetime.datetime | None:
684
- return datetime.datetime.fromtimestamp(self.timestamp, tz=PROFILE.timezone)
684
+ return datetime.datetime.fromtimestamp(self.timestamp, tz=PROFILE.time_zone)
685
685
 
686
686
  @property
687
687
  def placed_time(self) -> datetime.datetime | None:
688
688
  if 'ts_placed' in self:
689
- return datetime.datetime.fromtimestamp(self['ts_placed'], tz=PROFILE.timezone)
689
+ return datetime.datetime.fromtimestamp(self['ts_placed'], tz=PROFILE.time_zone)
690
690
 
691
691
  return None
692
692
 
693
693
  @property
694
694
  def canceled_time(self) -> datetime.datetime | None:
695
695
  if 'ts_canceled' in self:
696
- return datetime.datetime.fromtimestamp(self['ts_canceled'], tz=PROFILE.timezone)
696
+ return datetime.datetime.fromtimestamp(self['ts_canceled'], tz=PROFILE.time_zone)
697
697
 
698
698
  return None
699
699
 
700
700
  @property
701
701
  def finished_time(self) -> datetime.datetime | None:
702
702
  if 'ts_finished' in self:
703
- return datetime.datetime.fromtimestamp(self['ts_finished'], tz=PROFILE.timezone)
703
+ return datetime.datetime.fromtimestamp(self['ts_finished'], tz=PROFILE.time_zone)
704
704
 
705
705
  return None
706
706
 
@@ -453,14 +453,14 @@ class AlgoTemplate(object, metaclass=abc.ABCMeta):
453
453
  if self.ts_started is None:
454
454
  return None
455
455
 
456
- return datetime.datetime.fromtimestamp(self.ts_started, tz=self.algo_engine.mds.profile.timezone)
456
+ return datetime.datetime.fromtimestamp(self.ts_started, tz=self.algo_engine.mds.profile.time_zone)
457
457
 
458
458
  @property
459
459
  def finish_time(self) -> datetime.datetime | None:
460
460
  if self.ts_finished is None:
461
461
  return None
462
462
 
463
- return datetime.datetime.fromtimestamp(self.ts_finished, tz=self.algo_engine.mds.profile.timezone)
463
+ return datetime.datetime.fromtimestamp(self.ts_finished, tz=self.algo_engine.mds.profile.time_zone)
464
464
 
465
465
 
466
466
  class Passive(AlgoTemplate):
@@ -8,7 +8,7 @@ from typing import Self
8
8
 
9
9
  from . import LOGGER
10
10
  from ..base import TickData, TradeData, OrderBook, MarketData, TransactionSide
11
- from ..profile import PROFILE, Profile, PROFILE_CN
11
+ from ..profile import PROFILE, Profile
12
12
 
13
13
  LOGGER = LOGGER.getChild('MarketEngine')
14
14
 
@@ -199,9 +199,6 @@ class MarketDataService(object):
199
199
  self.monitor.pop(monitor_id)
200
200
  self.monitor_manager.pop_monitor(monitor_id)
201
201
 
202
- def init_cn_override(self):
203
- self.profile = PROFILE_CN
204
-
205
202
  def _on_trade_data(self, trade_data: TradeData):
206
203
  ticker = trade_data.ticker
207
204
 
@@ -281,8 +278,8 @@ class MarketDataService(object):
281
278
  def trade_time_between(self, start_time: datetime.datetime | float, end_time: datetime.datetime | float, **kwargs) -> datetime.timedelta:
282
279
  return self.profile.trade_time_between(start_time=start_time, end_time=end_time, **kwargs)
283
280
 
284
- def in_trade_session(self, market_time: datetime.datetime | float) -> bool:
285
- return self.profile.in_trade_session(market_time=market_time)
281
+ def is_market_session(self, market_time: datetime.datetime | float | int) -> bool:
282
+ return self.profile.is_market_session(timestamp=market_time)
286
283
 
287
284
  def clear(self):
288
285
  # self._market_price.clear()
@@ -310,7 +307,7 @@ class MarketDataService(object):
310
307
  if self._timestamp is None:
311
308
  return None
312
309
  else:
313
- return datetime.datetime.fromtimestamp(self._timestamp, tz=self.profile.timezone)
310
+ return datetime.datetime.fromtimestamp(self._timestamp, tz=self.profile.time_zone)
314
311
  else:
315
312
  return self._market_time
316
313
 
@@ -14,7 +14,7 @@ class Profile(object, metaclass=abc.ABCMeta):
14
14
  self.session_end = session_end
15
15
  self.session_break = [] if session_break is None else session_break
16
16
 
17
- self.timezone = None
17
+ self.time_zone = None
18
18
 
19
19
  @abc.abstractmethod
20
20
  def override_profile(self, profile: Self): ...
@@ -24,9 +24,16 @@ class Profile(object, metaclass=abc.ABCMeta):
24
24
  ...
25
25
 
26
26
  @abc.abstractmethod
27
- def in_trade_session(self, market_time: datetime.datetime | float) -> bool:
27
+ def is_market_session(self, timestamp: float | int | datetime.datetime) -> bool:
28
28
  ...
29
29
 
30
+ @property
31
+ def range_break(self) -> list[dict]:
32
+ """
33
+ an range break designed for plotly.
34
+ """
35
+ return []
36
+
30
37
 
31
38
  class DefaultProfile(Profile):
32
39
  def __init__(self):
@@ -41,10 +48,10 @@ class DefaultProfile(Profile):
41
48
 
42
49
  def trade_time_between(self, start_time: datetime.datetime | float, end_time: datetime.datetime | float, **kwargs) -> datetime.timedelta:
43
50
  if start_time is not None and isinstance(start_time, (float, int)):
44
- start_time = datetime.datetime.fromtimestamp(start_time, tz=self.timezone)
51
+ start_time = datetime.datetime.fromtimestamp(start_time, tz=self.time_zone)
45
52
 
46
53
  if end_time is not None and isinstance(end_time, (float, int)):
47
- end_time = datetime.datetime.fromtimestamp(end_time, tz=self.timezone)
54
+ end_time = datetime.datetime.fromtimestamp(end_time, tz=self.time_zone)
48
55
 
49
56
  if start_time is None or end_time is None:
50
57
  return datetime.timedelta(seconds=0)
@@ -54,7 +61,7 @@ class DefaultProfile(Profile):
54
61
 
55
62
  return end_time - start_time
56
63
 
57
- def in_trade_session(self, market_time: datetime.datetime | float) -> bool:
64
+ def is_market_session(self, timestamp: float | int | datetime.datetime) -> bool:
58
65
  return True
59
66
 
60
67
 
@@ -31,7 +31,7 @@ class ProfileCN(Profile):
31
31
  profile.in_trade_session = self.in_trade_session
32
32
 
33
33
  @functools.lru_cache
34
- def trade_calendar(self, start_date: datetime.date, end_date: datetime.date, market='XSHG', tz='UTC') -> list[datetime.date]:
34
+ def query_trade_calendar(self, start_date: datetime.date, end_date: datetime.date, market='XSHG', tz='UTC') -> list[datetime.date]:
35
35
  import pandas as pd
36
36
 
37
37
  if market in self.trade_calendar:
@@ -72,7 +72,7 @@ class ProfileCN(Profile):
72
72
  if start_date == end_date:
73
73
  offset = 0
74
74
  else:
75
- market_date_list = self.trade_calendar(start_date=start_date, end_date=end_date, **kwargs)
75
+ market_date_list = self.query_trade_calendar(start_date=start_date, end_date=end_date, **kwargs)
76
76
  if not market_date_list:
77
77
  offset = 0
78
78
  else:
@@ -106,11 +106,11 @@ class ProfileCN(Profile):
106
106
  implied_date = datetime.date.today()
107
107
 
108
108
  if isinstance(start_time, (float, int)):
109
- start_time = datetime.datetime.fromtimestamp(start_time, tz=self.timezone)
109
+ start_time = datetime.datetime.fromtimestamp(start_time, tz=self.time_zone)
110
110
  implied_date = start_time.date()
111
111
 
112
112
  if isinstance(end_time, (float, int)):
113
- end_time = datetime.datetime.fromtimestamp(end_time, tz=self.timezone)
113
+ end_time = datetime.datetime.fromtimestamp(end_time, tz=self.time_zone)
114
114
  implied_date = end_time.date()
115
115
 
116
116
  if isinstance(start_time, datetime.time):
@@ -164,29 +164,24 @@ class ProfileCN(Profile):
164
164
  else:
165
165
  raise NotImplementedError(f'Invalid fmt {fmt}, should be "timestamp" or "timedelta"')
166
166
 
167
- def in_trade_session(self, market_time: datetime.datetime | float | int = None) -> bool:
168
- if market_time is None:
169
- market_time = datetime.datetime.now()
170
-
171
- if isinstance(market_time, (float, int)):
172
- market_time = datetime.datetime.fromtimestamp(market_time, tz=self.timezone)
173
-
174
- market_date = market_time.date()
175
- market_time = market_time.time()
176
-
177
- if not self.is_trade_day(market_date=market_date):
178
- return False
179
-
180
- if market_time < datetime.time(9, 30):
181
- return False
182
-
183
- if datetime.time(11, 30) < market_time < datetime.time(13, 00):
184
- return False
167
+ def is_market_session(self, timestamp: float | int | datetime.datetime) -> bool:
168
+ if isinstance(timestamp, (float, int)):
169
+ market_time = datetime.datetime.fromtimestamp(timestamp, tz=self.time_zone).time()
170
+ elif isinstance(timestamp, datetime.datetime):
171
+ market_time = timestamp
172
+ else:
173
+ raise TypeError(f'Expect timestamp to be a float, int or datetime, got {type(timestamp)}!')
185
174
 
186
- if market_time > datetime.time(15, 00):
175
+ if (market_time < datetime.time(9, 30)
176
+ or datetime.time(11, 30) < market_time < datetime.time(13, 0)
177
+ or datetime.time(15, 0) < market_time):
187
178
  return False
188
179
 
189
180
  return True
190
181
 
182
+ @property
183
+ def range_break(self) -> list[dict]:
184
+ return [dict(bounds=[0, 9.5], pattern="hour"), dict(bounds=[11.5, 13], pattern="hour"), dict(bounds=[15, 24], pattern="hour")]
185
+
191
186
 
192
187
  PROFILE_CN = ProfileCN()
File without changes
File without changes
File without changes
File without changes