Commit Graph

9 Commits

Author SHA1 Message Date
joungmin
0b264b304c feat: add backtest module with DB cache and scenario comparison
Backtest improvements:
- Add backtest.py with Oracle DB-backed OHLCV cache (no repeated API calls)
- Add backtest_trades table to cache simulation results by params hash
  (same params -> instant load, skip re-simulation)
- Add walk-forward scenario comparison (--walkforward-cmp)
- Add trend ceiling filter (--trend-cmp, max gain threshold)
- Add ticker win-rate filter (--ticker-cmp, SQL-based instant analysis)
- Precompute daily_features once per data load (not per scenario)

Live bot fixes:
- monitor: add hard stop-loss from buy price (in addition to trailing)
- strategy: fix re-entry condition to require +1% above last sell price
- price_collector: add 48h backfill on startup for trend calculation
- main: call backfill_prices() at startup

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-28 23:28:27 +09:00
joungmin
4888aa0faa feat: add walk-forward trade filter to prevent re-entry on losing tickers
- Add trade_results table to Oracle DB for persistent trade history
- Record win/loss after each sell with pnl_pct
- Load last N trades per ticker from DB on startup (survives restarts)
- Block buy() when recent win rate (last 5 trades) < 40% threshold
- Configurable via WF_WINDOW and WF_MIN_WIN_RATE env vars
- Backtest showed improvement from -7.5% to +37.4% cumulative return

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-28 23:28:07 +09:00
joungmin
80ab004eba feat: replace volatility breakout with DB-backed real-time trend check
- price_history table on Oracle ADB stores prices every 10 minutes
- check_trend(): current price vs N hours ago (default 1h, +3% threshold)
- check_momentum(): unchanged (MA20 + 2x volume still applies)
- Ticker list cached 5 minutes to avoid 429 rate limits
- Collector starts 30s after boot to avoid simultaneous API calls
- Configurable: TREND_HOURS, TREND_MIN_GAIN_PCT in .env

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-28 11:26:26 +09:00
joungmin
9fe3ce488e fix: auto-restart scanner on crash with Telegram notification
Wrap run_scanner() in while True loop so main thread recovers from
unhandled exceptions. Sends Telegram alert on crash before restarting.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-28 10:42:05 +09:00
joungmin
2585d47140 feat: add hourly position status report via Telegram
Run status reporter thread every 60 minutes, sends current price,
PnL, drop from peak, and holding time for each position.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-28 10:39:30 +09:00
joungmin
a287e48522 fix: restore positions on restart and fix notify env loading
- restore_positions(): read Upbit balances on startup to prevent
  double-buying after restart
- notify.py: read TOKEN/CHAT_ID inside _send() to avoid empty values
  when module is imported before load_dotenv()

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-28 10:36:17 +09:00
joungmin
a799fbebbd feat: add Telegram notifications and configurable stop loss
- notify.py: buy/sell/error alerts via upbit_trading_jm_bot
- STOP_LOSS_PCT: trailing stop configurable via .env (default -5%)
- notify_buy/notify_sell called on every trade execution

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-28 10:31:03 +09:00
joungmin
0713fb1e11 feat: add time stop rule for stale positions
Sell position if held for TIME_STOP_HOURS (default 24h) with less than
TIME_STOP_MIN_GAIN_PCT (default +3%) gain. Frees up capital for
fresh momentum opportunities.

Priority: trailing stop (-10%) checked first, then time stop.
Both thresholds configurable via .env.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-28 10:23:32 +09:00
joungmin
83bd51117f feat: initial upbit auto-trader implementation
Strategy C: volatility breakout (Larry Williams K=0.5) AND momentum
(MA20 + 2x volume surge) must both trigger for a buy signal.

Hard rules:
- Trailing stop: sell when price drops -10% from peak
- Max budget: 1,000,000 KRW total, up to 3 positions (333,333 KRW each)
- Scan top 20 KRW tickers by 24h trading volume every 60s
- Monitor positions every 10s

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-28 10:20:02 +09:00