tradepose-client 0.1.0__py3-none-any.whl → 0.1.2__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.
Potentially problematic release.
This version of tradepose-client might be problematic. Click here for more details.
- tradepose_client/__init__.py +24 -4
- tradepose_client/builder/__init__.py +22 -0
- tradepose_client/builder/blueprint_builder.py +276 -0
- tradepose_client/builder/indicator_wrapper.py +126 -0
- tradepose_client/builder/strategy_builder.py +312 -0
- tradepose_client/builder/trading_context.py +140 -0
- tradepose_client/enums.py +176 -0
- tradepose_client/indicator_models.py +300 -0
- tradepose_client/models.py +266 -261
- {tradepose_client-0.1.0.dist-info → tradepose_client-0.1.2.dist-info}/METADATA +1 -1
- tradepose_client-0.1.2.dist-info/RECORD +22 -0
- tradepose_client-0.1.0.dist-info/RECORD +0 -15
- {tradepose_client-0.1.0.dist-info → tradepose_client-0.1.2.dist-info}/WHEEL +0 -0
- {tradepose_client-0.1.0.dist-info → tradepose_client-0.1.2.dist-info}/licenses/LICENSE +0 -0
tradepose_client/__init__.py
CHANGED
|
@@ -19,14 +19,25 @@ from .models import (
|
|
|
19
19
|
Blueprint,
|
|
20
20
|
Trigger,
|
|
21
21
|
IndicatorSpec,
|
|
22
|
-
Freq,
|
|
23
|
-
OrderStrategy,
|
|
24
22
|
Indicator,
|
|
25
23
|
create_trigger,
|
|
26
24
|
create_blueprint,
|
|
27
25
|
create_indicator_spec,
|
|
28
26
|
parse_strategy,
|
|
29
27
|
)
|
|
28
|
+
from .enums import (
|
|
29
|
+
Freq,
|
|
30
|
+
OrderStrategy,
|
|
31
|
+
TradeDirection,
|
|
32
|
+
TrendType,
|
|
33
|
+
Weekday,
|
|
34
|
+
IndicatorType,
|
|
35
|
+
)
|
|
36
|
+
from .builder import (
|
|
37
|
+
TradingContext,
|
|
38
|
+
BlueprintBuilder,
|
|
39
|
+
StrategyBuilder,
|
|
40
|
+
)
|
|
30
41
|
from .schema import (
|
|
31
42
|
enhanced_ohlcv_schema,
|
|
32
43
|
trades_schema,
|
|
@@ -68,13 +79,22 @@ __all__ = [
|
|
|
68
79
|
"Blueprint",
|
|
69
80
|
"Trigger",
|
|
70
81
|
"IndicatorSpec",
|
|
71
|
-
"Freq",
|
|
72
|
-
"OrderStrategy",
|
|
73
82
|
"Indicator",
|
|
74
83
|
"create_trigger",
|
|
75
84
|
"create_blueprint",
|
|
76
85
|
"create_indicator_spec",
|
|
77
86
|
"parse_strategy",
|
|
87
|
+
# Enums
|
|
88
|
+
"Freq",
|
|
89
|
+
"OrderStrategy",
|
|
90
|
+
"TradeDirection",
|
|
91
|
+
"TrendType",
|
|
92
|
+
"Weekday",
|
|
93
|
+
"IndicatorType",
|
|
94
|
+
# Builder API (New)
|
|
95
|
+
"TradingContext",
|
|
96
|
+
"BlueprintBuilder",
|
|
97
|
+
"StrategyBuilder",
|
|
78
98
|
# Schema
|
|
79
99
|
"enhanced_ohlcv_schema",
|
|
80
100
|
"trades_schema",
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"""Strategy Builder API
|
|
2
|
+
|
|
3
|
+
Provides a more concise and user-friendly strategy building interface.
|
|
4
|
+
|
|
5
|
+
Core classes:
|
|
6
|
+
- TradingContext: Trading Context fixed field accessor
|
|
7
|
+
- IndicatorSpecWrapper: Indicator wrapper (.col(), .display_name)
|
|
8
|
+
- BlueprintBuilder: Blueprint builder with chain calls
|
|
9
|
+
- StrategyBuilder: Strategy builder (main entry)
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
from .trading_context import TradingContext
|
|
13
|
+
from .indicator_wrapper import IndicatorSpecWrapper
|
|
14
|
+
from .blueprint_builder import BlueprintBuilder
|
|
15
|
+
from .strategy_builder import StrategyBuilder
|
|
16
|
+
|
|
17
|
+
__all__ = [
|
|
18
|
+
"TradingContext",
|
|
19
|
+
"IndicatorSpecWrapper",
|
|
20
|
+
"BlueprintBuilder",
|
|
21
|
+
"StrategyBuilder",
|
|
22
|
+
]
|
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Blueprint 链式构建器
|
|
3
|
+
|
|
4
|
+
支持链式添加 entry/exit triggers,最后通过 .build() 返回 BlueprintConfig。
|
|
5
|
+
|
|
6
|
+
Usage:
|
|
7
|
+
from tradepose_client.builder import BlueprintBuilder, TradingContext
|
|
8
|
+
import polars as pl
|
|
9
|
+
|
|
10
|
+
# 创建 Base Blueprint
|
|
11
|
+
base_bp = BlueprintBuilder(
|
|
12
|
+
name="base_trend",
|
|
13
|
+
direction="Long",
|
|
14
|
+
trend_type="Trend",
|
|
15
|
+
note="基础趋势策略"
|
|
16
|
+
).add_entry_trigger(
|
|
17
|
+
name="entry",
|
|
18
|
+
conditions=[pl.col("ema_20") > pl.col("ema_50")],
|
|
19
|
+
price_expr=pl.col("open"),
|
|
20
|
+
order_strategy="ImmediateEntry",
|
|
21
|
+
priority=1,
|
|
22
|
+
note="EMA 金叉"
|
|
23
|
+
).add_exit_trigger(
|
|
24
|
+
name="exit",
|
|
25
|
+
conditions=[pl.col("ema_20") < pl.col("ema_50")],
|
|
26
|
+
price_expr=pl.col("open"),
|
|
27
|
+
order_strategy="ImmediateExit",
|
|
28
|
+
priority=1,
|
|
29
|
+
note="EMA 死叉"
|
|
30
|
+
).build()
|
|
31
|
+
|
|
32
|
+
# 创建 Advanced Blueprint
|
|
33
|
+
adv_bp = BlueprintBuilder("risk_mgmt", "Long", "Trend")\
|
|
34
|
+
.add_exit_trigger(
|
|
35
|
+
name="stop_loss",
|
|
36
|
+
conditions=[],
|
|
37
|
+
price_expr=TradingContext.advanced_entry.entry_price - pl.col("atr") * 2,
|
|
38
|
+
order_strategy="StopLoss",
|
|
39
|
+
priority=1
|
|
40
|
+
)\
|
|
41
|
+
.add_exit_trigger(
|
|
42
|
+
name="take_profit",
|
|
43
|
+
conditions=[],
|
|
44
|
+
price_expr=TradingContext.advanced_entry.entry_price + pl.col("atr") * 3,
|
|
45
|
+
order_strategy="TakeProfit",
|
|
46
|
+
priority=2
|
|
47
|
+
)\
|
|
48
|
+
.build()
|
|
49
|
+
"""
|
|
50
|
+
|
|
51
|
+
import polars as pl
|
|
52
|
+
from typing import List, Literal, Optional, Union, TYPE_CHECKING
|
|
53
|
+
|
|
54
|
+
if TYPE_CHECKING:
|
|
55
|
+
from tradepose_client.models import Blueprint, Trigger, OrderStrategy
|
|
56
|
+
from tradepose_client.enums import TradeDirection, TrendType
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
class BlueprintBuilder:
|
|
60
|
+
"""
|
|
61
|
+
Blueprint 链式构建器
|
|
62
|
+
|
|
63
|
+
支持链式添加 entry/exit triggers,提供流畅的 API 体验。
|
|
64
|
+
|
|
65
|
+
Attributes:
|
|
66
|
+
name (str): Blueprint 名称
|
|
67
|
+
direction (str): 交易方向("Long", "Short", "Both")
|
|
68
|
+
trend_type (str): 趋势类型("Trend", "Range", "Reversal")
|
|
69
|
+
entry_first (bool): 是否必须先进场才能出场
|
|
70
|
+
note (str): 备注
|
|
71
|
+
|
|
72
|
+
Methods:
|
|
73
|
+
add_entry_trigger(...) -> BlueprintBuilder: 添加进场触发器(链式)
|
|
74
|
+
add_exit_trigger(...) -> BlueprintBuilder: 添加出场触发器(链式)
|
|
75
|
+
build() -> Blueprint: 构建最终 Blueprint 对象
|
|
76
|
+
"""
|
|
77
|
+
|
|
78
|
+
def __init__(
|
|
79
|
+
self,
|
|
80
|
+
name: str,
|
|
81
|
+
direction: Union["TradeDirection", str],
|
|
82
|
+
trend_type: Union["TrendType", str] = "Trend",
|
|
83
|
+
entry_first: bool = True,
|
|
84
|
+
note: str = "",
|
|
85
|
+
):
|
|
86
|
+
"""
|
|
87
|
+
初始化 Blueprint 构建器
|
|
88
|
+
|
|
89
|
+
Args:
|
|
90
|
+
name: Blueprint 名称(唯一标识)
|
|
91
|
+
direction: 交易方向
|
|
92
|
+
- "Long": 做多
|
|
93
|
+
- "Short": 做空
|
|
94
|
+
- "Both": 双向(暂不支持)
|
|
95
|
+
trend_type: 趋势类型
|
|
96
|
+
- "Trend": 趋势跟随
|
|
97
|
+
- "Range": 区间震荡
|
|
98
|
+
- "Reversal": 反转交易
|
|
99
|
+
entry_first: 是否必须先进场才能出场(推荐 True)
|
|
100
|
+
note: Blueprint 说明
|
|
101
|
+
|
|
102
|
+
Examples:
|
|
103
|
+
>>> # Base Blueprint(简洁形式)
|
|
104
|
+
>>> bp = BlueprintBuilder("base", "Long", "Trend")
|
|
105
|
+
>>>
|
|
106
|
+
>>> # Advanced Blueprint(完整形式)
|
|
107
|
+
>>> adv_bp = BlueprintBuilder(
|
|
108
|
+
... name="risk_management",
|
|
109
|
+
... direction="Long",
|
|
110
|
+
... trend_type="Trend",
|
|
111
|
+
... entry_first=True,
|
|
112
|
+
... note="Stop Loss + Take Profit"
|
|
113
|
+
... )
|
|
114
|
+
"""
|
|
115
|
+
self.name = name
|
|
116
|
+
self.direction = direction
|
|
117
|
+
self.trend_type = trend_type
|
|
118
|
+
self.entry_first = entry_first
|
|
119
|
+
self.note = note
|
|
120
|
+
|
|
121
|
+
self._entry_triggers: List["Trigger"] = []
|
|
122
|
+
self._exit_triggers: List["Trigger"] = []
|
|
123
|
+
|
|
124
|
+
def add_entry_trigger(
|
|
125
|
+
self,
|
|
126
|
+
name: str,
|
|
127
|
+
conditions: List[pl.Expr],
|
|
128
|
+
price_expr: pl.Expr,
|
|
129
|
+
order_strategy: Union["OrderStrategy", str],
|
|
130
|
+
priority: int,
|
|
131
|
+
note: str = "",
|
|
132
|
+
) -> "BlueprintBuilder":
|
|
133
|
+
"""
|
|
134
|
+
添加进场触发器(链式调用)
|
|
135
|
+
|
|
136
|
+
Args:
|
|
137
|
+
name: 触发器名称(唯一标识)
|
|
138
|
+
conditions: 条件表达式列表(全部为 True 才触发)
|
|
139
|
+
price_expr: 价格表达式(Polars Expr)
|
|
140
|
+
order_strategy: 订单策略
|
|
141
|
+
- Base Blueprint 必须使用 "ImmediateEntry"
|
|
142
|
+
- Advanced Blueprint 可使用 "FavorableDelayEntry", "AdverseDelayEntry" 等
|
|
143
|
+
priority: 优先级(1-100,越小优先级越高)
|
|
144
|
+
note: 触发器说明
|
|
145
|
+
|
|
146
|
+
Returns:
|
|
147
|
+
BlueprintBuilder: 返回自身,支持链式调用
|
|
148
|
+
|
|
149
|
+
Examples:
|
|
150
|
+
>>> bp = BlueprintBuilder("base", "Long", "Trend")\
|
|
151
|
+
... .add_entry_trigger(
|
|
152
|
+
... name="entry",
|
|
153
|
+
... conditions=[pl.col("ema_20") > pl.col("ema_50")],
|
|
154
|
+
... price_expr=pl.col("open"),
|
|
155
|
+
... order_strategy="ImmediateEntry",
|
|
156
|
+
... priority=1,
|
|
157
|
+
... note="EMA 金叉"
|
|
158
|
+
... )
|
|
159
|
+
"""
|
|
160
|
+
from tradepose_client.models import create_trigger
|
|
161
|
+
|
|
162
|
+
trigger = create_trigger(
|
|
163
|
+
name=name,
|
|
164
|
+
conditions=conditions,
|
|
165
|
+
price_expr=price_expr,
|
|
166
|
+
order_strategy=order_strategy,
|
|
167
|
+
priority=priority,
|
|
168
|
+
note=note,
|
|
169
|
+
)
|
|
170
|
+
self._entry_triggers.append(trigger)
|
|
171
|
+
return self
|
|
172
|
+
|
|
173
|
+
def add_exit_trigger(
|
|
174
|
+
self,
|
|
175
|
+
name: str,
|
|
176
|
+
conditions: List[pl.Expr],
|
|
177
|
+
price_expr: pl.Expr,
|
|
178
|
+
order_strategy: Union["OrderStrategy", str],
|
|
179
|
+
priority: int,
|
|
180
|
+
note: str = "",
|
|
181
|
+
) -> "BlueprintBuilder":
|
|
182
|
+
"""
|
|
183
|
+
添加出场触发器(链式调用)
|
|
184
|
+
|
|
185
|
+
Args:
|
|
186
|
+
name: 触发器名称(唯一标识)
|
|
187
|
+
conditions: 条件表达式列表(全部为 True 才触发)
|
|
188
|
+
price_expr: 价格表达式(Polars Expr)
|
|
189
|
+
order_strategy: 订单策略
|
|
190
|
+
- Base Blueprint 必须使用 "ImmediateExit"
|
|
191
|
+
- Advanced Blueprint 可使用 "StopLoss", "TakeProfit", "TrailingStop",
|
|
192
|
+
"Breakeven", "TimeoutExit" 等
|
|
193
|
+
priority: 优先级(1-100,越小优先级越高)
|
|
194
|
+
note: 触发器说明
|
|
195
|
+
|
|
196
|
+
Returns:
|
|
197
|
+
BlueprintBuilder: 返回自身,支持链式调用
|
|
198
|
+
|
|
199
|
+
Examples:
|
|
200
|
+
>>> bp = BlueprintBuilder("risk_mgmt", "Long", "Trend")\
|
|
201
|
+
... .add_exit_trigger(
|
|
202
|
+
... name="stop_loss",
|
|
203
|
+
... conditions=[],
|
|
204
|
+
... price_expr=TradingContext.advanced_entry.entry_price - pl.col("atr") * 2,
|
|
205
|
+
... order_strategy="StopLoss",
|
|
206
|
+
... priority=1,
|
|
207
|
+
... note="固定止损 2 ATR"
|
|
208
|
+
... )\
|
|
209
|
+
... .add_exit_trigger(
|
|
210
|
+
... name="take_profit",
|
|
211
|
+
... conditions=[],
|
|
212
|
+
... price_expr=TradingContext.advanced_entry.entry_price + pl.col("atr") * 3,
|
|
213
|
+
... order_strategy="TakeProfit",
|
|
214
|
+
... priority=2,
|
|
215
|
+
... note="目标止盈 3 ATR"
|
|
216
|
+
... )
|
|
217
|
+
"""
|
|
218
|
+
from tradepose_client.models import create_trigger
|
|
219
|
+
|
|
220
|
+
trigger = create_trigger(
|
|
221
|
+
name=name,
|
|
222
|
+
conditions=conditions,
|
|
223
|
+
price_expr=price_expr,
|
|
224
|
+
order_strategy=order_strategy,
|
|
225
|
+
priority=priority,
|
|
226
|
+
note=note,
|
|
227
|
+
)
|
|
228
|
+
self._exit_triggers.append(trigger)
|
|
229
|
+
return self
|
|
230
|
+
|
|
231
|
+
def build(self) -> "Blueprint":
|
|
232
|
+
"""
|
|
233
|
+
构建最终 Blueprint 对象
|
|
234
|
+
|
|
235
|
+
Returns:
|
|
236
|
+
Blueprint: 完整的 Blueprint 配置对象
|
|
237
|
+
|
|
238
|
+
Raises:
|
|
239
|
+
ValueError: 如果未添加任何 trigger
|
|
240
|
+
|
|
241
|
+
Examples:
|
|
242
|
+
>>> bp = BlueprintBuilder("base", "Long", "Trend")\
|
|
243
|
+
... .add_entry_trigger(...)\
|
|
244
|
+
... .add_exit_trigger(...)\
|
|
245
|
+
... .build()
|
|
246
|
+
>>>
|
|
247
|
+
>>> # 用于 StrategyBuilder
|
|
248
|
+
>>> builder.set_base_blueprint(bp)
|
|
249
|
+
>>> builder.add_advanced_blueprint(adv_bp)
|
|
250
|
+
"""
|
|
251
|
+
from tradepose_client.models import create_blueprint
|
|
252
|
+
|
|
253
|
+
if not self._entry_triggers and not self._exit_triggers:
|
|
254
|
+
raise ValueError(
|
|
255
|
+
f"Blueprint '{self.name}' must have at least one entry or exit trigger. "
|
|
256
|
+
f"Use .add_entry_trigger() or .add_exit_trigger() before calling .build()"
|
|
257
|
+
)
|
|
258
|
+
|
|
259
|
+
return create_blueprint(
|
|
260
|
+
name=self.name,
|
|
261
|
+
direction=self.direction,
|
|
262
|
+
entry_triggers=self._entry_triggers,
|
|
263
|
+
exit_triggers=self._exit_triggers,
|
|
264
|
+
trend_type=self.trend_type,
|
|
265
|
+
entry_first=self.entry_first,
|
|
266
|
+
note=self.note,
|
|
267
|
+
)
|
|
268
|
+
|
|
269
|
+
def __repr__(self) -> str:
|
|
270
|
+
"""字符串表示"""
|
|
271
|
+
return (
|
|
272
|
+
f"BlueprintBuilder(name='{self.name}', "
|
|
273
|
+
f"direction='{self.direction}', "
|
|
274
|
+
f"entry_triggers={len(self._entry_triggers)}, "
|
|
275
|
+
f"exit_triggers={len(self._exit_triggers)})"
|
|
276
|
+
)
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
"""
|
|
2
|
+
IndicatorSpec 包装器
|
|
3
|
+
|
|
4
|
+
提供更便捷的指标访问方式:
|
|
5
|
+
- .col() -> pl.Expr(用于条件表达式)
|
|
6
|
+
- .display_name -> str(用于依赖引用,作为属性访问)
|
|
7
|
+
- .spec -> IndicatorSpec(返回原始对象,用于最终 build)
|
|
8
|
+
|
|
9
|
+
Usage:
|
|
10
|
+
from tradepose_client.builder import StrategyBuilder
|
|
11
|
+
|
|
12
|
+
builder = StrategyBuilder(...)
|
|
13
|
+
atr = builder.add_indicator("atr", period=21, freq="1D", shift=1)
|
|
14
|
+
|
|
15
|
+
# 使用 .col() 在条件表达式中
|
|
16
|
+
condition = atr.col() > 100
|
|
17
|
+
stop_loss_price = entry_price - atr.col() * 2
|
|
18
|
+
|
|
19
|
+
# 使用 .display_name 引用依赖(SuperTrend 引用 ATR)
|
|
20
|
+
st = builder.add_indicator(
|
|
21
|
+
"supertrend",
|
|
22
|
+
multiplier=3.0,
|
|
23
|
+
volatility_column=atr.display_name, # 属性访问
|
|
24
|
+
freq="1D",
|
|
25
|
+
shift=1
|
|
26
|
+
)
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
import polars as pl
|
|
30
|
+
from typing import TYPE_CHECKING
|
|
31
|
+
|
|
32
|
+
if TYPE_CHECKING:
|
|
33
|
+
from tradepose_client.models import IndicatorSpec
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class IndicatorSpecWrapper:
|
|
37
|
+
"""
|
|
38
|
+
IndicatorSpec 包装器
|
|
39
|
+
|
|
40
|
+
封装 IndicatorSpec,提供更便捷的访问方式。
|
|
41
|
+
|
|
42
|
+
Attributes:
|
|
43
|
+
display_name (str): 完整列名(属性访问)
|
|
44
|
+
spec (IndicatorSpec): 原始 IndicatorSpec 对象
|
|
45
|
+
|
|
46
|
+
Methods:
|
|
47
|
+
col() -> pl.Expr: 返回 Polars 表达式
|
|
48
|
+
"""
|
|
49
|
+
|
|
50
|
+
def __init__(self, spec: "IndicatorSpec"):
|
|
51
|
+
"""
|
|
52
|
+
初始化包装器
|
|
53
|
+
|
|
54
|
+
Args:
|
|
55
|
+
spec: IndicatorSpec 对象
|
|
56
|
+
"""
|
|
57
|
+
self._spec = spec
|
|
58
|
+
|
|
59
|
+
def col(self) -> pl.Expr:
|
|
60
|
+
"""
|
|
61
|
+
返回 Polars 表达式
|
|
62
|
+
|
|
63
|
+
用于条件表达式或价格计算。
|
|
64
|
+
|
|
65
|
+
Returns:
|
|
66
|
+
pl.Expr: Polars 列表达式,等价于 pl.col(display_name)
|
|
67
|
+
|
|
68
|
+
Examples:
|
|
69
|
+
>>> atr = builder.add_indicator("atr", period=21, freq="1D", shift=1)
|
|
70
|
+
>>>
|
|
71
|
+
>>> # 在条件中使用
|
|
72
|
+
>>> condition = atr.col() > 100
|
|
73
|
+
>>>
|
|
74
|
+
>>> # 在价格表达式中使用
|
|
75
|
+
>>> stop_loss_price = entry_price - atr.col() * 2
|
|
76
|
+
>>>
|
|
77
|
+
>>> # 访问 struct 字段(如 SuperTrend)
|
|
78
|
+
>>> st = builder.add_indicator("supertrend", ...)
|
|
79
|
+
>>> direction = st.col().struct.field("direction")
|
|
80
|
+
"""
|
|
81
|
+
return self._spec.col()
|
|
82
|
+
|
|
83
|
+
@property
|
|
84
|
+
def display_name(self) -> str:
|
|
85
|
+
"""
|
|
86
|
+
完整列名(属性访问)
|
|
87
|
+
|
|
88
|
+
用于指标依赖引用(如 SuperTrend 引用 ATR 的列名)。
|
|
89
|
+
|
|
90
|
+
Returns:
|
|
91
|
+
str: 完整的列名,格式为 "{instrument_id}_{freq}_{indicator_short_name}"
|
|
92
|
+
|
|
93
|
+
Examples:
|
|
94
|
+
>>> atr = builder.add_indicator("atr", period=21, freq="1D", shift=1)
|
|
95
|
+
>>> print(atr.display_name)
|
|
96
|
+
"US100.cash_M15_FTMO_FUTURE_1D_ATR|21"
|
|
97
|
+
>>>
|
|
98
|
+
>>> # 用于依赖引用
|
|
99
|
+
>>> st = builder.add_indicator(
|
|
100
|
+
... "supertrend",
|
|
101
|
+
... multiplier=3.0,
|
|
102
|
+
... volatility_column=atr.display_name, # 引用 ATR 列名
|
|
103
|
+
... freq="1D",
|
|
104
|
+
... shift=1
|
|
105
|
+
... )
|
|
106
|
+
"""
|
|
107
|
+
return self._spec.display_name()
|
|
108
|
+
|
|
109
|
+
@property
|
|
110
|
+
def spec(self) -> "IndicatorSpec":
|
|
111
|
+
"""
|
|
112
|
+
返回原始 IndicatorSpec 对象
|
|
113
|
+
|
|
114
|
+
用于最终构建 StrategyConfig。
|
|
115
|
+
|
|
116
|
+
Returns:
|
|
117
|
+
IndicatorSpec: 原始指标规范对象
|
|
118
|
+
|
|
119
|
+
Note:
|
|
120
|
+
用户通常不需要直接访问此属性,仅在高级场景下使用。
|
|
121
|
+
"""
|
|
122
|
+
return self._spec
|
|
123
|
+
|
|
124
|
+
def __repr__(self) -> str:
|
|
125
|
+
"""字符串表示"""
|
|
126
|
+
return f"IndicatorSpecWrapper(display_name='{self.display_name}')"
|