Skip to content

Commit a50bc3b

Browse files
committed
example cleanup
1 parent e6afd16 commit a50bc3b

13 files changed

+246
-176
lines changed

examples/09_get_check_available_instruments.py

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
from project_x_py.models import Instrument
2727

2828

29-
def display_instrument(instrument: Instrument, prefix: str = ""):
29+
def display_instrument(instrument: Instrument, prefix: str = "") -> None:
3030
"""Display instrument details in a formatted way"""
3131
print(f"{prefix}┌─ Contract Details ─────────────────────────────")
3232
print(f"{prefix}│ ID: {instrument.id}")
@@ -39,7 +39,7 @@ def display_instrument(instrument: Instrument, prefix: str = ""):
3939
print(f"{prefix}└" + "─" * 47)
4040

4141

42-
async def search_and_display(client: ProjectX, symbol: str):
42+
async def search_and_display(client: ProjectX, symbol: str) -> None:
4343
"""Search for instruments and display results asynchronously"""
4444
print(f"\n{'=' * 60}")
4545
print(f"Searching for: '{symbol}'")
@@ -107,13 +107,13 @@ def show_common_symbols():
107107
print("└─────────┴──────────────────────────────────────────┘")
108108

109109

110-
async def get_user_input(prompt):
110+
async def get_user_input(prompt: str) -> str:
111111
"""Get user input"""
112112
loop = asyncio.get_event_loop()
113113
return await loop.run_in_executor(None, input, prompt)
114114

115115

116-
async def run_interactive_search(client):
116+
async def run_interactive_search(client: ProjectX) -> None:
117117
"""Run the interactive search loop."""
118118
show_common_symbols()
119119

@@ -144,7 +144,7 @@ async def run_interactive_search(client):
144144
await search_and_display(client, symbol.upper())
145145

146146

147-
async def main():
147+
async def main() -> None:
148148
"""Main entry point."""
149149
print("╔═══════════════════════════════════════════════════════╗")
150150
print("║ Async ProjectX Instrument Search Interactive Demo ║")
@@ -161,15 +161,16 @@ async def main():
161161
print(f"✓ Using account: {client.account_info.name}")
162162

163163
# Show client performance stats periodically
164-
async def show_stats():
164+
async def show_stats() -> None:
165165
while True:
166166
await asyncio.sleep(60) # Every minute
167167
stats = await client.get_health_status()
168-
if stats["client_stats"]["api_calls"] > 0:
168+
# Using defined PerformanceStatsResponse keys
169+
if stats["api_calls"] > 0:
169170
print(
170-
f"\n[Stats] API calls: {stats['client_stats']['api_calls']}, "
171-
f"Cache hits: {stats['client_stats']['cache_hits']} "
172-
f"({stats['client_stats']['cache_hit_rate']:.1%} hit rate)"
171+
f"\n[Stats] API calls: {stats['api_calls']}, "
172+
f"Cache hits: {stats['cache_hits']} "
173+
f"({(stats['cache_hits'] / max(stats['api_calls'], 1)):.1%} hit rate)"
173174
)
174175

175176
# Run stats display in background

examples/11_simplified_data_access.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
from project_x_py import TradingSuite
2525

2626

27-
async def demonstrate_simplified_access():
27+
async def demonstrate_simplified_access() -> None:
2828
"""Show the new simplified data access methods."""
2929

3030
# Create trading suite with 3 timeframes
@@ -42,7 +42,7 @@ async def demonstrate_simplified_access():
4242

4343
# 2. Get latest price - much cleaner than get_current_price()
4444
price = await suite.data.get_latest_price()
45-
if price:
45+
if price is not None:
4646
print(f"\n📊 Current Price: ${price:,.2f}")
4747

4848
# 3. Get OHLC as a simple dictionary
@@ -110,7 +110,7 @@ async def demonstrate_simplified_access():
110110
print(f" {tf}: ${close:,.2f} (vol: {volume:,.0f})")
111111

112112

113-
async def demonstrate_trading_usage():
113+
async def demonstrate_trading_usage() -> None:
114114
"""Show how simplified access improves trading logic."""
115115

116116
async with await TradingSuite.create("MNQ") as suite:
@@ -126,7 +126,7 @@ async def demonstrate_trading_usage():
126126
range_stats = await suite.data.get_price_range(bars=20)
127127
vol_stats = await suite.data.get_volume_stats(bars=20)
128128

129-
if price and range_stats and vol_stats:
129+
if price is not None and range_stats and vol_stats:
130130
# Example strategy logic
131131
print(f"Current Price: ${price:,.2f}")
132132
print(f"20-bar Range: ${range_stats['range']:,.2f}")
@@ -152,7 +152,7 @@ async def demonstrate_trading_usage():
152152
print(f"Price is {range_position:.1%} within the 20-bar range")
153153

