Files
auto-stock/backend/alembic/versions/0002_add_performance_indexes.py
shuim 9d096ddd57
Some checks failed
CI/CD Pipeline / test-backend (push) Has been cancelled
CI/CD Pipeline / test-frontend (push) Has been cancelled
CI/CD Pipeline / build-and-push (push) Has been cancelled
M1 │ 스캐너 최소 거래량 100만→10만주 │ kosdaq_scanner.py │
├─────┼─────────────────────────────────────────────────────┼────────────────────────────────┤
  │ M2  │ ADX 히스테리시스 18/22 (플리핑 방지)                │ mean_reversion_strategy.py     │
  ├─────┼─────────────────────────────────────────────────────┼────────────────────────────────┤
  │ M3  │ 분할매도 최소 수익 1.0%→0.5%                        │ mean_reversion_strategy.py     │
  ├─────┼─────────────────────────────────────────────────────┼────────────────────────────────┤
  │ M4  │ ORB 갭 필터 4% + 레인지 폭 0.3% 최소                │ day_trading_strategy.py        │
  ├─────┼─────────────────────────────────────────────────────┼────────────────────────────────┤
  │ M5  │ 쿨다운 스트릭 부분매도 시 미변경                    │ daytrading/position_manager.py │
  ├─────┼─────────────────────────────────────────────────────┼────────────────────────────────┤
  │ M6  │ MDD 강제매도 loss_tracker 기록 제거 (허위 ban 방지) │ mdd_manager.py                 │
  ├─────┼─────────────────────────────────────────────────────┼────────────────────────────────┤
  │ M7  │ RSI Wilder 스무딩으로 통일                          │ mean_reversion_strategy.py
2026-04-03 11:41:52 +09:00

74 lines
4.2 KiB
Python

"""add performance indexes
쿼리 성능 향상을 위한 복합 인덱스 추가.
자주 사용되는 필터 및 조회 패턴에 맞춰 인덱스를 생성합니다.
Revision ID: 0002
Revises: 0001
Create Date: 2026-03-10
"""
from typing import Sequence, Union
from alembic import op
import sqlalchemy as sa
revision: str = "0002"
down_revision: Union[str, None] = "0001"
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
def _safe_create_index(table, index_name, columns):
"""인덱스가 이미 존재하면 스킵."""
conn = op.get_bind()
result = conn.execute(sa.text(
"SELECT 1 FROM pg_indexes WHERE tablename=:t AND indexname=:i"
), {"t": table, "i": index_name})
if not result.fetchone():
op.create_index(index_name, table, columns)
def upgrade() -> None:
_safe_create_index("trade_history", "ix_trade_history_status_created_at", ["status", "created_at"])
_safe_create_index("trade_history", "ix_trade_history_stock_order_created", ["stock_code", "order_type", "created_at"])
_safe_create_index("market_data", "ix_market_data_stock_code_timestamp", ["stock_code", "timestamp"])
_safe_create_index("stock_analysis", "ix_stock_analysis_stock_code_analysis_date", ["stock_code", "analysis_date"])
_safe_create_index("portfolio", "ix_portfolio_quantity", ["quantity"])
_safe_create_index("active_trades", "ix_active_trades_stock_code_status", ["stock_code", "status"])
_safe_create_index("active_trades", "ix_active_trades_status", ["status"])
_safe_create_index("watchlist_stocks", "ix_watchlist_stocks_is_active_stock_code", ["is_active", "stock_code"])
_safe_create_index("claude_analysis_log", "ix_claude_analysis_log_stock_code_created_at", ["stock_code", "created_at"])
def downgrade() -> None:
# ── claude_analysis_log ───────────────────────────────────────────────
with op.batch_alter_table("claude_analysis_log", schema=None) as batch_op:
batch_op.drop_index("ix_claude_analysis_log_stock_code_created_at")
# ── watchlist_stocks ──────────────────────────────────────────────────
with op.batch_alter_table("watchlist_stocks", schema=None) as batch_op:
batch_op.drop_index("ix_watchlist_stocks_is_active_stock_code")
# ── active_trades ─────────────────────────────────────────────────────
with op.batch_alter_table("active_trades", schema=None) as batch_op:
batch_op.drop_index("ix_active_trades_status")
batch_op.drop_index("ix_active_trades_stock_code_status")
# ── portfolio ─────────────────────────────────────────────────────────
with op.batch_alter_table("portfolio", schema=None) as batch_op:
batch_op.drop_index("ix_portfolio_quantity")
# ── stock_analysis ────────────────────────────────────────────────────
with op.batch_alter_table("stock_analysis", schema=None) as batch_op:
batch_op.drop_index("ix_stock_analysis_stock_code_analysis_date")
# ── market_data ───────────────────────────────────────────────────────
with op.batch_alter_table("market_data", schema=None) as batch_op:
batch_op.drop_index("ix_market_data_stock_code_timestamp")
# ── trade_history ─────────────────────────────────────────────────────
with op.batch_alter_table("trade_history", schema=None) as batch_op:
batch_op.drop_index("ix_trade_history_stock_order_created")
batch_op.drop_index("ix_trade_history_status_created_at")