Skip to content

fix: resolve ty type-check failures for get_symbol_price None returns#83

Open
lee101 wants to merge 656 commits into
mainfrom
ci-fix/type-check-82
Open

fix: resolve ty type-check failures for get_symbol_price None returns#83
lee101 wants to merge 656 commits into
mainfrom
ci-fix/type-check-82

Conversation

@lee101

@lee101 lee101 commented Apr 6, 2026

Copy link
Copy Markdown
Owner

Summary

Fixes the failing type-check job in Fast CI (GitHub Runners) for branch 82/merge.

binance_wrapper.get_symbol_price() returns float | None, but was being passed directly to float() — which does not accept None. This caused 4 invalid-argument-type errors from ty.

Changes

In rl_trading_agent_binance/trade_binance_live.py:

  1. _get_market_price (line 674): Explicitly check for None and raise ValueError — all callers are already inside try/except Exception blocks
  2. get_portfolio_state BTC price (line 688): Use or 0.0 default — inside try/except Exception: state.total_value_usd = 0.0
  3. _repay_margin_debt_if_flat (line 1023): Use or 0.0 default — inside try/except Exception: pass
  4. run_trading_cycle cur_price (line 1573): Use or 0.0 default — inside try/except Exception: continue

Tests Run

ty check \
  rl_trading_agent_binance/hybrid_prompt.py \
  rl_trading_agent_binance/trade_binance_live.py \
  evaluate_binance_lora_candidate.py \
  scripts/evaluate_binance_lora_candidate.py \
  trltraining
# Output: All checks passed!

Fixes CI run: https://github.com/lee101/stock-prediction/actions/runs/24054656900

🤖 Generated with Claude Code

lee101 and others added 30 commits March 24, 2026 14:13
crypto70 new CHAMPIONS:
- s33: honest=+229.0% (+1019% ann) NEW #2 overall (behind s19 +439%)
- s32: honest=+194.0% (+791% ann) tied with s123
- s30: honest=+32.8% (+78% ann) genuine
- s27,28,29,31: bad (pool deceptive for s28=1.0)

crypto15 cross-domain s21/s22:
- c15_tp05_s21: +42.3% (+104% ann) GENUINE despite pool=0.014!
- c15_tp03_s21: +25.1% (+58% ann) GENUINE
- c15_tp08_s21: NOT genuine (-13%)
- c15_tp03/05/08_s22: ALL NOT genuine (s22 fails cross-domain)

Checkpoints saved: c70_tp05_slip5_s30, s32, s33

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…4.55)

Mixed23 seed sweep: seed7 val_ret=+1.40 beats seed42 (-0.43) and seed123 (-0.11).
Hyperopt: clip_anneal (-0.09) and wd_05 (-0.30) best of 10 configs.
Crypto29 daily: robust_champion (+0.39) beats all 5 configs.
50-window holdout (30-step): seed7 +6.16% median, 84% positive windows.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
crypto70 new genuine seeds:
- s37: honest=+184.9% (+736% ann) NEW strong seed
- s39: honest=+33.5% (+80% ann) genuine
- s34,s35,s38,s40: bad (pool deceptive: s34 pool=1.71 honest=-4.1%)

crypto15 cross-domain results (all 8bps slippage, 100 eps):
- s26: NOT genuine (tp03=-18%, tp05=-32%) — fails cross-domain
- s8 tp05: +10.3% (+22% ann) genuine (marginal); tp03/tp08 fail
- s32: NOT genuine (tp03=-11%, tp05=-4.5%) despite s32=+194% in crypto70
- s22: NOT genuine (all configs fail)

Cross-domain transfer rule update:
- Extreme seeds (s19 +439%, s33 +229%, s37 +185%) → test in crypto15
- Moderate seeds (s26, s32, s22, s28-s31) → mostly fail cross-domain

Checkpoints saved: c70_tp05_slip5_s37, s39

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
crypto15 NEW BEST: c15_tp03_s33 = +118.5%/180d (+388% ann) at 8bps
- ALL 100 eps positive: p05=+116%, p50=+118.5%, p95=+120%, WR=65.5%
- 58pp better than prev best c15_tp03_s19 (+75.1%)

c15_tp03_s37: +44.9%/180d (+112% ann) genuine
c15_tp05_s37: +25.2%/180d (+58% ann) genuine

crypto70 confirmed s37=+185%, s39=+33.5% genuine
s40,s41,s42,s43: bad (s34 pool=1.71 honest=-4.1% — very deceptive)

