feat: refactor portfolio strategy references

This commit is contained in:
2026-04-03 08:16:07 +00:00
parent ebd4559939
commit 908068d9aa
14 changed files with 294 additions and 139 deletions
+56 -63
View File
@@ -20,13 +20,12 @@ _SELECT_PORTFOLIO = """
broker,
status,
symbol,
strategy_name,
strategy_params,
cash_balance,
asset_quantity,
asset_price,
profit_buffer,
current_strategy_set_id,
active_strategy_id,
avabile_strategies,
created_at,
updated_at,
last_trade_at
@@ -98,13 +97,12 @@ class PostgresPortfolioRepository:
broker TEXT NOT NULL DEFAULT 'kis',
status TEXT NOT NULL DEFAULT 'enabled',
symbol TEXT NOT NULL,
strategy_name TEXT NOT NULL DEFAULT '',
strategy_params JSONB NOT NULL DEFAULT '{}'::jsonb,
cash_balance DOUBLE PRECISION NOT NULL,
asset_quantity DOUBLE PRECISION NOT NULL,
asset_price DOUBLE PRECISION NOT NULL DEFAULT 0,
profit_buffer DOUBLE PRECISION NOT NULL DEFAULT 0,
current_strategy_set_id TEXT DEFAULT NULL,
active_strategy_id TEXT DEFAULT NULL,
avabile_strategies TEXT[] DEFAULT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
last_trade_at TIMESTAMPTZ
@@ -155,32 +153,28 @@ class PostgresPortfolioRepository:
if row is None:
raise ValueError("포트폴리오를 찾을 수 없습니다")
raw_params = row[5] if len(row) > 5 else {}
if isinstance(raw_params, str):
try:
strategy_params = json.loads(raw_params) if raw_params else {}
except json.JSONDecodeError:
strategy_params = {}
elif isinstance(raw_params, dict):
strategy_params = raw_params
raw_available = row[9] if len(row) > 9 else None
if raw_available is None:
avabile_strategies = None
elif isinstance(raw_available, list):
avabile_strategies = [str(item) for item in raw_available]
else:
strategy_params = {}
avabile_strategies = [str(raw_available)]
return Portfolio(
portfolio_id=row[0],
broker=row[1] or "kis",
status=row[2] or "enabled",
symbol=row[3],
strategy_name=row[4] or "",
strategy_params=strategy_params,
cash_balance=float(row[6]),
asset_quantity=float(row[7]),
price=float(row[8]),
profit_buffer=float(row[9]),
current_strategy_set_id=row[10] if len(row) > 10 else None,
created_at=row[11] if len(row) > 11 else None,
updated_at=row[12] if len(row) > 12 else None,
last_trade_at=row[13] if len(row) > 13 else None,
cash_balance=float(row[4]),
asset_quantity=float(row[5]),
price=float(row[6]),
profit_buffer=float(row[7]),
active_strategy_id=row[8] if len(row) > 8 else None,
avabile_strategies=avabile_strategies,
created_at=row[10] if len(row) > 10 else None,
updated_at=row[11] if len(row) > 11 else None,
last_trade_at=row[12] if len(row) > 12 else None,
)
@staticmethod
@@ -215,8 +209,8 @@ class PostgresPortfolioRepository:
*,
broker: str = "kis",
status: str = "enabled",
strategy_name: str = "",
strategy_params: dict[str, Any] | None = None,
active_strategy_id: str | None = None,
avabile_strategies: list[str] | None = None,
initial_cash: float = 0.0,
) -> Portfolio:
self.ensure_schema()
@@ -224,10 +218,11 @@ class PostgresPortfolioRepository:
cur.execute(
"""
INSERT INTO portfolios (
portfolio_id, broker, status, symbol, strategy_name, strategy_params,
cash_balance, asset_quantity, asset_price, profit_buffer
portfolio_id, broker, status, symbol,
cash_balance, asset_quantity, asset_price, profit_buffer,
active_strategy_id, avabile_strategies
)
VALUES (%s, %s, %s, %s, %s, %s::jsonb, %s, %s, %s, %s)
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
ON CONFLICT (portfolio_id) DO NOTHING
""",
(
@@ -235,12 +230,12 @@ class PostgresPortfolioRepository:
broker,
status,
symbol,
strategy_name,
json.dumps(strategy_params or {}),
float(initial_cash),
0.0,
0.0,
0.0,
active_strategy_id,
avabile_strategies,
),
)
cur.execute(_SELECT_PORTFOLIO + "WHERE portfolio_id = %s", (portfolio_id,))
@@ -254,12 +249,12 @@ class PostgresPortfolioRepository:
broker: str,
status: str,
symbol: str,
strategy_name: str,
strategy_params: dict,
cash_balance: float,
asset_quantity: float,
asset_price: float,
profit_buffer: float,
active_strategy_id: str | None,
avabile_strategies: list[str] | None,
) -> Portfolio:
self.ensure_schema()
with self._connect().cursor() as cur:
@@ -269,25 +264,26 @@ class PostgresPortfolioRepository:
cur.execute(
"""
INSERT INTO portfolios (
portfolio_id, broker, status, symbol, strategy_name, strategy_params,
cash_balance, asset_quantity, asset_price, profit_buffer
) VALUES (%s, %s, %s, %s, %s, %s::jsonb, %s, %s, %s, %s)
RETURNING
portfolio_id, broker, status, symbol, strategy_name, strategy_params,
portfolio_id, broker, status, symbol,
cash_balance, asset_quantity, asset_price, profit_buffer,
current_strategy_set_id, created_at, updated_at, last_trade_at
active_strategy_id, avabile_strategies
) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
RETURNING
portfolio_id, broker, status, symbol,
cash_balance, asset_quantity, asset_price, profit_buffer,
active_strategy_id, avabile_strategies, created_at, updated_at, last_trade_at
""",
(
portfolio_id,
broker,
status,
symbol,
strategy_name,
json.dumps(strategy_params),
float(cash_balance),
float(asset_quantity),
float(asset_price),
float(profit_buffer),
active_strategy_id,
avabile_strategies,
),
)
row = cur.fetchone()
@@ -299,19 +295,18 @@ class PostgresPortfolioRepository:
"broker": "broker",
"status": "status",
"symbol": "symbol",
"strategy_name": "strategy_name",
"strategy_params": "strategy_params",
"asset_price": "asset_price",
"current_strategy_set_id": "current_strategy_set_id",
"active_strategy_id": "active_strategy_id",
"avabile_strategies": "avabile_strategies",
}
assignments: list[str] = []
params: list[object] = []
for key, value in fields.items():
if value is None or key not in allowed:
continue
if key == "strategy_params":
assignments.append("strategy_params = %s::jsonb")
params.append(json.dumps(value))
if key == "avabile_strategies":
assignments.append("avabile_strategies = %s")
params.append(value)
else:
assignments.append(f"{allowed[key]} = %s")
params.append(value)
@@ -326,9 +321,9 @@ class PostgresPortfolioRepository:
SET {', '.join(assignments)}
WHERE portfolio_id = %s
RETURNING
portfolio_id, broker, status, symbol, strategy_name, strategy_params,
portfolio_id, broker, status, symbol,
cash_balance, asset_quantity, asset_price, profit_buffer,
current_strategy_set_id, created_at, updated_at, last_trade_at
active_strategy_id, avabile_strategies, created_at, updated_at, last_trade_at
""",
(*params, portfolio_id),
)
@@ -413,13 +408,12 @@ class PostgresPortfolioRepository:
SET broker = %s,
status = %s,
symbol = %s,
strategy_name = %s,
strategy_params = %s::jsonb,
cash_balance = %s,
asset_quantity = %s,
asset_price = %s,
profit_buffer = %s,
current_strategy_set_id = %s,
active_strategy_id = %s,
avabile_strategies = %s,
updated_at = %s,
last_trade_at = CASE WHEN %s IN ('BUY', 'SELL') THEN %s ELSE last_trade_at END
WHERE portfolio_id = %s
@@ -428,13 +422,12 @@ class PostgresPortfolioRepository:
portfolio.broker,
portfolio.status,
portfolio.symbol,
portfolio.strategy_name,
json.dumps(portfolio.strategy_params),
float(portfolio.cash_balance),
float(portfolio.asset_quantity),
float(current_price),
float(portfolio.profit_buffer),
portfolio.current_strategy_set_id,
portfolio.active_strategy_id,
portfolio.avabile_strategies,
trade_time,
action,
trade_time,
@@ -496,14 +489,14 @@ class PostgresPortfolioRepository:
asset_quantity = 0,
asset_price = 0,
profit_buffer = 0,
current_strategy_set_id = NULL,
active_strategy_id = NULL,
updated_at = NOW(),
last_trade_at = NULL
WHERE portfolio_id = %s
RETURNING
portfolio_id, broker, status, symbol, strategy_name, strategy_params,
portfolio_id, broker, status, symbol,
cash_balance, asset_quantity, asset_price, profit_buffer,
current_strategy_set_id, created_at, updated_at, last_trade_at
active_strategy_id, avabile_strategies, created_at, updated_at, last_trade_at
""",
(portfolio_id,),
)
@@ -540,9 +533,9 @@ class PostgresPortfolioRepository:
updated_at = NOW()
WHERE portfolio_id = %s
RETURNING
portfolio_id, broker, status, symbol, strategy_name, strategy_params,
portfolio_id, broker, status, symbol,
cash_balance, asset_quantity, asset_price, profit_buffer,
current_strategy_set_id, created_at, updated_at, last_trade_at
active_strategy_id, avabile_strategies, created_at, updated_at, last_trade_at
""",
(updated_buffer, portfolio_id),
)
@@ -609,9 +602,9 @@ class PostgresPortfolioRepository:
updated_at = NOW()
WHERE portfolio_id = %s
RETURNING
portfolio_id, broker, status, symbol, strategy_name, strategy_params,
portfolio_id, broker, status, symbol,
cash_balance, asset_quantity, asset_price, profit_buffer,
current_strategy_set_id, created_at, updated_at, last_trade_at
active_strategy_id, avabile_strategies, created_at, updated_at, last_trade_at
""",
(cash, buf, portfolio_id),
)