AI ๊ธฐ๋ฐ ์ค์๊ฐ ๊ธ์ต ๋ฐ์ดํฐ ๋ถ์ ๋ฐ ํฌ์ ์ปค๋ฎค๋ํฐ ํ๋ซํผ
๋ถํธ์บ ํ 4๊ฐ์์ฐจ์ ์ ์ํ ํ์คํ ๊ธ์ต ํธ๋ ์ด๋ฉ ํ๋ซํผ
์ค์๊ฐ ์ฃผ์ ์ฐจํธ, AI ํฌ์ ์ด์์คํดํธ, ๋ด์ค ๋ถ์, ์ปค๋ฎค๋ํฐ ๊ธฐ๋ฅ ์ ๊ณต
- ๊ฐ๋ฐ ๊ธฐ๊ฐ: 2025.01.20 ~ 2025.02.05 (์ฝ 2์ฃผ)
- ํ ๊ตฌ์ฑ: Team EOD (Error Overflow Delay)
- ๊ฐ๋ฐ ์ธ์: ํ ํ๋ก์ ํธ
- ๊ฐ๋ฐ ํ๊ฒฝ: Docker Compose ๊ธฐ๋ฐ ๋ง์ดํฌ๋ก์๋น์ค
- ์ค์๊ฐ ์ฐจํธ: Highcharts ๊ธฐ๋ฐ ๊ตญ๋ด์ธ ์ฃผ์ ์๊ฐํ
- WebSocket ์คํธ๋ฆฌ๋ฐ: ์ค์๊ฐ ์ฃผ๊ฐ ์ ๋ฐ์ดํธ
- ์ฃผ๊ฐ ์์ธก: scikit-learn, PyTorch ๊ธฐ๋ฐ ML ๋ชจ๋ธ
- ๊ธฐ์ ์ ์งํ: ์ด๋ํ๊ท ์ , RSI, MACD ๋ฑ
- CrewAI ๋ฉํฐ ์์ด์ ํธ: ์ฌ๋ฌ AI ์์ด์ ํธ๊ฐ ํ์ ํ์ฌ ๋ถ์
- ์ค์๊ฐ ์ฑํ : WebSocket ๊ธฐ๋ฐ ์ฆ๊ฐ ์๋ต
- ๊ฐ์ฑ ๋ถ์: transformers, KoNLPy๋ก ๋ด์ค ๊ฐ์ฑ ๋ถ์
- ๋ง์ถค ์ถ์ฒ: ์ฌ์ฉ์ ํฌํธํด๋ฆฌ์ค ๊ธฐ๋ฐ ์ข ๋ชฉ ์ถ์ฒ
- ๋ก์ปฌ LLM ์ง์: ๊ฐ๋ฐ/ํ
์คํธ ํ๊ฒฝ์์ Ollama ์ฌ์ฉ ๊ฐ๋ฅ
(Ollama ์คํ โ ๋ชจ๋ธ pull โ backend .env ์ค์ ํ docker ์ฌ์์)
- ์๋ ํฌ๋กค๋ง: Celery๋ก ์ฃผ๊ธฐ์ ๋ด์ค ์์ง (crawl4ai)
- ์๋ํด๋ผ์ฐ๋: ํค์๋ ์๊ฐํ
- ๊ฐ์ฑ ๋ถ์: ๊ธ์ /๋ถ์ ๋ด์ค ์๋ ๋ถ๋ฅ
- ์ข ๋ชฉ ํ๊น : ๊ด๋ จ ์ข ๋ชฉ ์๋ ์ฐ๊ฒฐ
- ์ค์๊ฐ ์ฑํ : Django Channels (WebSocket)
- ๊ฒ์ํ: ์์ ๊ฒ์ํ, ํ ๋ก ๋ฐฉ, ์ข ๋ชฉ ํ ๋ก
- ์์ ๊ธฐ๋ฅ: ๋๊ธ, ์ข์์, ํ๋ก์ฐ
- JWT ์ธ์ฆ: Access/Refresh Token
- ์์ ๋ก๊ทธ์ธ: ๋ค์ด๋ฒ, ๊ตฌ๊ธ, ์นด์นด์ค
- ์ด๋ฉ์ผ ์ธ์ฆ: ํ์๊ฐ์ ์ ์ด๋ฉ์ผ ํ์ธ
- ํ๋กํ: ํฌํธํด๋ฆฌ์ค ๊ด๋ฆฌ
React 18 + Vite
โโโ UI: Material-UI, Ant Design, Tailwind CSS
โโโ State: Redux Toolkit
โโโ Charts: Highcharts, Plotly, D3.js
โโโ Animation: Framer Motion, GSAP
โโโ Real-time: WebSocket
Django 5.1 + DRF
โโโ Real-time: Django Channels (WebSocket)
โโโ Task Queue: Celery + Redis
โโโ Database: PostgreSQL
โโโ Auth: JWT, django-allauth
โโโ Server: Gunicorn + Uvicorn
โโโ LLM: OpenAI GPT, Google Gemini, Ollama (Local)
โโโ Framework: PyTorch, scikit-learn, transformers
โโโ NLP: KoNLPy
โโโ Agent: CrewAI
โโโ Data: finance-datareader
Docker Compose
โโโ Web: Nginx
โโโ Cache: Redis
โโโ DB: PostgreSQL
โโโ Admin: pgAdmin, RedisInsight
tradevortex/
โโโ frontend/ # React ํ๋ก ํธ์๋
โ โโโ src/
โ โ โโโ components/ # ์ฌ์ฌ์ฉ ์ปดํฌ๋ํธ
โ โ โโโ pages/ # ํ์ด์ง ์ปดํฌ๋ํธ
โ โ โโโ redux/ # Redux ์ํ ๊ด๋ฆฌ
โ โ โโโ api/ # API ํธ์ถ
โ โโโ package.json
โ
โโโ backend/ # Django ๋ฐฑ์๋
โ โโโ TradeVortex/ # ํ๋ก์ ํธ ์ค์
โ โโโ accounts/ # ์ฌ์ฉ์ ์ธ์ฆ
โ โโโ financedata/ # ๊ธ์ต ๋ฐ์ดํฐ
โ โโโ newspage/ # ๋ด์ค ํฌ๋กค๋ง
โ โโโ aiassist/ # AI ์ด์์คํดํธ
โ โโโ graphs/ # ์ค์๊ฐ ์ฐจํธ
โ โโโ board/ # ๊ฒ์ํ
โ โโโ toron/ # ํ ๋ก ๋ฐฉ
โ โโโ realtimechat/ # ์ค์๊ฐ ์ฑํ
โ โโโ requirements.txt
โ
โโโ docker-compose.yml # ์๋น์ค ์ค์ผ์คํธ๋ ์ด์
โโโ nginx.conf # Nginx ์ค์
โโโ README.md
- Docker & Docker Compose
- Git
# 1. ์ ์ฅ์ ํด๋ก
git clone https://github.com/yourusername/tradevortex.git
cd tradevortex
# 2. ํ๊ฒฝ ๋ณ์ ์ค์ (์๋ ํ๊ฒฝ ๋ณ์ ์น์
์ฐธ๊ณ )
cp backend/.env.example backend/.env
cp frontend/.env.example frontend/.env
# .env ํ์ผ ์์ ํ์
# 3. Docker Compose ์คํ
docker-compose up -d
# 4. ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ง์ด๊ทธ๋ ์ด์
docker-compose exec django python manage.py migrate
# 5. ์ํผ์ ์ ์์ฑ (์ ํ)
docker-compose exec django python manage.py createsuperuser- Frontend: http://localhost:3000
- Backend API: http://localhost:8000
- Admin: http://localhost:8000/admin
- pgAdmin: http://localhost:5050
- RedisInsight: http://localhost:5540
# Django
SECRET_KEY=your-secret-key-here
DEBUG=False
ALLOWED_HOSTS=localhost,127.0.0.1
# Database
DATABASE_URL=postgresql://postgres:postgres@postgres:5432/tradevortex
# Redis
CELERY_BROKER_URL=redis://redis:6379/0
CELERY_RESULT_BACKEND=redis://redis:6379/0
# ๊ฐ๋ฐ/ํ
์คํธ ํ๊ฒฝ์์ ๋ก์ปฌ LLM(Ollama)์ ์ฌ์ฉํ ๊ฒฝ์ฐ ์๋ ์ต์
์ ์ค์
# Local LLM (optional)
OLLAMA_BASE_URL=http://host.docker.internal:11434
OLLAMA_MODEL=qwen3:4b-instruct-2507-q4_K_M
# AI APIs
OPENAI_API_KEY=your-openai-key
GEMINI_API_KEY=your-gemini-key
# Social Login
NAVER_CLIENT_ID=your-naver-client-id
NAVER_CLIENT_SECRET=your-naver-secret
GOOGLE_CLIENT_ID=your-google-client-id
# Email
EMAIL_HOST_USER=your-email@gmail.com
EMAIL_HOST_PASSWORD=your-app-passwordVITE_API_URL=http://localhost:8000
VITE_WS_URL=ws://localhost:8000
VITE_GOOGLE_CLIENT_ID=your-google-client-id
VITE_NAVER_CLIENT_ID=your-naver-client-id
VITE_KAKAO_JAVASCRIPT_KEY=your-kakao-keyPOST /api/accounts/signup/ # ํ์๊ฐ์
POST /api/accounts/login/ # ๋ก๊ทธ์ธ
POST /api/accounts/logout/ # ๋ก๊ทธ์์
POST /api/accounts/token/refresh/ # ํ ํฐ ๊ฐฑ์
GET /api/financedata/stocks/ # ์ฃผ์ ๋ชฉ๋ก
GET /api/financedata/chart/{symbol}/ # ์ฐจํธ ๋ฐ์ดํฐ
GET /api/financedata/predict/{symbol}/ # ์ฃผ๊ฐ ์์ธก
GET /api/news/ # ๋ด์ค ๋ชฉ๋ก
GET /api/news/{id}/ # ๋ด์ค ์์ธ
GET /api/news/wordcloud/ # ์๋ํด๋ผ์ฐ๋
POST /api/aiassist/chat/ # AI ์ฑํ
GET /api/aiassist/recommend/ # ์ข
๋ชฉ ์ถ์ฒ
ws://localhost:8000/ws/stock/{symbol}/ # ์ค์๊ฐ ์ฃผ๊ฐ
ws://localhost:8000/ws/chat/{room}/ # ์ค์๊ฐ ์ฑํ
# backend/graphs/consumers.py
class StockConsumer(AsyncWebsocketConsumer):
async def connect(self):
self.symbol = self.scope['url_route']['kwargs']['symbol']
await self.channel_layer.group_add(f"stock_{self.symbol}", self.channel_name)
await self.accept()
async def stock_update(self, event):
await self.send(text_data=json.dumps(event['data']))# backend/aiassist/crew.py
analyst = Agent(
role='Financial Analyst',
goal='Analyze stock data and provide investment insights',
tools=[stock_analysis_tool, news_sentiment_tool]
)
researcher = Agent(
role='Market Researcher',
goal='Research market trends and news',
tools=[news_crawler_tool, market_data_tool]
)
crew = Crew(agents=[analyst, researcher], tasks=[...])# backend/newspage/tasks.py
@shared_task
def crawl_financial_news():
crawler = NewsCrawler()
articles = crawler.fetch_latest()
for article in articles:
sentiment = analyze_sentiment(article.content)
article.sentiment_score = sentiment
article.save()- WebSocket์ผ๋ก 1์ด๋ง๋ค ์ฃผ๊ฐ ์ ๋ฐ์ดํธ
- Highcharts๋ก ์บ๋ค์คํฑ, ๋ผ์ธ ์ฐจํธ ์ง์
- ๊ธฐ์ ์ ์งํ ์ค๋ฒ๋ ์ด
- ์์ฐ์ด๋ก ์ข ๋ชฉ ์ง๋ฌธ
- ๋ฉํฐ ์์ด์ ํธ๊ฐ ํ์ ํ์ฌ ๋ถ์
- ์ค์๊ฐ ์๋ต ์คํธ๋ฆฌ๋ฐ
- 10๋ถ๋ง๋ค ์๋ ํฌ๋กค๋ง
- ๊ฐ์ฑ ๋ถ์์ผ๋ก ๊ธ์ /๋ถ์ ๋ถ๋ฅ
- ์๋ํด๋ผ์ฐ๋๋ก ํธ๋ ๋ ํ์
docker-compose down -v
docker-compose up --builddocker-compose exec django python manage.py migrate --run-syncdbdocker-compose restart redis celery# docker-compose.yml์์ ํฌํธ ๋ณ๊ฒฝ
ports:
- "3001:3000" # 3000 ๋์ 3001 ์ฌ์ฉ- Redis ์บ์ฑ: API ์๋ต ์๋ 50% ๊ฐ์
- Celery ๋น๋๊ธฐ: ๋ฌด๊ฑฐ์ด ์์ ๋ฐฑ๊ทธ๋ผ์ด๋ ์ฒ๋ฆฌ
- WebSocket: HTTP ํด๋ง ๋๋น 90% ํธ๋ํฝ ๊ฐ์
- DB ์ธ๋ฑ์ฑ: ์ฟผ๋ฆฌ ์๋ 3๋ฐฐ ํฅ์
โ ๏ธ ์ฃผ์: ์ด ํ๋ก์ ํธ๋ ํ์ต/ํฌํธํด๋ฆฌ์ค ๋ชฉ์ ์ ๋๋ค.
ํ๋ก๋์ ๋ฐฐํฌ ์ ์๋ ์ฌํญ์ ๋ฐ๋์ ์์ ํ์ธ์.
- SECRET_KEY ํ๊ฒฝ๋ณ์๋ก ๋ถ๋ฆฌ
- DEBUG=False ์ค์
- ALLOWED_HOSTS ์ ํ
- CORS_ALLOW_ALL_ORIGINS=False
- HTTPS ์ ์ฉ
- API ํค ์ฌ๋ฐ๊ธ
- .env ํ์ผ .gitignore ์ถ๊ฐ
- Django Channels๋ก WebSocket ๊ตฌํ
- Celery๋ก ๋น๋๊ธฐ ์์ ์ฒ๋ฆฌ
- Docker Compose๋ก ๋ฉํฐ ์ปจํ ์ด๋ ๊ด๋ฆฌ
- CrewAI๋ก ๋ฉํฐ ์์ด์ ํธ ์์คํ ๊ตฌ์ถ
- JWT ์ธ์ฆ ๊ตฌํ
- WebSocket ์ฐ๊ฒฐ ๊ด๋ฆฌ ๋ฐ ์๋ฌ ํธ๋ค๋ง
- Celery ํ์คํฌ ์ค์ผ์ค๋ง ๋ฐ ๋ชจ๋ํฐ๋ง
- CORS/CSRF ์ค์
- Docker ๋คํธ์ํฌ ์ค์
- ํ ์คํธ ์ฝ๋ ์์ฑ
- ์๋ฌ ํธ๋ค๋ง ๊ฐํ
- ์ฝ๋ ๋ฆฌํฉํ ๋ง
- ์ฑ๋ฅ ์ต์ ํ
- AWS ๋ฐฐํฌ (EC2, RDS, S3)
- CI/CD ํ์ดํ๋ผ์ธ ๊ตฌ์ถ
- ํ ์คํธ ์ฝ๋ ์์ฑ (pytest, Jest)
- ๋ชจ๋ฐ์ผ ๋ฐ์ํ ๊ฐ์
- ์๋ฆผ ๊ธฐ๋ฅ ์ถ๊ฐ
- ํฌํธํด๋ฆฌ์ค ๋ฐฑํ ์คํ ๊ธฐ๋ฅ
- Fork the Project
- Create your Feature Branch (
git checkout -b feature/AmazingFeature) - Commit your Changes (
git commit -m 'Add some AmazingFeature') - Push to the Branch (
git push origin feature/AmazingFeature) - Open a Pull Request
This project is licensed under the MIT License.
Team EOD (Error Overflow Delay)
- ๋ถํธ์บ ํ 4๊ฐ์์ฐจ ํ ํ๋ก์ ํธ
- ๊ฐ๋ฐ ๊ธฐ๊ฐ: ์ฝ 2์ฃผ
ํ๋ก์ ํธ ๊ด๋ จ ๋ฌธ์: fakeprice@naver.com
GitHub: antziku
์ด ํ๋ก์ ํธ๋ ๋ถํธ์บ ํ์์ ๋ฐฐ์ด ๋ด์ฉ์ ๋ฐํ์ผ๋ก ์ ์ํ์ต๋๋ค.
๋ถ์กฑํ ์ ์ด ๋ง์ง๋ง, ๊ณ์ ๊ฐ์ ํด ๋๊ฐ๊ฒ ์ต๋๋ค.
โญ ์ด ํ๋ก์ ํธ๊ฐ ๋์์ด ๋์๋ค๋ฉด Star๋ฅผ ๋๋ฌ์ฃผ์ธ์!