61 lines
2.4 KiB
Python
61 lines
2.4 KiB
Python
from __future__ import annotations
|
|
|
|
from app.engine.strategies.base import BaseStrategy, Signal
|
|
|
|
|
|
class ConditionalStrategy(BaseStrategy):
|
|
"""조건부 지정가/시장가 전략"""
|
|
|
|
def evaluate(self, current_price: dict, price_history: list[dict], holding_qty: int) -> Signal:
|
|
price = current_price.get("current_price", 0)
|
|
if price <= 0:
|
|
return Signal(action="hold", stock_code=self.stock_code)
|
|
|
|
buy_price = self.params.get("buy_price", 0)
|
|
sell_price = self.params.get("sell_price", 0)
|
|
change_rate_limit = self.params.get("change_rate_limit", 0)
|
|
qty = self.params.get("qty", 1)
|
|
|
|
if change_rate_limit:
|
|
change_rate = current_price.get("change_rate", 0)
|
|
if change_rate <= -change_rate_limit and price > 0:
|
|
return Signal(
|
|
action="buy",
|
|
stock_code=self.stock_code,
|
|
qty=qty,
|
|
price=price,
|
|
reason=f"하락률 조건 충족: {change_rate:.2f}% <= -{change_rate_limit}%",
|
|
confidence=min(abs(change_rate) / change_rate_limit, 1.0),
|
|
)
|
|
if change_rate >= change_rate_limit and holding_qty > 0:
|
|
return Signal(
|
|
action="sell",
|
|
stock_code=self.stock_code,
|
|
qty=min(qty, holding_qty),
|
|
price=price,
|
|
reason=f"상승률 조건 충족: {change_rate:.2f}% >= {change_rate_limit}%",
|
|
confidence=min(abs(change_rate) / change_rate_limit, 1.0),
|
|
)
|
|
|
|
if buy_price and price <= buy_price and holding_qty == 0:
|
|
return Signal(
|
|
action="buy",
|
|
stock_code=self.stock_code,
|
|
qty=qty,
|
|
price=price,
|
|
reason=f"매수 조건 충족: 현재가 {price} <= 목표가 {buy_price}",
|
|
confidence=1.0,
|
|
)
|
|
|
|
if sell_price and price >= sell_price and holding_qty > 0:
|
|
return Signal(
|
|
action="sell",
|
|
stock_code=self.stock_code,
|
|
qty=min(qty, holding_qty),
|
|
price=price,
|
|
reason=f"매도 조건 충족: 현재가 {price} >= 목표가 {sell_price}",
|
|
confidence=1.0,
|
|
)
|
|
|
|
return Signal(action="hold", stock_code=self.stock_code)
|