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,80 @@
|
|
|
1
|
+
"""Trader command model (Issue #307).
|
|
2
|
+
|
|
3
|
+
Command model for Redis Stream messages sent to Trader.
|
|
4
|
+
Stream pattern: trader:commands:{user_id}:{node_seq}:{slot_idx}
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from datetime import datetime, timezone
|
|
8
|
+
from decimal import Decimal
|
|
9
|
+
from enum import Enum
|
|
10
|
+
from typing import Optional
|
|
11
|
+
from uuid import UUID
|
|
12
|
+
|
|
13
|
+
from pydantic import BaseModel, Field
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class CommandType(str, Enum):
|
|
17
|
+
"""Types of commands that can be sent to Trader."""
|
|
18
|
+
|
|
19
|
+
EXECUTE_ORDER = "execute_order"
|
|
20
|
+
"""Execute an order (entry, exit, SL, TP)."""
|
|
21
|
+
|
|
22
|
+
CANCEL_ORDER = "cancel_order"
|
|
23
|
+
"""Cancel an existing order."""
|
|
24
|
+
|
|
25
|
+
MODIFY_ORDER = "modify_order"
|
|
26
|
+
"""Modify an existing order (SL/TP levels)."""
|
|
27
|
+
|
|
28
|
+
SYNC_BROKER_STATUS = "sync_broker_status"
|
|
29
|
+
"""Synchronize broker account status (positions, orders)."""
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class TraderCommand(BaseModel):
|
|
33
|
+
"""Command sent to Trader via Redis Stream.
|
|
34
|
+
|
|
35
|
+
Attributes:
|
|
36
|
+
command_type: Type of command
|
|
37
|
+
engagement_id: Associated engagement (optional for sync commands)
|
|
38
|
+
account_id: Target account
|
|
39
|
+
symbol: Trading symbol (for order commands)
|
|
40
|
+
direction: Trade direction 1=Long, -1=Short (for order commands)
|
|
41
|
+
quantity: Order quantity (for order commands)
|
|
42
|
+
entry_price: Entry price (for execute commands)
|
|
43
|
+
sl_price: Stop loss price (optional)
|
|
44
|
+
tp_price: Take profit price (optional)
|
|
45
|
+
broker_order_id: Broker's order ID (for cancel/modify)
|
|
46
|
+
new_sl_price: New SL price (for modify)
|
|
47
|
+
new_tp_price: New TP price (for modify)
|
|
48
|
+
timestamp: Command timestamp
|
|
49
|
+
"""
|
|
50
|
+
|
|
51
|
+
command_type: CommandType = Field(..., description="Type of command")
|
|
52
|
+
engagement_id: Optional[UUID] = Field(None, description="Engagement UUID")
|
|
53
|
+
account_id: UUID = Field(..., description="Target account UUID")
|
|
54
|
+
|
|
55
|
+
# Order details (for EXECUTE_ORDER)
|
|
56
|
+
symbol: Optional[str] = Field(None, description="Trading symbol")
|
|
57
|
+
direction: Optional[int] = Field(None, description="Trade direction: 1=Long, -1=Short")
|
|
58
|
+
quantity: Optional[Decimal] = Field(None, description="Order quantity")
|
|
59
|
+
entry_price: Optional[Decimal] = Field(None, description="Entry price")
|
|
60
|
+
sl_price: Optional[Decimal] = Field(None, description="Stop loss price")
|
|
61
|
+
tp_price: Optional[Decimal] = Field(None, description="Take profit price")
|
|
62
|
+
|
|
63
|
+
# Cancel/Modify details
|
|
64
|
+
broker_order_id: Optional[str] = Field(None, description="Broker's order ID")
|
|
65
|
+
new_sl_price: Optional[Decimal] = Field(None, description="New stop loss price")
|
|
66
|
+
new_tp_price: Optional[Decimal] = Field(None, description="New take profit price")
|
|
67
|
+
|
|
68
|
+
timestamp: datetime = Field(
|
|
69
|
+
default_factory=lambda: datetime.now(timezone.utc),
|
|
70
|
+
description="Command timestamp",
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
class Config:
|
|
74
|
+
"""Pydantic config."""
|
|
75
|
+
|
|
76
|
+
json_encoders = {
|
|
77
|
+
Decimal: str,
|
|
78
|
+
UUID: str,
|
|
79
|
+
datetime: lambda v: v.isoformat(),
|
|
80
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"""DataFeed event models for Redis Stream communication."""
|
|
2
|
+
|
|
3
|
+
from tradepose_models.datafeed.events import (
|
|
4
|
+
BatchOHLCVDownloadEvent,
|
|
5
|
+
DatafeedEvent,
|
|
6
|
+
DatafeedEventType,
|
|
7
|
+
InstrumentCrudEvent,
|
|
8
|
+
InstrumentOperation,
|
|
9
|
+
OHLCVDownloadEvent,
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
__all__ = [
|
|
13
|
+
"DatafeedEventType",
|
|
14
|
+
"InstrumentOperation",
|
|
15
|
+
"InstrumentCrudEvent",
|
|
16
|
+
"OHLCVDownloadEvent",
|
|
17
|
+
"BatchOHLCVDownloadEvent",
|
|
18
|
+
"DatafeedEvent",
|
|
19
|
+
]
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
"""DataFeed event models for Redis Stream communication.
|
|
2
|
+
|
|
3
|
+
Security Design Principle:
|
|
4
|
+
Events carry entity IDs only, never sensitive data like credentials.
|
|
5
|
+
The consuming service (DataFeed) queries the database directly
|
|
6
|
+
to retrieve sensitive data when needed.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from datetime import datetime, timezone
|
|
10
|
+
from enum import StrEnum
|
|
11
|
+
from typing import Literal, Union
|
|
12
|
+
from uuid import UUID
|
|
13
|
+
|
|
14
|
+
from pydantic import BaseModel, Field
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def _utc_now() -> datetime:
|
|
18
|
+
"""Return current UTC datetime (timezone-aware)."""
|
|
19
|
+
return datetime.now(timezone.utc)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class DatafeedEventType(StrEnum):
|
|
23
|
+
"""DataFeed 事件類型"""
|
|
24
|
+
|
|
25
|
+
INSTRUMENT_CRUD = "instrument_crud"
|
|
26
|
+
OHLCV_DOWNLOAD = "ohlcv_download"
|
|
27
|
+
BATCH_OHLCV_DOWNLOAD = "batch_ohlcv_download"
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class InstrumentOperation(StrEnum):
|
|
31
|
+
"""Instrument CRUD 操作類型"""
|
|
32
|
+
|
|
33
|
+
CREATE = "create"
|
|
34
|
+
UPDATE = "update"
|
|
35
|
+
DELETE = "delete"
|
|
36
|
+
SYNC = "sync" # Scheduler 觸發的全量同步
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class InstrumentCrudEvent(BaseModel):
|
|
40
|
+
"""Instrument CRUD 事件
|
|
41
|
+
|
|
42
|
+
用於管理金融商品資料的新增、更新、刪除操作。
|
|
43
|
+
- SYNC: 需要 account_id 來從 broker 下載所有商品
|
|
44
|
+
- CREATE/UPDATE/DELETE: 需要 instrument_id 來操作單一商品
|
|
45
|
+
|
|
46
|
+
Note: Uses IDs only - DataFeed queries DB for full objects.
|
|
47
|
+
"""
|
|
48
|
+
|
|
49
|
+
event_type: Literal[DatafeedEventType.INSTRUMENT_CRUD] = DatafeedEventType.INSTRUMENT_CRUD
|
|
50
|
+
task_id: str = Field(..., description="任務唯一識別碼")
|
|
51
|
+
operation: InstrumentOperation = Field(..., description="CRUD 操作類型")
|
|
52
|
+
|
|
53
|
+
# SYNC 操作需要 account_id 來連接 broker
|
|
54
|
+
account_id: UUID | None = Field(default=None, description="Account UUID(SYNC 操作必填)")
|
|
55
|
+
# CREATE/UPDATE/DELETE 操作需要 instrument_id
|
|
56
|
+
instrument_id: int | None = Field(default=None, description="Instrument ID")
|
|
57
|
+
|
|
58
|
+
created_at: datetime = Field(default_factory=_utc_now)
|
|
59
|
+
retry_count: int = Field(default=0, description="重試次數")
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
class OHLCVDownloadEvent(BaseModel):
|
|
63
|
+
"""OHLCV 資料下載事件
|
|
64
|
+
|
|
65
|
+
用於透過 BrokerAdapter 下載 OHLCV 資料並儲存到 PostgreSQL。
|
|
66
|
+
|
|
67
|
+
Note: Uses IDs only - DataFeed queries DB for full objects.
|
|
68
|
+
"""
|
|
69
|
+
|
|
70
|
+
event_type: Literal[DatafeedEventType.OHLCV_DOWNLOAD] = DatafeedEventType.OHLCV_DOWNLOAD
|
|
71
|
+
task_id: str = Field(..., description="任務唯一識別碼")
|
|
72
|
+
account_id: UUID = Field(..., description="Account UUID")
|
|
73
|
+
|
|
74
|
+
# Instrument 識別(二選一)
|
|
75
|
+
instrument_id: int | None = Field(default=None, description="Instrument ID")
|
|
76
|
+
instrument_key: str | None = Field(
|
|
77
|
+
default=None,
|
|
78
|
+
description="Unique key: {source}:{market_type}:{symbol}",
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
timeframe: str = Field(..., description="時間框架 e.g., '1h', '4h', '1d'")
|
|
82
|
+
start_time: datetime = Field(..., description="下載開始時間")
|
|
83
|
+
end_time: datetime = Field(..., description="下載結束時間")
|
|
84
|
+
created_at: datetime = Field(default_factory=_utc_now)
|
|
85
|
+
retry_count: int = Field(default=0, description="重試次數")
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
class BatchOHLCVDownloadEvent(BaseModel):
|
|
89
|
+
"""批次 OHLCV 資料下載事件
|
|
90
|
+
|
|
91
|
+
由 Scheduler 發送,包含多個 instruments 的下載任務。
|
|
92
|
+
DataFeed 根據 broker_type 決定下載方式(MT5、Binance 等)。
|
|
93
|
+
|
|
94
|
+
下載邏輯(由 DataFeed 處理):
|
|
95
|
+
1. 如果 force_full=True,忽略 DB 資料,從 start_time 完整下載
|
|
96
|
+
2. 如果 DB 有該 instrument+freq 的資料,從 last_ts 開始增量下載
|
|
97
|
+
3. 如果沒有資料且有 start_time,從 start_time 開始下載
|
|
98
|
+
4. 否則使用 bars_count 從最新往回下載
|
|
99
|
+
|
|
100
|
+
Note: Uses IDs only - DataFeed queries DB for full objects.
|
|
101
|
+
"""
|
|
102
|
+
|
|
103
|
+
event_type: Literal[DatafeedEventType.BATCH_OHLCV_DOWNLOAD] = (
|
|
104
|
+
DatafeedEventType.BATCH_OHLCV_DOWNLOAD
|
|
105
|
+
)
|
|
106
|
+
task_id: str = Field(..., description="任務唯一識別碼")
|
|
107
|
+
account_id: UUID = Field(..., description="Account UUID")
|
|
108
|
+
instrument_ids: list[int] = Field(..., description="Instrument ID 列表")
|
|
109
|
+
|
|
110
|
+
# 下載參數
|
|
111
|
+
timeframe: str = Field(default="1m", description="時間框架 e.g., '1m', '5m', '1h'")
|
|
112
|
+
start_time: datetime | None = Field(
|
|
113
|
+
default=None, description="起始時間(從 config 傳入,當 DB 無資料時使用)"
|
|
114
|
+
)
|
|
115
|
+
end_time: datetime | None = Field(
|
|
116
|
+
default=None,
|
|
117
|
+
description="結束時間(None = 下載到最新,自動填為 now + 30 天)",
|
|
118
|
+
)
|
|
119
|
+
bars_count: int | None = Field(
|
|
120
|
+
default=None, description="K 線數量(從最新往回,當無 start_time 時的備用方案)"
|
|
121
|
+
)
|
|
122
|
+
force_full: bool = Field(
|
|
123
|
+
default=False,
|
|
124
|
+
description="強制完整下載(忽略 DB 現有資料,從 start_time 重新下載)",
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
created_at: datetime = Field(default_factory=_utc_now)
|
|
128
|
+
retry_count: int = Field(default=0, description="重試次數")
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
# Union Type for Worker event dispatching
|
|
132
|
+
DatafeedEvent = Union[InstrumentCrudEvent, OHLCVDownloadEvent, BatchOHLCVDownloadEvent]
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Enumerations for TradePose platform
|
|
3
|
+
|
|
4
|
+
All enums are aligned with Rust backend types for JSON serialization.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from .account_source import AccountSource
|
|
8
|
+
from .broker_type import BrokerType
|
|
9
|
+
from .currency import Currency
|
|
10
|
+
from .engagement_phase import EngagementPhase
|
|
11
|
+
from .execution_mode import ExecutionMode
|
|
12
|
+
from .export_type import ExportType
|
|
13
|
+
from .freq import Freq
|
|
14
|
+
from .indicator_type import IndicatorType
|
|
15
|
+
from .operation_type import OperationType
|
|
16
|
+
from .order_strategy import OrderStrategy
|
|
17
|
+
from .orderbook_event_type import OrderbookEventType
|
|
18
|
+
from .persist_mode import PersistMode
|
|
19
|
+
from .stream import RedisStream
|
|
20
|
+
from .task_status import TaskStatus
|
|
21
|
+
from .trade_direction import TradeDirection
|
|
22
|
+
from .trend_type import TrendType
|
|
23
|
+
from .weekday import Weekday
|
|
24
|
+
|
|
25
|
+
# Backwards compatibility alias (deprecated, use BrokerType instead)
|
|
26
|
+
Platform = BrokerType
|
|
27
|
+
|
|
28
|
+
__all__ = [
|
|
29
|
+
"AccountSource",
|
|
30
|
+
"BrokerType",
|
|
31
|
+
"Currency",
|
|
32
|
+
"EngagementPhase",
|
|
33
|
+
"ExecutionMode",
|
|
34
|
+
"ExportType",
|
|
35
|
+
"Freq",
|
|
36
|
+
"IndicatorType",
|
|
37
|
+
"OperationType",
|
|
38
|
+
"OrderStrategy",
|
|
39
|
+
"OrderbookEventType",
|
|
40
|
+
"PersistMode",
|
|
41
|
+
"Platform", # Deprecated alias for BrokerType
|
|
42
|
+
"RedisStream",
|
|
43
|
+
"TaskStatus",
|
|
44
|
+
"TradeDirection",
|
|
45
|
+
"TrendType",
|
|
46
|
+
"Weekday",
|
|
47
|
+
]
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"""AccountSource enumeration for brokers and prop firms."""
|
|
2
|
+
|
|
3
|
+
from datetime import datetime
|
|
4
|
+
from enum import StrEnum
|
|
5
|
+
from zoneinfo import ZoneInfo
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class AccountSource(StrEnum):
|
|
9
|
+
"""帳戶來源 / Broker / Prop firm"""
|
|
10
|
+
|
|
11
|
+
FTMO = "FTMO"
|
|
12
|
+
IB = "IB"
|
|
13
|
+
FIVEPERCENT = "FIVEPERCENT"
|
|
14
|
+
BINANCE = "BINANCE"
|
|
15
|
+
SHIOAJI = "SHIOAJI"
|
|
16
|
+
|
|
17
|
+
def timezone(self) -> str:
|
|
18
|
+
"""Returns IANA timezone string for this account source.
|
|
19
|
+
|
|
20
|
+
Returns:
|
|
21
|
+
IANA timezone string (e.g., "Europe/Athens", "America/New_York")
|
|
22
|
+
"""
|
|
23
|
+
timezones = {
|
|
24
|
+
AccountSource.FTMO: "Europe/Athens",
|
|
25
|
+
AccountSource.IB: "America/New_York",
|
|
26
|
+
AccountSource.FIVEPERCENT: "Europe/Moscow",
|
|
27
|
+
AccountSource.BINANCE: "Etc/UTC",
|
|
28
|
+
AccountSource.SHIOAJI: "Asia/Taipei",
|
|
29
|
+
}
|
|
30
|
+
return timezones.get(self, "Etc/UTC")
|
|
31
|
+
|
|
32
|
+
def tz_offset(self) -> int:
|
|
33
|
+
"""動態計算當前 UTC 偏移(考慮 DST)
|
|
34
|
+
|
|
35
|
+
Returns:
|
|
36
|
+
Current UTC offset in hours (DST-aware)
|
|
37
|
+
"""
|
|
38
|
+
tz = ZoneInfo(self.timezone())
|
|
39
|
+
offset = datetime.now(tz).utcoffset()
|
|
40
|
+
if offset is None:
|
|
41
|
+
return 0
|
|
42
|
+
return int(offset.total_seconds() / 3600)
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"""Broker type enumeration for trading platforms."""
|
|
2
|
+
|
|
3
|
+
from enum import StrEnum
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class BrokerType(StrEnum):
|
|
7
|
+
"""Supported broker types for trading platforms.
|
|
8
|
+
|
|
9
|
+
This enum represents the different trading platforms/brokers that can be used.
|
|
10
|
+
Use this instead of the deprecated Platform enum.
|
|
11
|
+
|
|
12
|
+
Values are lowercase to match database enum values.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
MT5 = "mt5"
|
|
16
|
+
BINANCE = "binance"
|
|
17
|
+
OKX = "okx"
|
|
18
|
+
SHIOAJI = "shioaji" # Taiwan Sinopac
|
|
19
|
+
CCXT = "ccxt" # Generic CCXT adapter
|
|
20
|
+
INTERACTIVE_BROKERS = "ib"
|
|
21
|
+
TRADEPOSE_MOCK = "tradepose_mock" # Mock broker for testing
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"""Currency enumeration for trading platforms."""
|
|
2
|
+
|
|
3
|
+
from enum import StrEnum
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Currency(StrEnum):
|
|
7
|
+
"""貨幣類型"""
|
|
8
|
+
|
|
9
|
+
USD = "USD"
|
|
10
|
+
USDT = "USDT"
|
|
11
|
+
TWD = "TWD"
|
|
12
|
+
EUR = "EUR"
|
|
13
|
+
JPY = "JPY"
|
|
14
|
+
BTC = "BTC"
|
|
15
|
+
ETH = "ETH"
|
|
16
|
+
XAU = "XAU" # Gold
|
|
17
|
+
TAIEX = "TAIEX" # Taiwan Index
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"""Engagement phase enum for 8-state lifecycle (Issue #305).
|
|
2
|
+
|
|
3
|
+
Represents the complete lifecycle of a trade engagement from creation
|
|
4
|
+
to closure, including failure states.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from enum import IntEnum
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class EngagementPhase(IntEnum):
|
|
11
|
+
"""Engagement phase (aligned with Rust #[repr(i16)]).
|
|
12
|
+
|
|
13
|
+
8-state lifecycle for engagement execution tracking.
|
|
14
|
+
Stored as SMALLINT in PostgreSQL.
|
|
15
|
+
|
|
16
|
+
State transitions:
|
|
17
|
+
PENDING(0) → ENTERING(1) → HOLDING(2) → EXITING(3) → CLOSED(4)
|
|
18
|
+
│ │
|
|
19
|
+
▼ ▼
|
|
20
|
+
FAILED(5) EXIT_FAILED(7)
|
|
21
|
+
|
|
22
|
+
CANCELLED(6) - Signal cancelled before execution
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
PENDING = 0
|
|
26
|
+
"""Initial state: Engagement created, awaiting entry order submission."""
|
|
27
|
+
|
|
28
|
+
ENTERING = 1
|
|
29
|
+
"""Entry order submitted, waiting for fill."""
|
|
30
|
+
|
|
31
|
+
HOLDING = 2
|
|
32
|
+
"""Entry filled, position is open and being held."""
|
|
33
|
+
|
|
34
|
+
EXITING = 3
|
|
35
|
+
"""Exit order submitted (SL, TP, or manual), waiting for fill."""
|
|
36
|
+
|
|
37
|
+
CLOSED = 4
|
|
38
|
+
"""Position fully closed (exit filled successfully)."""
|
|
39
|
+
|
|
40
|
+
FAILED = 5
|
|
41
|
+
"""Entry failed (rejected, expired, or cancelled)."""
|
|
42
|
+
|
|
43
|
+
CANCELLED = 6
|
|
44
|
+
"""Signal cancelled before entry (user or system action)."""
|
|
45
|
+
|
|
46
|
+
EXIT_FAILED = 7
|
|
47
|
+
"""Exit failed but position may still be open (requires manual intervention)."""
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"""Execution mode enum for account-portfolio bindings."""
|
|
2
|
+
|
|
3
|
+
from enum import Enum
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class ExecutionMode(str, Enum):
|
|
7
|
+
"""Binding execution mode.
|
|
8
|
+
|
|
9
|
+
Determines how orders are executed when binding an account to a portfolio.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
PRICE_PRIORITY = "price_priority"
|
|
13
|
+
"""Prioritize price execution (default). Wait for better price."""
|
|
14
|
+
|
|
15
|
+
SIGNAL_PRIORITY = "signal_priority"
|
|
16
|
+
"""Prioritize signal execution. Execute immediately at market."""
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Export type enumeration for export tasks
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from enum import Enum
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class ExportType(int, Enum):
|
|
9
|
+
"""導出類型枚舉(與 Rust ExportType enum 一致)
|
|
10
|
+
|
|
11
|
+
對應 Rust 的 ExportType enum,定義支援的導出格式
|
|
12
|
+
|
|
13
|
+
Rust 對應關係(#[repr(i16)]):
|
|
14
|
+
- Rust: ExportType::BacktestResults = 0 → Python: ExportType.BACKTEST_RESULTS = 0
|
|
15
|
+
- Rust: ExportType::LatestTrades = 1 → Python: ExportType.LATEST_TRADES = 1
|
|
16
|
+
- Rust: ExportType::EnhancedOhlcv = 2 → Python: ExportType.ENHANCED_OHLCV = 2
|
|
17
|
+
- Rust: ExportType::OnDemandOhlcv = 3 → Python: ExportType.ON_DEMAND_OHLCV = 3
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
BACKTEST_RESULTS = 0 # 完整回測結果(trades + performance)
|
|
21
|
+
LATEST_TRADES = 1 # 最新持倉狀態
|
|
22
|
+
ENHANCED_OHLCV = 2 # 增強 OHLCV(包含所有指標和信號)
|
|
23
|
+
ON_DEMAND_OHLCV = 3 # 按需 OHLCV(無需註冊策略)
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Time frequency enumeration
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from enum import Enum
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class Freq(str, Enum):
|
|
9
|
+
"""
|
|
10
|
+
Time frequency enum (aligned with Rust Freq enum)
|
|
11
|
+
|
|
12
|
+
Values:
|
|
13
|
+
MIN_1: 1 minute
|
|
14
|
+
MIN_5: 5 minutes
|
|
15
|
+
MIN_15: 15 minutes
|
|
16
|
+
MIN_30: 30 minutes
|
|
17
|
+
HOUR_1: 1 hour
|
|
18
|
+
HOUR_4: 4 hours
|
|
19
|
+
DAY_1: 1 day
|
|
20
|
+
WEEK_1: 1 week
|
|
21
|
+
MONTH_1: 1 month
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
MIN_1 = "1min"
|
|
25
|
+
MIN_5 = "5min"
|
|
26
|
+
MIN_15 = "15min"
|
|
27
|
+
MIN_30 = "30min"
|
|
28
|
+
HOUR_1 = "1h"
|
|
29
|
+
HOUR_4 = "4h"
|
|
30
|
+
DAY_1 = "1D"
|
|
31
|
+
WEEK_1 = "1W"
|
|
32
|
+
MONTH_1 = "1M"
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Indicator type enumeration
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from enum import Enum
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class IndicatorType(str, Enum):
|
|
9
|
+
"""
|
|
10
|
+
Indicator type enum
|
|
11
|
+
|
|
12
|
+
Maps to Indicator factory methods in models.py.
|
|
13
|
+
|
|
14
|
+
Values:
|
|
15
|
+
SMA: Simple Moving Average
|
|
16
|
+
EMA: Exponential Moving Average
|
|
17
|
+
SMMA: Smoothed Moving Average
|
|
18
|
+
WMA: Weighted Moving Average
|
|
19
|
+
ATR: Average True Range
|
|
20
|
+
ATR_QUANTILE: ATR Rolling Quantile
|
|
21
|
+
SUPERTREND: SuperTrend
|
|
22
|
+
MARKET_PROFILE: Market Profile
|
|
23
|
+
CCI: Commodity Channel Index
|
|
24
|
+
RSI: Relative Strength Index
|
|
25
|
+
BOLLINGER_BANDS: Bollinger Bands
|
|
26
|
+
MACD: Moving Average Convergence Divergence
|
|
27
|
+
STOCHASTIC: Stochastic Oscillator
|
|
28
|
+
ADX: Average Directional Index
|
|
29
|
+
RAW_OHLCV: Raw OHLCV column
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
SMA = "sma"
|
|
33
|
+
EMA = "ema"
|
|
34
|
+
SMMA = "smma"
|
|
35
|
+
WMA = "wma"
|
|
36
|
+
ATR = "atr"
|
|
37
|
+
ATR_QUANTILE = "atr_quantile"
|
|
38
|
+
SUPERTREND = "supertrend"
|
|
39
|
+
MARKET_PROFILE = "market_profile"
|
|
40
|
+
CCI = "cci"
|
|
41
|
+
RSI = "rsi"
|
|
42
|
+
BOLLINGER_BANDS = "bollinger_bands"
|
|
43
|
+
MACD = "macd"
|
|
44
|
+
STOCHASTIC = "stochastic"
|
|
45
|
+
ADX = "adx"
|
|
46
|
+
RAW_OHLCV = "raw_ohlcv"
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"""Operation type enum for task operations."""
|
|
2
|
+
|
|
3
|
+
from enum import Enum
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class OperationType(str, Enum):
|
|
7
|
+
"""Task operation types for Gateway."""
|
|
8
|
+
|
|
9
|
+
# Backtest operations
|
|
10
|
+
BACKTEST_RESULTS = "backtest-results"
|
|
11
|
+
ENHANCED_OHLCV = "enhanced-ohlcv"
|
|
12
|
+
LATEST_TRADES = "latest-trades"
|
|
13
|
+
ON_DEMAND_OHLCV = "on-demand-ohlcv"
|
|
14
|
+
|
|
15
|
+
# Strategy operations
|
|
16
|
+
REGISTER_STRATEGY = "register_strategy"
|
|
17
|
+
LIST_STRATEGIES = "list_strategies"
|
|
18
|
+
GET_STRATEGY = "get_strategy"
|
|
19
|
+
DELETE_STRATEGY = "delete_strategy"
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Order strategy enumeration
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from enum import Enum
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class OrderStrategy(str, Enum):
|
|
9
|
+
"""
|
|
10
|
+
Order strategy enum (aligned with Rust OrderStrategy enum)
|
|
11
|
+
|
|
12
|
+
Used to specify the execution strategy for entry/exit triggers.
|
|
13
|
+
|
|
14
|
+
Rust mapping:
|
|
15
|
+
- Rust: OrderStrategy::ImmediateEntry → Python: OrderStrategy.IMMEDIATE_ENTRY (u32: 0)
|
|
16
|
+
- Rust: OrderStrategy::FavorableDelayEntry → Python: OrderStrategy.FAVORABLE_DELAY_ENTRY (u32: 1)
|
|
17
|
+
- Rust: OrderStrategy::AdverseDelayEntry → Python: OrderStrategy.ADVERSE_DELAY_ENTRY (u32: 2)
|
|
18
|
+
- Rust: OrderStrategy::ImmediateExit → Python: OrderStrategy.IMMEDIATE_EXIT (u32: 3)
|
|
19
|
+
- Rust: OrderStrategy::StopLoss → Python: OrderStrategy.STOP_LOSS (u32: 4)
|
|
20
|
+
- Rust: OrderStrategy::TakeProfit → Python: OrderStrategy.TAKE_PROFIT (u32: 5)
|
|
21
|
+
- Rust: OrderStrategy::TrailingStop → Python: OrderStrategy.TRAILING_STOP (u32: 6)
|
|
22
|
+
- Rust: OrderStrategy::Breakeven → Python: OrderStrategy.BREAKEVEN (u32: 7)
|
|
23
|
+
- Rust: OrderStrategy::TimeoutExit → Python: OrderStrategy.TIMEOUT_EXIT (u32: 8)
|
|
24
|
+
|
|
25
|
+
Entry Strategies:
|
|
26
|
+
IMMEDIATE_ENTRY: Immediate entry on signal (required for Base Blueprint)
|
|
27
|
+
FAVORABLE_DELAY_ENTRY: Wait for favorable price (pullback/retracement)
|
|
28
|
+
ADVERSE_DELAY_ENTRY: Wait for breakout/aggressive entry
|
|
29
|
+
|
|
30
|
+
Exit Strategies:
|
|
31
|
+
IMMEDIATE_EXIT: Immediate exit on signal (required for Base Blueprint)
|
|
32
|
+
STOP_LOSS: Fixed stop loss
|
|
33
|
+
TAKE_PROFIT: Fixed take profit
|
|
34
|
+
TRAILING_STOP: Dynamic trailing stop
|
|
35
|
+
BREAKEVEN: Move stop to breakeven after profit
|
|
36
|
+
TIMEOUT_EXIT: Exit after time limit
|
|
37
|
+
"""
|
|
38
|
+
|
|
39
|
+
IMMEDIATE_ENTRY = "ImmediateEntry"
|
|
40
|
+
FAVORABLE_DELAY_ENTRY = "FavorableDelayEntry"
|
|
41
|
+
ADVERSE_DELAY_ENTRY = "AdverseDelayEntry"
|
|
42
|
+
IMMEDIATE_EXIT = "ImmediateExit"
|
|
43
|
+
STOP_LOSS = "StopLoss"
|
|
44
|
+
TAKE_PROFIT = "TakeProfit"
|
|
45
|
+
TRAILING_STOP = "TrailingStop"
|
|
46
|
+
BREAKEVEN = "Breakeven"
|
|
47
|
+
TIMEOUT_EXIT = "TimeoutExit"
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"""Orderbook event type enum for event sourcing."""
|
|
2
|
+
|
|
3
|
+
from enum import IntEnum
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class OrderbookEventType(IntEnum):
|
|
7
|
+
"""Orderbook event type (aligned with Rust #[repr(i16)]).
|
|
8
|
+
|
|
9
|
+
Represents events in the order lifecycle for event sourcing.
|
|
10
|
+
Stored as SMALLINT in PostgreSQL.
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
ORDER_CREATED = 0
|
|
14
|
+
"""Order created and submitted to broker."""
|
|
15
|
+
|
|
16
|
+
ORDER_MODIFIED = 1
|
|
17
|
+
"""Order modified (price, quantity, etc.)."""
|
|
18
|
+
|
|
19
|
+
ORDER_CANCELLED = 2
|
|
20
|
+
"""Order cancelled by user or system."""
|
|
21
|
+
|
|
22
|
+
PARTIAL_FILL = 3
|
|
23
|
+
"""Order partially filled."""
|
|
24
|
+
|
|
25
|
+
FULLY_FILLED = 4
|
|
26
|
+
"""Order fully filled."""
|
|
27
|
+
|
|
28
|
+
REJECTED = 5
|
|
29
|
+
"""Order rejected by broker."""
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"""
|
|
2
|
+
PersistMode enum for export task persistence options.
|
|
3
|
+
|
|
4
|
+
Determines where backtest results are stored:
|
|
5
|
+
- REDIS: Default, stores Parquet in Redis (7-day TTL)
|
|
6
|
+
- PSQL: Dual-write to Redis + PostgreSQL trades table
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from enum import IntEnum
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class PersistMode(IntEnum):
|
|
13
|
+
"""Persistence mode for backtest results.
|
|
14
|
+
|
|
15
|
+
Used in ExportRequest to control where Worker stores trades data.
|
|
16
|
+
|
|
17
|
+
Values:
|
|
18
|
+
REDIS (0): Store only in Redis (Parquet format, default)
|
|
19
|
+
PSQL (1): Dual-write to Redis (Parquet) + PostgreSQL (trades table)
|
|
20
|
+
|
|
21
|
+
Examples:
|
|
22
|
+
>>> from tradepose_models.enums import PersistMode
|
|
23
|
+
>>> mode = PersistMode.REDIS # Default
|
|
24
|
+
>>> mode = PersistMode.PSQL # Persist to PostgreSQL
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
REDIS = 0 # Default: Redis only (Parquet)
|
|
28
|
+
PSQL = 1 # Dual-write: Redis + PostgreSQL trades table
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"""Redis Stream name enums."""
|
|
2
|
+
|
|
3
|
+
from enum import Enum
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class RedisStream(str, Enum):
|
|
7
|
+
"""Redis Stream names used across the platform."""
|
|
8
|
+
|
|
9
|
+
BACKTEST_TASKS = "backtest:tasks"
|
|
10
|
+
DATAFEED_TASKS = "datafeed:tasks"
|
|
11
|
+
TRADER_COMMANDS = (
|
|
12
|
+
"trader:commands" # Base, actual format: trader:commands:{user_id}:{node_seq}:{slot_idx}
|
|
13
|
+
)
|
|
14
|
+
ORDER_EVENTS = "order:events" # Base, actual format: order:events:{user_id}:{account_id}
|