feat: 구조 리팩토링
This commit is contained in:
parent
67a9b23fa5
commit
23cada68f7
1
src/ui/components/__init__.py
Normal file
1
src/ui/components/__init__.py
Normal file
@ -0,0 +1 @@
|
||||
__all__ = ['charts']
|
||||
189
src/ui/components/charts.py
Normal file
189
src/ui/components/charts.py
Normal file
@ -0,0 +1,189 @@
|
||||
"""
|
||||
Charting components for the Streamlit Quant application.
|
||||
"""
|
||||
import streamlit as st
|
||||
import pandas as pd
|
||||
import numpy as np
|
||||
import plotly.graph_objects as go
|
||||
import plotly.express as px
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
def plot_stock_price(price_data, ticker_column='종목코드', date_column='날짜',
|
||||
price_column='종가', name_column='종목명'):
|
||||
"""
|
||||
Plot stock price chart for selected stocks.
|
||||
|
||||
Args:
|
||||
price_data: DataFrame with price data
|
||||
ticker_column: Column name for ticker code
|
||||
date_column: Column name for date
|
||||
price_column: Column name for price
|
||||
name_column: Column name for stock name
|
||||
"""
|
||||
if price_data.empty:
|
||||
st.warning("가격 데이터가 없습니다.")
|
||||
return
|
||||
|
||||
# Get unique tickers
|
||||
tickers = price_data[ticker_column].unique()
|
||||
|
||||
if len(tickers) == 0:
|
||||
st.warning("표시할 종목이 없습니다.")
|
||||
return
|
||||
|
||||
# Create figure
|
||||
fig = go.Figure()
|
||||
|
||||
# Add traces
|
||||
for ticker in tickers:
|
||||
ticker_data = price_data[price_data[ticker_column] == ticker]
|
||||
|
||||
name = ticker
|
||||
if name_column in ticker_data.columns:
|
||||
name = ticker_data[name_column].iloc[0] if not ticker_data.empty else ticker
|
||||
name = f"{name} ({ticker})"
|
||||
|
||||
fig.add_trace(
|
||||
go.Scatter(
|
||||
x=ticker_data[date_column],
|
||||
y=ticker_data[price_column],
|
||||
mode='lines',
|
||||
name=name
|
||||
)
|
||||
)
|
||||
|
||||
# Update layout
|
||||
fig.update_layout(
|
||||
title='주가 차트',
|
||||
xaxis_title='날짜',
|
||||
yaxis_title='가격',
|
||||
legend_title='종목',
|
||||
hovermode='x unified'
|
||||
)
|
||||
|
||||
st.plotly_chart(fig, use_container_width=True)
|
||||
|
||||
|
||||
def plot_returns_comparison(returns_data, benchmark_data=None,
|
||||
date_column='날짜', returns_column='누적수익률'):
|
||||
"""
|
||||
Plot returns comparison chart for strategy vs benchmark.
|
||||
|
||||
Args:
|
||||
returns_data: DataFrame with strategy returns
|
||||
benchmark_data: DataFrame with benchmark returns (optional)
|
||||
date_column: Column name for date
|
||||
returns_column: Column name for returns
|
||||
"""
|
||||
if returns_data.empty:
|
||||
st.warning("수익률 데이터가 없습니다.")
|
||||
return
|
||||
|
||||
# Create figure
|
||||
fig = go.Figure()
|
||||
|
||||
# Add strategy trace
|
||||
fig.add_trace(
|
||||
go.Scatter(
|
||||
x=returns_data[date_column],
|
||||
y=returns_data[returns_column],
|
||||
mode='lines',
|
||||
name='전략'
|
||||
)
|
||||
)
|
||||
|
||||
# Add benchmark trace if provided
|
||||
if benchmark_data is not None and not benchmark_data.empty:
|
||||
fig.add_trace(
|
||||
go.Scatter(
|
||||
x=benchmark_data[date_column],
|
||||
y=benchmark_data[returns_column],
|
||||
mode='lines',
|
||||
name='벤치마크'
|
||||
)
|
||||
)
|
||||
|
||||
# Update layout
|
||||
fig.update_layout(
|
||||
title='수익률 비교',
|
||||
xaxis_title='날짜',
|
||||
yaxis_title='누적수익률 (%)',
|
||||
legend_title='전략',
|
||||
hovermode='x unified'
|
||||
)
|
||||
|
||||
st.plotly_chart(fig, use_container_width=True)
|
||||
|
||||
|
||||
def plot_factor_distribution(data, factor_column, title=None):
|
||||
"""
|
||||
Plot histogram for factor distribution.
|
||||
|
||||
Args:
|
||||
data: DataFrame with factor data
|
||||
factor_column: Column name for factor
|
||||
title: Chart title (optional)
|
||||
"""
|
||||
if data.empty:
|
||||
st.warning("데이터가 없습니다.")
|
||||
return
|
||||
|
||||
if factor_column not in data.columns:
|
||||
st.warning(f"{factor_column} 칼럼이, 데이터에 없습니다.")
|
||||
return
|
||||
|
||||
# Create histogram
|
||||
fig = px.histogram(
|
||||
data,
|
||||
x=factor_column,
|
||||
nbins=30,
|
||||
marginal="box",
|
||||
title=title or f"{factor_column} 분포"
|
||||
)
|
||||
|
||||
# Update layout
|
||||
fig.update_layout(
|
||||
xaxis_title=factor_column,
|
||||
yaxis_title='종목 수'
|
||||
)
|
||||
|
||||
st.plotly_chart(fig, use_container_width=True)
|
||||
|
||||
|
||||
def plot_scatter_matrix(data, columns, color_column=None, size_column=None, title=None):
|
||||
"""
|
||||
Plot scatter matrix for multiple factors.
|
||||
|
||||
Args:
|
||||
data: DataFrame with factor data
|
||||
columns: List of column names to plot
|
||||
color_column: Column name for color (optional)
|
||||
size_column: Column name for point size (optional)
|
||||
title: Chart title (optional)
|
||||
"""
|
||||
if data.empty:
|
||||
st.warning("데이터가 없습니다.")
|
||||
return
|
||||
|
||||
# Validate columns
|
||||
missing_cols = [col for col in columns if col not in data.columns]
|
||||
if missing_cols:
|
||||
st.warning(f"다음 칼럼이 데이터에 없습니다: {', '.join(missing_cols)}")
|
||||
return
|
||||
|
||||
# Create scatter matrix
|
||||
fig = px.scatter_matrix(
|
||||
data,
|
||||
dimensions=columns,
|
||||
color=color_column if color_column in data.columns else None,
|
||||
size=size_column if size_column in data.columns else None,
|
||||
title=title or "팩터 상관관계"
|
||||
)
|
||||
|
||||
# Update layout
|
||||
fig.update_layout(
|
||||
height=600,
|
||||
width=800
|
||||
)
|
||||
|
||||
st.plotly_chart(fig, use_container_width=True)
|
||||
Loading…
x
Reference in New Issue
Block a user