tradepose-models 1.1.0__py3-none-any.whl

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 (94) hide show
  1. tradepose_models/__init__.py +44 -0
  2. tradepose_models/auth/__init__.py +13 -0
  3. tradepose_models/auth/api_keys.py +52 -0
  4. tradepose_models/auth/auth.py +20 -0
  5. tradepose_models/base.py +57 -0
  6. tradepose_models/billing/__init__.py +33 -0
  7. tradepose_models/billing/checkout.py +17 -0
  8. tradepose_models/billing/plans.py +32 -0
  9. tradepose_models/billing/subscriptions.py +34 -0
  10. tradepose_models/billing/usage.py +71 -0
  11. tradepose_models/broker/__init__.py +34 -0
  12. tradepose_models/broker/account_config.py +93 -0
  13. tradepose_models/broker/account_models.py +61 -0
  14. tradepose_models/broker/binding.py +54 -0
  15. tradepose_models/broker/connection_status.py +14 -0
  16. tradepose_models/commands/__init__.py +8 -0
  17. tradepose_models/commands/trader_command.py +80 -0
  18. tradepose_models/datafeed/__init__.py +19 -0
  19. tradepose_models/datafeed/events.py +132 -0
  20. tradepose_models/enums/__init__.py +47 -0
  21. tradepose_models/enums/account_source.py +42 -0
  22. tradepose_models/enums/broker_type.py +21 -0
  23. tradepose_models/enums/currency.py +17 -0
  24. tradepose_models/enums/engagement_phase.py +47 -0
  25. tradepose_models/enums/execution_mode.py +16 -0
  26. tradepose_models/enums/export_type.py +23 -0
  27. tradepose_models/enums/freq.py +32 -0
  28. tradepose_models/enums/indicator_type.py +46 -0
  29. tradepose_models/enums/operation_type.py +19 -0
  30. tradepose_models/enums/order_strategy.py +47 -0
  31. tradepose_models/enums/orderbook_event_type.py +29 -0
  32. tradepose_models/enums/persist_mode.py +28 -0
  33. tradepose_models/enums/stream.py +14 -0
  34. tradepose_models/enums/task_status.py +23 -0
  35. tradepose_models/enums/trade_direction.py +42 -0
  36. tradepose_models/enums/trend_type.py +22 -0
  37. tradepose_models/enums/weekday.py +30 -0
  38. tradepose_models/enums.py +32 -0
  39. tradepose_models/events/__init__.py +11 -0
  40. tradepose_models/events/order_events.py +79 -0
  41. tradepose_models/export/__init__.py +19 -0
  42. tradepose_models/export/request.py +52 -0
  43. tradepose_models/export/requests.py +75 -0
  44. tradepose_models/export/task_metadata.py +97 -0
  45. tradepose_models/gateway/__init__.py +19 -0
  46. tradepose_models/gateway/responses.py +37 -0
  47. tradepose_models/indicators/__init__.py +56 -0
  48. tradepose_models/indicators/base.py +42 -0
  49. tradepose_models/indicators/factory.py +254 -0
  50. tradepose_models/indicators/market_profile.md +60 -0
  51. tradepose_models/indicators/market_profile.py +333 -0
  52. tradepose_models/indicators/market_profile_developer.md +1782 -0
  53. tradepose_models/indicators/market_profile_trading.md +1060 -0
  54. tradepose_models/indicators/momentum.py +53 -0
  55. tradepose_models/indicators/moving_average.py +63 -0
  56. tradepose_models/indicators/other.py +40 -0
  57. tradepose_models/indicators/trend.py +80 -0
  58. tradepose_models/indicators/volatility.py +57 -0
  59. tradepose_models/instruments/__init__.py +13 -0
  60. tradepose_models/instruments/instrument.py +87 -0
  61. tradepose_models/scheduler/__init__.py +9 -0
  62. tradepose_models/scheduler/results.py +49 -0
  63. tradepose_models/schemas/__init__.py +15 -0
  64. tradepose_models/schemas/enhanced_ohlcv.py +111 -0
  65. tradepose_models/schemas/performance.py +40 -0
  66. tradepose_models/schemas/trades.py +64 -0
  67. tradepose_models/schemas.py +34 -0
  68. tradepose_models/shared.py +15 -0
  69. tradepose_models/strategy/__init__.py +52 -0
  70. tradepose_models/strategy/base.py +56 -0
  71. tradepose_models/strategy/blueprint.py +55 -0
  72. tradepose_models/strategy/config.py +142 -0
  73. tradepose_models/strategy/entities.py +104 -0
  74. tradepose_models/strategy/helpers.py +173 -0
  75. tradepose_models/strategy/indicator_spec.py +531 -0
  76. tradepose_models/strategy/performance.py +66 -0
  77. tradepose_models/strategy/portfolio.py +171 -0
  78. tradepose_models/strategy/registry.py +249 -0
  79. tradepose_models/strategy/requests.py +33 -0
  80. tradepose_models/strategy/trigger.py +77 -0
  81. tradepose_models/trading/__init__.py +55 -0
  82. tradepose_models/trading/engagement.py +160 -0
  83. tradepose_models/trading/orderbook.py +73 -0
  84. tradepose_models/trading/orders.py +137 -0
  85. tradepose_models/trading/positions.py +78 -0
  86. tradepose_models/trading/trader_commands.py +138 -0
  87. tradepose_models/trading/trades_execution.py +27 -0
  88. tradepose_models/types.py +35 -0
  89. tradepose_models/utils/__init__.py +13 -0
  90. tradepose_models/utils/rate_converter.py +112 -0
  91. tradepose_models/validators.py +32 -0
  92. tradepose_models-1.1.0.dist-info/METADATA +633 -0
  93. tradepose_models-1.1.0.dist-info/RECORD +94 -0
  94. tradepose_models-1.1.0.dist-info/WHEEL +4 -0