154154

155-
async def main():
155+
async def main() -> None:
156156
"""Run all demonstrations."""
157157
try:
158158
# Show simplified data access

examples/12_simplified_multi_timeframe.py

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,10 @@ class SimplifiedMTFStrategy:
2323
def __init__(self, suite: TradingSuite):
2424
self.suite = suite
2525
self.data = suite.data # Direct access to data manager
26-
self.position_size = 0
27-
self.last_signal_time = None
26+
self.position_size: int = 0
27+
self.last_signal_time: float | None = None
2828

29-
async def analyze_market(self):
29+
async def analyze_market(self) -> dict | None:
3030
"""Analyze market across multiple timeframes."""
3131
# Much cleaner than checking data is None and len(data) < X
3232

@@ -88,7 +88,7 @@ async def analyze_market(self):
8888
"volume_strength": volume_stats["relative"] if volume_stats else 1.0,
8989
}
9090

91-
async def check_entry_conditions(self):
91+
async def check_entry_conditions(self) -> dict | None:
9292
"""Check if all conditions align for entry."""
9393
analysis = await self.analyze_market()
9494
if not analysis:
@@ -133,7 +133,7 @@ async def check_entry_conditions(self):
133133
return None
134134

135135

136-
async def run_simplified_mtf_strategy():
136+
async def run_simplified_mtf_strategy() -> None:
137137
"""Run the simplified multi-timeframe strategy."""
138138

139139
# Create suite with multiple timeframes
@@ -163,12 +163,14 @@ async def run_simplified_mtf_strategy():
163163
ohlc = await suite.data.get_ohlc("15min")
164164

165165
print(f"\n🎯 SIGNAL: {signal['action']}")
166-
print(f" Price: ${price:,.2f}")
166+
if price is not None:
167+
print(f" Price: ${price:,.2f}")
167168
print(f" Confidence: {signal['confidence']:.1%}")
168-
print(
169-
f" 15min Bar: O:{ohlc['open']:,.2f} H:{ohlc['high']:,.2f} "
170-
f"L:{ohlc['low']:,.2f} C:{ohlc['close']:,.2f}"
171-
)
169+
if ohlc is not None:
170+
print(
171+
f" 15min Bar: O:{ohlc['open']:,.2f} H:{ohlc['high']:,.2f} "
172+
f"L:{ohlc['low']:,.2f} C:{ohlc['close']:,.2f}"
173+
)
172174

173175
# Show multi-timeframe alignment
174176
print("\n Timeframe Alignment:")
@@ -205,7 +207,7 @@ async def run_simplified_mtf_strategy():
205207
print("\n\n✅ Strategy demonstration complete!")
206208

207209

208-
async def compare_verbose_vs_simplified():
210+
async def compare_verbose_vs_simplified() -> None:
209211
"""Show the difference between verbose and simplified patterns."""
210212

211213
async with await TradingSuite.create("MNQ") as suite:
@@ -259,11 +261,11 @@ async def compare_verbose_vs_simplified():
259261
# New simplified way
260262
start = time.time()
261263
price = await suite.data.get_latest_price()
262-
if price:
264+
if price is not None:
263265
print(f"Simplified method: ${price:,.2f} (took {time.time() - start:.3f}s)")
264266

265267

266-
async def main():
268+
async def main() -> None:
267269
"""Run all demonstrations."""
268270
try:
269271
# Run simplified multi-timeframe strategy

examples/14_phase4_comprehensive_test.py

Lines changed: 42 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,9 @@ def __init__(self, suite: TradingSuite):
3131
self.profit_target_ticks = 20
3232
self.stop_loss_ticks = 10
3333

34-
async def analyze_market(self) -> dict | None:
34+
async def analyze_market(
35+
self,
36+
) -> dict[str, float | int | str | dict[str, float]] | None:
3537
"""Analyze market using simplified data access."""
3638
# Use new get_data_or_none for cleaner code
3739
data = await self.data.get_data_or_none("5min", min_bars=50)
@@ -47,7 +49,12 @@ async def analyze_market(self) -> dict | None:
4749
price_range = await self.data.get_price_range(bars=20)
4850
volume_stats = await self.data.get_volume_stats(bars=20)
4951

50-
if not all([current_price, ohlc, price_range, volume_stats]):
52+
if (
53+
current_price is None
54+
or ohlc is None
55+
or price_range is None
56+
or volume_stats is None
57+
):
5158
return None
5259

