fix: overseas price API exchange code + VTS balance fallback (#147) #148

Merged
jihoson merged 2 commits from feature/issue-147-overseas-price-balance-fix into main 2026-02-19 05:49:38 +09:00
Collaborator

문제 요약 (Issue #147)

미국 해외주식 거래 시 BUY 결정이 나와도 실제 주문이 실행되지 않는 두 가지 원인을 수정합니다.

원인 1: 가격 API 거래소 코드 불일치

get_overseas_price() 가 HHDFS00000300 API에 NASD/NYSE/AMEX (긴 형식)를 전송했으나
실제 API는 NAS/NYS/AMS (짧은 형식)를 요구 → last='' 빈 응답 → price=0

수정: _PRICE_EXCHANGE_MAP_RANKING_EXCHANGE_MAP과 동일하게 설정,
get_overseas_price() 내부에서 매핑 적용

원인 2: VTS 해외 잔고 API 오류

VTTS3012R API가 이 계좌에서 "ERROR : INPUT INVALID_CHECK_ACNO" 반환 → total_cash=0
_determine_order_quantity() 가 0 반환 → 주문 건너뜀

수정:

  • PAPER_OVERSEAS_CASH 설정 추가 (기본값 $50,000)
  • paper 모드에서 잔고 API가 0을 반환하면 PAPER_OVERSEAS_CASH 값으로 폴백
  • 가격 API가 0을 반환하면 스캐너 후보의 candidate.price 로 폴백

변경 파일

파일 변경 내용
src/broker/overseas.py _PRICE_EXCHANGE_MAP 추가 및 get_overseas_price()에 적용
src/config.py PAPER_OVERSEAS_CASH: float = Field(default=50000.0) 추가
src/main.py paper cash 폴백 및 candidate price 폴백 (trading_cycle, run_daily_session)
tests/test_overseas_broker.py 기존 테스트 수정 + TestPriceExchangeMap, TestPaperOverseasCash 추가

테스트 결과

616 passed in 16.00s  (전체 커버리지 76%)
TestPriceExchangeMap: 5 tests ✓
TestPaperOverseasCash: 3 tests ✓

실제 확인된 로그 (수정 전)

Scenario matched for MRNX: BUY (confidence=80)  ✓
Decision for EWUS (NYSE American): BUY (confidence=80)  ✓
Skip BUY APLZ (NYSE American): no affordable quantity (cash=0.00, price=0.00)  ✗

이 PR 적용 후 해외 주식 BUY 주문이 실제로 전송되어야 합니다.

Closes #147

## 문제 요약 (Issue #147) 미국 해외주식 거래 시 BUY 결정이 나와도 실제 주문이 실행되지 않는 두 가지 원인을 수정합니다. ### 원인 1: 가격 API 거래소 코드 불일치 `get_overseas_price()` 가 HHDFS00000300 API에 `NASD`/`NYSE`/`AMEX` (긴 형식)를 전송했으나 실제 API는 `NAS`/`NYS`/`AMS` (짧은 형식)를 요구 → `last=''` 빈 응답 → `price=0` **수정**: `_PRICE_EXCHANGE_MAP`을 `_RANKING_EXCHANGE_MAP`과 동일하게 설정, `get_overseas_price()` 내부에서 매핑 적용 ### 원인 2: VTS 해외 잔고 API 오류 `VTTS3012R` API가 이 계좌에서 "ERROR : INPUT INVALID_CHECK_ACNO" 반환 → `total_cash=0` → `_determine_order_quantity()` 가 0 반환 → 주문 건너뜀 **수정**: - `PAPER_OVERSEAS_CASH` 설정 추가 (기본값 $50,000) - paper 모드에서 잔고 API가 0을 반환하면 `PAPER_OVERSEAS_CASH` 값으로 폴백 - 가격 API가 0을 반환하면 스캐너 후보의 `candidate.price` 로 폴백 ## 변경 파일 | 파일 | 변경 내용 | |------|----------| | `src/broker/overseas.py` | `_PRICE_EXCHANGE_MAP` 추가 및 `get_overseas_price()`에 적용 | | `src/config.py` | `PAPER_OVERSEAS_CASH: float = Field(default=50000.0)` 추가 | | `src/main.py` | paper cash 폴백 및 candidate price 폴백 (`trading_cycle`, `run_daily_session`) | | `tests/test_overseas_broker.py` | 기존 테스트 수정 + `TestPriceExchangeMap`, `TestPaperOverseasCash` 추가 | ## 테스트 결과 ``` 616 passed in 16.00s (전체 커버리지 76%) TestPriceExchangeMap: 5 tests ✓ TestPaperOverseasCash: 3 tests ✓ ``` ## 실제 확인된 로그 (수정 전) ``` Scenario matched for MRNX: BUY (confidence=80) ✓ Decision for EWUS (NYSE American): BUY (confidence=80) ✓ Skip BUY APLZ (NYSE American): no affordable quantity (cash=0.00, price=0.00) ✗ ``` 이 PR 적용 후 해외 주식 BUY 주문이 실제로 전송되어야 합니다. Closes #147
agentson added 2 commits 2026-02-18 23:48:36 +09:00
fix: use smart rule-based fallback playbook when Gemini fails (issue #145)
Some checks failed
CI / test (pull_request) Has been cancelled
96e2ad4f1f
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>
fix: price API exchange code mapping and VTS overseas balance fallback (#147)
Some checks failed
CI / test (pull_request) Has been cancelled
3a54db8948
- 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>
jihoson merged commit 45b48fa7cd into main 2026-02-19 05:49:38 +09:00
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: jihoson/The-Ouroboros#148