ํฐ์คํ ๋ฆฌ ๋ทฐ
๐ AI ํํธ ํตํฉ ์ด์ฉ ๋์๋ณด๋ ๊ตฌ์ถ – Streamlit์ผ๋ก ์ค์๊ฐ ํธ๋ ์ด๋ฉ·๋ฆฌ์คํฌ·์ฑ๊ณผ๋ฅผ ํ๋์
octo54 2025. 11. 12. 14:04๐ AI ํํธ ํตํฉ ์ด์ฉ ๋์๋ณด๋ ๊ตฌ์ถ – Streamlit์ผ๋ก ์ค์๊ฐ ํธ๋ ์ด๋ฉ·๋ฆฌ์คํฌ·์ฑ๊ณผ๋ฅผ ํ๋์
— “AI๊ฐ ํฌ์ํ๊ณ , ๋๋ ๊ฒฐ๊ณผ๋ง ํ์ธํ๋ค.” ์์ ์๋ํ๋ ํํธ ๋์๋ณด๋ ๋ง๋ค๊ธฐ
์ด์ ์ฐ๋ฆฌ ์์คํ
์ AI๊ฐ ์ค์ค๋ก ํ์ตํ๊ณ , ์์ธกํ๊ณ , ํฌ์ํ๋ ๋จ๊ณ๊น์ง ์์ต๋๋ค.
์ด๋ฒ ๊ธ์์๋ ๊ทธ ๋ชจ๋ ๊ฒฐ๊ณผ๋ฅผ ํ ํ๋ฉด์์ ์ง๊ด์ ์ผ๋ก ๋ชจ๋ํฐ๋งํ ์ ์๋ ๋์๋ณด๋๋ฅผ ๋ง๋ค์ด๋ด
๋๋ค.
์ฆ, ์ง๊ธ๊น์ง ๋ง๋
- ๋ฐ์ดํฐ ์์ง
- ๋ชจ๋ธ ์์ธก
- ๋ฆฌ์คํฌ ๊ด๋ฆฌ
- ์์ฐ๋ฐฐ๋ถ
- ๋ฐฑํ
์คํธ ๋ฐ ์ค๊ฑฐ๋ ๊ฒฐ๊ณผ
์ด ๋ชจ๋ ๊ฑธ ํตํฉํ๋ AI ์ด์ฉ ์ฝ์์ ์์ฑํฉ๋๋ค.
๐ฏ ๋ชฉํ
“ํ๋์ Streamlit ํ๋ฉด์์
โ AI ๋ชจ๋ธ ์ํ,
โก ์ค์๊ฐ ์์ฅ ๋ฐ์ดํฐ,
โข ํฌํธํด๋ฆฌ์ค ๋น์ค,
โฃ ๋์ ์์ต๋ฅ ,
โค ๋ฆฌ์คํฌ ์งํ๋ฅผ
์ค์๊ฐ์ผ๋ก ๋ชจ๋ํฐ๋งํ๋ค.”
โ๏ธ 1๏ธโฃ Streamlit ํ๊ฒฝ ๊ตฌ์ฑ
pip install streamlit plotly requests pandas redis sqlalchemy
- plotly: ์ค์๊ฐ ์ฐจํธ ์๊ฐํ
- redis: ์ค์๊ฐ ๋ฐ์ดํฐ ์บ์
- sqlalchemy: PostgreSQL ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐ๊ฒฐ
๐งฑ 2๏ธโฃ ์ ์ฒด ๋ ์ด์์ ๊ตฌ์ฑ
import streamlit as st
import pandas as pd
import plotly.express as px
import requests, redis, json
from sqlalchemy import create_engine
st.set_page_config(page_title="AI Quant Dashboard", layout="wide")
st.title("๐ AI Quant Investment Control Panel")
r = redis.Redis()
engine = create_engine("postgresql://quant_user:quant_pass@localhost:5432/quantdb")
col1, col2 = st.columns([2, 1])
๐งฉ 3๏ธโฃ ์ค์๊ฐ ์์ฅ ๋ฐ์ดํฐ ํ์
st.sidebar.header("๐ ์ค์๊ฐ ์์ธ")
live_quotes = {k.decode(): float(v) for k, v in r.hgetall("live_quotes").items()}
df_quotes = pd.DataFrame(list(live_quotes.items()), columns=["Symbol", "Price"])
st.sidebar.table(df_quotes)
Redis์ ์์ด๋ ์ค์๊ฐ WebSocket ์์ธ(live_quotes)๋ฅผ ๊ทธ๋๋ก ํ์ํฉ๋๋ค.
๐ฐ 4๏ธโฃ ํฌํธํด๋ฆฌ์ค ํํฉ
col1.subheader("๐ผ Portfolio Overview")
df_port = pd.read_sql("SELECT * FROM portfolio_snapshot", engine)
col1.dataframe(df_port[["ticker", "quantity", "entry_price", "current_price", "current_pnl"]])
โ ์ฃผ์ ์งํ
- current_pnl: ํ์ฌ ์์ต
- entry_price: ๋งค์ ๊ฐ
- quantity: ๋ณด์ ์๋
๐ 5๏ธโฃ ๋์ ์์ต๋ฅ ์ฐจํธ
cum_ret = df_port.groupby("date")["current_pnl"].sum().cumsum()
fig = px.line(cum_ret, title="๐ Cumulative P&L", labels={"value": "PnL", "index": "Date"})
col1.plotly_chart(fig, use_container_width=True)
์์ต๋ฅ ์ด ์ค์ ๊ฑฐ๋์ ๋ฐฑํ ์คํธ ์์ชฝ ๋ฐ์ดํฐ๋ฅผ ํตํฉํด ์๋ ์ ๋ฐ์ดํธ๋ฉ๋๋ค.
๐ง 6๏ธโฃ AI ๋ชจ๋ธ ์ํ
col2.subheader("๐ค AI Model Status")
mlflow_api = "http://localhost:5001/api/2.0/mlflow/experiments/list"
mlflow_data = requests.get(mlflow_api).json()
exp_df = pd.DataFrame(mlflow_data["experiments"])
col2.metric("ํ์ฑ ๋ชจ๋ธ ์", len(exp_df))
col2.json(exp_df[["name", "lifecycle_stage", "artifact_location"]].to_dict("records")[:3])
- MLflow์ ์ฐ๊ฒฐ๋์ด ๋ชจ๋ธ ๋ฒ์ , ์ํ(Production/Staging)๋ฅผ ํ์ํฉ๋๋ค.
- ์ต์ ๋ชจ๋ธ์ด ์๋ ๋ฐฐํฌ๋๋ฉด ์ด ํ๋ฉด์์ ์ฆ์ ๋ฐ์๋ฉ๋๋ค.
๐งญ 7๏ธโฃ ๋ฆฌ์คํฌ ์งํ ๋ชจ๋ํฐ๋ง
st.subheader("๐งญ Risk Metrics")
risk_data = json.loads(r.get("risk_status"))
c1, c2, c3 = st.columns(3)
c1.metric("VaR (99%)", f"{risk_data['VaR']*100:.2f}%")
c2.metric("CVaR (99%)", f"{risk_data['CVaR']*100:.2f}%")
c3.metric("MDD", f"{risk_data['MDD']*100:.2f}%")
if risk_data["Status"].startswith("โ ๏ธ"):
st.warning("๋ฆฌ์คํฌ ์ฃผ์ ๊ตฌ๊ฐ! ํ๊ธ ๋น์ค ํ๋ ๊ถ์ฅ โ ๏ธ")
else:
st.success("์์ ๊ตฌ๊ฐ์
๋๋ค โ
")
Flask API์์ ์ค์๊ฐ ๋ฆฌ์คํฌ ์ํ๋ฅผ ๋ถ๋ฌ์ ๊ฒฝ๊ณ ์ฌ๋ถ๋ฅผ ์๋ ํ์ํฉ๋๋ค.
๐ช 8๏ธโฃ ์์ฐ ๋ฐฐ๋ถ ๋ฐ ๋กํ ์ด์ ์ํ
st.subheader("๐ Global Asset Allocation")
alloc_api = "http://localhost:5000/allocation"
alloc = requests.get(alloc_api).json()
st.bar_chart(pd.Series(alloc))
- AI ์์ฐ๋ฐฐ๋ถ ๋ชจ๋ธ(๋ฉํฐ์์ /๋กํ ์ด์ )์ ์ต์ ์ถ์ฒ ๋น์ค ํ์
- ๋ง๋๊ทธ๋ํ ํํ๋ก ์ค์๊ฐ ๊ฐฑ์
๐ 9๏ธโฃ ์๋ฆผ ๋ฐ ๋ฆฌํฌํธ ๋งํฌ
st.subheader("๐ฐ Notifications")
st.info("๐
๋ค์ ๋ฆฌ๋ฐธ๋ฐ์ฑ ์ผ์ : 2025-12-01")
st.write("๐ [์ต๊ทผ ํฌ์ ๋ฆฌํฌํธ ๋ค์ด๋ก๋](./reports/quant_202511.pdf)")
Airflow DAG๊ณผ ์ฐ๋๋์ด ๋ฆฌ๋ฐธ๋ฐ์ฑ ์ค์ผ์ค ๋ฐ ๋ฆฌํฌํธ ๋งํฌ ์๋ ๊ฐฑ์ .
๐ง 10๏ธโฃ ์๋ ์๋ก๊ณ ์นจ
import time
st_autorefresh = st.sidebar.checkbox("์๋ ์๋ก๊ณ ์นจ", value=True)
if st_autorefresh:
st.experimental_rerun()
time.sleep(30)
๋์๋ณด๋๊ฐ 30์ด๋ง๋ค ์๋์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ์๋ก ๋ถ๋ฌ์
๊ฑฐ์ ์ค์๊ฐ์ ๊ฐ๊น์ด ์ด์ ๋ชจ๋ํฐ๋ง์ด ๊ฐ๋ฅํฉ๋๋ค.
๐ ๊ฒฐ๊ณผ – AI ํํธ ์ด์ฉ ์ฝ์
โ Streamlit ์ค์๊ฐ ๋์๋ณด๋ ์์ฑ
- ์ค์๊ฐ ์์ธ
- ํฌํธํด๋ฆฌ์ค ์์ต
- AI ๋ชจ๋ธ ์ํ
- VaR/CVaR ๋ฆฌ์คํฌ
- ์์ฐ๋ฐฐ๋ถ ์ฐจํธ
- ๋ฆฌํฌํธ ๋ค์ด๋ก๋
“AI๊ฐ ํฌ์ํ๊ณ , ์ฌ๋์ ๋ชจ๋ํฐ๋ง๋ง ํ๋ ์์ ์๋ํ ์์คํ ”
์ด์ ์ด์ฉ์ฌ ์์ค์ ์ฝ์์ ๊ฐ์ธ ๊ฐ๋ฐ์๋ ๊ตฌ์ถํ ์ ์์ต๋๋ค.
๐ ๋ค์ ๊ธ ์๊ณ
๋ค์ ํธ์์๋ **“AI ํํธ ์์คํ
๋ฐฐํฌ – Docker Compose + Nginx Reverse Proxy + SSL ์ค์ ๊น์ง”**๋ฅผ ๋ค๋ฃน๋๋ค.
๋ก์ปฌ์์ ๊ตฌ์ถํ AI ์ด์ฉ ์์คํ
์
ํด๋ผ์ฐ๋ ์๋ฒ์ ์์ ํ๊ฒ ๋ฐฐํฌํ๊ณ ์ธ๋ถ ์ ์ ๊ฐ๋ฅํ ์ค์ ํ๊ฒฝ์ผ๋ก ๋ง๋๋ ๋จ๊ณ์
๋๋ค.
AIํํธ,Streamlit,ํธ๋ ์ด๋ฉ๋์๋ณด๋,๋ฆฌ์คํฌ๊ด๋ฆฌ,ํฌํธํด๋ฆฌ์ค์๊ฐํ,MLflow,Redis,PostgreSQL,์ค์๊ฐํฌ์,ํํธ์ด์ฉ
'์ฃผ์' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
- Total
- Today
- Yesterday
- ์๋ฐ๋ฉด์
- CI/CD
- REACT
- Next.js
- nextJS
- Python
- DevOps
- ํ๋ก ํธ์๋๊ฐ๋ฐ
- fastapi
- Redis
- llm
- ๊ฐ๋ฐ๋ธ๋ก๊ทธ
- seo ์ต์ ํ 10๊ฐ
- Express
- Prisma
- ๋ฐฑ์๋๊ฐ๋ฐ
- JWT
- PostgreSQL
- SEO์ต์ ํ
- ai์ฒ ํ
- Docker
- JAX
- NestJS
- kotlin
- flax
- rag
- ์ฟ ๋ฒ๋คํฐ์ค
- node.js
- ๋ฅ๋ฌ๋
- ์น๊ฐ๋ฐ
| ์ผ | ์ | ํ | ์ | ๋ชฉ | ๊ธ | ํ |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | 7 |
| 8 | 9 | 10 | 11 | 12 | 13 | 14 |
| 15 | 16 | 17 | 18 | 19 | 20 | 21 |
| 22 | 23 | 24 | 25 | 26 | 27 | 28 |
