feat: integrate 398-400-401 for main merge REQ-OPS-001 TASK-OPS-003 TEST-ACC-009 #410
18
src/main.py
18
src/main.py
@@ -2084,6 +2084,15 @@ async def trading_cycle(
|
||||
quantity=quantity,
|
||||
price=order_price,
|
||||
)
|
||||
if result.get("rt_cd", "0") != "0":
|
||||
order_succeeded = False
|
||||
msg1 = result.get("msg1") or ""
|
||||
logger.warning(
|
||||
"KR order not accepted for %s: rt_cd=%s msg=%s",
|
||||
stock_code,
|
||||
result.get("rt_cd"),
|
||||
msg1,
|
||||
)
|
||||
else:
|
||||
# For overseas orders, always use limit orders (지정가):
|
||||
# - KIS market orders (ORD_DVSN=01) calculate quantity based on upper limit
|
||||
@@ -3293,6 +3302,15 @@ async def run_daily_session(
|
||||
quantity=quantity,
|
||||
price=order_price,
|
||||
)
|
||||
if result.get("rt_cd", "0") != "0":
|
||||
order_succeeded = False
|
||||
daily_msg1 = result.get("msg1") or ""
|
||||
logger.warning(
|
||||
"KR order not accepted for %s: rt_cd=%s msg=%s",
|
||||
stock_code,
|
||||
result.get("rt_cd"),
|
||||
daily_msg1,
|
||||
)
|
||||
else:
|
||||
# KIS VTS only accepts limit orders; use 0.5% premium for BUY
|
||||
if decision.action == "BUY":
|
||||
|
||||
@@ -913,6 +913,46 @@ class TestTradingCycleTelegramIntegration:
|
||||
# Verify notification was attempted
|
||||
mock_telegram.notify_trade_execution.assert_called_once()
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_kr_rejected_order_does_not_notify_or_log_trade(
|
||||
self,
|
||||
mock_broker: MagicMock,
|
||||
mock_overseas_broker: MagicMock,
|
||||
mock_scenario_engine: MagicMock,
|
||||
mock_playbook: DayPlaybook,
|
||||
mock_risk: MagicMock,
|
||||
mock_db: MagicMock,
|
||||
mock_decision_logger: MagicMock,
|
||||
mock_context_store: MagicMock,
|
||||
mock_criticality_assessor: MagicMock,
|
||||
mock_telegram: MagicMock,
|
||||
mock_market: MagicMock,
|
||||
) -> None:
|
||||
"""KR orders rejected by KIS should not trigger success side effects."""
|
||||
mock_broker.send_order = AsyncMock(
|
||||
return_value={"rt_cd": "1", "msg1": "장운영시간이 아닙니다."}
|
||||
)
|
||||
|
||||
with patch("src.main.log_trade") as mock_log_trade:
|
||||
await trading_cycle(
|
||||
broker=mock_broker,
|
||||
overseas_broker=mock_overseas_broker,
|
||||
scenario_engine=mock_scenario_engine,
|
||||
playbook=mock_playbook,
|
||||
risk=mock_risk,
|
||||
db_conn=mock_db,
|
||||
decision_logger=mock_decision_logger,
|
||||
context_store=mock_context_store,
|
||||
criticality_assessor=mock_criticality_assessor,
|
||||
telegram=mock_telegram,
|
||||
market=mock_market,
|
||||
stock_code="005930",
|
||||
scan_candidates={},
|
||||
)
|
||||
|
||||
mock_telegram.notify_trade_execution.assert_not_called()
|
||||
mock_log_trade.assert_not_called()
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_fat_finger_notification_sent(
|
||||
self,
|
||||
|
||||
Reference in New Issue
Block a user