Commit Graph

120 Commits

Author SHA1 Message Date
21in7
ffa6e443c1 feat: add --compare flag for OI derived features A/B comparison
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 20:13:07 +09:00
21in7
ff9e639142 feat: add OI derived features (oi_change_ma5, oi_price_spread) to dataset builder and ML features
Add two new OI-derived features to improve ML model's market microstructure
understanding:
- oi_change_ma5: 5-candle moving average of OI change rate (short-term trend)
- oi_price_spread: z-scored OI minus z-scored price return (divergence signal)

Both features use 96-candle rolling z-score window. FEATURE_COLS expanded from
24 to 26. Existing tests updated to reflect new feature counts.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 20:07:40 +09:00
21in7
676ec6ef5e docs: add OI derived features implementation plan
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 20:00:36 +09:00
21in7
33271013d3 docs: add OI derived features design doc
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 19:56:42 +09:00
21in7
b50306d68b docs: update README with ML_THRESHOLD configuration and add new training log entry
- Added `ML_THRESHOLD` parameter to README, specifying its role in ML filter predictions.
- Included a new entry in the training log with detailed metrics from a recent model training session, enhancing performance tracking and documentation.
2026-03-03 21:34:57 +09:00
4a2349bdbd Merge pull request 'claude/interesting-mcnulty' (#3) from claude/interesting-mcnulty into main
Reviewed-on: #3
2026-03-03 21:20:59 +09:00
21in7
c39097bf70 docs: add ADX ML migration design/plan and position monitor logging docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 21:18:22 +09:00
21in7
9c6f5dbd76 feat: remove ADX hard filter from dataset builder, add ADX as ML feature
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 21:17:49 +09:00
21in7
0aeb15ecfb feat: remove ADX hard filter, delegate to ML
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 21:14:50 +09:00
21in7
0b18a0b80d feat: add ADX as 24th ML feature for trend strength learning
Migrate ADX from hard filter (ADX < 25 blocks entry) to ML feature so
the model can learn optimal ADX thresholds from data. Updates FEATURE_COLS,
build_features(), and corresponding tests from 23 to 24 features.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 21:11:04 +09:00
038a1f84ec Merge pull request 'feat: add position monitor logging with real-time price tracking' (#2) from claude/intelligent-shtern into main
Reviewed-on: #2
2026-03-03 20:38:17 +09:00
21in7
a33283ecb3 feat: add position monitor logging with real-time price tracking
Log current price and unrealized PnL every 5 minutes while holding a position,
using the existing kline WebSocket's unclosed candle data for real-time price updates.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 20:36:46 +09:00
21in7
292ecc3e33 feat: update ML threshold and configuration for improved model performance
- Added ML_THRESHOLD to .env.example and updated Config class to include ml_threshold with a default value of 0.55.
- Modified MLFilter initialization in bot.py to utilize the new ml_threshold configuration.
- Updated Jenkinsfile to change the registry URL for Docker image management.

These changes enhance the model's adaptability by allowing for a configurable machine learning threshold, improving overall performance.
2026-03-03 20:09:03 +09:00
21in7
6fe2158511 feat: enhance precision optimization in model training
- Introduced a new plan to modify the Optuna objective function to prioritize precision under a recall constraint of 0.35, improving model performance in scenarios where false positives are costly.
- Updated training scripts to implement precision-based metrics and adjusted the walk-forward cross-validation process to incorporate precision and recall calculations.
- Enhanced the active LGBM parameters and training log to reflect the new metrics and model configurations.
- Added a new design document outlining the implementation steps for the precision-focused optimization.

This update aims to refine the model's decision-making process by emphasizing precision, thereby reducing potential losses from false positives.
2026-03-03 00:57:19 +09:00
21in7
3613e3bf18 feat: update active LGBM parameters and training log with new metrics
- Updated active LGBM parameters with new timestamp, trial results, and model configurations to reflect recent training outcomes.
- Added new entries to the training log, capturing detailed metrics including AUC, precision, recall, and tuned parameters for the latest model iterations.

This update enhances the tracking of model performance and parameter tuning in the ML pipeline.
2026-03-03 00:21:43 +09:00
21in7
fce4d536ea feat: implement HOLD negative sampling and stratified undersampling in ML pipeline
Added HOLD candles as negative samples to increase training data from ~535 to ~3,200 samples. Introduced a negative_ratio parameter in generate_dataset_vectorized() for sampling HOLD candles alongside signal candles. Implemented stratified undersampling to ensure signal samples are preserved during training. Updated relevant tests to validate new functionality and maintain compatibility with existing tests.

- Modified dataset_builder.py to include HOLD negative sampling logic
- Updated train_model.py to apply stratified undersampling
- Added tests for new sampling methods

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 00:13:42 +09:00
21in7
74966590b5 feat: apply stratified undersampling to hyperparameter tuning
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 00:09:43 +09:00
21in7
6cd54b46d9 feat: apply stratified undersampling to training pipeline
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 00:03:09 +09:00
21in7
0af138d8ee feat: add stratified_undersample helper function
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 23:58:15 +09:00
21in7
b7ad358a0a fix: make HOLD negative sampling tests non-vacuous
The two HOLD negative tests (test_hold_negative_labels_are_all_zero,
test_signal_samples_preserved_after_sampling) were passing vacuously
because sample_df produces 0 signal candles (ADX ~18, below threshold
25). Added signal_producing_df fixture with higher volatility and volume
surges to reliably generate signals. Removed if-guards so assertions
are mandatory. Also restored the full docstring for
generate_dataset_vectorized() documenting btc_df/eth_df,
time_weight_decay, and negative_ratio parameters.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 23:45:10 +09:00
21in7
8e56301d52 feat: add HOLD negative sampling to dataset_builder
Add negative_ratio parameter to generate_dataset_vectorized() that
samples HOLD candles as label=0 negatives alongside signal candles.
This increases training data from ~535 to ~3,200 samples when enabled.

- Split valid_rows into base_valid (shared) and sig_valid (signal-only)
- Add 'source' column ("signal" vs "hold_negative") for traceability
- HOLD samples get label=0 and random 50/50 side assignment
- Default negative_ratio=0 preserves backward compatibility
- Fix incorrect column count assertion in existing test

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 23:34:45 +09:00
21in7
99fa508db7 feat: add CLAUDE.md and settings.json for project documentation and plugin configuration
Introduced CLAUDE.md to provide comprehensive guidance on the CoinTrader project, including architecture, common commands, testing, and deployment details. Added settings.json to enable the superpowers plugin for Claude. This enhances the project's documentation and configuration management.
2026-03-02 20:01:18 +09:00
21in7
eeb5e9d877 feat: add ADX filter to block sideways market entries
ADX < 25 now returns HOLD in get_signal(), preventing entries during
trendless (sideways) markets. NaN ADX values fall through to existing
weighted signal logic. Also syncs the vectorized dataset builder with
the same ADX filter to keep training data consistent.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 19:55:12 +09:00
21in7
c8a2c36bfb feat: add ADX calculation to indicators
Add ADX (Average Directional Index) with period 14 to calculate_all()
for sideways market filtering. Includes test verifying the adx column
exists and contains non-negative values.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 19:47:18 +09:00
21in7
b8b99da207 feat: update training log and enhance ML filter functionality
- Added a new entry to the training log with detailed metrics for a LightGBM model, including AUC, precision, recall, and tuned parameters.
- Enhanced the MLFilter class to include a guard clause that prevents execution if the filter is disabled, improving robustness.
2026-03-02 18:24:38 +09:00
21in7
77590accf2 feat: add architecture documentation for CoinTrader
- Introduced a comprehensive architecture document detailing the CoinTrader system, including an overview, core layer architecture, MLOps pipeline, and key operational scenarios.
- Updated README to reference the new architecture document and added a configuration option to disable the ML filter.
- Enhanced the ML filter to allow for complete signal acceptance when the NO_ML_FILTER environment variable is set.
2026-03-02 18:02:05 +09:00
21in7
a8cba2cb4c docs: enhance README with detailed listenKey auto-renewal process and error handling
- Updated the README to clarify the listenKey auto-renewal mechanism, including the use of `stream.recv()` for message reception.
- Added information on immediate reconnection upon detecting internal error payloads to prevent zombie connections.
2026-03-02 16:43:45 +09:00
21in7
52affb5532 feat: implement User Data Stream for real-time TP/SL detection and PnL tracking
- Introduced User Data Stream to detect TP/SL executions in real-time.
- Added a new class `UserDataStream` for managing the stream and handling events.
- Updated `bot.py` to initialize and run the User Data Stream in parallel with the candle stream.
- Enhanced `notifier.py` to send detailed Discord notifications including estimated vs actual PnL.
- Added methods in `exchange.py` for managing listenKey lifecycle (create, keepalive, delete).
- Refactored PnL recording and notification logic to streamline handling of position closures.

Made-with: Cursor
2026-03-02 16:33:08 +09:00
21in7
05ae88dc61 fix: remove manual listenKey mgmt, add symbol filter, fix reenter race condition
Made-with: Cursor
2026-03-02 16:31:40 +09:00
21in7
6237efe4d3 docs: update README with User Data Stream TP/SL detection feature
Made-with: Cursor
2026-03-02 16:27:50 +09:00
21in7
4e8e61b5cf fix: guard against None current_trade_side in _calc_estimated_pnl
Made-with: Cursor
2026-03-02 16:27:17 +09:00
21in7
4ffee0ae8b feat: run UserDataStream in parallel with candle stream
Made-with: Cursor
2026-03-02 16:25:13 +09:00
21in7
7e7f0f4f22 fix: restore entry_price and entry_quantity on position recovery
Made-with: Cursor
2026-03-02 16:24:27 +09:00
21in7
c4f806fc35 feat: add entry state tracking and _on_position_closed callback
- __init__에 _entry_price, _entry_quantity 상태 변수 추가 (None 초기화)
- _open_position()에서 current_trade_side 저장 직후 진입가/수량 저장
- _calc_estimated_pnl() 헬퍼: LONG/SHORT 방향별 예상 PnL 계산
- _on_position_closed() 콜백: UDS 청산 감지 시 PnL 기록·알림·상태 초기화

Made-with: Cursor
2026-03-02 16:21:59 +09:00
21in7
22f1debb3d fix: re-raise CancelledError in UserDataStream for proper task cancellation
Made-with: Cursor
2026-03-02 16:20:37 +09:00
21in7
4f3183df47 feat: add UserDataStream with keepalive and reconnect loop
Made-with: Cursor
2026-03-02 16:17:38 +09:00
21in7
223608bec0 refactor: remove duplicate pnl/notify from _close_position (handled by callback)
Made-with: Cursor
2026-03-02 16:16:25 +09:00
21in7
e72126516b feat: extend notify_close with close_reason, net_pnl, diff fields
Made-with: Cursor
2026-03-02 16:14:26 +09:00
21in7
63c2eb8927 feat: add listenKey create/keepalive/delete methods to exchange
Made-with: Cursor
2026-03-02 16:11:33 +09:00
21in7
dcdaf9f90a chore: update active LGBM parameters and add new training log entry
- Updated timestamp and elapsed seconds in models/active_lgbm_params.json.
- Adjusted baseline AUC and fold AUCs to reflect new model performance.
- Added a new entry in models/training_log.json with detailed metrics from the latest training run, including tuned parameters and model path.

Made-with: Cursor
2026-03-02 15:03:35 +09:00
21in7
6d82febab7 feat: implement Active Config pattern for automatic param promotion
- tune_hyperparams.py: 탐색 완료 후 Best AUC > Baseline AUC 이면
  models/active_lgbm_params.json 자동 갱신
- tune_hyperparams.py: 베이스라인을 active 파일 기준으로 측정
  (active 없으면 코드 내 기본값 사용)
- train_model.py: _load_lgbm_params()에 active 파일 자동 탐색 추가
  우선순위: --tuned-params > active_lgbm_params.json > 하드코딩 기본값
- models/active_lgbm_params.json: 현재 best 파라미터로 초기화
- .gitignore: tune_results_*.json 제외, active 파일은 git 추적 유지

Made-with: Cursor
2026-03-02 14:56:42 +09:00
21in7
d5f8ed4789 feat: update default LightGBM params to Optuna best (trial #46, AUC=0.6002)
Optuna 50 trials Walk-Forward 5폴드 탐색 결과 (tune_results_20260302_144749.json):
- Baseline AUC: 0.5803 → Best AUC: 0.6002 (+0.0199, +3.4%)
- n_estimators: 500 → 434
- learning_rate: 0.05 → 0.123659
- max_depth: (미설정) → 6
- num_leaves: 31 → 14
- min_child_samples: 15 → 10
- subsample: 0.8 → 0.929062
- colsample_bytree: 0.8 → 0.946330
- reg_alpha: 0.05 → 0.573971
- reg_lambda: 0.1 → 0.000157
- weight_scale: 1.0 → 1.783105

Made-with: Cursor
2026-03-02 14:52:41 +09:00
21in7
ce02f1335c feat: add run_optuna.sh wrapper script for Optuna tuning
Made-with: Cursor
2026-03-02 14:50:50 +09:00
21in7
4afc7506d7 feat: connect Optuna tuning results to train_model.py via --tuned-params
- _load_lgbm_params() 헬퍼 추가: 기본 파라미터 반환, JSON 주어지면 덮어씀
- train(): tuned_params_path 인자 추가, weight_scale 적용
- walk_forward_auc(): tuned_params_path 인자 추가, weight_scale 적용
- main(): --tuned-params argparse 인자 추가, 두 함수에 전달
- training_log.json에 tuned_params_path, lgbm_params, weight_scale 기록

Made-with: Cursor
2026-03-02 14:45:15 +09:00
21in7
caaa81f5f9 fix: add shebang and executable permission to tune_hyperparams.py
Made-with: Cursor
2026-03-02 14:41:13 +09:00
21in7
8dd1389b16 feat: add Optuna Walk-Forward AUC hyperparameter tuning pipeline
- scripts/tune_hyperparams.py: Optuna + Walk-Forward 5폴드 AUC 목적 함수
  - 데이터셋 1회 캐싱으로 모든 trial 공유 (속도 최적화)
  - num_leaves <= 2^max_depth - 1 제약 강제 (소규모 데이터 과적합 방지)
  - MedianPruner로 저성능 trial 조기 종료
  - 결과: 콘솔 리포트 + models/tune_results_YYYYMMDD_HHMMSS.json
- requirements.txt: optuna>=3.6.0 추가
- README.md: 하이퍼파라미터 자동 튜닝 사용법 섹션 추가
- docs/plans/: 설계 문서 및 구현 플랜 추가

Made-with: Cursor
2026-03-02 14:39:07 +09:00
21in7
4c09d63505 feat: implement upsert functionality in fetch_history.py to accumulate OI/funding data
- Added `--upsert` flag to `fetch_history.py` for merging new data into existing parquet files.
- Implemented `upsert_parquet()` function to update existing rows with new values where `oi_change` and `funding_rate` are 0.0, while appending new rows.
- Created tests in `tests/test_fetch_history.py` to validate upsert behavior.
- Updated `.gitignore` to include `.cursor/` directory.

Made-with: Cursor
2026-03-02 14:16:09 +09:00
21in7
0fca14a1c2 feat: auto-detect first run in train_and_deploy.sh (365d full vs 35d upsert)
Made-with: Cursor
2026-03-02 14:15:00 +09:00
21in7
2f5227222b docs: add initial data setup instructions and OI accumulation strategy
Made-with: Cursor
2026-03-02 14:13:45 +09:00
21in7
10b1ecd273 feat: fetch 35 days for daily upsert instead of overwriting 365 days
Made-with: Cursor
2026-03-02 14:13:16 +09:00