commit
394901c4c7
@ -0,0 +1,17 @@
|
||||
__pycache__/
|
||||
*.pyc
|
||||
*.pyo
|
||||
*.db
|
||||
.git/
|
||||
.gitignore
|
||||
*.md
|
||||
.trae/
|
||||
.vscode/
|
||||
*.egg-info/
|
||||
dist/
|
||||
build/
|
||||
.eggs/
|
||||
*.egg
|
||||
docker-compose.yml
|
||||
Dockerfile
|
||||
.dockerignore
|
||||
@ -0,0 +1,35 @@
|
||||
# Python
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
*.so
|
||||
.Python
|
||||
*.egg-info/
|
||||
dist/
|
||||
build/
|
||||
|
||||
# Virtual environments
|
||||
venv/
|
||||
.venv/
|
||||
|
||||
# Database files
|
||||
data/*.db
|
||||
data/*.db-journal
|
||||
|
||||
# Config files with secrets
|
||||
config/ai_config.json
|
||||
|
||||
# Logs
|
||||
*.log
|
||||
data/collector.log
|
||||
|
||||
# IDE
|
||||
.vscode/
|
||||
.idea/
|
||||
|
||||
# OS
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
||||
# Cache
|
||||
cache/*.pkl
|
||||
@ -0,0 +1,28 @@
|
||||
FROM python:3.11-slim
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
ENV PYTHONDONTWRITEBYTECODE=1
|
||||
ENV PYTHONUNBUFFERED=1
|
||||
ENV BUFFER_DB_PATH=/app/data/buffer.db
|
||||
ENV BUFFER_HOST=0.0.0.0
|
||||
ENV BUFFER_PORT=8600
|
||||
|
||||
RUN rm -f /etc/apt/sources.list.d/debian.sources && \
|
||||
echo "deb http://mirrors.aliyun.com/debian trixie main" > /etc/apt/sources.list && \
|
||||
echo "deb http://mirrors.aliyun.com/debian trixie-updates main" >> /etc/apt/sources.list && \
|
||||
echo "deb http://mirrors.aliyun.com/debian-security trixie-security main" >> /etc/apt/sources.list && \
|
||||
apt-get update && \
|
||||
apt-get install -y --no-install-recommends gcc && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
COPY requirements.txt .
|
||||
RUN pip install --no-cache-dir -r requirements.txt -i https://mirrors.aliyun.com/pypi/simple/ --trusted-host mirrors.aliyun.com
|
||||
|
||||
COPY . .
|
||||
|
||||
RUN mkdir -p /app/data
|
||||
|
||||
EXPOSE 8600
|
||||
|
||||
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8600"]
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,36 @@
|
||||
"""
|
||||
期货智析数据库 - 独立存储
|
||||
"""
|
||||
from pathlib import Path
|
||||
from sqlalchemy import create_engine
|
||||
from sqlalchemy.orm import sessionmaker, declarative_base
|
||||
from datetime import datetime
|
||||
|
||||
# 数据目录
|
||||
DATA_DIR = Path(__file__).resolve().parent.parent / "data"
|
||||
DATA_DIR.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
ANALYSIS_DB_PATH = DATA_DIR / "futures_analysis.db"
|
||||
|
||||
analysis_engine = create_engine(
|
||||
f"sqlite:///{ANALYSIS_DB_PATH}",
|
||||
connect_args={"check_same_thread": False},
|
||||
pool_pre_ping=True,
|
||||
)
|
||||
|
||||
AnalysisSessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=analysis_engine)
|
||||
AnalysisBase = declarative_base()
|
||||
|
||||
|
||||
def get_analysis_db():
|
||||
"""获取期货智析数据库会话"""
|
||||
db = AnalysisSessionLocal()
|
||||
try:
|
||||
yield db
|
||||
finally:
|
||||
db.close()
|
||||
|
||||
|
||||
def init_analysis_db():
|
||||
"""初始化期货智析数据库表"""
|
||||
AnalysisBase.metadata.create_all(bind=analysis_engine)
|
||||
@ -0,0 +1,88 @@
|
||||
"""
|
||||
期货智析数据模型
|
||||
"""
|
||||
from datetime import datetime
|
||||
from sqlalchemy import Column, String, Integer, Float, Text, DateTime, Boolean, Index, UniqueConstraint, JSON
|
||||
from app.analysis_db import AnalysisBase
|
||||
|
||||
|
||||
class FuturesAnalysis(AnalysisBase):
|
||||
"""期货分析报告表"""
|
||||
__tablename__ = "futures_analysis"
|
||||
|
||||
id = Column(Integer, primary_key=True, autoincrement=True)
|
||||
symbol = Column(String(32), nullable=False, index=True, comment="品种合约代码")
|
||||
analysis_time = Column(DateTime, nullable=False, default=datetime.now, index=True, comment="分析时间")
|
||||
period = Column(String(16), nullable=False, default="15min", comment="分析周期")
|
||||
# 分析结果
|
||||
suggestion = Column(String(32), nullable=True, comment="交易建议: 逢低做多/逢高做空/观望等待")
|
||||
suggestion_type = Column(String(16), nullable=True, comment="建议类型: up/down/neutral")
|
||||
entry_price = Column(Float, nullable=True, comment="建议入场价")
|
||||
target_price = Column(Float, nullable=True, comment="目标价位")
|
||||
stop_loss = Column(Float, nullable=True, comment="止损价位")
|
||||
risk_level = Column(String(16), nullable=True, comment="风险等级: 低/中/高")
|
||||
# 技术指标
|
||||
macd_signal = Column(String(16), nullable=True, comment="MACD信号")
|
||||
rsi_value = Column(Float, nullable=True, comment="RSI值")
|
||||
boll_signal = Column(String(16), nullable=True, comment="布林带信号")
|
||||
kdj_signal = Column(String(16), nullable=True, comment="KDJ信号")
|
||||
# 趋势评分
|
||||
trend_score = Column(Integer, nullable=True, comment="趋势评分 0-100")
|
||||
success_rate = Column(Float, nullable=True, comment="交易成功率")
|
||||
# 关键点位
|
||||
resistance_levels = Column(JSON, nullable=True, comment="压力位列表")
|
||||
support_levels = Column(JSON, nullable=True, comment="支撑位列表")
|
||||
# 多周期趋势
|
||||
period_trends = Column(JSON, nullable=True, comment="各周期趋势")
|
||||
|
||||
def __repr__(self):
|
||||
return f"<FuturesAnalysis {self.symbol} {self.analysis_time}>"
|
||||
|
||||
|
||||
class WatchedSymbol(AnalysisBase):
|
||||
"""用户关注品种表"""
|
||||
__tablename__ = "watched_symbols"
|
||||
|
||||
id = Column(Integer, primary_key=True, autoincrement=True)
|
||||
symbol = Column(String(32), nullable=False, unique=True, comment="品种合约代码")
|
||||
name = Column(String(64), nullable=True, comment="品种名称")
|
||||
note = Column(Text, nullable=True, comment="备注")
|
||||
created_at = Column(DateTime, nullable=False, default=datetime.now)
|
||||
updated_at = Column(DateTime, nullable=False, default=datetime.now, onupdate=datetime.now)
|
||||
|
||||
def __repr__(self):
|
||||
return f"<WatchedSymbol {self.symbol}>"
|
||||
|
||||
|
||||
class AIModelConfig(AnalysisBase):
|
||||
"""AI模型配置表"""
|
||||
__tablename__ = "ai_model_configs"
|
||||
|
||||
id = Column(Integer, primary_key=True, autoincrement=True)
|
||||
provider = Column(String(32), nullable=False, comment="AI提供商: openai/anthropic/google等")
|
||||
model_name = Column(String(64), nullable=False, comment="模型名称")
|
||||
api_key = Column(String(256), nullable=False, comment="API密钥")
|
||||
api_base = Column(String(256), nullable=True, comment="API基础URL")
|
||||
model_id = Column(String(64), nullable=True, comment="模型ID")
|
||||
temperature = Column(Float, nullable=True, default=0.7, comment="温度参数")
|
||||
max_tokens = Column(Integer, nullable=True, default=2000, comment="最大输出token")
|
||||
enabled = Column(Boolean, nullable=False, default=True, comment="是否启用")
|
||||
is_active = Column(Boolean, nullable=False, default=False, comment="是否为当前活跃模型")
|
||||
created_at = Column(DateTime, nullable=False, default=datetime.now)
|
||||
updated_at = Column(DateTime, nullable=False, default=datetime.now, onupdate=datetime.now)
|
||||
|
||||
def __repr__(self):
|
||||
return f"<AIModelConfig {self.provider} {self.model_name}>"
|
||||
|
||||
|
||||
class AnalysisSettings(AnalysisBase):
|
||||
"""分析设置表(单例配置)"""
|
||||
__tablename__ = "analysis_settings"
|
||||
|
||||
id = Column(Integer, primary_key=True, autoincrement=True)
|
||||
key = Column(String(64), nullable=False, unique=True, comment="配置键")
|
||||
value = Column(JSON, nullable=False, comment="配置值")
|
||||
updated_at = Column(DateTime, nullable=False, default=datetime.now, onupdate=datetime.now)
|
||||
|
||||
def __repr__(self):
|
||||
return f"<AnalysisSettings {self.key}>"
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,23 @@
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
buffer-platform:
|
||||
build: .
|
||||
container_name: buffer-platform
|
||||
ports:
|
||||
- "9600:8600"
|
||||
volumes:
|
||||
- E:\docker_workspace\futures_datas:/app/data
|
||||
environment:
|
||||
- BUFFER_DB_PATH=/app/data/buffer.db
|
||||
- BUFFER_HOST=0.0.0.0
|
||||
- BUFFER_PORT=8600
|
||||
- CACHE_TTL=300
|
||||
- BUFFER_LOG_LEVEL=INFO
|
||||
restart: unless-stopped
|
||||
healthcheck:
|
||||
test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8600/api/v1/health')"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 40s
|
||||
Loading…
Reference in new issue