# source: https://raw.githubusercontent.com/CETANGZHI/flowainew/94cc7095db1259c5f1cb053bdf5c74bb0c4c16c3/backend/scripts/init_knowledge_base.py
#!/usr/bin/env python3
"""
RAG 知识库初始化脚本
添加加密货币交易的专业知识到向量数据库
"""

import sys
import os

# 添加项目根目录到 Python 路径
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))

from langchain_core.documents import Document
from app.services.rag_service import get_rag_service
import logging

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

# 专业知识库内容
KNOWLEDGE_BASE = [
    {
        "title": "技术指标 - MACD（指数平滑异同移动平均线）",
        "content": """
## MACD 指标详解

### 基本原理
MACD 由 Gerald Appel 在 1970 年代提出，是趋势跟踪和动量指标的结合。

### 计算方法
1. **DIF（快线）** = EMA(12) - EMA(26)
2. **DEA（慢线）** = DIF 的 9 日 EMA
3. **MACD 柱状图** = (DIF - DEA) × 2

### 交易信号
**金叉买入信号**：
- DIF 上穿 DEA，且都在零轴上方 → 强烈买入
- DIF 上穿 DEA，但在零轴下方 → 谨慎买入

**死叉卖出信号**：
- DIF 下穿 DEA，且都在零轴下方 → 强烈卖出
- DIF 下穿 DEA，但在零轴上方 → 谨慎卖出

**背离信号**：
- 价格创新高，MACD 未创新高 → 顶背离，看跌
- 价格创新低，MACD 未创新低 → 底背离，看涨

### 最佳参数
- **日线级别**：12, 26, 9（标准）
- **4小时级别**：12, 26, 9
- **1小时级别**：6, 13, 5（灵敏）
- **15分钟级别**：6, 13, 5

### 实战策略
```python
# Freqtrade MACD 金叉策略
def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
    dataframe.loc[
        (
            (dataframe['macd'] > dataframe['macdsignal']) &
            (dataframe['macd'].shift(1) <= dataframe['macdsignal'].shift(1)) &
            (dataframe['volume'] > 0)
        ),
        'enter_long'] = 1
    return dataframe
```

### 注意事项
- ⚠️ 震荡市场容易产生假信号，建议结合趋势指标（如 MA）
- ⚠️ 加密货币波动大，建议调整参数或结合 RSI
- ✅ 配合成交量使用，成交量放大的信号更可靠
""",
        "category": "technical_analysis"
    },
    {
        "title": "技术指标 - RSI（相对强弱指数）",
        "content": """
## RSI 指标详解

### 基本原理
RSI 由 Welles Wilder 在 1978 年提出，衡量价格变动的速度和幅度，判断超买超卖。

### 计算方法
RSI = 100 - [100 / (1 + RS)]
其中 RS = n 日平均上涨幅度 / n 日平均下跌幅度

### 标准参数
- **常用周期**：14（标准）、6（快速）、28（慢速）
- **超买线**：70
- **超卖线**：30

### 交易信号
**超买超卖信号**：
- RSI > 70 → 超买，可能回调
- RSI < 30 → 超卖，可能反弹
- RSI > 80 → 极度超买（加密货币）
- RSI < 20 → 极度超卖（加密货币）

**背离信号（重要！）**：
- **顶背离**：价格创新高，RSI 未创新高 → 强烈卖出信号
- **底背离**：价格创新低，RSI 未创新低 → 强烈买入信号

**中线突破**：
- RSI 上穿 50 → 多头占优
- RSI 下破 50 → 空头占优

### 加密货币特殊用法
由于加密货币波动性大：
- 超买线可调整到 80
- 超卖线可调整到 20
- 周期可缩短到 9-12

### 实战策略
```python
# Freqtrade RSI 超卖反弹策略
def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
    dataframe.loc[
        (
            (dataframe['rsi'] < 30) &
            (dataframe['rsi'] > dataframe['rsi'].shift(1)) &  # RSI 开始回升
            (dataframe['volume'] > dataframe['volume'].rolling(20).mean())  # 成交量放大
        ),
        'enter_long'] = 1
    return dataframe

def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
    dataframe.loc[
        (
            (dataframe['rsi'] > 70) |  # 超买
            (dataframe['close'] < dataframe['close'].shift(1) * 0.98)  # 或跌破 2%
        ),
        'exit_long'] = 1
    return dataframe
```

### 组合使用建议
- **RSI + MACD**：RSI 超卖 + MACD 金叉 = 强买入
- **RSI + MA**：RSI 超卖 + 站上 MA20 = 确认反弹
- **RSI + 布林带**：价格触及下轨 + RSI < 30 = 超卖反弹
""",
        "category": "technical_analysis"
    },
    {
        "title": "K线形态 - 头肩顶与头肩底",
        "content": """
## 头肩顶/底形态识别

### 头肩顶（看跌反转形态）

**形态特征**：
1. **左肩**：价格上涨到高点后回落
2. **头部**：价格再次上涨，突破左肩高点，然后回落
3. **右肩**：价格第三次上涨，但未能突破头部高点，形成右肩
4. **颈线**：连接左肩和头部之间的低点与头部和右肩之间的低点

**确认信号**：
- ✅ 价格有效跌破颈线（收盘价跌破 3%）
- ✅ 成交量：左肩>头部>右肩，跌破颈线时放量
- ✅ 反抽颈线未能收复，形成二次确认

**目标价位**：
下跌目标 = 颈线位 - 头部高点到颈线的垂直距离

**实战要点**：
- 头肩顶形成时间越长，反转力度越强（一般 3-6 个月）
- 颈线倾斜度：水平或微微上倾更可靠
- 假突破：跌破颈线后 3 日内反抽未能收复，才确认

### 头肩底（看涨反转形态）

**形态特征**（与头肩顶相反）：
1. 价格下跌形成左肩
2. 继续下跌形成头部（最低点）
3. 反弹后再次下跌形成右肩，但不破头部低点
4. 突破颈线确认

**确认信号**：
- ✅ 价格有效突破颈线（收盘价突破 3%）
- ✅ 成交量：突破颈线时明显放大
- ✅ 回踩颈线支撑有效

**目标价位**：
上涨目标 = 颈线位 + 头部低点到颈线的垂直距离

### 交易策略
```python
# 头肩顶策略（简化版）
def identify_head_shoulders_top(dataframe):
    # 识别头肩顶
    left_shoulder = dataframe['high'].rolling(20).max()
    head = dataframe['high'].rolling(40).max()
    right_shoulder = dataframe['high'].rolling(20).max()
    
    # 颈线
    neckline = (dataframe['low'].rolling(20).min() + dataframe['low'].shift(20).rolling(20).min()) / 2
    
    # 跌破颈线 = 卖出信号
    sell_signal = dataframe['close'] < neckline * 0.97
    
    return sell_signal
```

### 失败形态（陷阱）
- ❌ 右肩高于头部 → 形态失败
- ❌ 跌破颈线后立即反弹收复 → 假突破
- ❌ 成交量反常（左肩最大） → 可靠性降低
""",
        "category": "chart_patterns"
    },
    {
        "title": "风险管理 - 仓位管理与资金分配",
        "content": """
## 专业仓位管理策略

### 核心原则
1. **永远不要满仓**：留有余力应对突发情况
2. **单笔亏损不超过账户 2%**：保护本金
3. **相关性分散**：不要在相关品种上重复押注

### 凯利公式（Kelly Criterion）
最优仓位 = (胜率 × 盈亏比 - 败率) / 盈亏比

**示例**：
- 胜率 60%
- 盈亏比 2:1（平均盈利是平均亏损的 2 倍）
- 最优仓位 = (0.6 × 2 - 0.4) / 2 = 0.4 = 40%

**保守修正**：实际仓位 = 凯利仓位 × 0.5（减半使用更安全）

### 固定比例法
每笔交易风险固定为账户的 1-2%

**计算公式**：
仓位 = 可承受亏损金额 / 单笔止损幅度

**示例**：
- 账户 10,000 USDT
- 单笔风险 2% = 200 USDT
- 止损幅度 5%
- 仓位 = 200 / 0.05 = 4,000 USDT（40%）

### 分批建仓法（推荐）
**三分法**：
1. 首次建仓：30%
2. 确认趋势：加仓 30%
3. 突破关键位：再加 40%

**金字塔加仓**：
- 首次：50%
- 第一次加仓：30%
- 第二次加仓：20%

**反金字塔加仓（激进）**：
- 首次：20%
- 第一次加仓：30%
- 第二次加仓：50%

### 不同市场环境的仓位策略
| 市场状态 | 总仓位 | 单币种仓位 |
|---------|--------|-----------|
| 强势牛市 | 70-80% | 20-30% |
| 震荡市场 | 30-50% | 10-15% |
| 弱势熊市 | 10-20% | 5-10% |
| 单边暴跌 | 0-10% | 空仓为主 |

### 止损设置
**技术止损**：
- 跌破关键支撑位（如 MA20、前低）
- 跌幅达到 5-8%（加密货币）
- K线形态破坏（如破颈线）

**时间止损**：
- 持仓 3 天无利润 → 平仓
- 持仓 7 天未达预期 → 减仓

**盈利保护止损**：
- 盈利 10%时，止损移至成本价
- 盈利 20%时，止损移至+5%
- 盈利 30%时，止损移至+10%

### 实战代码
```python
# Freqtrade 动态仓位管理
def custom_stake_amount(self, pair: str, current_time, current_rate,
                        proposed_stake, min_stake, max_stake,
                        entry_tag, side: str, **kwargs) -> float:
    # 获取账户余额
    wallet_balance = self.wallets.get_total(self.config['stake_currency'])
    
    # 计算止损距离
    stop_loss_distance = 0.05  # 5%
    
    # 固定风险 2%
    risk_per_trade = wallet_balance * 0.02
    
    # 计算仓位
    stake_amount = risk_per_trade / stop_loss_distance
    
    # 限制最大仓位 30%
    max_position = wallet_balance * 0.3
    stake_amount = min(stake_amount, max_position)
    
    return stake_amount
```

### 心理建设
- ✅ 亏损是交易的一部分，接受小亏损
- ✅ 不要因为连续亏损而加大仓位（赌徒心态）
- ✅ 不要因为连续盈利而放松警惕（过度自信）
- ❌ 永远不要 ALL IN
""",
        "category": "risk_management"
    },
    {
        "title": "交易策略 - 双均线策略（Golden Cross）",
        "content": """
## 双均线交叉策略

### 策略原理
利用不同周期的移动平均线交叉产生买卖信号，是最经典的趋势跟踪策略。

### 常用参数组合
**短线交易**：
- MA5 / MA10
- MA10 / MA20

**中线交易**：
- MA20 / MA60
- MA30 / MA90

**长线交易**：
- MA50 / MA200（金叉/死叉）
- MA100 / MA300

### 信号规则
**金叉（买入）**：
- 短期均线向上穿越长期均线
- 两条均线都向上倾斜（趋势确认）
- 价格在均线上方

**死叉（卖出）**：
- 短期均线向下穿越长期均线
- 两条均线都向下倾斜
- 价格在均线下方

### 优化方法
1. **加入成交量过滤**：
   - 金叉时成交量放大 > 20 日均量
   - 避免无量上涨的假突破

2. **加入 MACD 确认**：
   - 金叉 + MACD 金叉 = 双重确认
   - 提高胜率，但会错过部分行情

3. **动态止损**：
   - 价格跌破短期均线 → 平仓 50%
   - 价格跌破长期均线 → 全部平仓

4. **分批入场**：
   - 金叉时买入 50%
   - 价格回踩均线不破时加仓 30%
   - 突破前高时再加仓 20%

### Freqtrade 完整策略代码
```python
from freqtrade.strategy import IStrategy
from pandas import DataFrame
import talib.abstract as ta

class Github_CETANGZHI_flowainew__init_knowledge_base__20260114_114646(IStrategy):
    # 策略参数
    minimal_roi = {
        "0": 0.20,   # 20% 止盈
        "60": 0.10,  # 持仓1小时后 10% 止盈
        "120": 0.05  # 持仓2小时后 5% 止盈
    }
    
    stoploss = -0.08  # 8% 止损
    
    timeframe = '1h'
    
    # 策略指标
    def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        # 计算移动平均线
        dataframe['ma_short'] = ta.SMA(dataframe, timeperiod=20)
        dataframe['ma_long'] = ta.SMA(dataframe, timeperiod=60)
        
        # 成交量均线
        dataframe['volume_ma'] = dataframe['volume'].rolling(20).mean()
        
        # MACD
        macd = ta.MACD(dataframe)
        dataframe['macd'] = macd['macd']
        dataframe['macdsignal'] = macd['macdsignal']
        
        return dataframe
    
    # 买入信号
    def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        dataframe.loc[
            (
                # 金叉
                (dataframe['ma_short'] > dataframe['ma_long']) &
                (dataframe['ma_short'].shift(1) <= dataframe['ma_long'].shift(1)) &
                
                # 两条均线都向上
                (dataframe['ma_short'] > dataframe['ma_short'].shift(1)) &
                (dataframe['ma_long'] > dataframe['ma_long'].shift(1)) &
                
                # 成交量放大
                (dataframe['volume'] > dataframe['volume_ma'] * 1.2) &
                
                # MACD 确认
                (dataframe['macd'] > dataframe['macdsignal']) &
                
                # 确保有成交量
                (dataframe['volume'] > 0)
            ),
            'enter_long'] = 1
        
        return dataframe
    
    # 卖出信号
    def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        dataframe.loc[
            (
                # 死叉
                (dataframe['ma_short'] < dataframe['ma_long']) &
                (dataframe['ma_short'].shift(1) >= dataframe['ma_long'].shift(1)) &
                
                # 或者价格跌破短期均线
                (dataframe['close'] < dataframe['ma_short'] * 0.97)
            ) |
            (
                # 或 MACD 死叉
                (dataframe['macd'] < dataframe['macdsignal']) &
                (dataframe['macd'].shift(1) >= dataframe['macdsignal'].shift(1))
            ),
            'exit_long'] = 1
        
        return dataframe
```

### 回测数据参考
基于 BTC/USDT 1小时级别（2023 年数据）：
- **胜率**：45%
- **盈亏比**：2.5:1
- **年化收益**：35%
- **最大回撤**：-15%

### 适用市场
- ✅ 趋势明显的牛市或熊市
- ✅ 波段较大的品种（如主流币）
- ❌ 震荡市场（容易被来回打止损）
- ❌ 低波动品种（信号少）

### 注意事项
1. **避免频繁交易**：震荡市会产生大量假信号，建议结合趋势指标（如 ADX）
2. **时间周期选择**：加密货币建议 1h 或 4h，避免 15m（噪音太多）
3. **滑点和手续费**：频繁交易会吃掉大部分利润，建议只在明确趋势时交易
""",
        "category": "trading_strategies"
    },
    {
        "title": "链上数据分析 - 交易所净流入/流出",
        "content": """
## 交易所资金流动分析

### 核心原理
- **净流入（Inflow）**：资金流入交易所 → 抛压增加 → 看跌
- **净流出（Outflow）**：资金流出交易所 → 长期持有 → 看涨

### 数据来源
- CryptoQuant
- Glassnode
- IntoTheBlock
- Nansen

### 关键指标

**1. 交易所余额变化**
- 余额持续下降 → 抛压减轻，利好
- 余额持续上升 → 抛压增加，利空
- 大额转入（>100 BTC）→ 可能即将砸盘

**2. 交易所储备比例**
- 低储备比例（<10%）→ 流动性紧张，利好
- 高储备比例（>15%）→ 抛压大，利空

**3. 矿工流向**
- 矿工向交易所转币 → 准备抛售，利空
- 矿工囤币 → 看好后市，利好

### 实战信号
**强烈看涨**：
- 交易所净流出 >5000 BTC/天
- 交易所余额创新低
- 巨鲸地址增持
- 稳定币流入交易所（准备抄底）

**强烈看跌**：
- 交易所净流入 >8000 BTC/天
- 矿工大量转入交易所
- 巨鲸地址减持
- 稳定币流出交易所

### 配合价格使用
| 链上信号 | 价格走势 | 判断 |
|---------|---------|-----|
| 净流出 | 上涨 | 健康上涨，可持有 |
| 净流出 | 下跌 | 底部吸筹，潜在反转 |
| 净流入 | 上涨 | 获利盘出逃，警惕回调 |
| 净流入 | 下跌 | 恐慌性抛售，超跌反弹 |

### 注意事项
- ⚠️ 单日数据波动大，建议看 7 日均值
- ⚠️ 大型交易所（Binance、Coinbase）的数据更有参考价值
- ⚠️ 结合价格和成交量综合判断
""",
        "category": "onchain_analysis"
    }
]