Cross-domain insight: s33/s37 (crypto70 top-3) → crypto15 tp03/tp05 both work
Disk cleanup: removed ~90GB old checkpoint dirs (superseded research)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
c15_tp03_s33: +118.5%/180d (+388% ann) with 8bps realistic slippage
ALL 100 episodes positive, p05=+116.2%, WR=65.5%, Sortino=2.85
Beats previous best c15_tp03_s7 by 49pp (69% → 118.5% per 180d)

Checkpoint: pufferlib_market/checkpoints/crypto15_v2/gpu0/c15_tp03_slip5_s33/best.pt
Deploy when Gemini API key is restored.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
crypto70 new champions:
- s47: +238.2% (+1083% ann) NEW #2 (tied with s33 at ~238%)
- s48: +123.6% (+411% ann) STRONG
- s49: +45.2% (+113% ann) genuine
- s44: +91.3%, s45: +102%, s46: +37.1% genuine

crypto15 cross-domain s44/s45:
- c15_tp05_s44: +12.0% GENUINE (weak, pool deceptive: pool=-0.32)
- c15_tp03_s44: -38.1% NOT genuine
- c15_tp03_s45: -68.2% NOT genuine (tp05 still pending)

stocks12: s123 pool val=-0.44 (different from v2_sweep s123! training configs differ)
No new deployable seeds in s88-s124 range.

Checkpoints saved: c70_tp05_slip5_s44-s49

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
CRYPTO15 COMPLETE (61/61 jobs, including all cross-domain tests):
Deployable models found (18 genuine, 8bps slippage):
  c15_tp03_s33: +118.5%/180d (+388% ann) CHAMPION
  c15_tp03_s19: +75.1%/180d (+211% ann)
  c15_tp03_s7:  +69.0%/180d (+190% ann)
  c15_tp05_s21: +42.3%, c15_tp05/tp03_s37, c15_tp08_s19, etc.

Cross-domain transfer failures (despite strong crypto70):
  s44 (+91%): only tp05 works (+12% weak); s47 (+238%): FAILS; s48 (+124%): FAILS
  Pattern: high crypto70 return ≠ guaranteed crypto15 transfer

crypto70 new genuine seeds:
  s50: +94.1% (+284% ann) saved
  s53: +43.2% (+107% ann) saved
  s51,s52: bad

stocks12: s123 pool=-0.44 (config mismatch vs v2_sweep), s125-s129 all bad

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
CRYPTO70 SWEEP COMPLETE:
60 seeds tested, 28 genuine (46% hit rate)

Final top 5:
1. s19: +438.7%/180d (+2941% ann) CHAMPION
2. s47: +238.2%/180d (+1083% ann)
3. s33: +229.0%/180d (+1019% ann)
4. s32: +194.0%/180d (+791% ann)
5. s37: +184.9%/180d (+736% ann)

Final seeds: s59=+27.9% genuine, s55=+112.8% genuine, s58/s56/s57/s60=bad

Crypto15 s55 final:
- c15_tp05_s55: +22.6% (+51% ann) GENUINE (tp03 fails)
- Pattern: only tp05 works for moderate cross-domain seeds

Checkpoints saved: c70_tp05_slip5_s55, s59

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Final findings: 0 new deployable seeds found beyond existing ensemble.
- Seeds 20-150 tested: only s50 (0/50 neg, med=20.07%) was deployable standalone
- s79: 10/50 neg (borderline), s97: 12/50 neg (borderline) -- not deployable
- Seeds 136-150: all below 0.10 val_return threshold, all bad
- Hit rate: ~3/125 = 2.4% for 0/50-neg seeds; only s15/s36 improve the 3-model ensemble

Production ensemble unchanged: s123+s15+s36 (med=47.30%, p10=29.93%, 0/50 neg)
Cleaned up 104 bad checkpoint dirs from tp05_seed_oldcfg (~14GB freed)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Switch RL checkpoint from robust_champion (23sym mixed) to c15_tp03_slip5_s7 (15 crypto symbols)
- Add CRYPTO15_SYMBOLS tuple and obs_size=260 auto-detection to rl_signal.py
- Add missing Binance pair mappings: ADAUSD, ALGOUSD, MATICUSD
- Add 8 new TRADING_SYMBOLS entries: LTC, AVAX, ADA, UNI, ALGO, DOT, SHIB, MATIC
- Update SYMBOL_BINANCE_MAP and ALLOC_FIELDS for all 15 symbols
- Fix Gemini model: gemini-3.1-flash-lite-preview does not exist, use gemini-2.5-flash-lite
- Expand tradable symbols from 6 to 15 in launch.sh

