Commit Graph

135 Commits

Author SHA1 Message Date
agentson
24fa22e77b fix: overseas order rt_cd check, limit price premium, paper cash fallback (#151)
Some checks failed
CI / test (pull_request) Has been cancelled
Three fixes for overseas stock trading failures:

1. Price API exchange code mapping:
   - get_overseas_price() now applies _PRICE_EXCHANGE_MAP (NASD→NAS, NYSE→NYS, AMEX→AMS)
   - Price API HHDFS00000300 requires short exchange codes same as ranking API

2. rt_cd check in send_overseas_order():
   - Log WARNING (not INFO) when rt_cd != "0" (e.g., "주문가능금액이 부족합니다")
   - Caller (main.py) checks rt_cd == "0" before calling log_trade()
   - Prevents DB from recording failed orders as successful trades

3. Limit order price premium for BUY:
   - BUY limit price = current_price * 1.005 (0.5% premium)
   - SELL limit price = current_price (no premium)
   - Improves fill probability: KIS VTS only accepts limit orders,
     and last price is typically at or below ask

4. PAPER_OVERSEAS_CASH fallback (config + main.py):
   - New setting: PAPER_OVERSEAS_CASH = 50000.0 (USD)
   - When VTS overseas balance API fails/returns 0, use this as simulated cash
   - Applied in both trading_cycle() and run_daily_session()

5. Candidate price fallback:
   - If price API returns 0, use scanner candidate price as fallback

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-19 05:58:15 +09:00
agentson
ccc97ebaa9 fix: use current_price for overseas limit orders (KIS VTS rejects market orders) (#149)
Some checks failed
CI / test (pull_request) Has been cancelled
KIS VTS (paper trading) rejects overseas market orders with:
  "모의투자 주문처리가 안되었습니다(지정가만 가능한 상품입니다)"

Root cause: send_overseas_order() was called with price=0.0 (market order)
in both trading_cycle() and run_daily_session(), even though current_price
was already computed correctly by Fix #147 (exchange code mapping).

Fix: pass current_price as the limit order price in both call sites.
Domestic broker send_order() keeps price=0 (market orders are fine on KRX).

Adds regression test TestOverseasBalanceParsing::test_overseas_buy_order_uses_limit_price
verifying price=182.5 is passed, not 0.0.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-18 23:53:15 +09:00
agentson
3a54db8948 fix: price API exchange code mapping and VTS overseas balance fallback (#147)
Some checks failed
CI / test (pull_request) Has been cancelled
- Apply _PRICE_EXCHANGE_MAP in get_overseas_price() to send short codes
  (NASD→NAS, NYSE→NYS, AMEX→AMS) required by HHDFS00000300 price API
- Add PAPER_OVERSEAS_CASH config setting (default $50,000) for simulated
  USD balance when VTS overseas balance API returns 0 in paper mode
- Fall back to scan candidate price when live price API returns 0
- Both fixes together resolve "no affordable quantity (cash=0, price=0)"
  which was preventing all overseas trade execution

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-18 23:48:14 +09:00
agentson
96e2ad4f1f fix: use smart rule-based fallback playbook when Gemini fails (issue #145)
Some checks failed
CI / test (pull_request) Has been cancelled
When gemini-2.5-flash quota is exhausted (20 RPD free tier), generate_playbook()
fell back to _defensive_playbook() which only had price_change_pct_below: -3.0 SELL
conditions — no BUY conditions — causing zero trades on US market despite scanner
finding strong momentum/oversold candidates.

Changes:
- Add _smart_fallback_playbook() that uses scanner signals to build BUY conditions:
  - momentum signal: BUY when volume_ratio_above=VOL_MULTIPLIER
  - oversold signal: BUY when rsi_below=RSI_OVERSOLD_THRESHOLD
  - always: SELL stop-loss at price_change_pct_below=-3.0
- Use _smart_fallback_playbook() instead of _defensive_playbook() on Gemini failure
- Add 10 new tests for _smart_fallback_playbook() covering momentum/oversold/empty cases
- Update existing test_gemini_failure_returns_defensive to match new behavior

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-18 22:23:57 +09:00
agentson
f7289606fc fix: use prompt_override in gemini_client.decide() for playbook generation
Some checks failed
CI / test (pull_request) Has been cancelled
decide() ignored market_data["prompt_override"], always building a generic
trade-decision prompt. This caused pre_market_planner playbook generation
to fail with JSONDecodeError on every market, falling back to defensive
playbooks. Now prompt_override takes priority over both optimization and
standard prompt building.

Closes #143

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 02:02:13 +09:00
agentson
b625f41621 fix: correct KIS overseas ranking API TR_IDs, paths, and exchange codes
Some checks failed
CI / test (pull_request) Has been cancelled
The overseas ranking API was returning 404 for all exchanges because the
TR_IDs, API paths, and exchange codes were all incorrect. Updated to match
KIS official API documentation:
- TR_ID: HHDFS76290000 (updown-rate), HHDFS76270000 (volume-surge)
- Path: /uapi/overseas-stock/v1/ranking/{updown-rate,volume-surge}
- Exchange codes: NASD→NAS, NYSE→NYS, AMEX→AMS via ranking-specific mapping

Fixes #141

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 01:02:52 +09:00
agentson
aeed881d85 fix: wait on token refresh cooldown instead of failing fast
Some checks failed
CI / test (pull_request) Has been cancelled
2026-02-18 00:03:42 +09:00
agentson
d0bbdb5dc1 fix: harden overseas ranking fallback and scanner visibility 2026-02-17 23:39:20 +09:00
agentson
733e6b36e9 feat: unify domestic scanner and sizing; update docs
Some checks failed
CI / test (pull_request) Has been cancelled
2026-02-17 06:29:36 +09:00
agentson
748b9b848e feat: prioritize overseas volatility scoring over raw rankings 2026-02-17 06:25:45 +09:00
agentson
6a1ad230ee feat: add overseas ranking integration with dynamic fallback 2026-02-17 06:25:45 +09:00
agentson
3fdb7a29d4 feat: US market code 정합성, Telegram 명령 4종, 손절 모니터링 (#132)
Some checks failed
CI / test (pull_request) Has been cancelled
- MARKET_SHORTHAND + expand_market_codes()로 config "US" → schedule "US_NASDAQ/NYSE/AMEX" 자동 확장
- /report, /scenarios, /review, /dashboard 텔레그램 명령 추가
- price_change_pct를 trading_cycle과 run_daily_session에 주입
- HOLD시 get_open_position 기반 손절 모니터링 및 자동 SELL 오버라이드
- 대시보드 /api/status 동적 market 조회로 변경

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 20:24:01 +09:00
agentson
63fa6841a2 feat: dashboard background thread with CLI flag (issue #97)
Some checks failed
CI / test (pull_request) Has been cancelled
Add --dashboard CLI flag and DASHBOARD_ENABLED env var to start
FastAPI dashboard in a daemon thread alongside the trading loop.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 00:01:29 +09:00
agentson
63f4e49d88 feat: read-only FastAPI dashboard with 7 API endpoints (issue #96)
Some checks failed
CI / test (pull_request) Has been cancelled
Add observability dashboard: status, playbook, scorecard, performance,
context browser, decisions, and active scenarios endpoints.
SQLite read-only on separate connections from trading loop.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 23:56:10 +09:00
agentson
e0a6b307a2 fix: add error handling to evolution loop telegram notification
Wrap evolution notification in try/except so telegram failures don't
crash the evolution loop. Add integration tests for market close flow.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 23:56:04 +09:00
agentson
afb31b7f4b feat: wire evolution loop into market close flow (issue #95)
Some checks failed
CI / test (pull_request) Has been cancelled
Run EvolutionOptimizer.evolve() at US market close, skip for other
markets, and notify via Telegram when a strategy PR is generated.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 23:41:41 +09:00
agentson
d9763def85 feat: integrate ContextScheduler into main loop (issue #89)
Some checks failed
CI / test (pull_request) Has been cancelled
Wire up periodic context rollups (weekly/monthly/quarterly/annual/legacy)
in both daily and realtime trading loops with dedup-safe scheduling.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 23:37:30 +09:00
agentson
6b3960a3a4 feat: inject self-market scorecard into planner prompt (issue #94)
Some checks failed
CI / test (pull_request) Has been cancelled
Add build_self_market_scorecard() to read previous day's own market
performance, and include it in the Gemini planning prompt alongside
cross-market context.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 23:27:01 +09:00
agentson
86c94cff62 feat: cross-market date fix and strategic context selector (issue #88)
Some checks failed
CI / test (pull_request) Has been cancelled
KR planner now reads US scorecard from previous day (timezone-aware),
and generate_playbook uses STRATEGIC context selection.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 23:20:24 +09:00
agentson
392422992b feat: integrate DailyReviewer into market close flow (issue #93)
Some checks failed
CI / test (pull_request) Has been cancelled
Extract _handle_market_close() helper that runs EOD aggregation,
generates scorecard with optional AI lessons, and sends Telegram summary.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 23:13:57 +09:00
agentson
8c27473fed feat: DailyReviewer for market-scoped scorecards and AI lessons (issue #91)
Some checks failed
CI / test (pull_request) Has been cancelled
Generate per-market daily scorecards from decision_logs and trades,
optional Gemini-powered lessons, and store results in L6 context.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 23:07:12 +09:00
agentson
a14f944fcc feat: link decision outcomes to trades via decision_id (issue #92)
Some checks failed
CI / test (pull_request) Has been cancelled
Add decision_id column to trades table, capture log_decision() return
value, and update original BUY decision outcome on SELL execution.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 21:36:57 +09:00
agentson
e3b1ecc572 feat: context aggregation scheduler (issue #87)
Some checks failed
CI / test (pull_request) Has been cancelled
- Add ContextScheduler with run_if_due() for periodic rollups
- Weekly (Sunday), monthly (last day), quarterly, annual, legacy schedules
- Daily cleanup of expired contexts via ContextStore
- Dedup guard: each task runs at most once per day

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-10 04:26:51 +09:00
agentson
c95102a0bd feat: DailyScorecard model for per-market performance review (issue #90)
Some checks failed
CI / test (pull_request) Has been cancelled
- Add DailyScorecard dataclass with market-scoped fields
- Fields: date, market, decisions, pnl, win_rate, scenario_match_rate, lessons, cross_market_note
- Export from src/evolution/__init__.py

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-10 04:25:37 +09:00
agentson
78021d4695 feat: EOD aggregation with market filter (issue #86)
Some checks failed
CI / test (pull_request) Has been cancelled
- Add market parameter to aggregate_daily_from_trades() for per-market L6 aggregation
- Store market-scoped keys (total_pnl_KR, win_rate_US, etc.) in L6/L5/L4 layers
- Hook aggregate_daily_from_trades() into market close detection in run()
- Update tests for market-scoped context keys

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-10 04:23:49 +09:00
agentson
c4e31be27a feat: L7 real-time context write with market-scoped keys (issue #85)
Some checks failed
CI / test (pull_request) Has been cancelled
- Add L7_REALTIME writes in trading_cycle() for volatility, price, rsi, volume_ratio
- Normalize key format to {metric}_{market}_{stock_code} across scanner and main
- Fix existing key mismatch between scanner writes and main reads
- Remove unused MarketScanner dead code

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-10 04:21:52 +09:00
agentson
f03cc6039b fix: derive all aggregation timeframes from trade timestamp (#112)
Some checks failed
CI / test (pull_request) Has been cancelled
run_all_aggregations() previously used datetime.now(UTC) for weekly
through annual layers while using the trade date only for daily,
causing data misalignment on backfill. Now all layers consistently
use the latest trade timestamp. Also adds "Z" suffix handling for
fromisoformat() compatibility and strengthens test assertions to
verify L4-L2 layer values end-to-end.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-10 00:40:28 +09:00
agentson
d64e072f06 fix: PR review — DB reload, market-local date, market-scoped scan_candidates
Some checks failed
CI / test (pull_request) Has been cancelled
Address PR #110 review findings:

1. High — Realtime mode now loads playbook from DB before calling Gemini,
   preventing duplicate API calls on process restart (4/day budget).
2. Medium — Pass market-local date (via market.timezone) to
   generate_playbook() and _empty_playbook() instead of date.today().
3. Medium — scan_candidates restructured from {stock_code: candidate}
   to {market_code: {stock_code: candidate}} to prevent KR/US symbol
   collision.

New test: test_scan_candidates_market_scoped verifies cross-market
isolation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 23:00:06 +09:00
agentson
b2312fbe01 fix: resolve lint issues in main.py and test_main.py
Some checks failed
CI / test (pull_request) Has been cancelled
Remove unused imports (sys, ScenarioMatch, asyncio, StockPlaybook),
fix import ordering, and split long lines for ruff compliance.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 22:28:31 +09:00
agentson
98c4a2413c feat: integrate scenario engine and playbook into main trading loop (issue #84)
Replace brain.decide() with scenario_engine.evaluate() in trading_cycle
and brain.decide_batch() with per-stock scenario evaluation in
run_daily_session. Initialize PreMarketPlanner, ScenarioEngine, and
PlaybookStore in run(). Add pre-market playbook generation on market
open (1 Gemini call per market per day), market_data enrichment from
scanner metrics (rsi, volume_ratio), portfolio_data for global rules,
scenario match notifications, and playbook lifecycle management.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 22:24:19 +09:00
agentson
be695a5d7c fix: address PR review — inject today param, remove unused imports, fix lint
Some checks failed
CI / test (pull_request) Has been cancelled
Review findings addressed:
- Finding 1 (ImportError): false positive — ContextLayer is re-exported from
  src.context.store, import works correctly at runtime
- Finding 2 (timezone): generate_playbook() and build_cross_market_context()
  now accept optional today parameter for market-local date injection
- Finding 3 (lint): removed unused imports (UTC, datetime, PlaybookStatus),
  fixed line-too-long in prompt template
- Tests simplified: replaced date patching with direct today= parameter

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 21:57:39 +09:00
agentson
149039a904 feat: implement pre-market planner with Gemini integration (issue #83)
PreMarketPlanner generates DayPlaybook via single Gemini API call per market:
- Structured JSON prompt with scan candidates + strategic context
- Cross-market context (KR reads US scorecard, US reads KR scorecard)
- Robust JSON parser with markdown fence stripping
- Unknown stock filtering (only scanner candidates allowed)
- MAX_SCENARIOS_PER_STOCK enforcement
- Defensive playbook on failure (HOLD + stop-loss)
- Empty playbook when no candidates (safe, no trades)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 21:35:57 +09:00
agentson
e8634b93c3 feat: add Telegram playbook notifications (issue #81)
Some checks failed
CI / test (pull_request) Has been cancelled
- notify_playbook_generated(): market, stock/scenario count, token usage (MEDIUM)
- notify_scenario_matched(): stock, action, condition, confidence (HIGH)
- notify_playbook_failed(): market, reason with 200-char truncation (HIGH)
- 6 new tests: 3 format + 3 priority validations

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 21:25:16 +09:00
agentson
7f2f96a819 feat: add playbook persistence with DB schema and CRUD store (issue #82)
Some checks failed
CI / test (pull_request) Has been cancelled
- Add playbooks table to src/db.py with UNIQUE(date, market) constraint
- PlaybookStore: save/load/delete, status management, match_count tracking,
  list_recent with market filter, stats without full deserialization
- DayPlaybook JSON serialization via Pydantic model_dump_json/model_validate_json
- 23 tests, 100% coverage on playbook_store.py

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 21:00:04 +09:00
agentson
e711d6702a fix: deduplicate missing-key warnings and normalize match_details
Some checks failed
CI / test (pull_request) Has been cancelled
Addresses second round of PR #102 review:
- _warn_missing_key(): logs each missing key only once per engine instance
  to prevent log spam in high-frequency trading loops
- _build_match_details(): uses _safe_float() normalized values instead of
  raw market_data to ensure consistent float types in logging/analysis
- Test: verify warning fires exactly once across repeated calls
- Test: verify match_details contains normalized float values

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 20:41:20 +09:00
agentson
d2fc829380 fix: add safe type casting and missing-key warnings in ScenarioEngine
Some checks failed
CI / test (pull_request) Has been cancelled
Addresses PR #102 review findings:
- _safe_float() prevents TypeError from str/Decimal/invalid market_data values
- Warning logs when condition references a key missing from market_data
- 5 new tests: string, percent string, Decimal, mixed invalid types, log check

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 16:23:54 +09:00
agentson
9599b188e8 feat: implement local scenario engine for playbook execution (issue #80)
Some checks failed
CI / test (pull_request) Has been cancelled
ScenarioEngine evaluates pre-defined playbook scenarios against real-time
market data with sub-100ms execution (zero API calls). Supports condition
AND-matching, global portfolio rules, and first-match-wins priority.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 02:23:53 +09:00
agentson
7fd48c7764 feat: add strategy/playbook Pydantic models (issue #79)
Some checks failed
CI / test (pull_request) Has been cancelled
Define data contracts for the proactive strategy system:
- StockCondition: AND-combined condition fields (RSI, volume, price)
- StockScenario: condition-action rules with stop loss/take profit
- StockPlaybook: per-stock scenario collection
- GlobalRule: portfolio-level rules (e.g. REDUCE_ALL on loss limit)
- DayPlaybook: complete daily playbook per market with validation
- CrossMarketContext: cross-market awareness (KR↔US)
- ScenarioAction, MarketOutlook, PlaybookStatus enums

33 tests covering validation, serialization, edge cases.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 02:06:16 +09:00
agentson
1a34a74232 feat: add pre-market planner config and remove static watchlists (issue #78)
Some checks failed
CI / test (pull_request) Has been cancelled
- Add pre-market planner settings: PRE_MARKET_MINUTES, MAX_SCENARIOS_PER_STOCK,
  PLANNER_TIMEOUT_SECONDS, DEFENSIVE_PLAYBOOK_ON_FAILURE, RESCAN_INTERVAL_SECONDS
- Change ENABLED_MARKETS default from KR to KR,US
- Remove static WATCHLISTS and STOCK_UNIVERSE dictionaries from main.py
- Replace watchlist-based trading with dynamic scanner-only stock discovery
- SmartVolatilityScanner is now the sole source of trading candidates
- Add active_stocks dict for scanner-discovered stocks per market
- Add smart_scanner parameter to run_daily_session()

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 01:58:09 +09:00
agentson
f0ae25c533 feat: implement Smart Volatility Scanner with RSI/volume filters (issue #76)
Some checks failed
CI / test (pull_request) Has been cancelled
Add Python-first scanning pipeline that reduces Gemini API calls by filtering
stocks before AI analysis: KIS rankings API -> RSI/volume filter -> AI judgment.

## Implementation
- Add RSI calculation (Wilder's smoothing method) to VolatilityAnalyzer
- Add KIS API methods: fetch_market_rankings() and get_daily_prices()
- Create SmartVolatilityScanner with configurable thresholds
- Integrate scanner into main.py realtime mode
- Add selection_context logging to trades table for Evolution system

## Configuration
- RSI_OVERSOLD_THRESHOLD: 30 (configurable 0-50)
- RSI_MOMENTUM_THRESHOLD: 70 (configurable 50-100)
- VOL_MULTIPLIER: 2.0 (minimum volume ratio, configurable 1-10)
- SCANNER_TOP_N: 3 (max candidates per scan, configurable 1-10)

## Benefits
- Reduces Gemini API calls (process 1-3 qualified stocks vs 20-30 ranked)
- Python-based technical filtering before expensive AI judgment
- Tracks selection criteria (RSI, volume_ratio, signal, score) for strategy optimization
- Graceful fallback to static watchlist if ranking API fails

## Tests
- 13 new tests for SmartVolatilityScanner and RSI calculation
- All existing tests updated and passing
- Coverage maintained at 73%

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-06 00:48:23 +09:00
agentson
18a098d9a6 fix: resolve Telegram command handler errors for /status and /positions (issue #74)
Some checks failed
CI / test (pull_request) Has been cancelled
Fixed AttributeError exceptions in /status and /positions commands:
- Replaced invalid risk.calculate_pnl() with inline P&L calculation from balance dict
- Changed risk.circuit_breaker_threshold to risk._cb_threshold
- Replaced balance.stocks access with account summary from output2 dict
- Updated tests to match new account summary format

All 27 telegram command tests pass. Live bot testing confirms no errors.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-05 18:54:42 +09:00
d2b07326ed Merge pull request 'fix: remove /start command and handle @botname suffix (issue #71)' (#72) from fix/start-command-parsing into main
Some checks failed
CI / test (push) Has been cancelled
Reviewed-on: #72
2026-02-05 17:15:14 +09:00
agentson
1c5eadc23b fix: remove /start command and handle @botname suffix
Some checks failed
CI / test (pull_request) Has been cancelled
Remove /start command as name doesn't match functionality, and fix
command parsing to handle @botname suffix for group chat compatibility.

Changes:
- Remove handle_start function and registration
- Remove /start from help command list
- Remove test_start_command_content test
- Strip @botname suffix from commands (e.g., /help@mybot → help)

Rationale:
- /start command name implies bot initialization, but it was just
  showing help text (duplicate of /help)
- Better to have one clear /help command
- @botname suffix handling needed for group chats

Test:
- 27 tests pass (1 removed, 1 added for @botname handling)
- All existing functionality preserved

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-05 15:59:07 +09:00
agentson
0ca3fe9f5d feat: add configuration and documentation for Telegram commands (issue #69)
Some checks failed
CI / test (pull_request) Has been cancelled
Add configuration options and comprehensive documentation for the new
bidirectional command feature.

Changes:
- Add TELEGRAM_COMMANDS_ENABLED to config.py
- Add TELEGRAM_POLLING_INTERVAL to config.py
- Add extensive "Bidirectional Commands" section to README.md

Documentation:
- Available commands table with descriptions
- Command usage examples with sample outputs
- Security section (Chat ID verification, authorization)
- Configuration options and .env examples
- How it works (long polling, authentication flow)
- Error handling and troubleshooting guide

Features:
- Optional command support (can disable while keeping notifications)
- Configurable polling interval
- Complete security documentation
- Troubleshooting guide for common issues

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-05 15:39:02 +09:00
agentson
57a45a24cb feat: implement status query commands /status and /positions (issue #67)
Some checks failed
CI / test (pull_request) Has been cancelled
Add real-time status and portfolio monitoring via Telegram.

Changes:
- Implement /status handler (mode, markets, P&L, trading state)
- Implement /positions handler (holdings with grouping by market)
- Integrate with Broker API and RiskManager
- Add 5 comprehensive tests for status commands

Features:
- /status: Shows trading mode, enabled markets, pause state, P&L, circuit breaker
- /positions: Lists holdings grouped by market (domestic/overseas)
- Error handling: Graceful degradation on API failures
- Empty state: Handles portfolios with no positions

Integration:
- Uses broker.get_balance() for account data
- Uses risk.calculate_pnl() for P&L calculation
- Accesses pause_trading.is_set() for trading state
- Groups positions by market for better readability

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-05 15:29:52 +09:00
agentson
70701bf73a feat: implement trading control commands /stop and /resume (issue #65)
Some checks failed
CI / test (pull_request) Has been cancelled
Add pause/resume functionality for remote trading control via Telegram.

Changes:
- Add pause_trading Event to main.py
- Implement /stop handler (pause trading)
- Implement /resume handler (resume trading)
- Integrate pause logic into both daily and realtime trading loops
- Add 4 comprehensive tests for trading control

Features:
- /stop: Pauses all trading operations
- /resume: Resumes trading operations
- Idempotent: Handles repeated stop/resume gracefully
- Status feedback: Informs if already paused/active
- Works in both daily and realtime trading modes

Security:
- Commands verified by TelegramCommandHandler chat_id check
- Only authorized users can control trading

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-05 14:40:19 +09:00
agentson
48a99962e3 feat: implement basic commands /start and /help (issue #63)
Some checks failed
CI / test (pull_request) Has been cancelled
Integrate TelegramCommandHandler into main.py and implement
welcome and help commands.

Changes:
- Import TelegramCommandHandler in main.py
- Initialize command handler and register /start and /help
- Start/stop command handler with proper lifecycle management
- Add tests for command content validation

Features:
- /start: Welcome message with bot introduction
- /help: Complete command reference
- Handlers respond with HTML-formatted messages
- Clean startup/shutdown integration

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-05 13:55:52 +09:00
agentson
065c9daaad feat: implement TelegramCommandHandler core structure (issue #61)
Some checks failed
CI / test (pull_request) Has been cancelled
Add TelegramCommandHandler class with long polling, command routing,
and security features.

Changes:
- Add TelegramCommandHandler class to telegram_client.py
- Implement long polling with getUpdates API
- Add command registration and routing mechanism
- Implement chat ID verification for security
- Add comprehensive tests (16 tests)
- Coverage: 85% for telegram_client.py

Features:
- start_polling() / stop_polling() lifecycle management
- register_command() for handler registration
- Chat ID verification to prevent unauthorized access
- Error isolation (command failures don't crash system)
- Graceful handling of API errors and timeouts

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-05 13:47:27 +09:00
agentson
259f9d2e24 feat: add generic send_message method to TelegramClient (issue #59)
Some checks failed
CI / test (pull_request) Has been cancelled
Add send_message(text, parse_mode) method that can be used for both
notifications and command responses. Refactor _send_notification to
use the new method.

Changes:
- Add send_message() method with return value for success/failure
- Refactor _send_notification() to call send_message()
- Add comprehensive tests for send_message()
- Coverage: 93% for telegram_client.py

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-05 13:39:09 +09:00
agentson
0057de4d12 feat: implement daily trading mode with batch decisions (issue #57)
Some checks failed
CI / test (pull_request) Has been cancelled
Add API-efficient daily trading mode for Gemini Free tier compatibility:

## Features

- **Batch Decisions**: GeminiClient.decide_batch() analyzes multiple stocks
  in a single API call using compressed JSON format
- **Daily Trading Mode**: run_daily_session() executes N sessions per day
  at configurable intervals (default: 4 sessions, 6 hours apart)
- **Mode Selection**: TRADE_MODE env var switches between daily (batch)
  and realtime (per-stock) modes
- **Requirements Log**: docs/requirements-log.md tracks user feedback
  chronologically for project evolution

## Configuration

- TRADE_MODE: "daily" (default) | "realtime"
- DAILY_SESSIONS: 1-10 (default: 4)
- SESSION_INTERVAL_HOURS: 1-24 (default: 6)

## API Efficiency

- 2 markets × 4 sessions = 8 API calls/day (within Free tier 20 calls)
- 3 markets × 4 sessions = 12 API calls/day (within Free tier 20 calls)

## Testing

- 9 new batch decision tests (all passing)
- All existing tests maintained (298 passed)

## Documentation

- docs/architecture.md: Trading Modes section with daily vs realtime
- CLAUDE.md: Requirements Management section
- docs/requirements-log.md: Initial entries for API efficiency needs

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