anti-gambling-trader-tw
무료 오픈소스 투자 사기 방지·거래 통계·자동매매 도구, 기본 PaperBroker와 14개 증권사 옵션 제공, 로컬 분석
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기메이커가 쓴 소개는 위의 한 줄이 전부입니다. 더 자세한 내용은 저장소 README에서 읽을 수 있습니다. 저장소 README ↗
README 전체를 불러오는 중입니다.
README 전문 보기 ↗일반 ChatGPT는 "요즘 비트코인 흐름 어때?"라고 물어도 내가 가진 데이터를 모릅니다. 이 서비스는 내가 저장한 비트코인 일별 종가 200일치를 분석해 요약을 만들고, 그 요약을 AI의 시스템 프롬프트에 넣어서 내 데이터 기준으로 대답하게 합니다. 데이터는 화면에서 직접 추가·수정·삭제할 수 있고, 바뀐 데이터는 곧바로 요약과 AI 답변에 반영됩니다.
데이터 출처: 이전 미션(M1-1)에서 바이낸스 API로 수집한 BTC/USDT 일봉 중 최근 200일 (2026-04-04 ~ 2026-10-20)
| 구분 | URL |
|---|---|
| 프론트엔드 (Vercel) | https://codyssey-native-m1-2-frontend.vercel.app |
| 백엔드 API (Render) | https://btc-data-assistant-api.onrender.com |
| Swagger UI | https://btc-data-assistant-api.onrender.com/docs |
⏳ 백엔드는 Render 무료 플랜이라 15분 동안 요청이 없으면 잠듭니다. 첫 접속은 1분 가까이 걸릴 수 있고 (실측 약 56초), 그동안 화면 상단에 "서버 깨우는 중" 안내가 뜨고 자동으로 다시 연결을 시도합니다.
| 영역 | 사용 기술 |
|---|---|
| 백엔드 | Python 3.12, FastAPI, Uvicorn, Pydantic v2 |
| DB | Firebase Firestore (firebase-admin) |
| AI | OpenAI Chat Completions API (gpt-5.4-mini) + Function Calling |
| 프론트엔드 | HTML / CSS / JavaScript (프레임워크 없음), 그래프는 SVG 직접 그리기 |
| 배포 | Render (백엔드), Vercel (프론트엔드) |
(date, value, memo) 추가/수정/삭제, 목록 즉시 갱신, 저장 결과 메시지├── backend/
│ ├── main.py # FastAPI 앱: CORS, 라우터 연결, 공통 예외 처리
│ ├── app/
│ │ ├── config.py # 환경 변수 읽기 (키는 전부 여기로만 들어옴)
│ │ ├── db.py # 저장소 계층: Firestore / 메모리(로컬 테스트용)
│ │ ├── schemas.py # Pydantic 요청·응답 검증 규칙
│ │ ├── routers/ # URL ↔ 함수 연결만 담당 (HTTP 층)
│ │ │ ├── data.py # /api/data ...
│ │ │ ├── conversations.py # /api/conversations ...
│ │ │ └── chat.py # /api/chat
│ │ └── services/ # 실제 로직 (라우터와 분리)
│ │ ├── summary.py # 시계열 분석 → 요약·통계
│ │ ├── data_service.py # 데이터 CRUD
│ │ ├── conversation_service.py
│ │ └── chat_service.py # 컨텍스트 주입 + GPT 호출 + 도구 실행 + 자동 저장
│ ├── data/btc_daily.csv # 초기 데이터 200일
│ ├── scripts/seed_firestore.py# CSV → Firestore 업로드 (1회)
│ ├── requirements.txt
│ └── .env.example
├── frontend/
│ ├── index.html / style.css / app.js
│ ├── build.sh # Vercel 빌드 시 API_BASE_URL → config.js 생성
│ └── vercel.json
├── render.yaml # Render 배포 설정
└── docs/screenshots/ # 제출 스크린샷
/api/data/summary와 /api/chat이 함께 쓰므로 계산이 한곳에만 있다.STORAGE=memory로
같은 코드를 돌려 볼 수 있고, 나중에 DB를 바꿔도 서비스 코드는 그대로다.| 메서드 | 경로 | 설명 |
|---|---|---|
| POST | /api/data | 새 데이터 추가 (같은 날짜가 있으면 409) |
| GET | /api/data?start=&end= | 데이터 목록 (날짜 오름차순, 기간 필터 선택) |
| PUT | /api/data/{id} | 데이터 수정 (보낸 필드만 변경) |
| DELETE | /api/data/{id} | 데이터 삭제 |
| GET | /api/data/summary | 데이터 요약 (프롬프트 주입용) |
| GET | /api/data/statistics | [보너스] 7일 이동평균·월별 평균·최대 상승/하락일·상승/하락 일수 |
| POST | /api/conversations | 대화 저장 |
| GET | /api/conversations | 대화 목록 — messages는 포함하지 않음 (message_count, preview만) |
| GET | /api/conversations/{id} | 특정 대화 불러오기 — 전체 messages 포함 (요구사항 (A) 방식) |
| DELETE | /api/conversations/{id} | 대화 삭제 |
| POST | /api/chat | AI 채팅 (요약 주입 → GPT → 대화 자동 저장) |
data/{자동ID}
date: "2026-10-20" value: 83028.15 memo: "" created_at updated_at
conversations/{자동ID}
title: "최근 일주일 추세 어때?"
messages: [ {role: "user"|"assistant", content, created_at}, ... ]
created_at updated_at
| 필드 | 규칙 | 틀리면 |
|---|---|---|
date | 실제 존재하는 날짜 (YYYY-MM-DD) | 422 |
value | 0보다 크고 1천만 이하, NaN·무한대 불가 | 422 |
memo | 200자 이하, 앞뒤 공백 제거 | 422 |
| 수정 요청 | date/value/memo 중 최소 1개 | 422 |
| 같은 날짜 중복 | 하루에 값 1개만 | 409 |
message (채팅) | 1~1000자, 공백만은 불가 | 422 |
라우터 함수까지 오기 전에 FastAPI가 자동으로 막아 주므로, 잘못된 값이 DB에 들어갈 수 없습니다.
예상하지 못한 에러는 공통 핸들러가 받아 내부 정보 없이 500 "서버 내부 오류"로만 응답합니다.
Firestore data (200일)
│ build_summary()
▼
요약: 기간 / 개수 / 최신값 / 평균 / 최고·최저(날짜) / 기간 변화율 / 최근 추세 / 30일 변동성
│ summary_to_prompt()
▼
시스템 프롬프트 "[사용자 데이터 요약] ..." 에 삽입
│
▼
GPT 호출 ── 요약만으로 부족하면 도구 호출 ──► get_data_range / get_statistics ...
│ (서버가 실행해 결과를 다시 GPT에게)
▼
최종 답변 → conversations에 질문·답변 자동 저장 → 화면 표시
증가, -2% 미만이면 감소, 그 사이면 유지| 도구 | 돌려주는 것 (예시 질문) |
|---|---|
get_statistics(start_date?, end_date?, last_days?) | 지정한 기간(비우면 전체)의 변화율·평균·최고/최저·최대 상승/하락일(종가 포함)·상승/하락 일수·변동성·월별 평균 — "9월 중 가장 크게 오른 날은?", "요즘 어때?" |
get_data_range(start_date, end_date | last_days) | 그 기간의 일별 값·메모·전일 대비 변동률 (최대 120일) — "10월 15일 값은?", "9월 한 달 흐름 요약해줘" |
list_conversations() | 저장된 이전 대화 목록 — "전에 내가 뭐 물어봤지?" |
기간은 start_date~end_date로 주거나, last_days(마지막 데이터 날짜까지 최근 N일)로 줍니다.
last_days는 AI가 날짜 계산을 직접 하다 틀리지 않도록 서버가 날짜로 바꿔 줍니다.
질문마다 도구를 정해 주는 대신, 시스템 프롬프트에는 "질문이 가리키는 기간을 대화 흐름에서 먼저 정하고
그 범위로 도구를 부른다"는 원칙만 두었습니다. 기간 표현이 없으면 전체 기간,
"요즘·최근"처럼 길이 없이 최근을 말하면 최근 30일로 봅니다.
그래서 "요즘 어때?" → "그 중 가장 많이 오른 날은?" 같은 이어 묻기도 앞 질문의 기간으로 계산합니다.
도구 설명(description)과 이 원칙을 보고 GPT가 스스로 고르며,
화면에서는 답변 아래 🔧 get_statistics 처럼 실제로 호출된 도구가 표시됩니다.
비용 보호를 위해 도구 호출은 최대 3번, 답변은 최대 600토큰으로 제한했습니다.
cd backend
python3 -m venv .venv
.venv/bin/pip install -r requirements.txt
cp .env.example .env # 값 채우기 (아래 환경 변수 표 참고)
.venv/bin/python -m scripts.seed_firestore # 처음 1번만: CSV 200일 → Firestore
.venv/bin/uvicorn main:app --reload # http://127.0.0.1:8000/docs
키 없이 화면만 먼저 보고 싶다면
STORAGE=memory .venv/bin/uvicorn main:app --reload(CSV 데이터가 메모리에 자동으로 채워지고, 서버를 끄면 사라짐. 채팅은 OpenAI 키가 있어야 동작)
cd frontend
echo 'window.APP_CONFIG = { API_BASE_URL: "http://127.0.0.1:8000" };' > config.js
python3 -m http.server 5500 # http://127.0.0.1:5500
backend/.env)| 이름 | 필수 | 설명 |
|---|---|---|
OPENAI_API_KEY | ✅ | OpenAI API 키 |
FIREBASE_SERVICE_ACCOUNT_JSON | ✅ (배포) | 서비스 계정 키 JSON 내용 전체를 한 줄 문자열로 |
FIREBASE_SERVICE_ACCOUNT_PATH | (로컬 대안) | 서비스 계정 키 파일 경로 — 위 JSON 대신 사용 가능 |
ALLOWED_ORIGINS | ✅ | CORS 허용 프론트 주소, 쉼표 구분 (예: https://xxx.vercel.app) |
OPENAI_BASE_URL | OpenAI 호환 프록시 주소 (예: https://copa.codyssey.kr/v1), 비우면 OpenAI 공식 주소 | |
OPENAI_MODEL | 기본 gpt-5.4-mini | |
OPENAI_MAX_TOKENS | 답변 최대 토큰, 기본 600 | |
STORAGE | firestore(기본) 또는 memory |
| 이름 | 필수 | 설명 |
|---|---|---|
API_BASE_URL | ✅ | 백엔드 주소 (예: https://xxx.onrender.com). 빌드 때 build.sh가 config.js로 만들어 줌 |
.env와 키 파일은 .gitignore로 제외하고, 키는 백엔드에만 두며 프론트(브라우저)에는 절대 넣지 않습니다.백엔드 (Render) — GitHub에 푸시 → Render New > Blueprint로 이 저장소 선택(render.yaml 자동 인식)
→ OPENAI_API_KEY, FIREBASE_SERVICE_ACCOUNT_JSON, ALLOWED_ORIGINS 입력 → 배포 후 /docs 확인
프론트엔드 (Vercel) — Add New > Project → 같은 저장소 선택 → Root Directory frontend
→ 환경 변수 API_BASE_URL 입력 → Deploy → 나온 주소를 Render의 ALLOWED_ORIGINS에 추가
| 화면 | 이미지 |
|---|---|
| 데이터 요약이 보이는 채팅 (질문+답변) — 상단 요약 카드, "요즘" 질문을 최근 30일로 계산, 호출한 도구 표시 | |
| 데이터 관리 (CRUD 동작) — 2026-10-20 메모 수정 후 저장 결과와 갱신된 목록 | |
| 대화 기록 불러오기 — 왼쪽 목록에서 이전 대화를 선택해 메시지를 다시 표시 | |
| Swagger UI |