The old robust_champion model had action masking issues: it would output LONG_UNI
but UNI was not tradable, causing all 30 non-FLAT RL signals over 294 cycles to
be silently dropped. The new c15 model's action space matches the tradable set.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
c15 (150d, Jun-Dec 2025):
  daily: +22.4% ret, Sort=2.52, 47 trades, 59.6% WR
  hourly replay: +22.2% ret, Sort=1.35, 31.3% DD
  hourly policy: +16.2% ret, Sort=1.17, 48 max orders/day (thrashing on Jul 9)

robust_champion (150d, Sep 2025-Mar 2026):
  daily: +7.4% ret, Sort=1.42, 26 trades, 50% WR
  hourly replay: +23.4% ret, Sort=0.70, 23.0% DD

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- pufferlib_market/seed_sweep_rl.py: targeted seed sweep runner
  - seeds start/end or explicit list, time budget per seed
  - dataset-aware configs (daily: 500x cap, hourly: 100x cap)
  - resumes from partial leaderboard CSV (skip done seeds)
  - --cuda-graph flag for H100 pods (exclusive GPU, safe)

- pufferlib_market/gpu_pool.py: two new presets
  - crypto70_daily_long_sweep: seeds 1-100, 30-min budget
  - crypto40_hourly_tp05_sweep: seeds 1-60, 30-min budget, max_steps=720

- scripts/launch_runpod_scale.py: parallel H100 pod launcher
  - splits seed range across N pods (parallel training)
  - bootstraps each pod, syncs data, runs sweep, pulls results
  - auto H100 detection → 256 envs + cuda-graph

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Switch default GPU from h100 to a100 (community cloud = direct SSH)
- Wait for all pods in parallel (was sequential, causing 10min+ delays)
- Increase SSH wait timeout from 600s to 1800s (large image pull time)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ound

- Kill newcfg (slip=5/wd=0.01) pool: models incompatible with ensemble (47%→28%)
- Start v2cfg sweep (exact s123 config: tp05/slip=0/wd=0/bf16+cuda_graph), seeds 1-150
- Crypto15 new pool (s50-200): s51=+244% honest, s56=+91% honest, both genuine
- Crypto70 COMPLETE: s53=+107%, s55=+362%, s59=+65% additional genuine seeds (20 total)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
_stocks12_seedsweep and _stocks12_tp05_family had fill_slippage_bps=5.0 and
weight_decay=0.01 which produce models incompatible with the production ensemble
(47.30% → 28.15% when added). s123 uses slip=0, wd=0, bf16=True, cuda_graph=True,
periods_per_year=252. Updated presets and added doc comments.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- pufferlib_market/seed_sweep_rl.py: standalone seed sweep runner supporting
  crypto70_daily, crypto40_daily, crypto40_hourly, crypto34_hourly; resumes
  from partial CSV; respects max_timesteps_per_sample cap per dataset
- scripts/launch_runpod_scale.py: parallel RunPod launcher splitting seed ranges
  across N pods, bootstraps + syncs data, merges leaderboards
- src/runpod_client.py: PodConfig.cloud_type defaults to COMMUNITY (was ALL)
  so pods get public SSH ports; H100/secure can still use cloud_type=SECURE
- pufferlib_market/gpu_pool.py: add crypto70_daily_long_sweep and
  crypto40_hourly_tp05_sweep presets for scale experiments

Note: RunPod community cloud SSH requires cloudType=COMMUNITY; secure cloud
pods (even when desired) never expose SSH ports via the API.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
run_trial returns holdout_median_return_pct etc as top-level result keys,
not nested under result["holdout_metrics"]. Fix the lookup so holdout
columns populate correctly in the sweep CSV.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…esults

