feat(portfolio): add asset name field across API, DB, and CLI

This commit is contained in:
2026-04-03 14:51:36 +00:00
parent aeb4f10fd0
commit 0654b24d66
13 changed files with 115 additions and 19 deletions
+4
View File
@@ -79,6 +79,7 @@ def portfolio_status(
def create_portfolio( def create_portfolio(
ctx: typer.Context, ctx: typer.Context,
portfolio_id: str = typer.Argument(..., help="Portfolio identifier."), portfolio_id: str = typer.Argument(..., help="Portfolio identifier."),
name: str | None = typer.Option(None, help="Asset display name."),
symbol: str = typer.Option(..., help="Trading symbol."), symbol: str = typer.Option(..., help="Trading symbol."),
broker: str = typer.Option("kis", help="Broker code."), broker: str = typer.Option("kis", help="Broker code."),
status: str = typer.Option("enabled", help="Portfolio status."), status: str = typer.Option("enabled", help="Portfolio status."),
@@ -96,6 +97,7 @@ def create_portfolio(
lambda service, app_context: service.create_portfolio( lambda service, app_context: service.create_portfolio(
CreatePortfolioRequest( CreatePortfolioRequest(
portfolio_id=portfolio_id, portfolio_id=portfolio_id,
name=name,
symbol=symbol, symbol=symbol,
broker=broker, broker=broker,
status=status, status=status,
@@ -117,6 +119,7 @@ def update_portfolio(
portfolio_id: str = typer.Argument(..., help="Portfolio identifier."), portfolio_id: str = typer.Argument(..., help="Portfolio identifier."),
broker: str | None = typer.Option(None, help="Broker code."), broker: str | None = typer.Option(None, help="Broker code."),
status: str | None = typer.Option(None, help="Portfolio status."), status: str | None = typer.Option(None, help="Portfolio status."),
name: str | None = typer.Option(None, help="Asset display name."),
symbol: str | None = typer.Option(None, help="Trading symbol."), symbol: str | None = typer.Option(None, help="Trading symbol."),
strategy_name: str | None = typer.Option(None, help="Strategy name."), strategy_name: str | None = typer.Option(None, help="Strategy name."),
strategy_params: str | None = typer.Option(None, help="Strategy params as JSON object."), strategy_params: str | None = typer.Option(None, help="Strategy params as JSON object."),
@@ -132,6 +135,7 @@ def update_portfolio(
UpdatePortfolioRequest( UpdatePortfolioRequest(
broker=broker, broker=broker,
status=status, status=status,
name=name,
symbol=symbol, symbol=symbol,
strategy_name=strategy_name, strategy_name=strategy_name,
strategy_params=parsed_strategy_params, strategy_params=parsed_strategy_params,
+1
View File
@@ -70,6 +70,7 @@ class Portfolio:
portfolio_id: str portfolio_id: str
broker: str broker: str
status: str status: str
name: str
symbol: str symbol: str
cash_balance: float = 0.0 cash_balance: float = 0.0
asset_quantity: float = 0.0 asset_quantity: float = 0.0
+4
View File
@@ -22,6 +22,7 @@ class PortfolioDomainRepository(Protocol):
portfolio_id: str, portfolio_id: str,
symbol: str, symbol: str,
*, *,
name: str | None = None,
broker: str = "kis", broker: str = "kis",
status: str = "enabled", status: str = "enabled",
active_strategy_id: str | None = None, active_strategy_id: str | None = None,
@@ -34,6 +35,7 @@ class PortfolioDomainRepository(Protocol):
*, *,
broker: str, broker: str,
status: str, status: str,
name: str,
symbol: str, symbol: str,
cash_balance: float, cash_balance: float,
asset_quantity: float, asset_quantity: float,
@@ -99,6 +101,7 @@ def apply_buy(
portfolio_id=portfolio.portfolio_id, portfolio_id=portfolio.portfolio_id,
broker=portfolio.broker, broker=portfolio.broker,
status=portfolio.status, status=portfolio.status,
name=portfolio.name,
symbol=portfolio.symbol, symbol=portfolio.symbol,
cash_balance=float(portfolio.cash_balance) - total_cost, cash_balance=float(portfolio.cash_balance) - total_cost,
asset_quantity=float(portfolio.asset_quantity) + quantity, asset_quantity=float(portfolio.asset_quantity) + quantity,
@@ -159,6 +162,7 @@ def apply_sell(
portfolio_id=portfolio.portfolio_id, portfolio_id=portfolio.portfolio_id,
broker=portfolio.broker, broker=portfolio.broker,
status=portfolio.status, status=portfolio.status,
name=portfolio.name,
symbol=portfolio.symbol, symbol=portfolio.symbol,
cash_balance=float(portfolio.cash_balance) + net_proceeds, cash_balance=float(portfolio.cash_balance) + net_proceeds,
asset_quantity=float(portfolio.asset_quantity) - quantity, asset_quantity=float(portfolio.asset_quantity) - quantity,
+2
View File
@@ -86,6 +86,7 @@ class PortfolioRepository(Protocol):
portfolio_id: str, portfolio_id: str,
symbol: str, symbol: str,
*, *,
name: str | None = None,
broker: str = "kis", broker: str = "kis",
status: str = "enabled", status: str = "enabled",
active_strategy_id: str | None = None, active_strategy_id: str | None = None,
@@ -99,6 +100,7 @@ class PortfolioRepository(Protocol):
*, *,
broker: str, broker: str,
status: str, status: str,
name: str,
symbol: str, symbol: str,
cash_balance: float, cash_balance: float,
asset_quantity: float, asset_quantity: float,
+27 -16
View File
@@ -62,6 +62,7 @@ _SELECT_PORTFOLIO = """
portfolio_id, portfolio_id,
broker, broker,
status, status,
name,
symbol, symbol,
cash_balance, cash_balance,
asset_quantity, asset_quantity,
@@ -214,6 +215,7 @@ class PostgresPortfolioRepository:
portfolio_id TEXT PRIMARY KEY, portfolio_id TEXT PRIMARY KEY,
broker TEXT NOT NULL DEFAULT 'kis', broker TEXT NOT NULL DEFAULT 'kis',
status TEXT NOT NULL DEFAULT 'enabled', status TEXT NOT NULL DEFAULT 'enabled',
name TEXT NOT NULL,
symbol TEXT NOT NULL, symbol TEXT NOT NULL,
cash_balance DOUBLE PRECISION NOT NULL, cash_balance DOUBLE PRECISION NOT NULL,
asset_quantity DOUBLE PRECISION NOT NULL, asset_quantity DOUBLE PRECISION NOT NULL,
@@ -227,6 +229,9 @@ class PostgresPortfolioRepository:
) )
""" """
) )
cur.execute("ALTER TABLE portfolios ADD COLUMN IF NOT EXISTS name TEXT")
cur.execute("UPDATE portfolios SET name = symbol WHERE name IS NULL OR name = ''")
cur.execute("ALTER TABLE portfolios ALTER COLUMN name SET NOT NULL")
cur.execute( cur.execute(
""" """
CREATE TABLE IF NOT EXISTS portfolio_ledger ( CREATE TABLE IF NOT EXISTS portfolio_ledger (
@@ -321,7 +326,7 @@ class PostgresPortfolioRepository:
if row is None: if row is None:
raise ValueError("포트폴리오를 찾을 수 없습니다") raise ValueError("포트폴리오를 찾을 수 없습니다")
raw_available = row[9] if len(row) > 9 else None raw_available = row[10] if len(row) > 10 else None
if raw_available is None: if raw_available is None:
avabile_strategies = None avabile_strategies = None
elif isinstance(raw_available, list): elif isinstance(raw_available, list):
@@ -333,16 +338,17 @@ class PostgresPortfolioRepository:
portfolio_id=row[0], portfolio_id=row[0],
broker=row[1] or "kis", broker=row[1] or "kis",
status=row[2] or "enabled", status=row[2] or "enabled",
symbol=row[3], name=row[3],
cash_balance=float(row[4]), symbol=row[4],
asset_quantity=float(row[5]), cash_balance=float(row[5]),
price=float(row[6]), asset_quantity=float(row[6]),
profit_buffer=float(row[7]), price=float(row[7]),
active_strategy_id=row[8] if len(row) > 8 else None, profit_buffer=float(row[8]),
active_strategy_id=row[9] if len(row) > 9 else None,
avabile_strategies=avabile_strategies, avabile_strategies=avabile_strategies,
created_at=row[10] if len(row) > 10 else None, created_at=row[11] if len(row) > 11 else None,
updated_at=row[11] if len(row) > 11 else None, updated_at=row[12] if len(row) > 12 else None,
last_trade_at=row[12] if len(row) > 12 else None, last_trade_at=row[13] if len(row) > 13 else None,
) )
@staticmethod @staticmethod
@@ -698,6 +704,7 @@ class PostgresPortfolioRepository:
portfolio_id: str, portfolio_id: str,
symbol: str, symbol: str,
*, *,
name: str | None = None,
broker: str = "kis", broker: str = "kis",
status: str = "enabled", status: str = "enabled",
active_strategy_id: str | None = None, active_strategy_id: str | None = None,
@@ -709,17 +716,18 @@ class PostgresPortfolioRepository:
cur.execute( cur.execute(
""" """
INSERT INTO portfolios ( INSERT INTO portfolios (
portfolio_id, broker, status, symbol, portfolio_id, broker, status, name, symbol,
cash_balance, asset_quantity, asset_price, profit_buffer, cash_balance, asset_quantity, asset_price, profit_buffer,
active_strategy_id, avabile_strategies active_strategy_id, avabile_strategies
) )
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
ON CONFLICT (portfolio_id) DO NOTHING ON CONFLICT (portfolio_id) DO NOTHING
""", """,
( (
portfolio_id, portfolio_id,
broker, broker,
status, status,
name or symbol,
symbol, symbol,
float(initial_cash), float(initial_cash),
0.0, 0.0,
@@ -739,6 +747,7 @@ class PostgresPortfolioRepository:
*, *,
broker: str, broker: str,
status: str, status: str,
name: str,
symbol: str, symbol: str,
cash_balance: float, cash_balance: float,
asset_quantity: float, asset_quantity: float,
@@ -755,12 +764,12 @@ class PostgresPortfolioRepository:
cur.execute( cur.execute(
""" """
INSERT INTO portfolios ( INSERT INTO portfolios (
portfolio_id, broker, status, symbol, portfolio_id, broker, status, name, symbol,
cash_balance, asset_quantity, asset_price, profit_buffer, cash_balance, asset_quantity, asset_price, profit_buffer,
active_strategy_id, avabile_strategies active_strategy_id, avabile_strategies
) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s) ) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
RETURNING RETURNING
portfolio_id, broker, status, symbol, portfolio_id, broker, status, name, symbol,
cash_balance, asset_quantity, asset_price, profit_buffer, cash_balance, asset_quantity, asset_price, profit_buffer,
active_strategy_id, avabile_strategies, created_at, updated_at, last_trade_at active_strategy_id, avabile_strategies, created_at, updated_at, last_trade_at
""", """,
@@ -768,6 +777,7 @@ class PostgresPortfolioRepository:
portfolio_id, portfolio_id,
broker, broker,
status, status,
name,
symbol, symbol,
float(cash_balance), float(cash_balance),
float(asset_quantity), float(asset_quantity),
@@ -785,6 +795,7 @@ class PostgresPortfolioRepository:
allowed = { allowed = {
"broker": "broker", "broker": "broker",
"status": "status", "status": "status",
"name": "name",
"symbol": "symbol", "symbol": "symbol",
"asset_price": "asset_price", "asset_price": "asset_price",
"active_strategy_id": "active_strategy_id", "active_strategy_id": "active_strategy_id",
@@ -812,7 +823,7 @@ class PostgresPortfolioRepository:
SET {', '.join(assignments)} SET {', '.join(assignments)}
WHERE portfolio_id = %s WHERE portfolio_id = %s
RETURNING RETURNING
portfolio_id, broker, status, symbol, portfolio_id, broker, status, name, symbol,
cash_balance, asset_quantity, asset_price, profit_buffer, cash_balance, asset_quantity, asset_price, profit_buffer,
active_strategy_id, avabile_strategies, created_at, updated_at, last_trade_at active_strategy_id, avabile_strategies, created_at, updated_at, last_trade_at
""", """,
+3
View File
@@ -35,6 +35,7 @@ class LedgerEntryResponse(BaseModel):
class PortfolioBase(BaseModel): class PortfolioBase(BaseModel):
broker: str = "kis" broker: str = "kis"
status: str = "enabled" status: str = "enabled"
name: str | None = None
symbol: str symbol: str
@@ -42,6 +43,7 @@ class PortfolioSummary(BaseModel):
portfolio_id: str portfolio_id: str
broker: str broker: str
status: str status: str
name: str
symbol: str symbol: str
cash_balance: float = 0.0 cash_balance: float = 0.0
asset_quantity: float = 0.0 asset_quantity: float = 0.0
@@ -80,6 +82,7 @@ class CreatePortfolioRequest(PortfolioBase):
class UpdatePortfolioRequest(BaseModel): class UpdatePortfolioRequest(BaseModel):
broker: str | None = None broker: str | None = None
status: str | None = None status: str | None = None
name: str | None = None
symbol: str | None = None symbol: str | None = None
strategy_name: str | None = None strategy_name: str | None = None
strategy_params: dict[str, Any] | None = None strategy_params: dict[str, Any] | None = None
+2
View File
@@ -44,6 +44,7 @@ def _to_portfolio_summary(portfolio: Portfolio):
portfolio_id=portfolio.portfolio_id, portfolio_id=portfolio.portfolio_id,
broker=portfolio.broker, broker=portfolio.broker,
status=portfolio.status, status=portfolio.status,
name=portfolio.name,
symbol=portfolio.symbol, symbol=portfolio.symbol,
cash_balance=portfolio.cash_balance, cash_balance=portfolio.cash_balance,
asset_quantity=portfolio.asset_quantity, asset_quantity=portfolio.asset_quantity,
@@ -150,6 +151,7 @@ class PortfolioService:
payload.portfolio_id, payload.portfolio_id,
broker=payload.broker, broker=payload.broker,
status=payload.status, status=payload.status,
name=payload.name or payload.symbol,
symbol=payload.symbol, symbol=payload.symbol,
cash_balance=payload.cash_balance, cash_balance=payload.cash_balance,
asset_quantity=payload.asset_quantity, asset_quantity=payload.asset_quantity,
+4
View File
@@ -50,6 +50,7 @@ Response 200:
"portfolio_id": "krw-btc", "portfolio_id": "krw-btc",
"broker": "upbit", "broker": "upbit",
"status": "enabled", "status": "enabled",
"name": "Bitcoin",
"symbol": "KRW-BTC", "symbol": "KRW-BTC",
"cash_balance": 1000000.0, "cash_balance": 1000000.0,
"asset_quantity": 0.1, "asset_quantity": 0.1,
@@ -82,6 +83,7 @@ Response 200:
"portfolio_id": "krw-btc", "portfolio_id": "krw-btc",
"broker": "upbit", "broker": "upbit",
"status": "enabled", "status": "enabled",
"name": "Bitcoin",
"symbol": "KRW-BTC", "symbol": "KRW-BTC",
"cash_balance": 1000000.0, "cash_balance": 1000000.0,
"asset_quantity": 0.1, "asset_quantity": 0.1,
@@ -133,6 +135,7 @@ curl -X POST "http://localhost:8000/portfolios" \
"portfolio_id": "krw-btc", "portfolio_id": "krw-btc",
"broker": "upbit", "broker": "upbit",
"status": "enabled", "status": "enabled",
"name": "Bitcoin",
"symbol": "KRW-BTC", "symbol": "KRW-BTC",
"strategy_name": "target_value", "strategy_name": "target_value",
"strategy_params": {}, "strategy_params": {},
@@ -159,6 +162,7 @@ curl -X PATCH "http://localhost:8000/portfolios/krw-btc" \
-H "Content-Type: application/json" \ -H "Content-Type: application/json" \
-d '{ -d '{
"broker": "upbit", "broker": "upbit",
"name": "Bitcoin",
"symbol": "KRW-BTC" "symbol": "KRW-BTC"
}' }'
``` ```
+5 -2
View File
@@ -5,7 +5,7 @@
This document defines the database schema in an AI-agent-friendly format. This document defines the database schema in an AI-agent-friendly format.
- Source of truth: Alembic revisions in `migrations/versions` - Source of truth: Alembic revisions in `migrations/versions`
- Current baseline revision: `20260403_0007` - Current baseline revision: `20260403_0008`
- Baseline files: - Baseline files:
- `migrations/versions/20260403_0001_initial_portfolio_schema.py` - `migrations/versions/20260403_0001_initial_portfolio_schema.py`
- `migrations/versions/20260403_0002_strategy_set_columns.py` - `migrations/versions/20260403_0002_strategy_set_columns.py`
@@ -14,6 +14,7 @@ This document defines the database schema in an AI-agent-friendly format.
- `migrations/versions/20260403_0005_auth_user_fields_and_tokens.py` - `migrations/versions/20260403_0005_auth_user_fields_and_tokens.py`
- `migrations/versions/20260403_0006_bot_principals_and_bot_tokens.py` - `migrations/versions/20260403_0006_bot_principals_and_bot_tokens.py`
- `migrations/versions/20260403_0007_bot_principal_permission_only.py` - `migrations/versions/20260403_0007_bot_principal_permission_only.py`
- `migrations/versions/20260403_0008_portfolio_name_column.py`
## 2. Scope ## 2. Scope
@@ -145,7 +146,7 @@ Purpose:
Current baseline note: Current baseline note:
- The columns below describe the currently migrated schema through revision `20260403_0005`. - The columns below describe the currently migrated schema through revision `20260403_0008`.
Columns: Columns:
@@ -154,6 +155,7 @@ Columns:
| portfolio_id | Text | NO | - | Primary Key | | portfolio_id | Text | NO | - | Primary Key |
| broker | Text | NO | "kis" | Broker code | | broker | Text | NO | "kis" | Broker code |
| status | Text | NO | "enabled" | Portfolio status | | status | Text | NO | "enabled" | Portfolio status |
| name | Text | NO | - | Asset name |
| symbol | Text | NO | - | Trading symbol | | symbol | Text | NO | - | Trading symbol |
| cash_balance | Float | NO | - | Current cash balance | | cash_balance | Float | NO | - | Current cash balance |
| asset_quantity | Float | NO | - | Current asset quantity | | asset_quantity | Float | NO | - | Current asset quantity |
@@ -294,3 +296,4 @@ When schema changes:
| 20260403_0005 | migrations/versions/20260403_0005_auth_user_fields_and_tokens.py | Add password/permission/login fields to `users` and create `auth_tokens` table | | 20260403_0005 | migrations/versions/20260403_0005_auth_user_fields_and_tokens.py | Add password/permission/login fields to `users` and create `auth_tokens` table |
| 20260403_0006 | migrations/versions/20260403_0006_bot_principals_and_bot_tokens.py | Add `bot_principals` table and `auth_tokens.bot_principal_id` for bot API key management | | 20260403_0006 | migrations/versions/20260403_0006_bot_principals_and_bot_tokens.py | Add `bot_principals` table and `auth_tokens.bot_principal_id` for bot API key management |
| 20260403_0007 | migrations/versions/20260403_0007_bot_principal_permission_only.py | Remove `bot_principals.owner_user_id` and enforce bot-local `permission` model | | 20260403_0007 | migrations/versions/20260403_0007_bot_principal_permission_only.py | Remove `bot_principals.owner_user_id` and enforce bot-local `permission` model |
| 20260403_0008 | migrations/versions/20260403_0008_portfolio_name_column.py | Add non-null `portfolios.name` (asset display name), backfilled from `symbol` |
+4 -1
View File
@@ -387,6 +387,7 @@ Bootstrap rule:
- `portfolio_id: str` - `portfolio_id: str`
- `broker: str = "kis"` - `broker: str = "kis"`
- `status: str = "enabled"` - `status: str = "enabled"`
- `name: str | null` (when null, defaults to `symbol`)
- `symbol: str` - `symbol: str`
- `strategy_name: str = "target_value"` - `strategy_name: str = "target_value"`
- `strategy_params: object = {}` - `strategy_params: object = {}`
@@ -401,6 +402,7 @@ Bootstrap rule:
- `broker: str | null` - `broker: str | null`
- `status: str | null` - `status: str | null`
- `name: str | null`
- `symbol: str | null` - `symbol: str | null`
- `strategy_name: str | null` - `strategy_name: str | null`
- `strategy_params: object | null` - `strategy_params: object | null`
@@ -492,6 +494,7 @@ Bootstrap rule:
- `portfolio_id: str` - `portfolio_id: str`
- `broker: str` - `broker: str`
- `status: str` - `status: str`
- `name: str`
- `symbol: str` - `symbol: str`
- `cash_balance: float` - `cash_balance: float`
- `asset_quantity: float` - `asset_quantity: float`
@@ -553,7 +556,7 @@ Portfolio subcommands:
- `portfoliohub portfolio list [--broker ...] [--status ...]` - `portfoliohub portfolio list [--broker ...] [--status ...]`
- `portfoliohub portfolio status <portfolio_id> [--recent 5]` - `portfoliohub portfolio status <portfolio_id> [--recent 5]`
- `portfoliohub portfolio create <portfolio_id> --symbol ... [options] [--force]` - `portfoliohub portfolio create <portfolio_id> --symbol ... [--name ...] [options] [--force]`
- `portfoliohub portfolio update <portfolio_id> [options] [--force]` - `portfoliohub portfolio update <portfolio_id> [options] [--force]`
- `portfoliohub portfolio buy <portfolio_id> --quantity ... --price ... [options] [--force]` - `portfoliohub portfolio buy <portfolio_id> --quantity ... --price ... [options] [--force]`
- `portfoliohub portfolio sell <portfolio_id> --quantity ... --price ... [options] [--force]` - `portfoliohub portfolio sell <portfolio_id> --quantity ... --price ... [options] [--force]`
@@ -0,0 +1,51 @@
"""add portfolio name column
Revision ID: 20260403_0008
Revises: 20260403_0007
Create Date: 2026-04-03 14:45:00
"""
from __future__ import annotations
import sqlalchemy as sa
from alembic import op
from sqlalchemy import inspect
revision = "20260403_0008"
down_revision = "20260403_0007"
branch_labels = None
depends_on = None
def _table_exists(inspector, table_name: str) -> bool:
return table_name in inspector.get_table_names()
def _column_exists(inspector, table_name: str, column_name: str) -> bool:
return any(column["name"] == column_name for column in inspector.get_columns(table_name))
def upgrade() -> None:
bind = op.get_bind()
inspector = inspect(bind)
if not _table_exists(inspector, "portfolios"):
return
if not _column_exists(inspector, "portfolios", "name"):
op.add_column("portfolios", sa.Column("name", sa.Text(), nullable=True))
op.execute("UPDATE portfolios SET name = symbol WHERE name IS NULL OR name = ''")
op.alter_column("portfolios", "name", existing_type=sa.Text(), nullable=False)
def downgrade() -> None:
bind = op.get_bind()
inspector = inspect(bind)
if not _table_exists(inspector, "portfolios"):
return
if _column_exists(inspector, "portfolios", "name"):
op.drop_column("portfolios", "name")
+5
View File
@@ -110,6 +110,7 @@ class FakeRepo:
portfolio_id: str, portfolio_id: str,
symbol: str, symbol: str,
*, *,
name: str | None = None,
broker: str = "kis", broker: str = "kis",
status: str = "enabled", status: str = "enabled",
active_strategy_id: str | None = None, active_strategy_id: str | None = None,
@@ -121,6 +122,7 @@ class FakeRepo:
portfolio_id=portfolio_id, portfolio_id=portfolio_id,
broker=broker, broker=broker,
status=status, status=status,
name=name or symbol,
symbol=symbol, symbol=symbol,
cash_balance=initial_cash, cash_balance=initial_cash,
active_strategy_id=active_strategy_id, active_strategy_id=active_strategy_id,
@@ -134,6 +136,7 @@ class FakeRepo:
*, *,
broker: str, broker: str,
status: str, status: str,
name: str,
symbol: str, symbol: str,
cash_balance: float, cash_balance: float,
asset_quantity: float, asset_quantity: float,
@@ -146,6 +149,7 @@ class FakeRepo:
portfolio_id=portfolio_id, portfolio_id=portfolio_id,
broker=broker, broker=broker,
status=status, status=status,
name=name,
symbol=symbol, symbol=symbol,
cash_balance=cash_balance, cash_balance=cash_balance,
asset_quantity=asset_quantity, asset_quantity=asset_quantity,
@@ -275,6 +279,7 @@ def _portfolio() -> Portfolio:
portfolio_id="005930:tv", portfolio_id="005930:tv",
broker="kis", broker="kis",
status="enabled", status="enabled",
name="Samsung Electronics",
symbol="005930", symbol="005930",
cash_balance=1_000_000.0, cash_balance=1_000_000.0,
asset_quantity=1.0, asset_quantity=1.0,
+3
View File
@@ -26,6 +26,7 @@ class FakeRepo:
portfolio_id: str, portfolio_id: str,
symbol: str, symbol: str,
*, *,
name: str | None = None,
broker: str = "kis", broker: str = "kis",
status: str = "enabled", status: str = "enabled",
active_strategy_id: str | None = None, active_strategy_id: str | None = None,
@@ -36,6 +37,7 @@ class FakeRepo:
portfolio_id=portfolio_id, portfolio_id=portfolio_id,
broker=broker, broker=broker,
status=status, status=status,
name=name or symbol,
symbol=symbol, symbol=symbol,
cash_balance=initial_cash, cash_balance=initial_cash,
active_strategy_id=active_strategy_id, active_strategy_id=active_strategy_id,
@@ -155,6 +157,7 @@ def _portfolio() -> Portfolio:
portfolio_id="p1", portfolio_id="p1",
broker="kis", broker="kis",
status="enabled", status="enabled",
name="Samsung Electronics",
symbol="005930", symbol="005930",
cash_balance=1_000_000.0, cash_balance=1_000_000.0,
asset_quantity=0.0, asset_quantity=0.0,