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.
- tradepose_models/__init__.py +44 -0
- tradepose_models/auth/__init__.py +13 -0
- tradepose_models/auth/api_keys.py +52 -0
- tradepose_models/auth/auth.py +20 -0
- tradepose_models/base.py +57 -0
- tradepose_models/billing/__init__.py +33 -0
- tradepose_models/billing/checkout.py +17 -0
- tradepose_models/billing/plans.py +32 -0
- tradepose_models/billing/subscriptions.py +34 -0
- tradepose_models/billing/usage.py +71 -0
- tradepose_models/broker/__init__.py +34 -0
- tradepose_models/broker/account_config.py +93 -0
- tradepose_models/broker/account_models.py +61 -0
- tradepose_models/broker/binding.py +54 -0
- tradepose_models/broker/connection_status.py +14 -0
- tradepose_models/commands/__init__.py +8 -0
- tradepose_models/commands/trader_command.py +80 -0
- tradepose_models/datafeed/__init__.py +19 -0
- tradepose_models/datafeed/events.py +132 -0
- tradepose_models/enums/__init__.py +47 -0
- tradepose_models/enums/account_source.py +42 -0
- tradepose_models/enums/broker_type.py +21 -0
- tradepose_models/enums/currency.py +17 -0
- tradepose_models/enums/engagement_phase.py +47 -0
- tradepose_models/enums/execution_mode.py +16 -0
- tradepose_models/enums/export_type.py +23 -0
- tradepose_models/enums/freq.py +32 -0
- tradepose_models/enums/indicator_type.py +46 -0
- tradepose_models/enums/operation_type.py +19 -0
- tradepose_models/enums/order_strategy.py +47 -0
- tradepose_models/enums/orderbook_event_type.py +29 -0
- tradepose_models/enums/persist_mode.py +28 -0
- tradepose_models/enums/stream.py +14 -0
- tradepose_models/enums/task_status.py +23 -0
- tradepose_models/enums/trade_direction.py +42 -0
- tradepose_models/enums/trend_type.py +22 -0
- tradepose_models/enums/weekday.py +30 -0
- tradepose_models/enums.py +32 -0
- tradepose_models/events/__init__.py +11 -0
- tradepose_models/events/order_events.py +79 -0
- tradepose_models/export/__init__.py +19 -0
- tradepose_models/export/request.py +52 -0
- tradepose_models/export/requests.py +75 -0
- tradepose_models/export/task_metadata.py +97 -0
- tradepose_models/gateway/__init__.py +19 -0
- tradepose_models/gateway/responses.py +37 -0
- tradepose_models/indicators/__init__.py +56 -0
- tradepose_models/indicators/base.py +42 -0
- tradepose_models/indicators/factory.py +254 -0
- tradepose_models/indicators/market_profile.md +60 -0
- tradepose_models/indicators/market_profile.py +333 -0
- tradepose_models/indicators/market_profile_developer.md +1782 -0
- tradepose_models/indicators/market_profile_trading.md +1060 -0
- tradepose_models/indicators/momentum.py +53 -0
- tradepose_models/indicators/moving_average.py +63 -0
- tradepose_models/indicators/other.py +40 -0
- tradepose_models/indicators/trend.py +80 -0
- tradepose_models/indicators/volatility.py +57 -0
- tradepose_models/instruments/__init__.py +13 -0
- tradepose_models/instruments/instrument.py +87 -0
- tradepose_models/scheduler/__init__.py +9 -0
- tradepose_models/scheduler/results.py +49 -0
- tradepose_models/schemas/__init__.py +15 -0
- tradepose_models/schemas/enhanced_ohlcv.py +111 -0
- tradepose_models/schemas/performance.py +40 -0
- tradepose_models/schemas/trades.py +64 -0
- tradepose_models/schemas.py +34 -0
- tradepose_models/shared.py +15 -0
- tradepose_models/strategy/__init__.py +52 -0
- tradepose_models/strategy/base.py +56 -0
- tradepose_models/strategy/blueprint.py +55 -0
- tradepose_models/strategy/config.py +142 -0
- tradepose_models/strategy/entities.py +104 -0
- tradepose_models/strategy/helpers.py +173 -0
- tradepose_models/strategy/indicator_spec.py +531 -0
- tradepose_models/strategy/performance.py +66 -0
- tradepose_models/strategy/portfolio.py +171 -0
- tradepose_models/strategy/registry.py +249 -0
- tradepose_models/strategy/requests.py +33 -0
- tradepose_models/strategy/trigger.py +77 -0
- tradepose_models/trading/__init__.py +55 -0
- tradepose_models/trading/engagement.py +160 -0
- tradepose_models/trading/orderbook.py +73 -0
- tradepose_models/trading/orders.py +137 -0
- tradepose_models/trading/positions.py +78 -0
- tradepose_models/trading/trader_commands.py +138 -0
- tradepose_models/trading/trades_execution.py +27 -0
- tradepose_models/types.py +35 -0
- tradepose_models/utils/__init__.py +13 -0
- tradepose_models/utils/rate_converter.py +112 -0
- tradepose_models/validators.py +32 -0
- tradepose_models-1.1.0.dist-info/METADATA +633 -0
- tradepose_models-1.1.0.dist-info/RECORD +94 -0
- 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
|
+
}
|