async def init_knowledge_base():
    """初始化知识库"""
    try:
        logger.info("开始初始化 RAG 知识库...")
        
        # 获取 RAG 服务
        rag_service = get_rag_service()
        
        # 转换为 RAG 服务期望的格式
        documents = []
        for item in KNOWLEDGE_BASE:
            doc = {
                "content": item["content"],
                "title": item["title"],
                "category": item["category"],
                "source": "official_knowledge_base"
            }
            documents.append(doc)
        
        logger.info(f"准备导入 {len(documents)} 条知识...")
        
        # 批量导入到默认集合
        collection_name = "trading_knowledge"
        await rag_service.ingest_documents(
            documents=documents,
            collection_name=collection_name
        )
        
        logger.info(f"✅ 知识库初始化完成！共导入 {len(documents)} 条专业知识")
        logger.info(f"集合名称: {collection_name}")
        
        # 测试检索
        logger.info("\n测试检索功能...")
        results = await rag_service.search(
            query="MACD 指标怎么用？",
            collection_name=collection_name,
            top_k=2
        )
        
        logger.info(f"检索到 {len(results)} 条相关结果：")
        for i, doc in enumerate(results, 1):
            title = doc.get('title', '未命名') if isinstance(doc, dict) else getattr(doc, 'metadata', {}).get('title', '未命名')
            logger.info(f"{i}. {title}")
        
        return True
        
    except Exception as e:
        logger.error(f"❌ 初始化知识库失败: {e}")
        import traceback
        traceback.print_exc()
        return False


if __name__ == "__main__":
    import asyncio
    success = asyncio.run(init_knowledge_base())
    sys.exit(0 if success else 1)
