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,633 @@
1
+ Metadata-Version: 2.4
2
+ Name: tradepose-models
3
+ Version: 1.1.0
4
+ Summary: Shared Pydantic models for TradePose platform
5
+ Author-email: TradePose Team <codeotter0201@gmail.com>
6
+ License: MIT
7
+ Keywords: models,pydantic,trading
8
+ Classifier: Development Status :: 4 - Beta
9
+ Classifier: Intended Audience :: Developers
10
+ Classifier: License :: OSI Approved :: MIT License
11
+ Classifier: Operating System :: OS Independent
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Programming Language :: Python :: 3.13
14
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
15
+ Requires-Python: >=3.13
16
+ Requires-Dist: polars
17
+ Requires-Dist: pydantic>=2.12.1
18
+ Description-Content-Type: text/markdown
19
+
20
+ # TradePose Models
21
+
22
+ Shared Pydantic models, enums, and schemas for the TradePose quantitative trading platform.
23
+
24
+ ## What is this?
25
+
26
+ Core data models shared across all TradePose packages (gateway, client, workers). Provides:
27
+
28
+ - **Strategy Configuration** - Complete strategy definition with blueprints and triggers
29
+ - **Registry & Portfolio** - Multi-strategy management with unique key indexing
30
+ - **Enumerations** - Type-safe enums for frequencies, directions, platforms
31
+ - **Polars Schemas** - DataFrame schemas for trades, performance, OHLCV
32
+ - **Type Safety** - Full Pydantic validation with IDE autocomplete
33
+
34
+ ## Installation
35
+
36
+ ```bash
37
+ pip install tradepose-models
38
+ ```
39
+
40
+ **Requirements:**
41
+ - Python 3.13+
42
+ - Dependencies: pydantic, polars
43
+
44
+ ---
45
+
46
+ ## Quick Start
47
+
48
+ ### Strategy Configuration
49
+
50
+ ```python
51
+ from tradepose_models.strategy import (
52
+ StrategyConfig,
53
+ Blueprint,
54
+ Trigger,
55
+ IndicatorSpec,
56
+ )
57
+ from tradepose_models.enums import (
58
+ Freq,
59
+ TradeDirection,
60
+ TrendType,
61
+ OrderStrategy,
62
+ )
63
+ from tradepose_models.indicators import Indicator
64
+ import polars as pl
65
+
66
+ # Create indicator
67
+ atr_spec = IndicatorSpec(
68
+ freq=Freq.DAY_1,
69
+ shift=1,
70
+ indicator=Indicator.atr(period=14),
71
+ )
72
+
73
+ # Create trigger
74
+ entry_trigger = Trigger(
75
+ name="breakout_entry",
76
+ order_strategy=OrderStrategy.IMMEDIATE_ENTRY,
77
+ priority=1,
78
+ conditions=[pl.col("close") > pl.col("high").shift(1)],
79
+ price_expr=pl.col("close"),
80
+ )
81
+
82
+ # Create blueprint
83
+ blueprint = Blueprint(
84
+ name="trend_long",
85
+ direction=TradeDirection.LONG,
86
+ trend_type=TrendType.TREND,
87
+ entry_first=True,
88
+ entry_triggers=[entry_trigger],
89
+ exit_triggers=[...],
90
+ )
91
+
92
+ # Create strategy
93
+ strategy = StrategyConfig(
94
+ name="ES_Breakout",
95
+ base_instrument="ES",
96
+ base_freq=Freq.MIN_15,
97
+ note="E-mini S&P breakout strategy",
98
+ indicators=[atr_spec],
99
+ base_blueprint=blueprint,
100
+ )
101
+
102
+ # Save/Load
103
+ strategy.save("strategy.json")
104
+ loaded = StrategyConfig.load("strategy.json")
105
+ ```
106
+
107
+ ### Strategy Registry
108
+
109
+ Manage multiple strategies with `(strategy_name, blueprint_name)` unique keys:
110
+
111
+ ```python
112
+ from tradepose_models.strategy import StrategyRegistry, StrategyConfig
113
+
114
+ # Create registry
115
+ registry = StrategyRegistry()
116
+
117
+ # Add strategy (auto-splits blueprints into separate entries)
118
+ strategy = StrategyConfig.load("multi_blueprint_strategy.json")
119
+ keys = registry.add(strategy)
120
+ # keys = [(BlueprintSelection("MyStrategy", "long_bp"), BlueprintSelection("MyStrategy", "short_bp")]
121
+
122
+ # Access entries
123
+ entry = registry.get("MyStrategy", "long_bp")
124
+ print(entry.blueprint.direction) # TradeDirection.LONG
125
+
126
+ # Get all configs for backtesting
127
+ configs = registry.get_configs() # List[StrategyConfig] with single blueprints
128
+ ```
129
+
130
+ ### Portfolio Selection
131
+
132
+ Create portfolios by selecting from registry:
133
+
134
+ ```python
135
+ from tradepose_models.strategy import StrategyRegistry
136
+
137
+ registry = StrategyRegistry()
138
+ registry.add(strategy1) # 2 blueprints
139
+ registry.add(strategy2) # 3 blueprints
140
+
141
+ # Create portfolio (selection view)
142
+ portfolio = registry.select(
143
+ name="Q1_Momentum",
144
+ selections=[
145
+ ("Strategy1", "momentum_long"),
146
+ ("Strategy1", "momentum_short"),
147
+ ("Strategy2", "trend_follow"),
148
+ ],
149
+ capital=100000,
150
+ currency="USD",
151
+ platform="MT5",
152
+ )
153
+
154
+ # Get configs for BatchTester
155
+ configs = portfolio.get_configs(registry)
156
+
157
+ # Use with BatchTester
158
+ from tradepose_client import BatchTester
159
+ from tradepose_client.batch import Period
160
+
161
+ tester = BatchTester(api_key="tp_xxx")
162
+ batch = tester.submit(strategies=configs, periods=[Period.Q1(2024)])
163
+ batch.wait()
164
+ ```
165
+
166
+ ---
167
+
168
+ ## Core Concepts
169
+
170
+ ### Strategy Hierarchy
171
+
172
+ ```
173
+ StrategyConfig
174
+ ├── name, base_instrument, base_freq
175
+ ├── indicators: List[IndicatorSpec]
176
+ ├── base_blueprint: Blueprint
177
+ │ ├── name, direction, trend_type
178
+ │ ├── entry_triggers: List[Trigger]
179
+ │ │ └── conditions: List[pl.Expr], price_expr: pl.Expr
180
+ │ └── exit_triggers: List[Trigger]
181
+ └── advanced_blueprints: List[Blueprint]
182
+ ```
183
+
184
+ ### Registry & Portfolio
185
+
186
+ ```
187
+ StrategyRegistry (storage, guarantees uniqueness)
188
+
189
+ │ Key: (strategy_name, blueprint_name)
190
+
191
+ ├── add(config) → auto-split blueprints
192
+ ├── get(name, bp) → RegistryEntry
193
+ ├── get_configs() → List[StrategyConfig] ──> for BatchTester
194
+ └── select(...) → Portfolio
195
+
196
+
197
+ Portfolio (selection view)
198
+ ├── selections: List[(name, bp)]
199
+ ├── capital, currency, platform
200
+ └── get_configs(registry) → configs
201
+ ```
202
+
203
+ ---
204
+
205
+ ## API Reference
206
+
207
+ ### Enumerations
208
+
209
+ #### Freq (Time Frequency)
210
+ ```python
211
+ from tradepose_models.enums import Freq
212
+
213
+ Freq.MIN_1 # "1min"
214
+ Freq.MIN_5 # "5min"
215
+ Freq.MIN_15 # "15min"
216
+ Freq.MIN_30 # "30min"
217
+ Freq.HOUR_1 # "1h"
218
+ Freq.HOUR_4 # "4h"
219
+ Freq.DAY_1 # "1D"
220
+ Freq.WEEK_1 # "1W"
221
+ Freq.MONTH_1 # "1M"
222
+ ```
223
+
224
+ #### TradeDirection
225
+ ```python
226
+ from tradepose_models.enums import TradeDirection
227
+
228
+ TradeDirection.LONG # Long trades only
229
+ TradeDirection.SHORT # Short trades only
230
+ TradeDirection.BOTH # Both directions
231
+ ```
232
+
233
+ #### TrendType
234
+ ```python
235
+ from tradepose_models.enums import TrendType
236
+
237
+ TrendType.TREND # Trend-following
238
+ TrendType.RANGE # Mean-reversion
239
+ TrendType.REVERSAL # Counter-trend
240
+ ```
241
+
242
+ #### OrderStrategy
243
+ ```python
244
+ from tradepose_models.enums import OrderStrategy
245
+
246
+ # Entry
247
+ OrderStrategy.IMMEDIATE_ENTRY # Execute immediately
248
+ OrderStrategy.FAVORABLE_DELAY_ENTRY # Wait for pullback
249
+ OrderStrategy.ADVERSE_DELAY_ENTRY # Wait for breakout
250
+
251
+ # Exit
252
+ OrderStrategy.IMMEDIATE_EXIT # Exit immediately
253
+ OrderStrategy.STOP_LOSS # Fixed stop loss
254
+ OrderStrategy.TAKE_PROFIT # Fixed profit target
255
+ OrderStrategy.TRAILING_STOP # Dynamic trailing
256
+ OrderStrategy.BREAKEVEN # Move to breakeven
257
+ OrderStrategy.TIMEOUT_EXIT # Time-based exit
258
+ ```
259
+
260
+ #### Currency
261
+ ```python
262
+ from tradepose_models.enums import Currency
263
+
264
+ Currency.USD, Currency.USDT, Currency.TWD
265
+ Currency.EUR, Currency.JPY
266
+ Currency.BTC, Currency.ETH
267
+ Currency.XAU, Currency.TAIEX
268
+ ```
269
+
270
+ #### Platform
271
+ ```python
272
+ from tradepose_models.enums import Platform
273
+
274
+ Platform.MT5 # MetaTrader 5
275
+ Platform.BINANCE # Binance
276
+ Platform.SHIOAJI # Shioaji (Taiwan)
277
+ Platform.CCXT # CCXT unified
278
+ ```
279
+
280
+ #### AccountSource
281
+ ```python
282
+ from tradepose_models.enums import AccountSource
283
+
284
+ AccountSource.FTMO # tz_offset: 2
285
+ AccountSource.IB # tz_offset: 0
286
+ AccountSource.FIVEPERCENT # tz_offset: 2
287
+ AccountSource.BINANCE # tz_offset: 8
288
+ AccountSource.SHIOAJI # tz_offset: 8
289
+
290
+ # Get timezone offset
291
+ offset = AccountSource.FTMO.tz_offset() # 2
292
+ ```
293
+
294
+ ### Strategy Models
295
+
296
+ #### StrategyConfig
297
+ ```python
298
+ from tradepose_models.strategy import StrategyConfig
299
+
300
+ # Fields
301
+ strategy.name # str: Strategy name
302
+ strategy.base_instrument # str: Trading instrument
303
+ strategy.base_freq # Freq: Base timeframe
304
+ strategy.note # str: Description
305
+ strategy.indicators # List[IndicatorSpec]
306
+ strategy.base_blueprint # Blueprint: Primary blueprint
307
+ strategy.advanced_blueprints # List[Blueprint]: Additional blueprints
308
+
309
+ # Methods
310
+ StrategyConfig.load(path) # Load from JSON file
311
+ strategy.save(path) # Save to JSON file
312
+ strategy.to_json() # Serialize to JSON string
313
+ strategy.to_dict() # Convert to dict
314
+ StrategyConfig.from_api(data) # Parse from API response
315
+ ```
316
+
317
+ #### Blueprint
318
+ ```python
319
+ from tradepose_models.strategy import Blueprint
320
+
321
+ # Fields
322
+ blueprint.name # str: Blueprint name
323
+ blueprint.direction # TradeDirection: LONG/SHORT/BOTH
324
+ blueprint.trend_type # TrendType: TREND/RANGE/REVERSAL
325
+ blueprint.entry_first # bool: Entry signals priority
326
+ blueprint.entry_triggers # List[Trigger]
327
+ blueprint.exit_triggers # List[Trigger]
328
+ ```
329
+
330
+ #### Trigger
331
+ ```python
332
+ from tradepose_models.strategy import Trigger
333
+ import polars as pl
334
+
335
+ trigger = Trigger(
336
+ name="breakout",
337
+ order_strategy=OrderStrategy.IMMEDIATE_ENTRY,
338
+ priority=1,
339
+ conditions=[
340
+ pl.col("close") > pl.col("high").shift(1),
341
+ pl.col("volume") > pl.col("volume").rolling_mean(20),
342
+ ],
343
+ price_expr=pl.col("close"),
344
+ )
345
+
346
+ # Access Polars expressions directly
347
+ expr = trigger.conditions[0] # pl.Expr
348
+ ```
349
+
350
+ #### IndicatorSpec
351
+ ```python
352
+ from tradepose_models.strategy import IndicatorSpec
353
+ from tradepose_models.indicators import Indicator
354
+
355
+ spec = IndicatorSpec(
356
+ freq=Freq.DAY_1,
357
+ shift=1,
358
+ indicator=Indicator.atr(period=14),
359
+ )
360
+
361
+ # Properties
362
+ spec.short_name() # "ATR|14"
363
+ spec.display_name() # "1D_ATR|14_s1"
364
+ spec.col() # pl.col("1D_ATR|14_s1")
365
+ ```
366
+
367
+ ### Registry Models
368
+
369
+ #### StrategyRegistry
370
+ ```python
371
+ from tradepose_models.strategy import StrategyRegistry
372
+
373
+ registry = StrategyRegistry()
374
+
375
+ # Add strategy (auto-splits blueprints)
376
+ keys = registry.add(strategy) # Returns List[BlueprintSelection]
377
+
378
+ # Add or replace
379
+ keys = registry.add_or_replace(strategy)
380
+
381
+ # Get entry
382
+ entry = registry.get("StrategyName", "blueprint_name")
383
+
384
+ # Get original strategy (with all blueprints)
385
+ original = registry.get_strategy("StrategyName")
386
+
387
+ # Get all configs (single-blueprint each)
388
+ configs = registry.get_configs()
389
+
390
+ # Remove strategy
391
+ removed_count = registry.remove("StrategyName")
392
+
393
+ # Create portfolio
394
+ portfolio = registry.select(
395
+ name="MyPortfolio",
396
+ selections=[("Strat1", "bp1"), ("Strat2", "bp2")],
397
+ capital=100000,
398
+ )
399
+
400
+ # Iteration
401
+ for entry in registry:
402
+ print(entry.key)
403
+
404
+ # Membership
405
+ if ("StrategyName", "blueprint") in registry:
406
+ ...
407
+
408
+ # Length
409
+ print(f"Entries: {len(registry)}")
410
+ ```
411
+
412
+ #### Portfolio
413
+ ```python
414
+ from tradepose_models.strategy import Portfolio, BlueprintSelection
415
+
416
+ # Create directly
417
+ portfolio = Portfolio(
418
+ name="Q1_Portfolio",
419
+ selections=[BlueprintSelection(strategy_name="Strat1", blueprint_name="bp1")],
420
+ capital=100000,
421
+ currency="USD",
422
+ account_source="FTMO",
423
+ platform="MT5",
424
+ )
425
+
426
+ # Or via registry.select()
427
+ portfolio = registry.select(...)
428
+
429
+ # Get configs for backtesting
430
+ configs = portfolio.get_configs(registry)
431
+
432
+ # Immutable operations (return new instance)
433
+ new_portfolio = portfolio.add_selection("Strat2", "bp2")
434
+ new_portfolio = portfolio.remove_selection("Strat1", "bp1")
435
+
436
+ # Properties
437
+ portfolio.strategy_names # List[str] unique names
438
+ portfolio.selection_count # int
439
+
440
+ # Serialization
441
+ portfolio.save("portfolio.json")
442
+ loaded = Portfolio.load("portfolio.json")
443
+ portfolio.to_json()
444
+ portfolio.to_dict()
445
+ ```
446
+
447
+ ### Indicators
448
+
449
+ #### Indicator Factory
450
+ ```python
451
+ from tradepose_models.indicators import Indicator
452
+
453
+ # Moving Averages
454
+ Indicator.sma(period=20, column="close")
455
+ Indicator.ema(period=20, column="close")
456
+ Indicator.smma(period=20, column="close")
457
+ Indicator.wma(period=20, column="close")
458
+
459
+ # Volatility
460
+ Indicator.atr(period=14)
461
+ Indicator.atr_quantile(period=14, quantile=0.5, window=252)
462
+ Indicator.bollinger_bands(period=20, num_std=2.0)
463
+
464
+ # Trend
465
+ Indicator.supertrend(multiplier=3.0, volatility_column="ATR|14")
466
+ Indicator.macd(fast=12, slow=26, signal=9)
467
+ Indicator.adx(period=14)
468
+
469
+ # Momentum
470
+ Indicator.rsi(period=14)
471
+ Indicator.cci(period=20)
472
+ Indicator.stochastic(k_period=14, d_period=3)
473
+
474
+ # Volume Profile
475
+ Indicator.market_profile(
476
+ period=30,
477
+ tick_size=0.25,
478
+ value_area_pct=0.70,
479
+ )
480
+
481
+ # Raw OHLCV
482
+ Indicator.raw_ohlcv(column="close")
483
+ ```
484
+
485
+ ---
486
+
487
+ ## Usage Examples
488
+
489
+ ### Multi-Strategy Backtesting
490
+
491
+ ```python
492
+ from tradepose_models.strategy import StrategyConfig, StrategyRegistry
493
+ from tradepose_client import BatchTester
494
+ from tradepose_client.batch import Period
495
+
496
+ # Setup registry
497
+ registry = StrategyRegistry()
498
+
499
+ # Load multiple strategies
500
+ for path in ["strat1.json", "strat2.json", "strat3.json"]:
501
+ strategy = StrategyConfig.load(path)
502
+ registry.add(strategy)
503
+
504
+ print(f"Registry: {len(registry)} entries")
505
+ # Registry: 8 entries (if strategies have multiple blueprints)
506
+
507
+ # Backtest all
508
+ configs = registry.get_configs()
509
+ tester = BatchTester(api_key="tp_xxx")
510
+ batch = tester.submit(
511
+ strategies=configs,
512
+ periods=[Period.Q1(2024), Period.Q2(2024)],
513
+ )
514
+ batch.wait()
515
+ print(batch.summary())
516
+ ```
517
+
518
+ ### Portfolio-Based Testing
519
+
520
+ ```python
521
+ # Create focused portfolio
522
+ momentum_portfolio = registry.select(
523
+ name="Momentum_Suite",
524
+ selections=[
525
+ ("TrendFollower", "momentum_long"),
526
+ ("TrendFollower", "momentum_short"),
527
+ ("BreakoutTrader", "range_breakout"),
528
+ ],
529
+ capital=50000,
530
+ currency="USD",
531
+ )
532
+
533
+ # Test portfolio only
534
+ configs = momentum_portfolio.get_configs(registry)
535
+ batch = tester.submit(strategies=configs, periods=[Period.Q1(2024)])
536
+
537
+ # Save portfolio for later
538
+ momentum_portfolio.save("momentum_portfolio.json")
539
+ ```
540
+
541
+ ### Indicator with Struct Fields
542
+
543
+ ```python
544
+ from tradepose_models.strategy import IndicatorSpec, Trigger
545
+ from tradepose_models.indicators import Indicator
546
+ from tradepose_models.enums import Freq, OrderStrategy
547
+ import polars as pl
548
+
549
+ # SuperTrend returns struct with multiple fields
550
+ supertrend = IndicatorSpec(
551
+ freq=Freq.DAY_1,
552
+ shift=1,
553
+ indicator=Indicator.supertrend(multiplier=3.0, volatility_column="ATR|14"),
554
+ )
555
+
556
+ # Access struct fields in conditions
557
+ trigger = Trigger(
558
+ name="supertrend_long",
559
+ conditions=[
560
+ supertrend.col().struct.field("direction") == 1, # Long signal
561
+ supertrend.col().struct.field("supertrend") < pl.col("close"),
562
+ ],
563
+ price_expr=pl.col("close"),
564
+ order_strategy=OrderStrategy.IMMEDIATE_ENTRY,
565
+ priority=1,
566
+ )
567
+ ```
568
+
569
+ ---
570
+
571
+ ## File Structure
572
+
573
+ ```
574
+ packages/models/src/tradepose_models/
575
+ ├── __init__.py
576
+ ├── base.py # BaseModel configuration
577
+ ├── enums/
578
+ │ ├── __init__.py
579
+ │ ├── freq.py # Time frequencies
580
+ │ ├── trade_direction.py # LONG/SHORT/BOTH
581
+ │ ├── trend_type.py # TREND/RANGE/REVERSAL
582
+ │ ├── order_strategy.py # Entry/exit strategies
583
+ │ ├── currency.py # Currency types
584
+ │ ├── platform.py # Trading platforms
585
+ │ ├── account_source.py # Brokers/prop firms
586
+ │ └── ...
587
+ ├── strategy/
588
+ │ ├── __init__.py
589
+ │ ├── config.py # StrategyConfig
590
+ │ ├── blueprint.py # Blueprint
591
+ │ ├── trigger.py # Trigger
592
+ │ ├── indicator_spec.py # IndicatorSpec
593
+ │ ├── registry.py # StrategyRegistry, RegistryEntry, BlueprintSelection
594
+ │ ├── portfolio.py # Portfolio
595
+ │ └── helpers.py # Factory functions
596
+ ├── indicators/
597
+ │ ├── __init__.py
598
+ │ ├── factory.py # Indicator factory
599
+ │ └── ... # Indicator type definitions
600
+ ├── schemas/
601
+ │ ├── __init__.py
602
+ │ ├── trades.py # Trades schema
603
+ │ ├── performance.py # Performance schema
604
+ │ └── ohlcv.py # OHLCV schema
605
+ └── ...
606
+ ```
607
+
608
+ ---
609
+
610
+ ## Development
611
+
612
+ ### Running Tests
613
+
614
+ ```bash
615
+ # Run models tests
616
+ uv run python -m pytest tests/models/ -v
617
+
618
+ # Run with coverage
619
+ uv run python -m pytest tests/models/ --cov=tradepose_models
620
+ ```
621
+
622
+ ---
623
+
624
+ ## License
625
+
626
+ MIT License - see [LICENSE](../../LICENSE) file for details.
627
+
628
+ ---
629
+
630
+ ## Support
631
+
632
+ - **Documentation**: [docs/](../../docs/)
633
+ - **Issues**: [GitHub Issues](https://github.com/tradepose/tradepose-python/issues)