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