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,53 @@
1
+ """
2
+ Momentum Indicator Models
3
+
4
+ RSI, CCI, and Stochastic indicators aligned with Rust backend.
5
+ """
6
+
7
+ from typing import List, Literal, Optional
8
+
9
+ from pydantic import BaseModel, Field
10
+
11
+
12
+ class RSIIndicator(BaseModel):
13
+ """Relative Strength Index (RSI) 指标
14
+
15
+ 对应 Rust: Indicator::RSI { period, column }
16
+
17
+ Returns:
18
+ 单一数值字段(0-100 范围)
19
+ """
20
+
21
+ type: Literal["RSI"] = "RSI"
22
+ period: int = Field(default=14, gt=0, le=100)
23
+ column: str = Field(default="close", pattern="^(open|high|low|close|volume)$")
24
+
25
+
26
+ class CCIIndicator(BaseModel):
27
+ """Commodity Channel Index (CCI) 指标
28
+
29
+ 对应 Rust: Indicator::CCI { period }
30
+
31
+ Returns:
32
+ 单一数值字段
33
+ """
34
+
35
+ type: Literal["CCI"] = "CCI"
36
+ period: int = Field(default=20, gt=0, le=100)
37
+
38
+
39
+ class StochasticIndicator(BaseModel):
40
+ """Stochastic Oscillator 指标
41
+
42
+ 对应 Rust: Indicator::Stochastic { k_period, d_period, fields }
43
+
44
+ Returns:
45
+ Struct { k: f64, d: f64 }
46
+ """
47
+
48
+ type: Literal["Stochastic"] = "Stochastic"
49
+ k_period: int = Field(default=14, gt=0, le=100, description="%K period")
50
+ d_period: int = Field(default=3, gt=0, le=50, description="%D period (smoothing)")
51
+ fields: Optional[List[str]] = Field(
52
+ default=None, description="Select specific fields: ['k', 'd']"
53
+ )
@@ -0,0 +1,63 @@
1
+ """
2
+ Moving Average Indicator Models
3
+
4
+ SMA, EMA, SMMA, WMA indicators aligned with Rust backend.
5
+ """
6
+
7
+ from typing import Literal
8
+
9
+ from pydantic import BaseModel, Field
10
+
11
+
12
+ class SMAIndicator(BaseModel):
13
+ """Simple Moving Average (SMA) 指标
14
+
15
+ 对应 Rust: Indicator::SMA { period, column }
16
+
17
+ Args:
18
+ period: 计算周期(必须 > 0)
19
+ column: 计算列名(默认 "close")
20
+
21
+ Example:
22
+ >>> sma = SMAIndicator(period=20)
23
+ >>> sma = SMAIndicator(period=50, column="high")
24
+ """
25
+
26
+ type: Literal["SMA"] = "SMA"
27
+ period: int = Field(gt=0, le=500, description="Period must be > 0 and <= 500")
28
+ column: str = Field(
29
+ default="close", pattern="^(open|high|low|close|volume)$", description="OHLCV column name"
30
+ )
31
+
32
+
33
+ class EMAIndicator(BaseModel):
34
+ """Exponential Moving Average (EMA) 指标
35
+
36
+ 对应 Rust: Indicator::EMA { period, column }
37
+ """
38
+
39
+ type: Literal["EMA"] = "EMA"
40
+ period: int = Field(gt=0, le=500)
41
+ column: str = Field(default="close", pattern="^(open|high|low|close|volume)$")
42
+
43
+
44
+ class SMMAIndicator(BaseModel):
45
+ """Smoothed Moving Average (SMMA) 指标
46
+
47
+ 对应 Rust: Indicator::SMMA { period, column }
48
+ """
49
+
50
+ type: Literal["SMMA"] = "SMMA"
51
+ period: int = Field(gt=0, le=500)
52
+ column: str = Field(default="close", pattern="^(open|high|low|close|volume)$")
53
+
54
+
55
+ class WMAIndicator(BaseModel):
56
+ """Weighted Moving Average (WMA) 指标
57
+
58
+ 对应 Rust: Indicator::WMA { period, column }
59
+ """
60
+
61
+ type: Literal["WMA"] = "WMA"
62
+ period: int = Field(gt=0, le=500)
63
+ column: str = Field(default="close", pattern="^(open|high|low|close|volume)$")
@@ -0,0 +1,40 @@
1
+ """
2
+ Other Indicator Models
3
+
4
+ Bollinger Bands and RawOhlcv indicators aligned with Rust backend.
5
+ """
6
+
7
+ from typing import List, Literal, Optional
8
+
9
+ from pydantic import BaseModel, Field
10
+
11
+
12
+ class BollingerBandsIndicator(BaseModel):
13
+ """Bollinger Bands 指标
14
+
15
+ 对应 Rust: Indicator::BollingerBands { period, num_std, column, fields }
16
+
17
+ Returns:
18
+ Struct { upper: f64, middle: f64, lower: f64, bandwidth: f64 }
19
+ """
20
+
21
+ type: Literal["BollingerBands"] = "BollingerBands"
22
+ period: int = Field(default=20, gt=0, le=200)
23
+ num_std: float = Field(default=2.0, gt=0, le=5.0, description="Standard deviation multiplier")
24
+ column: str = Field(default="close", pattern="^(open|high|low|close|volume)$")
25
+ fields: Optional[List[str]] = Field(
26
+ default=None,
27
+ description="Select specific fields: ['upper', 'middle', 'lower', 'bandwidth']",
28
+ )
29
+
30
+
31
+ class RawOhlcvIndicator(BaseModel):
32
+ """Raw OHLCV Column 指标
33
+
34
+ 对应 Rust: Indicator::RawOhlcv { column }
35
+
36
+ 直接引用 OHLCV 列,用于需要原始数据的场景。
37
+ """
38
+
39
+ type: Literal["RawOhlcv"] = "RawOhlcv"
40
+ column: str = Field(pattern="^(open|high|low|close|volume)$")
@@ -0,0 +1,80 @@
1
+ """
2
+ Trend Indicator Models
3
+
4
+ SuperTrend, MACD, and ADX indicators aligned with Rust backend.
5
+ """
6
+
7
+ from typing import List, Literal, Optional
8
+
9
+ from pydantic import BaseModel, Field
10
+
11
+
12
+ class SuperTrendIndicator(BaseModel):
13
+ """SuperTrend 指标
14
+
15
+ 对应 Rust: Indicator::SuperTrend { multiplier, volatility_column, high, low, close }
16
+
17
+ Args:
18
+ multiplier: ATR 倍数(通常 2.0-3.0)
19
+ volatility_column: 引用的波动率列名(如 "ATR|14",注意是列名不是 struct 字段)
20
+ high: 高价列名(默认 "high")
21
+ low: 低价列名(默认 "low")
22
+ close: 收盘价列名(默认 "close")
23
+
24
+ Returns:
25
+ Struct { direction: i32, value: f64, trend: f64, ...}
26
+
27
+ Example:
28
+ >>> st = SuperTrendIndicator(
29
+ ... multiplier=3.0,
30
+ ... volatility_column="ATR|21"
31
+ ... )
32
+ """
33
+
34
+ type: Literal["SuperTrend"] = "SuperTrend"
35
+ multiplier: float = Field(gt=0, le=10, description="ATR multiplier (typically 2.0-3.0)")
36
+ volatility_column: str = Field(
37
+ min_length=1, description="Reference to volatility column (e.g., 'ATR|14')"
38
+ )
39
+ high: str = Field(default="high", pattern="^(high|open|low|close)$")
40
+ low: str = Field(default="low", pattern="^(high|open|low|close)$")
41
+ close: str = Field(default="close", pattern="^(high|open|low|close)$")
42
+ fields: Optional[List[str]] = Field(
43
+ default=None,
44
+ description="Select specific fields: ['direction', 'supertrend', 'long', 'short']",
45
+ )
46
+
47
+
48
+ class MACDIndicator(BaseModel):
49
+ """Moving Average Convergence Divergence (MACD) 指标
50
+
51
+ 对应 Rust: Indicator::MACD { fast_period, slow_period, signal_period, column, fields }
52
+
53
+ Returns:
54
+ Struct { macd: f64, signal: f64, histogram: f64 }
55
+ """
56
+
57
+ type: Literal["MACD"] = "MACD"
58
+ fast_period: int = Field(default=12, gt=0, le=100)
59
+ slow_period: int = Field(default=26, gt=0, le=200)
60
+ signal_period: int = Field(default=9, gt=0, le=50)
61
+ column: str = Field(default="close", pattern="^(open|high|low|close|volume)$")
62
+ fields: Optional[List[str]] = Field(
63
+ default=None, description="Select specific fields: ['macd', 'signal', 'histogram']"
64
+ )
65
+
66
+
67
+ class ADXIndicator(BaseModel):
68
+ """Average Directional Index (ADX) 指标
69
+
70
+ 对应 Rust: Indicator::ADX { period, fields }
71
+
72
+ Returns:
73
+ Struct { adx: f64, plus_di: f64, minus_di: f64 }
74
+ """
75
+
76
+ type: Literal["ADX"] = "ADX"
77
+ period: int = Field(default=14, gt=0, le=100)
78
+ fields: Optional[List[str]] = Field(
79
+ default=None, description="Select specific fields: ['adx', 'plus_di', 'minus_di']"
80
+ )
@@ -0,0 +1,57 @@
1
+ """
2
+ Volatility Indicator Models
3
+
4
+ ATR and ATRQuantile indicators aligned with Rust backend.
5
+ """
6
+
7
+ from typing import Literal
8
+
9
+ from pydantic import BaseModel, Field
10
+
11
+
12
+ class ATRIndicator(BaseModel):
13
+ """Average True Range (ATR) 指标
14
+
15
+ 对应 Rust: Indicator::ATR { period }
16
+
17
+ Returns:
18
+ 单一数值字段(不是 struct)
19
+
20
+ Example:
21
+ >>> atr = ATRIndicator(period=14)
22
+ >>> atr = ATRIndicator(period=21)
23
+ """
24
+
25
+ type: Literal["ATR"] = "ATR"
26
+ period: int = Field(gt=0, le=200, description="Period must be > 0 and <= 200")
27
+
28
+
29
+ class ATRQuantileIndicator(BaseModel):
30
+ """ATR Rolling Quantile 指标
31
+
32
+ 对应 Rust: Indicator::AtrQuantile { atr_column, window, quantile }
33
+
34
+ 计算 ATR 的滚动分位数,用于动态止损等场景。
35
+
36
+ 注意:这是依赖指标,必须先定义 ATR 指标。
37
+
38
+ Args:
39
+ atr_column: 引用的 ATR 列名(如 "ATR|14")
40
+ window: 滚动窗口大小
41
+ quantile: 分位数值 (0, 1),0.5 表示中位数
42
+
43
+ Returns:
44
+ 单一数值字段(不是 struct)
45
+
46
+ Example:
47
+ >>> atr_q = ATRQuantileIndicator(
48
+ ... atr_column="ATR|21",
49
+ ... window=40,
50
+ ... quantile=0.75 # 75th percentile
51
+ ... )
52
+ """
53
+
54
+ type: Literal["AtrQuantile"] = "AtrQuantile"
55
+ atr_column: str = Field(min_length=1, description="Reference to existing ATR column")
56
+ window: int = Field(gt=0, le=500, description="Rolling window size")
57
+ quantile: float = Field(gt=0, lt=1, description="Quantile value in (0, 1)")
@@ -0,0 +1,13 @@
1
+ """Instrument models."""
2
+
3
+ from tradepose_models.instruments.instrument import (
4
+ Instrument,
5
+ InstrumentStatus,
6
+ get_instrument_key,
7
+ )
8
+
9
+ __all__ = [
10
+ "Instrument",
11
+ "InstrumentStatus",
12
+ "get_instrument_key",
13
+ ]
@@ -0,0 +1,87 @@
1
+ """Instrument (trading instrument) models."""
2
+
3
+ from datetime import datetime
4
+ from decimal import Decimal
5
+ from enum import Enum
6
+
7
+ from pydantic import BaseModel, Field
8
+
9
+ from tradepose_models.broker.account_config import BrokerType, MarketType
10
+ from tradepose_models.enums import AccountSource
11
+
12
+
13
+ class InstrumentStatus(str, Enum):
14
+ """Instrument trading status."""
15
+
16
+ ACTIVE = "active"
17
+ INACTIVE = "inactive"
18
+ TRADING_HALT = "trading_halt"
19
+
20
+
21
+ class Instrument(BaseModel):
22
+ """
23
+ 金融商品核心模型
24
+
25
+ Unique Key: (symbol, source, market_type)
26
+ """
27
+
28
+ # === 資料庫 ID (從 DB 查詢時填入) ===
29
+ id: int | None = Field(default=None, description="資料庫自動生成的 ID")
30
+
31
+ # === 識別欄位 (Composite Key) ===
32
+ symbol: str = Field(..., description="券商原生符號: BTCUSDT, EURUSD")
33
+ source: AccountSource = Field(..., description="帳戶來源: BINANCE, FTMO, SHIOAJI")
34
+ broker_type: BrokerType = Field(..., description="券商類型: binance, mt5, sinopac")
35
+ market_type: MarketType = Field(..., description="市場類型: SPOT, FUTURES, SWAP")
36
+
37
+ # === 貨幣定義 ===
38
+ base_currency: str = Field(..., description="基礎資產: BTC, EUR")
39
+ quote_currency: str = Field(..., description="計價貨幣: USDT, USD")
40
+
41
+ # === 交易規格 (必要) ===
42
+ tick_size: Decimal = Field(..., description="最小跳動點")
43
+ lot_size: Decimal = Field(..., description="最小下單量")
44
+ price_precision: int = Field(..., description="價格精度 (小數位數)")
45
+ quantity_precision: int = Field(..., description="數量精度 (小數位數)")
46
+
47
+ # === 交易規格 (可選) ===
48
+ contract_size: Decimal = Field(default=Decimal("1"), description="合約大小 (衍生品)")
49
+ contract_expiry: datetime | None = Field(default=None, description="到期日 (季度期貨)")
50
+ min_notional: Decimal | None = Field(default=None, description="最小名義價值")
51
+
52
+ # === 狀態 ===
53
+ status: InstrumentStatus = Field(default=InstrumentStatus.ACTIVE)
54
+
55
+ # === 擴展 ===
56
+ metadata: dict = Field(default_factory=dict)
57
+
58
+
59
+ def get_instrument_key(instrument: Instrument) -> str:
60
+ """
61
+ 獲取 Instrument 的唯一鍵值
62
+
63
+ 用於 OHLCV 資料庫主鍵或唯一索引。
64
+
65
+ Args:
66
+ instrument: Instrument 實例
67
+
68
+ Returns:
69
+ 唯一的 key 字符串
70
+
71
+ Examples:
72
+ >>> inst = Instrument(
73
+ ... symbol="BTCUSDT",
74
+ ... source=AccountSource.BINANCE,
75
+ ... broker_type=BrokerType.BINANCE,
76
+ ... market_type=MarketType.SPOT,
77
+ ... base_currency="BTC",
78
+ ... quote_currency="USDT",
79
+ ... tick_size=Decimal("0.01"),
80
+ ... lot_size=Decimal("0.001"),
81
+ ... price_precision=2,
82
+ ... quantity_precision=3,
83
+ ... )
84
+ >>> get_instrument_key(inst)
85
+ 'BINANCE:spot:BTCUSDT'
86
+ """
87
+ return f"{instrument.source.value}:{instrument.market_type.value}:{instrument.symbol}"
@@ -0,0 +1,9 @@
1
+ """Scheduler models and responses."""
2
+
3
+ from .results import OperationStatus, TradesUpdateJobResult, UpdateTradesResult
4
+
5
+ __all__ = [
6
+ "OperationStatus",
7
+ "TradesUpdateJobResult",
8
+ "UpdateTradesResult",
9
+ ]
@@ -0,0 +1,49 @@
1
+ """Result models for scheduler operations."""
2
+
3
+ from enum import Enum
4
+
5
+ from pydantic import BaseModel, ConfigDict, Field
6
+
7
+
8
+ class OperationStatus(str, Enum):
9
+ """Status of an operation."""
10
+
11
+ COMPLETED = "completed"
12
+ COMPLETED_WITH_ERRORS = "completed_with_errors"
13
+ FAILED = "failed"
14
+
15
+
16
+ class UpdateTradesResult(BaseModel):
17
+ """Result of updating trades for a user.
18
+
19
+ Returned by TradesUpdaterService.update_trades_for_user()
20
+ """
21
+
22
+ status: OperationStatus = Field(..., description="Operation status")
23
+ user_id: str = Field(..., description="User UUID")
24
+ sb_combinations: int = Field(..., description="Number of strategy+blueprint combinations found")
25
+ batches_published: int = Field(..., description="Number of batches successfully published")
26
+ tasks_published: list[str] = Field(
27
+ default_factory=list, description="List of task IDs published"
28
+ )
29
+ errors: list[str] | None = Field(None, description="List of errors encountered (if any)")
30
+ error: str | None = Field(None, description="Fatal error message (if failed)")
31
+
32
+ model_config = ConfigDict(use_enum_values=True)
33
+
34
+
35
+ class TradesUpdateJobResult(BaseModel):
36
+ """Result of TradesUpdateJob execution.
37
+
38
+ Returned by TradesUpdateJob.run()
39
+ """
40
+
41
+ status: OperationStatus = Field(..., description="Job execution status")
42
+ users_processed: int = Field(..., description="Number of users processed")
43
+ total_batches: int = Field(..., description="Total batches published across all users")
44
+ lookback_days: int = Field(..., description="Lookback period used")
45
+ errors: list[str] | None = Field(None, description="List of errors encountered (if any)")
46
+ error: str | None = Field(None, description="Fatal error message (if failed)")
47
+ message: str | None = Field(None, description="Additional message (if applicable)")
48
+
49
+ model_config = ConfigDict(use_enum_values=True)
@@ -0,0 +1,15 @@
1
+ """
2
+ Polars Schema Definitions
3
+
4
+ Provides schema definitions for Enhanced OHLCV, Trades, and Performance data.
5
+ """
6
+
7
+ from .enhanced_ohlcv import enhanced_ohlcv_schema
8
+ from .performance import performance_schema
9
+ from .trades import trades_schema
10
+
11
+ __all__ = [
12
+ "enhanced_ohlcv_schema",
13
+ "trades_schema",
14
+ "performance_schema",
15
+ ]
@@ -0,0 +1,111 @@
1
+ """
2
+ Enhanced OHLCV Schema
3
+
4
+ Polars schema definition for enhanced OHLCV data with signals and trading context.
5
+ """
6
+
7
+ import polars as pl
8
+
9
+ # Enhanced OHLCV Schema
10
+ enhanced_ohlcv_schema = {
11
+ "idx": pl.Int64,
12
+ "ts": pl.Datetime("ms"),
13
+ "open": pl.Float64,
14
+ "high": pl.Float64,
15
+ "low": pl.Float64,
16
+ "close": pl.Float64,
17
+ "volume": pl.Float64,
18
+ "gap_type": pl.Int64,
19
+ "gap_points": pl.Float64,
20
+ "gap_range_min": pl.Float64,
21
+ "gap_range_max": pl.Float64,
22
+ "entry_signal": pl.Boolean,
23
+ "exit_signal": pl.Boolean,
24
+ "cleaned_entry_signal": pl.Boolean,
25
+ "cleaned_exit_signal": pl.Boolean,
26
+ "base_entry_price": pl.Float64,
27
+ "base_entry_strategy": pl.Int64,
28
+ "base_exit_price": pl.Float64,
29
+ "base_exit_strategy": pl.Int64,
30
+ "base_position_id": pl.Int64,
31
+ # 巢狀結構統一使用 Struct
32
+ "base_trading_context": pl.Struct(
33
+ [
34
+ pl.Field("bars_in_position", pl.Int64),
35
+ pl.Field("highest_since_entry", pl.Float64),
36
+ pl.Field("lowest_since_entry", pl.Float64),
37
+ pl.Field("position_entry_price", pl.Float64),
38
+ ]
39
+ ),
40
+ # 來自 trigger 自動產生
41
+ # "base_entry": pl.Struct(
42
+ # [
43
+ # pl.Field("cond", pl.Boolean),
44
+ # pl.Field("price", pl.Float64),
45
+ # pl.Field("strategy", pl.Int64),
46
+ # pl.Field("priority", pl.Int64),
47
+ # ]
48
+ # ),
49
+ "advanced_favorable_entry_hypo_price": pl.Float64,
50
+ "advanced_adverse_entry_hypo_price": pl.Float64,
51
+ "advanced_neutral_entry_hypo_price": pl.Float64,
52
+ "advanced_favorable_entry_strategy": pl.Int64,
53
+ "advanced_adverse_entry_strategy": pl.Int64,
54
+ "advanced_neutral_entry_strategy": pl.Int64,
55
+ "advanced_entry_price": pl.Float64,
56
+ "advanced_entry_strategy": pl.Int64,
57
+ "is_entry_gap_filled": pl.Boolean,
58
+ "advanced_cleaned_entry_signal": pl.Boolean,
59
+ "advanced_entry_position_id": pl.Int64,
60
+ "advanced_entry_trading_context": pl.Struct(
61
+ [
62
+ pl.Field("bars_since_advanced_entry", pl.Int64),
63
+ pl.Field("highest_since_advanced_entry", pl.Float64),
64
+ pl.Field("lowest_since_advanced_entry", pl.Float64),
65
+ pl.Field("position_entry_price", pl.Float64),
66
+ ]
67
+ ),
68
+ # 來自 trigger 自動產生
69
+ # "base_exit": pl.Struct(
70
+ # [
71
+ # pl.Field("cond", pl.Boolean),
72
+ # pl.Field("price", pl.Float64),
73
+ # pl.Field("strategy", pl.Int64),
74
+ # pl.Field("priority", pl.Int64),
75
+ # ]
76
+ # ),
77
+ "advanced_favorable_exit_hypo_price": pl.Float64,
78
+ "advanced_adverse_exit_hypo_price": pl.Float64,
79
+ "advanced_neutral_exit_hypo_price": pl.Float64,
80
+ "advanced_favorable_exit_strategy": pl.Int64,
81
+ "advanced_adverse_exit_strategy": pl.Int64,
82
+ "advanced_neutral_exit_strategy": pl.Int64,
83
+ "advanced_exit_price": pl.Float64,
84
+ "advanced_exit_strategy": pl.Int64,
85
+ "is_exit_gap_filled": pl.Boolean,
86
+ "advanced_cleaned_exit_signal": pl.Boolean,
87
+ "advanced_exit_position_id": pl.Int64,
88
+ "advanced_exit_trading_context": pl.Struct(
89
+ [
90
+ pl.Field("bars_since_advanced_entry", pl.Int64),
91
+ pl.Field("highest_since_advanced_entry", pl.Float64),
92
+ pl.Field("lowest_since_advanced_entry", pl.Float64),
93
+ pl.Field("position_entry_price", pl.Float64),
94
+ ]
95
+ ),
96
+ "is_entry_valid": pl.Boolean,
97
+ "entry_rejection_reason": pl.Utf8,
98
+ "validated_entry_signal": pl.Boolean,
99
+ "validated_exit_signal": pl.Boolean,
100
+ "final_position_id": pl.Int64,
101
+ "final_trading_context": pl.Struct(
102
+ [
103
+ pl.Field("bars_in_position", pl.Int64),
104
+ pl.Field("highest_since_entry", pl.Float64),
105
+ pl.Field("lowest_since_entry", pl.Float64),
106
+ pl.Field("position_entry_price", pl.Float64),
107
+ ]
108
+ ),
109
+ "strategy_name": pl.Utf8,
110
+ "blueprint_name": pl.Utf8,
111
+ }
@@ -0,0 +1,40 @@
1
+ """
2
+ Performance Schema
3
+
4
+ Polars schema definition for performance metrics from backtest results.
5
+ """
6
+
7
+ import polars as pl
8
+
9
+ # Performance Schema (from backtest-results export)
10
+ # Updated to match actual API response
11
+ performance_schema = {
12
+ # Identifiers
13
+ "strategy_name": pl.Utf8,
14
+ "blueprint_name": pl.Utf8,
15
+ "metric_type": pl.Utf8, # "pnl_pct" or "pnl"
16
+ # Basic trade statistics
17
+ "trades": pl.UInt32, # Total number of trades (renamed from total_trades)
18
+ "win_ratio": pl.Float64, # Win rate (renamed from win_rate)
19
+ # Time information
20
+ "first_entry_time": pl.Datetime("ms"),
21
+ "last_entry_time": pl.Datetime("ms"),
22
+ "last_exit_time": pl.Datetime("ms"),
23
+ # Performance metrics
24
+ "total": pl.Float64, # Total PnL (renamed from total_pnl)
25
+ "expect_payoff": pl.Float64, # Expected payoff per trade
26
+ "pnl_std": pl.Float64, # Standard deviation of PnL
27
+ # Risk metrics
28
+ "profit_factor": pl.Float64,
29
+ "sharpe_ratio": pl.Float64,
30
+ "sortino_ratio": pl.Float64,
31
+ "recovery_factor": pl.Float64,
32
+ # MAE/MFE risk analysis
33
+ "risk_mae_pct_p75": pl.Float64, # 75th percentile MAE (risk management)
34
+ "risk_mae_pct_conservative": pl.Float64, # Conservative MAE estimate
35
+ "risk_mae_pct_p95": pl.Float64, # 95th percentile MAE (worst case)
36
+ "g_mfe_after_mae_pct": pl.Float64, # Global MFE after MAE
37
+ # Advanced metrics
38
+ "kelly": pl.Float64, # Kelly criterion
39
+ "sqn": pl.Float64, # System Quality Number
40
+ }