@@ -0,0 +1,254 @@
1
+ """
2
+ Indicator Factory Class
3
+
4
+ Provides static methods to create indicator configurations with a Rust-like API.
5
+ """
6
+
7
+ from typing import Any, Dict, List, Optional
8
+
9
+ from .market_profile import MarketProfileIndicator
10
+ from .momentum import CCIIndicator, RSIIndicator, StochasticIndicator
11
+ from .moving_average import EMAIndicator, SMAIndicator, SMMAIndicator, WMAIndicator
12
+ from .other import BollingerBandsIndicator, RawOhlcvIndicator
13
+ from .trend import ADXIndicator, MACDIndicator, SuperTrendIndicator
14
+ from .volatility import ATRIndicator, ATRQuantileIndicator
15
+
16
+
17
+ class Indicator:
18
+ """指標工廠類(對應 Rust 的 Indicator enum)
19
+
20
+ 使用靜態方法創建各種指標配置,語法類似 Rust 的關聯函數
21
+
22
+ 支援的指標類型(15 種):
23
+ - 移動平均: SMA, EMA, SMMA, WMA
24
+ - 波動率: ATR, AtrQuantile
25
+ - 通道指標: BollingerBands
26
+ - 趨勢指標: SuperTrend, ADX, MACD
27
+ - 動量指標: RSI, CCI, Stochastic
28
+ - 價格分布: MarketProfile
29
+ - 原始數據: RawOhlcv
30
+
31
+ Example:
32
+ >>> from tradepose_models import Indicator
33
+ >>>
34
+ >>> # 移動平均
35
+ >>> sma = Indicator.sma(period=20)
36
+ >>> sma_on_high = Indicator.sma(period=20, column="high")
37
+ >>> ema = Indicator.ema(period=12)
38
+ >>>
39
+ >>> # 波動率
40
+ >>> atr = Indicator.atr(period=14)
41
+ >>> atr_q = Indicator.atr_quantile("ATR|14", window=20, quantile=0.75)
42
+ >>>
43
+ >>> # 通道指標
44
+ >>> bb = Indicator.bollinger_bands(period=20, num_std=2.0)
45
+ >>>
46
+ >>> # 趨勢指標
47
+ >>> st = Indicator.supertrend(multiplier=3.0, volatility_column="ATR|14")
48
+ >>> macd = Indicator.macd(fast_period=12, slow_period=26, signal_period=9)
49
+ >>> adx = Indicator.adx(period=14)
50
+ >>>
51
+ >>> # 動量指標
52
+ >>> rsi = Indicator.rsi(period=14)
53
+ >>> cci = Indicator.cci(period=20)
54
+ >>> stoch = Indicator.stochastic(k_period=14, d_period=3)
55
+ """
56
+
57
+ @staticmethod
58
+ def sma(period: int, column: str = "close") -> SMAIndicator:
59
+ """創建 SMA 指標配置(强类型)
60
+
61
+ 對應 Rust: Indicator::SMA { period, column }
62
+
63
+ Args:
64
+ period: 週期
65
+ column: 計算欄位(預設 "close")
66
+
67
+ Returns:
68
+ SMAIndicator 強類型模型
69
+
70
+ Example:
71
+ >>> sma = Indicator.sma(period=20)
72
+ >>> assert isinstance(sma, SMAIndicator)
73
+ >>> sma_high = Indicator.sma(period=20, column="high")
74
+ """
75
+ return SMAIndicator(period=period, column=column)
76
+
77
+ @staticmethod
78
+ def ema(period: int, column: str = "close") -> EMAIndicator:
79
+ """創建 EMA 指標配置(强类型)
80
+
81
+ 對應 Rust: Indicator::EMA { period, column }
82
+ """
83
+ return EMAIndicator(period=period, column=column)
84
+
85
+ @staticmethod
86
+ def smma(period: int, column: str = "close") -> SMMAIndicator:
87
+ """創建 SMMA 指標配置(强类型)
88
+
89
+ 對應 Rust: Indicator::SMMA { period, column }
90
+ """
91
+ return SMMAIndicator(period=period, column=column)
92
+
93
+ @staticmethod
94
+ def wma(period: int, column: str = "close") -> WMAIndicator:
95
+ """創建 WMA 指標配置(强类型)
96
+
97
+ 對應 Rust: Indicator::WMA { period, column }
98
+ """
99
+ return WMAIndicator(period=period, column=column)
100
+
101
+ @staticmethod
102
+ def atr(period: int) -> ATRIndicator:
103
+ """創建 ATR 指標配置(强类型)
104
+
105
+ 對應 Rust: Indicator::ATR { period }
106
+ """
107
+ return ATRIndicator(period=period)
108
+
109
+ @staticmethod
110
+ def atr_quantile(
111
+ atr_column: str,
112
+ window: int,
113
+ quantile: float,
114
+ ) -> ATRQuantileIndicator:
115
+ """創建 AtrQuantile 指標配置(强类型)
116
+
117
+ 對應 Rust: Indicator::AtrQuantile { atr_column, window, quantile }
118
+ """
119
+ return ATRQuantileIndicator(
120
+ atr_column=atr_column,
121
+ window=window,
122
+ quantile=quantile,
123
+ )
124
+
125
+ @staticmethod
126
+ def supertrend(
127
+ multiplier: float,
128
+ volatility_column: str,
129
+ high: str = "high",
130
+ low: str = "low",
131
+ close: str = "close",
132
+ fields: Optional[List[str]] = None,
133
+ ) -> SuperTrendIndicator:
134
+ """創建 SuperTrend 指標配置(强类型)
135
+
136
+ 對應 Rust: Indicator::SuperTrend { multiplier, volatility_column, high, low, close, fields }
137
+ """
138
+ return SuperTrendIndicator(
139
+ multiplier=float(multiplier),
140
+ volatility_column=volatility_column,
141
+ high=high,
142
+ low=low,
143
+ close=close,
144
+ fields=fields,
145
+ )
146
+
147
+ @staticmethod
148
+ def market_profile(
149
+ anchor_config: Dict[str, Any],
150
+ tick_size: float,
151
+ value_area_pct: float = 0.7,
152
+ fields: Optional[List[str]] = None,
153
+ shape_config: Optional[Dict[str, Any]] = None,
154
+ ) -> MarketProfileIndicator:
155
+ """創建 Market Profile 指標配置(强类型)
156
+
157
+ 對應 Rust: Indicator::MarketProfile { anchor_config, tick_size, ... }
158
+ """
159
+ return MarketProfileIndicator(
160
+ anchor_config=anchor_config,
161
+ tick_size=tick_size,
162
+ value_area_pct=value_area_pct,
163
+ fields=fields,
164
+ shape_config=shape_config,
165
+ )
166
+
167
+ @staticmethod
168
+ def cci(period: int = 20) -> CCIIndicator:
169
+ """創建 CCI 指標配置(强类型)
170
+
171
+ 對應 Rust: Indicator::CCI { period }
172
+ """
173
+ return CCIIndicator(period=period)
174
+
175
+ @staticmethod
176
+ def rsi(period: int = 14, column: str = "close") -> RSIIndicator:
177
+ """創建 RSI 指標配置(强类型)
178
+
179
+ 對應 Rust: Indicator::RSI { period, column }
180
+ """
181
+ return RSIIndicator(period=period, column=column)
182
+
183
+ @staticmethod
184
+ def bollinger_bands(
185
+ period: int = 20,
186
+ num_std: float = 2.0,
187
+ column: str = "close",
188
+ fields: Optional[List[str]] = None,
189
+ ) -> BollingerBandsIndicator:
190
+ """創建 Bollinger Bands 指標配置(强类型)
191
+
192
+ 對應 Rust: Indicator::BollingerBands { period, num_std, column, fields }
193
+ """
194
+ return BollingerBandsIndicator(
195
+ period=period,
196
+ num_std=float(num_std),
197
+ column=column,
198
+ fields=fields,
199
+ )
200
+
201
+ @staticmethod
202
+ def macd(
203
+ fast_period: int = 12,
204
+ slow_period: int = 26,
205
+ signal_period: int = 9,
206
+ column: str = "close",
207
+ fields: Optional[List[str]] = None,
208
+ ) -> MACDIndicator:
209
+ """創建 MACD 指標配置(强类型)
210
+
211
+ 對應 Rust: Indicator::MACD { fast_period, slow_period, signal_period, column, fields }
212
+ """
213
+ return MACDIndicator(
214
+ fast_period=fast_period,
215
+ slow_period=slow_period,
216
+ signal_period=signal_period,
217
+ column=column,
218
+ fields=fields,
219
+ )
220
+
221
+ @staticmethod
222
+ def stochastic(
223
+ k_period: int = 14,
224
+ d_period: int = 3,
225
+ fields: Optional[List[str]] = None,
226
+ ) -> StochasticIndicator:
227
+ """創建 Stochastic 指標配置(强类型)
228
+
229
+ 對應 Rust: Indicator::Stochastic { k_period, d_period, fields }
230
+ """
231
+ return StochasticIndicator(
232
+ k_period=k_period,
233
+ d_period=d_period,
234
+ fields=fields,
235
+ )
236
+
237
+ @staticmethod
238
+ def adx(period: int = 14, fields: Optional[List[str]] = None) -> ADXIndicator:
239
+ """創建 ADX 指標配置(强类型)
240
+
241
+ 對應 Rust: Indicator::ADX { period, fields }
242
+ """
243
+ return ADXIndicator(
244
+ period=period,
245
+ fields=fields,
246
+ )
247
+
248
+ @staticmethod
249
+ def raw_ohlcv(column: str) -> RawOhlcvIndicator:
250
+ """創建 RawOhlcv 指標配置(强类型)
251
+
252
+ 對應 Rust: Indicator::RawOhlcv { column }
253
+ """
254
+ return RawOhlcvIndicator(column=column)
@@ -0,0 +1,60 @@
1
+ # Market Profile 指標文件
2
+
3
+ Market Profile 是一種基於 **TPO (Time Price Opportunity)** 的價格分布分析工具,由 J. Peter Steidlmayer 於 1980 年代開發。
4
+
5
+ 本文件已拆分為兩份,針對不同讀者群:
6
+
7
+ ---
8
+
9
+ ## 文件索引
10
+
11
+ ### [開發者指南](./market_profile_developer.md)
12
+
13
+ 適合需要使用 Market Profile API 的**程式開發者**。
14
+
15
+ **內容包含**:
16
+ - API 參考與配置(MarketProfileIndicator、Helper Functions)
17
+ - 輸出欄位說明(POC、VAH、VAL、tpo_distribution、segment_id)
18
+ - 程式碼範例(7 個完整範例)
19
+ - 常見錯誤與除錯方法
20
+ - 進階主題(跨頻率合併、Performance 特性)
21
+
22
+ ---
23
+
24
+ ### [策略指南](./market_profile_trading.md)
25
+
26
+ 適合需要理解 Market Profile 交易理論的**策略開發者**。
27
+
28
+ **內容包含**:
29
+ - 日型分類(7 種日型:Normal、Trend、Neutral 等)
30
+ - 市場循環理論(AMT、Wyckoff、Steidlmayer 四步循環)
31
+ - Profile 形狀(D/P/b/B 型)與交易含義
32
+ - 形狀識別與交易策略對照表
33
+ - 行業標準與學術文獻參考
34
+
35
+ ---
36
+
37
+ ## 快速選擇
38
+
39
+ | 你的問題 | 建議閱讀 |
40
+ |---------|---------|
41
+ | 如何配置 MarketProfileIndicator? | [開發者指南](./market_profile_developer.md#api-參考) |
42
+ | tick_size 應該設多少? | [開發者指南](./market_profile_developer.md#tick_size-必填) |
43
+ | 什麼是 Trend Day? | [策略指南](./market_profile_trading.md#6-trend-day趨勢日) |
44
+ | P-shape 代表什麼? | [策略指南](./market_profile_trading.md#p-shape-p型-空頭回補) |
45
+ | 如何使用 segment_id 做 Window 操作? | [開發者指南](./market_profile_developer.md#使用-segment_id-進行-window-操作) |
46
+ | 市場循環理論是什麼? | [策略指南](./market_profile_trading.md#市場循環理論-market-cycle-theory) |
47
+
48
+ ---
49
+
50
+ ## 相關資源
51
+
52
+ ### 內部文件
53
+ - **ADR-050**: Market Profile Stateful Implementation
54
+ - **ADR-060**: Market Profile Shape Recognition 優化
55
+ - **KB-006**: Market Profile Shape Recognition 行業研究
56
+
57
+ ### 外部資源
58
+ - [TradingView TPO Indicator](https://www.tradingview.com/support/solutions/43000713306-time-price-opportunity-tpo-indicator/)
59
+ - [Sierra Chart TPO Charts](https://www.sierrachart.com/index.php?page=doc/StudiesReference/TimePriceOpportunityCharts.html)
60
+ - [Market Profile Guide - EMinimind](https://eminimind.com/the-ultimate-guide-to-market-profile/)
@@ -0,0 +1,333 @@
1
+ """
2
+ Market Profile Indicator Model and Configuration
3
+
4
+ Market Profile indicator with anchor config and shape recognition aligned with Rust backend.
5
+ """
6
+
7
+ from enum import Enum
8
+ from typing import Any, Dict, List, Literal, Optional, Union
9
+
10
+ from pydantic import BaseModel, Field
11
+
12
+ from ..enums import Weekday
13
+
14
+
15
+ class ProfileShape(str, Enum):
16
+ """Market Profile 形狀分類(對應 Rust ProfileShape enum)
17
+
18
+ 用於識別 TPO 分布的市場結構模式。
19
+
20
+ Shapes:
21
+ P_SHAPED: P型(快速上漲 + 高位盤整,看空信號)
22
+ B_SHAPED: b型(快速下跌 + 低位盤整,看多信號)
23
+ B_DOUBLE_DISTRIBUTION: B型雙峰(區間交易)
24
+ TREND_DAY: 趨勢日(持續單向移動,順勢交易)
25
+ NORMAL: 正態分布(對稱分布,區間交易)
26
+ UNDEFINED: 無法分類
27
+
28
+ Example:
29
+ >>> from tradepose_models.indicators.market_profile import ProfileShape
30
+ >>> shape = ProfileShape.P_SHAPED
31
+ >>> print(shape.value) # "p_shaped"
32
+ """
33
+
34
+ P_SHAPED = "p_shaped"
35
+ B_SHAPED = "b_shaped"
36
+ B_DOUBLE_DISTRIBUTION = "b_double_distribution"
37
+ TREND_DAY = "trend_day"
38
+ NORMAL = "normal"
39
+ UNDEFINED = "undefined"
40
+
41
+
42
+ class AtrQuantileConfig(BaseModel):
43
+ """ATR 分位數配置(用於 ATR 指標)
44
+
45
+ 對應 Rust: AtrQuantileConfig struct
46
+
47
+ 用於計算 ATR 的滾動分位數,可用於動態止損等場景
48
+
49
+ Example:
50
+ >>> config = AtrQuantileConfig(window=20, quantile=0.5) # 20 週期中位數
51
+ >>> config = AtrQuantileConfig(window=20, quantile=0.75) # 20 週期 75% 分位數
52
+ """
53
+
54
+ window: int = Field(..., gt=0, description="滾動窗口大小(必須 > 0)")
55
+ quantile: float = Field(
56
+ ..., gt=0, lt=1, description="分位數值,範圍 (0, 1),例如 0.5 表示中位數"
57
+ )
58
+
59
+
60
+ class ProfileShapeConfig(BaseModel):
61
+ """Profile 形狀識別配置(用於 MarketProfile 指標)
62
+
63
+ 對應 Rust: ProfileShapeConfig struct
64
+
65
+ 控制 Market Profile 形狀識別算法的閾值參數(進階功能,通常使用預設值即可)
66
+
67
+ Profile 形狀類型:
68
+ - "p_shaped": P型(快速上漲 + 高位盤整,看空信號)
69
+ - "b_shaped": b型(快速下跌 + 低位盤整,看多信號)
70
+ - "b_double_distribution": B型雙峰(區間交易)
71
+ - "trend_day": 趨勢日(持續單向移動,順勢交易)
72
+ - "normal": 正態分布(對稱分布,區間交易)
73
+ - "undefined": 無法分類
74
+
75
+ Example:
76
+ >>> # 使用預設值(推薦)
77
+ >>> config = ProfileShapeConfig()
78
+ >>>
79
+ >>> # 自訂閾值(進階)
80
+ >>> config = ProfileShapeConfig(
81
+ ... trend_monotonic_threshold=0.65,
82
+ ... pshape_concentration_threshold=0.65
83
+ ... )
84
+ """
85
+
86
+ early_period_ratio: float = Field(
87
+ 0.15, gt=0, le=1, description="早期時段比例(前 15% 視為早期)"
88
+ )
89
+ late_period_ratio: float = Field(
90
+ 0.15, gt=0, le=1, description="晚期時段比例(後 15% 視為晚期)"
91
+ )
92
+ trend_ib_max_ratio: float = Field(0.20, gt=0, le=1, description="趨勢日 IB 最大占比")
93
+ trend_monotonic_threshold: float = Field(0.60, gt=0, le=1, description="趨勢日單向移動閾值")
94
+ trend_imbalance_threshold: float = Field(
95
+ 0.70, gt=0, le=1, description="趨勢日早期/晚期 TPO 不平衡度閾值"
96
+ )
97
+ pshape_concentration_threshold: float = Field(
98
+ 0.60, gt=0, le=1, description="P型/b型 TPO 集中度閾值"
99
+ )
100
+ bshape_valley_threshold: float = Field(0.70, gt=0, le=1, description="B型雙峰之間谷的深度閾值")
101
+ normal_symmetry_threshold: float = Field(0.30, gt=0, le=1, description="Normal 型對稱性閾值")
102
+
103
+
104
+ class MarketProfileIndicator(BaseModel):
105
+ """Market Profile 指標
106
+
107
+ 對應 Rust: Indicator::MarketProfile { anchor_config, tick_size, value_area_pct, fields, shape_config }
108
+
109
+ 返回 Struct Series 包含以下欄位:
110
+ - poc: Point of Control (f64)
111
+ - vah: Value Area High (f64)
112
+ - val: Value Area Low (f64)
113
+ - value_area: VAH - VAL 範圍 (f64)
114
+ - tpo_distribution: TPO 分布詳情 (List<Struct{price, count, periods}>)
115
+ - segment_id: 時間區段 ID (u32,自動 ffill)
116
+ - profile_shape: Profile 形狀類型 (String,需啟用 shape_config)
117
+
118
+ Anchor 配置建議使用 helper functions:
119
+ - create_daily_anchor(): 每日 Anchor(24 小時滾動窗口)
120
+ - create_weekly_anchor(): 每週 Anchor(多日窗口)
121
+ - create_initial_balance_anchor(): IB/RTH 窗口
122
+ """
123
+
124
+ type: Literal["MarketProfile"] = "MarketProfile"
125
+ anchor_config: Dict[str, Any] = Field(
126
+ ...,
127
+ description="Anchor configuration (use create_daily_anchor, create_weekly_anchor, or create_initial_balance_anchor)",
128
+ )
129
+ tick_size: float = Field(gt=0, description="Tick size for price levels")
130
+ value_area_pct: float = Field(default=0.7, gt=0, lt=1, description="Value area percentage")
131
+ fields: Optional[List[str]] = Field(
132
+ default=None,
133
+ description="Select specific fields: ['poc', 'vah', 'val', 'value_area', 'tpo_distribution', 'profile_shape']",
134
+ )
135
+ shape_config: Optional[Dict[str, Any]] = Field(
136
+ default=None, description="Profile shape recognition config (advanced feature)"
137
+ )
138
+
139
+
140
+ # Helper functions for creating anchor configurations
141
+
142
+
143
+ def create_daily_anchor(
144
+ hour: int,
145
+ minute: int,
146
+ lookback_days: int = 1,
147
+ ) -> Dict[str, Any]:
148
+ """創建每日 Anchor 配置(用於 Market Profile)
149
+
150
+ Args:
151
+ hour: 小時 (0-23)
152
+ minute: 分鐘 (0-59)
153
+ lookback_days: 回溯天數(預設 1)
154
+
155
+ Returns:
156
+ Anchor 配置 dict
157
+
158
+ Note:
159
+ 系統固定使用 "ts" 和 "segment_id" 欄位名稱
160
+
161
+ Example:
162
+ >>> # 每日 09:15 結束,回溯 1 天
163
+ >>> anchor = create_daily_anchor(9, 15, 1)
164
+ >>> mp = Indicator.market_profile(
165
+ ... anchor_config=anchor,
166
+ ... tick_size=0.01
167
+ ... )
168
+ """
169
+ return {
170
+ "end_rule": {"type": "DailyTime", "hour": hour, "minute": minute},
171
+ "start_rule": None,
172
+ "lookback_days": lookback_days,
173
+ }
174
+
175
+
176
+ def create_weekly_anchor(
177
+ weekday: Union[int, str, Weekday],
178
+ hour: int,
179
+ minute: int,
180
+ lookback_days: int = 5,
181
+ ) -> Dict[str, Any]:
182
+ """創建每週 Anchor 配置(用於 Market Profile)
183
+
184
+ Args:
185
+ weekday: 星期幾,支持多種格式:
186
+ - int: 0=週一, 1=週二, ..., 6=週日
187
+ - str: "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"
188
+ - Weekday enum: Weekday.MON, Weekday.TUE, ...
189
+ hour: 小時 (0-23)
190
+ minute: 分鐘 (0-59)
191
+ lookback_days: 回溯天數(預設 5)
192
+
193
+ Returns:
194
+ Anchor 配置 dict
195
+
196
+ Note:
197
+ 系統固定使用 "ts" 和 "segment_id" 欄位名稱
198
+
199
+ Example:
200
+ >>> # 使用整數
201
+ >>> anchor = create_weekly_anchor(0, 9, 15, 5) # 週一
202
+ >>> # 使用字串
203
+ >>> anchor = create_weekly_anchor("Mon", 9, 15, 5)
204
+ >>> # 使用 Weekday enum
205
+ >>> anchor = create_weekly_anchor(Weekday.MON, 9, 15, 5)
206
+ >>> mp = Indicator.market_profile(
207
+ ... anchor_config=anchor,
208
+ ... tick_size=0.01
209
+ ... )
210
+ """
211
+ # 轉換 weekday 為字串格式
212
+ weekday_map = {
213
+ 0: "Mon",
214
+ 1: "Tue",
215
+ 2: "Wed",
216
+ 3: "Thu",
217
+ 4: "Fri",
218
+ 5: "Sat",
219
+ 6: "Sun",
220
+ }
221
+
222
+ if isinstance(weekday, int):
223
+ weekday_str = weekday_map[weekday]
224
+ elif isinstance(weekday, Weekday):
225
+ weekday_str = weekday.value
226
+ else:
227
+ weekday_str = str(weekday)
228
+
229
+ return {
230
+ "end_rule": {
231
+ "type": "WeeklyTime",
232
+ "weekday": weekday_str,
233
+ "hour": hour,
234
+ "minute": minute,
235
+ },
236
+ "start_rule": None,
237
+ "lookback_days": lookback_days,
238
+ }
239
+
240
+
241
+ def create_initial_balance_anchor(
242
+ start_hour: int,
243
+ start_minute: int,
244
+ end_hour: int,
245
+ end_minute: int,
246
+ ) -> Dict[str, Any]:
247
+ """創建 Initial Balance (IB) Anchor 配置(用於 Market Profile)
248
+
249
+ Args:
250
+ start_hour: 開始時間 - 小時 (0-23)
251
+ start_minute: 開始時間 - 分鐘 (0-59)
252
+ end_hour: 結束時間 - 小時 (0-23)
253
+ end_minute: 結束時間 - 分鐘 (0-59)
254
+
255
+ Returns:
256
+ Anchor 配置 dict
257
+
258
+ Note:
259
+ - lookback_days 固定為 0(只計算當日時段內的數據)
260
+ - 每天在 end_time 觸發一次計算
261
+ - 適用於 IB (Initial Balance) 或 RTH (Regular Trading Hours) 分析
262
+
263
+ Example:
264
+ >>> # 每日 09:00-10:00 的 Initial Balance
265
+ >>> anchor = create_initial_balance_anchor(9, 0, 10, 0)
266
+ >>> mp = Indicator.market_profile(
267
+ ... anchor_config=anchor,
268
+ ... tick_size=0.01
269
+ ... )
270
+ >>>
271
+ >>> # 美股 RTH (Regular Trading Hours): 09:30-16:00
272
+ >>> anchor_rth = create_initial_balance_anchor(9, 30, 16, 0)
273
+ """
274
+ return {
275
+ "start_rule": {"type": "DailyTime", "hour": start_hour, "minute": start_minute},
276
+ "end_rule": {"type": "DailyTime", "hour": end_hour, "minute": end_minute},
277
+ "lookback_days": 0,
278
+ }
279
+
280
+
281
+ def create_profile_shape_config(
282
+ early_period_ratio: float = 0.15,
283
+ late_period_ratio: float = 0.15,
284
+ trend_ib_max_ratio: float = 0.20,
285
+ trend_monotonic_threshold: float = 0.60,
286
+ trend_imbalance_threshold: float = 0.70,
287
+ pshape_concentration_threshold: float = 0.60,
288
+ bshape_valley_threshold: float = 0.70,
289
+ normal_symmetry_threshold: float = 0.30,
290
+ ) -> Dict[str, Any]:
291
+ """創建 Profile 形狀識別配置(用於 MarketProfile 指標)
292
+
293
+ Args:
294
+ early_period_ratio: 早期時段比例(前 15% 視為早期),預設 0.15
295
+ late_period_ratio: 晚期時段比例(後 15% 視為晚期),預設 0.15
296
+ trend_ib_max_ratio: 趨勢日 IB 最大占比,預設 0.20
297
+ trend_monotonic_threshold: 趨勢日單向移動閾值,預設 0.60
298
+ trend_imbalance_threshold: 趨勢日早期/晚期 TPO 不平衡度閾值,預設 0.70
299
+ pshape_concentration_threshold: P型/b型 TPO 集中度閾值,預設 0.60
300
+ bshape_valley_threshold: B型雙峰之間谷的深度閾值,預設 0.70
301
+ normal_symmetry_threshold: Normal 型對稱性閾值,預設 0.30
302
+
303
+ Returns:
304
+ Profile 形狀識別配置 dict
305
+
306
+ Note:
307
+ 通常使用預設值即可,僅在需要微調形狀識別邏輯時才自訂參數
308
+
309
+ Example:
310
+ >>> # 使用預設值(推薦)
311
+ >>> shape_config = create_profile_shape_config()
312
+ >>> Indicator.market_profile(
313
+ ... anchor_config=create_daily_anchor(9, 15, 1),
314
+ ... tick_size=0.5,
315
+ ... shape_config=shape_config
316
+ ... )
317
+ >>>
318
+ >>> # 自訂閾值(進階)
319
+ >>> shape_config = create_profile_shape_config(
320
+ ... trend_monotonic_threshold=0.65,
321
+ ... pshape_concentration_threshold=0.65
322
+ ... )
323
+ """
324
+ return {
325
+ "early_period_ratio": early_period_ratio,
326
+ "late_period_ratio": late_period_ratio,
327
+ "trend_ib_max_ratio": trend_ib_max_ratio,
328
+ "trend_monotonic_threshold": trend_monotonic_threshold,
329
+ "trend_imbalance_threshold": trend_imbalance_threshold,
330
+ "pshape_concentration_threshold": pshape_concentration_threshold,
331
+ "bshape_valley_threshold": bshape_valley_threshold,
332
+ "normal_symmetry_threshold": normal_symmetry_threshold,
333
+ }