5360
# Analyze trend
@@ -56,21 +63,30 @@ async def analyze_market(self) -> dict | None:
5663
atr = float(data["atr_14"][-1])
5764

5865
# Price position within range
59-
price_position = (current_price - price_range["low"]) / price_range["range"]
66+
price_position = (float(current_price) - float(price_range["low"])) / float(
67+
price_range["range"]
68+
)
6069

6170
return {
62-
"price": current_price,
63-
"trend": "bullish" if current_price > sma20 else "bearish",
64-
"trend_strength": abs(current_price - sma20) / sma20,
71+
"price": float(current_price),
72+
"trend": "bullish" if float(current_price) > sma20 else "bearish",
73+
"trend_strength": abs(float(current_price) - sma20) / sma20,
6574
"rsi": rsi,
6675
"atr": atr,
6776
"price_position": price_position,
68-
"volume_relative": volume_stats["relative"],
69-
"range": price_range["range"],
70-
"ohlc": ohlc,
77+
"volume_relative": float(volume_stats["relative"]),
78+
"range": float(price_range["range"]),
79+
"ohlc": {
80+
"open": float(ohlc["open"]),
81+
"high": float(ohlc["high"]),
82+
"low": float(ohlc["low"]),
83+
"close": float(ohlc["close"]),
84+
},
7185
}
7286

73-
async def check_positions(self) -> dict:
87+
async def check_positions(
88+
self,
89+
) -> dict[str, float | int | list[dict[str, float | int | str]]]:
7490
"""Check positions using enhanced model properties."""
7591
positions = await self.positions.get_all_positions()
7692

@@ -83,7 +99,7 @@ async def check_positions(self) -> dict:
8399
}
84100

85101
current_price = await self.data.get_latest_price()
86-
if not current_price:
102+
if current_price is None:
87103
return position_summary
88104

89105
for pos in positions:
@@ -96,7 +112,7 @@ async def check_positions(self) -> dict:
96112
position_summary["total_exposure"] += pos.total_cost
97113

98114
# Calculate P&L using the unrealized_pnl method
99-
pnl = pos.unrealized_pnl(current_price, tick_value=5.0) # MNQ tick value
115+
pnl = pos.unrealized_pnl(float(current_price), tick_value=5.0)
100116

101117
position_summary["positions"].append(
102118
{
@@ -113,7 +129,9 @@ async def check_positions(self) -> dict:
113129

114130
return position_summary
115131

116-
async def check_orders(self) -> dict:
132+
async def check_orders(
133+
self,
134+
) -> dict[str, float | int | list[dict[str, float | int | str]]]:
117135
"""Check orders using enhanced model properties."""
118136
orders = await self.orders.search_open_orders()
119137

@@ -145,13 +163,17 @@ async def check_orders(self) -> dict:
145163
"size": order.size,
146164
"remaining": order.remaining_size, # New property
147165
"filled_pct": order.filled_percent, # New property
148-
"price": order.limitPrice or order.stopPrice,
166+
"price": float(order.limitPrice)
167+
if order.limitPrice
168+
else float(order.stopPrice)
169+
if order.stopPrice
170+
else 0.0,
149171
}
150172
)
151173

152174
return order_summary
153175

154-
async def execute_strategy(self):
176+
async def execute_strategy(self) -> None:
155177
"""Execute trading strategy using all Phase 4 improvements."""
156178
print("\n=== Strategy Execution ===")
157179

@@ -221,7 +243,9 @@ async def execute_strategy(self):
221243
)
222244
print(f" Reason: {signal['reason']}")
223245

224-
def _generate_signal(self, analysis: dict, positions: dict) -> dict | None:
246+
def _generate_signal(
247+
self, analysis: dict, positions: dict
248+
) -> dict[str, float | str] | None:
225249
"""Generate trading signal based on analysis."""
226250
# No signal if we have max positions
227251
if positions["total_positions"] >= self.max_position_size:
@@ -264,7 +288,7 @@ def _generate_signal(self, analysis: dict, positions: dict) -> dict | None:
264288
return None
265289

266290

267-
async def demonstrate_phase4_improvements():
291+
async def demonstrate_phase4_improvements() -> None:
268292
"""Demonstrate all Phase 4 improvements in action."""
269293

270294
async with await TradingSuite.create(
@@ -365,7 +389,7 @@ async def demonstrate_phase4_improvements():
365389
print("\n✅ Overall: Cleaner, more readable, less error-prone code!")
366390

367391

368-
async def main():
392+
async def main() -> None:
369393
"""Run Phase 4 comprehensive test."""
370394
try:
371395
await demonstrate_phase4_improvements()

0 commit comments

Comments
 (0)