from app.database import Base from sqlalchemy import Column, Integer, String, Float, DateTime, BigInteger, Boolean, Text, Index, func from datetime import datetime class ProductInfo(Base): """品种元数据表""" __tablename__ = "product_info" id = Column(Integer, primary_key=True, autoincrement=True) product_code = Column(String(10), unique=True, nullable=False, comment="品种代码,如 rb") product_name = Column(String(50), nullable=False, comment="品种中文名,如 螺纹钢") exchange = Column(String(10), nullable=False, comment="所属交易所") multiplier = Column(Integer, default=10, comment="合约乘数") price_tick = Column(Float, comment="最小变动价位") margin_ratio = Column(Float, default=0.1, comment="保证金比例(%)") category = Column(String(20), comment="品种分类: 金属/农产品/能源化工/金融") is_active = Column(Boolean, default=True, comment="是否仍在交易") created_at = Column(DateTime, default=datetime.utcnow) updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow) __table_args__ = ( Index("idx_product_category", "category"), Index("idx_product_exchange", "exchange"), ) class ContractInfo(Base): """期货合约信息表""" __tablename__ = "contract_info" id = Column(Integer, primary_key=True, autoincrement=True) symbol = Column(String(20), unique=True, nullable=False, comment="合约代码,如 rb2401") exchange = Column(String(10), nullable=False, comment="交易所代码: SHFE/DCE/CZCE/INE/CFFEX") name = Column(String(50), comment="合约名称") product = Column(String(20), comment="品种代码,如 rb") multiplier = Column(Integer, default=10, comment="合约乘数") price_tick = Column(Float, comment="最小变动价位") limit_up_ratio = Column(Float, comment="涨停板比例") limit_down_ratio = Column(Float, comment="跌停板比例") expire_date = Column(DateTime, comment="到期日") is_active = Column(Boolean, default=True, comment="是否活跃") # 新增字段 year_month = Column(String(7), comment="交割年月,如 2024-01") delivery_month = Column(Integer, comment="交割月份,如 1") is_main = Column(Boolean, default=False, comment="是否主力合约") listing_date = Column(DateTime, comment="上市日期") volume = Column(BigInteger, default=0, comment="成交量(用于计算主力)") open_interest = Column(BigInteger, default=0, comment="持仓量") created_at = Column(DateTime, default=datetime.utcnow) updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow) __table_args__ = ( Index("idx_contract_product", "product"), Index("idx_contract_exchange", "exchange"), Index("idx_contract_year_month", "year_month"), Index("idx_contract_is_main", "is_main"), ) class KlineDaily(Base): """日K线表""" __tablename__ = "kline_daily" id = Column(Integer, primary_key=True, autoincrement=True) symbol = Column(String(20), nullable=False) trade_date = Column(DateTime, nullable=False) open = Column(Float) high = Column(Float) low = Column(Float) close = Column(Float) volume = Column(BigInteger, comment="成交量") turnover = Column(Float, comment="成交额") open_interest = Column(BigInteger, comment="持仓量") settle = Column(Float, comment="结算价") pre_settle = Column(Float, comment="昨结算") created_at = Column(DateTime, default=datetime.utcnow) updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow) __table_args__ = ( Index("idx_kline_daily_symbol_date", "symbol", "trade_date", unique=True), ) class KlineWeekly(Base): """周K线表""" __tablename__ = "kline_weekly" id = Column(Integer, primary_key=True, autoincrement=True) symbol = Column(String(20), nullable=False) trade_date = Column(DateTime, nullable=False, comment="周最后一天") open = Column(Float) high = Column(Float) low = Column(Float) close = Column(Float) volume = Column(BigInteger) turnover = Column(Float) open_interest = Column(BigInteger) created_at = Column(DateTime, default=datetime.utcnow) updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow) __table_args__ = ( Index("idx_kline_weekly_symbol_date", "symbol", "trade_date", unique=True), ) class KlineIntraday(Base): """分钟级K线表(5m/15m/30m/60m共用,通过period区分)""" __tablename__ = "kline_intraday" id = Column(Integer, primary_key=True, autoincrement=True) symbol = Column(String(20), nullable=False) period = Column(String(10), nullable=False, comment="周期: 5m/15m/30m/60m") trade_time = Column(DateTime, nullable=False) open = Column(Float) high = Column(Float) low = Column(Float) close = Column(Float) volume = Column(BigInteger) turnover = Column(Float) open_interest = Column(BigInteger) created_at = Column(DateTime, default=datetime.utcnow) updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow) __table_args__ = ( Index("idx_kline_intraday_symbol_period_time", "symbol", "period", "trade_time", unique=True), ) class DataSourceConfig(Base): """数据源配置表""" __tablename__ = "data_source_config" id = Column(Integer, primary_key=True, autoincrement=True) source_name = Column(String(30), unique=True, nullable=False, comment="数据源名称: tushare/ctp") display_name = Column(String(50), comment="显示名称") is_enabled = Column(Boolean, default=False, comment="是否启用") config_json = Column(Text, comment="JSON格式的配置信息") priority = Column(Integer, default=0, comment="优先级,数字越小优先级越高") last_sync_time = Column(DateTime, comment="最后同步时间") status = Column(String(20), default="unknown", comment="状态: ok/error/unknown") error_msg = Column(Text, comment="错误信息") created_at = Column(DateTime, default=datetime.utcnow) updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)