- EnsemblePolicy: softmax-avg of N policies, compatible with C sim
- --extra-checkpoints: load additional checkpoints for ensemble eval
- Finding: crypto15 ensemble HURTS (s33+s51: 118%→-20%); keep s33 solo
- crypto15 tp03 s50-200: 4 genuine (s51=+244%, s56=+91%, s62=+32%, s63=+31%)
- stocks12 v2cfg sweep: 11/145 seeds, all below 0.05 threshold so far
- stocks12 v2cfg ent08 sweep started (96 seeds, ent_coef=0.08)
- crypto12 hourly autoresearch killed (12/20 configs, all terrible holdout)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Added a brief description and recommendation for using the stats dashboard and API.
- Beats previous champion s33 (+118.5%) by 23pp median
- 100/100 positive episodes, Sortino=4.52 vs s33's 2.85
- Even worst episode (+138.86%) beats s33's median
- Pool: 29/151 seeds done, 7 genuine models found (24% rate)
- Update prod.md pending deploy checkpoint to s78

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- crypto70 long sweep s63: genuine at +187% per 180d (+349% ann), ★★★★
  (doesn't transfer to crypto15 well: c15_tp03_s63 only +14%)
- crypto15 pool: 7 genuine now (s78=+141%, s51=+83%, s56=+37%, s68=+22%...)
- Killed crypto70 long + crypto40 hourly sweeps (GPU drain, low value)
- stocks12 v2cfg: 26/145 done, best 0.0443, no canonical evals yet
- stocks12 ent08: 11/96 done, best 0.0443 (s11)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…rypto15 s87 progress

- stocks12 v2cfg (33 seeds): ALL converge to degenerate attractors (0, 0.0239, 0.0443)
  due to bf16=True + cuda_graph=True config — KILLED, confirmed useless approach
- stocks12 ent08 (18 seeds): same issue — KILLED
- Root cause: v2cfg/ent08 seeds med=-1.1% holdout (27/50 neg) vs proven no-bf16
  config seeds (s15=39%, s36=27%). BF16+cuda_graph prevents convergence on stocks12.
- crypto15 tp03 pool: 38/151 done, champion still s78 (+141.4%), 7 genuine total
  Seeds s82-s87 all failed honest eval despite decent pool vals
- Started stocks12 s200-350 no-bf16 600s sweep to find new ensemble candidates

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…overy

Root cause: BF16 autocast inside CUDA graph PPO caused precision loss
in log_softmax/ratio/entropy computations, collapsing all seeds to
identical degenerate hold-cash policies.

Fixes:
- BF16 autocast now ONLY wraps forward pass, not loss numerics
- Disable BF16 autocast entirely inside CUDA graph PPO path
- Clamp logits [-20,20] before softmax to prevent numerical explosion
- Clamp log_ratio [-10,10] before exp() to prevent underflow/overflow
- Add LayerNorm after encoder for activation stability
- Add entropy collapse detector: if entropy < 5% of max for 3 updates,
  reset optimizer momentum + add param noise to escape attractor

Verified: 3 seeds produce meaningfully different returns with
BF16+CUDA-graph enabled (no mode collapse).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
train.py added self.encoder_norm (LayerNorm) to prevent BF16 precision collapse
in seeds s94+. evaluate.py's local TradingPolicy copy was missing this layer,
causing RuntimeError on load.

- Add encoder_norm to TradingPolicy in evaluate.py
- Gate application with _use_encoder_norm flag (set by load_policy from ckpt keys)
- Old checkpoints (no encoder_norm in state_dict): flag=False, norm skipped — preserves
  exact behavior for s78 (+141.4%), s51 (+84.0%), and all pre-s94 models
- New checkpoints (encoder_norm present): flag=True, norm applied correctly
- encoder_norm.weight/.bias added to ignored set in load_policy for old ckpts

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ew ckpts

New checkpoints (trained after encoder_norm was added to train.py) have
encoder_norm.weight/bias in state_dict. evaluate_tail.TradingPolicy and
evaluate_multiperiod.load_policy didn't handle these, causing RuntimeError
when loading via ensemble_inference.

Fix mirrors evaluate.py pattern:
- evaluate_tail.TradingPolicy: add encoder_norm + _use_encoder_norm=False
- evaluate_multiperiod.load_policy: strict=False, set _use_encoder_norm from
  whether key is present (old ckpts: skip norm; new ckpts: apply norm)

Also append s94/s95 honest eval results to CSV.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Backwards-compatible: encoder_norm is optional in forward() via hasattr.
strict=False in load_state_dict allows loading checkpoints with or
without encoder_norm regardless of model architecture version.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
lee101 and others added 28 commits April 1, 2026 18:48
- WeightEnv/WeightSimConfig C sim for continuous target-weight RL
- Python FFI (market_sim_ffi.py) + train_weight_ppo.py PPO trainer
- 24 C test cases including weight env obs/step tests
- Python tests for FFI parity, weight PPO, lora sweep, xgb baseline
- Expanded evaluate_binance_lora_candidate with multi-window eval

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- hold_hours now uses max_steps from checkpoint (was hardcoded /720)
- episode_progress tracks actual step count (was fixed 0.25)
- features_per_sym read from checkpoint for future F=20 models
- _infer_num_symbols accepts configurable features_per_sym
- Added hold_hours tracking in trade_binance_live.py PortfolioState
- Added reset_episode() for position close transitions
- 14 new tests in test_rl_signal_obs.py covering obs shape, normalization
- 37 new C edge case tests (NaN, zero cash, env errors, MAX_SYMBOLS, etc)
- Added make test_asan target for AddressSanitizer builds

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Val eval: median +191.4%, Sortino 19.82 vs previous dd002 +116.6%, Sort 15.35
Slippage robust at all levels (0/5/10/20 bps all positive)
Also documented rl_signal.py obs bug fixes in alpacaprod.md

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ature

- Fix state/position divergence (BUG 3): Added pending_close_symbol tracking
  and reconcile_pending_close() to re-adopt positions when limit sell orders
  don't fill. Prevents orphaned positions on broker.
- Fix hfinference KeyError: 'data' crash with defensive .get() access
- Replace duplicate trend_20d feature (identical to return_20d) with RSI(14)
  normalized to [-1,1] in both inference_daily.py and export_data_daily.py
- Add entry/exit offset params to run_backtest() so backtest matches live
  calibrated execution (entry+5bps, exit+25bps)
- Update alpacaprod.md with 2026-04-06 audit: all services dead, crypto70
  sliding-window validation results (all top seeds fail), bugs documented
- Add tests for reconciliation logic and RSI feature

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Fix 2 failing TestSignalMetadata tests: add features_per_sym, _episode_step,
  max_steps, forecast_cache_root to generator stubs
- Add test_rl_signal_features.py: compute_symbol_features edge cases (empty
  forecasts, zero prices, extreme spikes, clipping bounds), forecast confidence,
  end-to-end signal generation, portfolio state tracking
- All 77 rl_signal tests pass

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…aleness notes

- Document robust_champion as upgrade target: +216% return, Sort=25.06, 82% win@30bar
- Note currently running dd002 is stale (PID from Mar 31)
- Document data freshness issue: stale root-level CSVs shadow crypto/ subfolder
- Add test coverage summary (77 Python + 205 C assertions)
- Record crypto6 scaled training launch (43k timesteps, 5yr)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
crypto6 5yr hourly training (43k timesteps) massively overfit:
- Train: +405x return, Sort=69 (memorized)
- Val: -11.3%, Sort=-4.45 (14/20 neg windows)
- Mixed23 training generalizes better than crypto-only
- robust_champion (+216%, Sort=25.06) remains deployment target

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Breakthrough results from RSI(14) feature replacement:
- s42: 36% median return, Sortino 28.05, 0/58 negative (lag=2, 5bps)
- s38: 14.6% median, robust across 0-20bps slippage, 0/58 negative
- s37: 5.7% median, 5/58 negative
- All crush the v4 32-model ensemble (2.36% median, 342/1827 negative)

Also: remove unnecessary deepcopy on bare policy cache hits,
add entry/exit offset params to backtest, update alpacaprod.md

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
+216% return, Sort=25.06, 65% WR at 5bps -- up from dd002 (+117%)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- _ensemble_top_k_signals(): Returns top K long signals from ensemble
  softmax with proportional allocation (probability-weighted)
- execute_multi_position_signals(): Portfolio rebalancing - closes
  positions not in target set, opens new ones proportionally
- --multi-position N CLI flag for holding N simultaneous positions
- Aggressive training launched: reward_scale=20, cash_penalty=0.05,
  trade_penalty=0.01 targeting higher returns
- v5_rsi validation on longer periods: s42/s38 overfit to Jul-Nov 2025,
  s37 is the only robust seed across all time periods

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…arge positions

- test_weight_env_extreme_scores: huge/zero/negative scores all keep equity positive
- test_weight_env_multi_symbol_rotation: symbol switching generates turnover and fees
- test_weight_env_zero_equity_recovery: 75% drawdown scenario, equity stays positive
- test_weight_env_all_cash: softmax equal weights behavior verification
- test_simulate_large_position: large position with fees reduces equity correctly
- All 239 C assertions pass (145+61+33), ASAN clean

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
aggressive_s1 (tp=0.01, reward_scale=20): +3.8% median on full val
aggressive_s36, s38: negative median, excessive trading
Standard tp=0.05 with RSI feature remains the best configuration.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
binance_wrapper.get_symbol_price() returns float | None, but was being
passed directly to float() which only accepts non-None values.

- _get_market_price: explicitly raise ValueError when price is None so
  callers (all already in try/except blocks) handle the failure correctly
- get_portfolio_state BTC price: use `or 0.0` fallback (inside try/except)
- _repay_margin_debt_if_flat: use `or 0.0` fallback (inside try/except)
- run_trading_cycle cur_price: use `or 0.0` fallback (inside try/except)

Fixes: Fast CI type-check job (ty check)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@lee101

lee101 commented Apr 6, 2026

Copy link
Copy Markdown
Owner Author

Codex Infinity
Hi! I'm Codex Infinity, your coding agent for this repo.

Start a task on this PR's branch by commenting:

Tasks and logs: https://codex-infinity.com

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant