- core/price_db.py: add wf_state table CRUD (ensure/upsert/load/delete)
to persist shadow_cons_wins across restarts
- core/trader.py: save WF blocked state on shadow enter/close,
restore shadow_cons_wins on startup from DB
- core/monitor.py: lower ATR_MAX_STOP 4.0% → 2.0% based on sweep results
- atr_sweep.py: new ATR_MAX_STOP sweep tool using real ATR calc from DB
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
When WF filter blocks a ticker, automatically start a virtual (shadow)
position with the same trailing/time stop logic. After WF_SHADOW_WINS
consecutive shadow wins, reset WF history to re-enable real trading.
- trader.py: add _shadow_positions, _shadow_cons_wins state;
_shadow_enter(), get_shadow_positions(), update_shadow_peak(),
close_shadow() functions; trigger shadow entry on WF block in buy()
- monitor.py: add _check_shadow_position() with ATR trailing + time stop;
check shadow positions every 10s in run_monitor()
- Env: WF_SHADOW_WINS=2 (2 consecutive wins to rehabilitate)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- 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>
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>
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>