์ถ์ธ์ถ์ข ํฌ์ ๋ฐฉ๋ฒ๋ก ์ ๊ธฐ๋ฐ์ผ๋ก ํ MCP(Model Context Protocol) ์๋ฒ์ ๋๋ค. ์ฃผ์ ์์ฅ ๋ถ์, ๋งค๋งค ์์ ํ๋จ, ํฌํธํด๋ฆฌ์ค ๊ด๋ฆฌ๋ฅผ ์ํ ์ข ํฉ์ ์ธ ํฌ์ ๋๊ตฌ๋ฅผ ์ ๊ณตํฉ๋๋ค.
Trend Following MCP Server๋ ๋ค์๊ณผ ๊ฐ์ ํต์ฌ ๊ธฐ๋ฅ์ ์ ๊ณตํฉ๋๋ค:
- ๐ ์ฃผ์ ์ ๋ณด ์์ง: ์ค์๊ฐ ์ฃผ๊ฐ, ์ฌ๋ฌด์ ํ, ๋ด์ค ๋ฐ์ดํฐ
- ๐ ๊ธฐ์ ์ ๋ถ์: ์ด๋ํ๊ท , RSI, MACD, ๋ณผ๋ฆฐ์ ๋ฐด๋ ๋ฑ
- ๐ฏ ๋งค๋งค ์์ ์ ํธ: ์ถ์ธ ์ถ์ข ์ ๋ต ๊ธฐ๋ฐ ๋งค์/๋งค๋ ์์ ํ๋จ
- ๐ ํฌํธํด๋ฆฌ์ค ๊ด๋ฆฌ: ์์ฐ ๋ฐฐ๋ถ, ๋ฆฌ์คํฌ ๊ด๋ฆฌ, ์ฑ๊ณผ ์ถ์
- ๐ค AI ๊ธฐ๋ฐ ๋ถ์: ๋จธ์ ๋ฌ๋์ ํ์ฉํ ์์ฅ ์์ธก ๋ฐ ์ต์ ํ
get_stock_info: ์ค์๊ฐ ์ฃผ๊ฐ ๋ฐ์ดํฐ ์์ง ๋ฐ ๊ธฐ์ ์ ๋ณด ์กฐํscreen_stocks: ๊ธฐ์ ์ /๊ธฐ๋ณธ์ ์กฐ๊ฑด์ ๋ฐ๋ฅธ ์ฃผ์ ์คํฌ๋ฆฌ๋- ๊ธฐ์ ์ฌ๋ฌด์ ํ ๋ถ์ (์์ต๊ณ์ฐ์, ์ฌ๋ฌด์ํํ, ํ๊ธํ๋ฆํ)
- ๋ด์ค ๋ฐ ์ด๋ฒคํธ ๋ชจ๋ํฐ๋ง
- ์นํฐ๋ณ ์์ฅ ๋ํฅ ๋ถ์
analyze_technical: ์ข ํฉ์ ์ธ ๊ธฐ์ ์ ๋ถ์ ์ํ- ์ด๋ํ๊ท ์ ๋ถ์ (20์ผ, 50์ผ, 200์ผ SMA/EMA)
- ๋ชจ๋ฉํ ์งํ (RSI, MACD, ์คํ ์บ์คํฑ)
- ๋ณ๋์ฑ ์งํ (๋ณผ๋ฆฐ์ ๋ฐด๋, ATR)
- ๊ฑฐ๋๋ ๋ถ์ (OBV, ๊ฑฐ๋๋ ๊ฐ์ค ํ๊ท )
- ์ถ์ธ ๋ฐฉํฅ ๋ฐ ๊ฐ๋ ๋ถ์
generate_signal: ์ถ์ธ ์ถ์ข ๋งค๋งค ์์ ํ๋จbacktest_signals: ์ ๋ต ๋ฐฑํ ์คํ ๋ฐ ์ฑ๊ณผ ๋ถ์- ๋ฆฌ์คํฌ ๊ด๋ฆฌ ๋ฐ ์์ ๋งค ์ค์
- ํฌ์ง์ ์ฌ์ด์ง ์ต์ ํ
- ์ ํธ ์ ๋ขฐ๋ ๋ฐ ๊ฐ๋ ๊ณ์ฐ
manage_portfolio: ํฌํธํด๋ฆฌ์ค ๋ถ์, ์ต์ ํ, ๋ฆฌ๋ฐธ๋ฐ์ฑanalyze_risk: ํฌํธํด๋ฆฌ์ค ๋ฆฌ์คํฌ ๋ถ์ (VaR, CVaR)- ์์ฐ ๋ฐฐ๋ถ ์ต์ ํ
- ๋ฆฌ์คํฌ ๋๋น ์์ต๋ฅ ๋ถ์
- ์ฑ๊ณผ ์ถ์ ๋ฐ ๋ฆฌํฌํ
TradeMonster/
โโโ src/
โ โโโ mcp/ # MCP ์๋ฒ ํต์ฌ
โ โ โโโ server.py # MCP ์๋ฒ ๋ฉ์ธ
โ โ โโโ schemas.py # ๋ฐ์ดํฐ ์คํค๋ง (Pydantic ๋ชจ๋ธ)
โ โ โโโ tools/ # MCP ๋๊ตฌ๋ค
โ โ โโโ stock_info.py # ์ฃผ์ ์ ๋ณด ๋๊ตฌ
โ โ โโโ technical.py # ๊ธฐ์ ์ ๋ถ์ ๋๊ตฌ
โ โ โโโ signals.py # ๋งค๋งค ์ ํธ ๋๊ตฌ
โ โ โโโ portfolio.py # ํฌํธํด๋ฆฌ์ค ๊ด๋ฆฌ ๋๊ตฌ
โ โโโ analysis/ # ๋ถ์ ์์ง
โ โ โโโ trend_analysis.py # ์ถ์ธ ๋ถ์ ์์ง
โ โ โโโ momentum.py # ๋ชจ๋ฉํ
๋ถ์ (๊ตฌํ ์์ )
โ โ โโโ volatility.py # ๋ณ๋์ฑ ๋ถ์ (๊ตฌํ ์์ )
โ โโโ utils/ # ์ ํธ๋ฆฌํฐ
โ โ โโโ config.py # ์ค์ ๊ด๋ฆฌ (Pydantic ๊ธฐ๋ฐ)
โ โ โโโ logger.py # ๋ก๊น
์์คํ
โ โโโ main.py # ๋ฉ์ธ ์คํ ํ์ผ
โโโ tests/ # ํ
์คํธ ํ์ผ๋ค
โ โโโ test_mcp_server.py # MCP ์๋ฒ ํ
์คํธ
โโโ pyproject.toml # ํ๋ก์ ํธ ์ค์ (์
๋ฐ์ดํธ๋จ)
โโโ README.md # ํ๋ก์ ํธ ๋ฌธ์
โโโ env.example # ํ๊ฒฝ ๋ณ์ ์์
โโโ LICENSE # MIT ๋ผ์ด์ ์ค
- ์ถ์ธ ํ์ธ: ์ฅ๊ธฐ ์ด๋ํ๊ท ์ ์ ๊ธฐ์ค์ผ๋ก ์์น/ํ๋ฝ ์ถ์ธ ํ๋จ
- ๋ชจ๋ฉํ ํ์ฉ: RSI, MACD ๋ฑ ๋ชจ๋ฉํ ์งํ๋ก ๊ฐ๋ ์ธก์
- ๋ณ๋์ฑ ๊ด๋ฆฌ: ๋ณผ๋ฆฐ์ ๋ฐด๋, ATR๋ก ๋ณ๋์ฑ ๊ธฐ๋ฐ ์ง์ /์ฒญ์ฐ
- ๋ฆฌ์คํฌ ์ ์ด: ์์ ๋งค, ์ต์ ๋งค, ํฌ์ง์ ์ฌ์ด์ง์ผ๋ก ๋ฆฌ์คํฌ ๊ด๋ฆฌ
- ๋งค์ ์กฐ๊ฑด: ์์น ์ถ์ธ + ๋ชจ๋ฉํ ์์น + ๋ณ๋์ฑ ํ๋
- ๋งค๋ ์กฐ๊ฑด: ํ๋ฝ ์ถ์ธ + ๋ชจ๋ฉํ ํ๋ฝ + ์ง์ง์ ์ดํ
- ํ๋ฉ ์กฐ๊ฑด: ์ถ์ธ ์ง์ + ๋ฆฌ์คํฌ ๊ด๋ฆฌ ๋ฒ์ ๋ด
# ๊ฐ๋ ฅํ ๋งค์ ์ ํธ
if (trend_direction == "up" and
current_price > sma_20 > sma_50 > sma_200 and
rsi < 70 and # ๊ณผ๋งค์ ์๋
macd > macd_signal and
price_position < 0.8): # ๋ณผ๋ฆฐ์ ์๋จ ๋ฐด๋ ์ดํ
signal_type = "strong_buy"# ์ ์ฅ์ ํด๋ก
git clone https://github.com/yourusername/TradeMonster.git
cd TradeMonster
# ๊ฐ์ํ๊ฒฝ ์์ฑ ๋ฐ ํ์ฑํ
python -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
# ์์กด์ฑ ์ค์น
pip install -e .# .env ํ์ผ ์์ฑ
cp env.example .env
# API ํค ์ค์ (์ ํ์ฌํญ - yfinance๋ ๊ธฐ๋ณธ์ ์ผ๋ก API ํค๊ฐ ํ์ ์์)
YAHOO_FINANCE_API_KEY=your_api_key
ALPHA_VANTAGE_API_KEY=your_alpha_vantage_api_key# ๋ฉ์ธ ์คํ ํ์ผ๋ก ์คํ
python src/main.py
# ๋๋ ์ง์ MCP ์๋ฒ ์คํ
python -m src.mcp.server --dev
# ๋๋ ๊ฐ๋ฐ ๋ชจ๋
python -m src.mcp.server --dev --stdio# ์ ์ฒด ํ
์คํธ ์คํ
pytest tests/
# ํน์ ํ
์คํธ ์คํ
pytest tests/test_mcp_server.py -v# Apple ์ฃผ์ ์ ๋ณด ์กฐํ
stock_info = await session.call_tool("get_stock_info", {
"symbol": "AAPL",
"include_financials": True,
"include_news": True
})# ๊ธฐ์ ์ ์งํ ๋ถ์
analysis = await session.call_tool("analyze_technical", {
"symbol": "AAPL",
"period": "1y",
"indicators": ["sma", "rsi", "macd", "bollinger"]
})# ์ถ์ธ์ถ์ข
๋งค๋งค ์ ํธ
signal = await session.call_tool("generate_signal", {
"symbol": "AAPL",
"strategy": "trend_following",
"risk_level": "moderate"
})# ํฌํธํด๋ฆฌ์ค ๋ถ์
portfolio = await session.call_tool("manage_portfolio", {
"action": "analyze",
"portfolio": [
{"symbol": "AAPL", "shares": 100, "cost_basis": 150.0},
{"symbol": "GOOGL", "shares": 50, "cost_basis": 2800.0}
]
})# ํฌํธํด๋ฆฌ์ค ๋ฆฌ์คํฌ ๋ถ์
risk_analysis = await session.call_tool("analyze_risk", {
"portfolio": portfolio_data,
"confidence_level": 0.95
})# src/mcp/tools/new_tool.py
from mcp import Tool
from typing import Dict, Any
class NewTool(Tool):
name = "new_tool"
description = "์๋ก์ด ๋๊ตฌ ์ค๋ช
"
async def execute(self, params: Dict[str, Any]) -> Dict[str, Any]:
# ๋๊ตฌ ๋ก์ง ๊ตฌํ
return {"result": "success"}# src/utils/config.py์์ ์ค์ ์ถ๊ฐ
class Config(BaseSettings):
new_setting: str = Field(default="default_value", description="์๋ก์ด ์ค์ ")from src.utils.logger import get_logger
logger = get_logger(__name__)
logger.info("์ ๋ณด ๋ฉ์์ง")
logger.error("์๋ฌ ๋ฉ์์ง")- ์น๋ฅ : 65% ์ด์ ๋ชฉํ
- ์คํ ๋น์จ: 1.5 ์ด์ ๋ชฉํ
- ์ต๋ ๋ํญ: 15% ์ดํ ๋ชฉํ
- ์ฐ๊ฐ ์์ต๋ฅ : 20% ์ด์ ๋ชฉํ
- ATR ๊ธฐ๋ฐ ์์ ๋งค: ๋ณ๋์ฑ์ ๋ฐ๋ฅธ ๋์ ์์ ๋งค ์ค์
- ํฌ์ง์ ์ฌ์ด์ง: ์ ๋ขฐ๋์ ๋ฆฌ์คํฌ ์์ค์ ๋ฐ๋ฅธ ํฌ์ง์ ํฌ๊ธฐ ์กฐ์
- ํฌํธํด๋ฆฌ์ค ๋ค๊ฐํ: ์์ฐ ๊ฐ ์๊ด๊ด๊ณ๋ฅผ ๊ณ ๋ คํ ๋ฐฐ๋ถ
- VaR/CVaR ๋ถ์: ํฌํธํด๋ฆฌ์ค ๋ฆฌ์คํฌ ์ธก์
# ๋ณด์์ (Conservative)
stop_loss_multiplier = 2.0
position_size = 0.05 # 5%
# ์ค๊ฐ (Moderate) - ๊ธฐ๋ณธ๊ฐ
stop_loss_multiplier = 1.5
position_size = 0.1 # 10%
# ๊ณต๊ฒฉ์ (Aggressive)
stop_loss_multiplier = 1.0
position_size = 0.15 # 15%- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
- Python 3.13+ ์ฌ์ฉ
- Type hints ํ์
- Pydantic ๋ชจ๋ธ ์ฌ์ฉ
- Async/await ํจํด ์ฌ์ฉ
- ํ ์คํธ ์ฝ๋ ์์ฑ
์ด ํ๋ก์ ํธ๋ MIT ๋ผ์ด์ ์ค ํ์ ๋ฐฐํฌ๋ฉ๋๋ค. ์์ธํ ๋ด์ฉ์ LICENSE ํ์ผ์ ์ฐธ์กฐํ์ธ์.
์ด ํ๋ก์ ํธ๋ ๊ต์ก ๋ฐ ์ฐ๊ตฌ ๋ชฉ์ ์ผ๋ก ์ ์๋์์ต๋๋ค. ์ค์ ํฌ์์ ์ฌ์ฉํ๊ธฐ ์ ์ ์ถฉ๋ถํ ๊ฒ์ฆ๊ณผ ํ ์คํธ๋ฅผ ๊ฑฐ์ณ์ผ ํฉ๋๋ค. ํฌ์ ์์ค์ ๋ํ ์ฑ ์์ ์ฌ์ฉ์์๊ฒ ์์ต๋๋ค.
์ค์: ์ด ๋๊ตฌ๋ ํฌ์ ์กฐ์ธ์ด ์๋๋๋ค. ๋ชจ๋ ํฌ์ ๊ฒฐ์ ์ ๋ณธ์ธ์ ํ๋จ์ ๋ฐ๋ผ ์ด๋ฃจ์ด์ ธ์ผ ํฉ๋๋ค.
ํ๋ก์ ํธ์ ๋ํ ๋ฌธ์์ฌํญ์ด๋ ์ ์์ฌํญ์ด ์์ผ์๋ฉด ์ด์๋ฅผ ์์ฑํด ์ฃผ์ธ์.
ํจ๊ป ๋ ๋์ ํฌ์ ๋๊ตฌ๋ฅผ ๋ง๋ค์ด๊ฐ์! ๐