From 7e5aeb4270fa91096410e66542273def7beaea5d Mon Sep 17 00:00:00 2001
From: Administrator <15274802129@163.com>
Date: Mon, 22 Dec 2025 11:55:52 +0800
Subject: [PATCH] feat(trading): 实现综合技术指标交易策略

---
 indicator_package_documentation.md                                                                            |  288 ++++++
 src/main/java/com/xcong/excoin/modules/okxNewPrice/indicator/strategy/TradeSignal.java                        |   54 +
 src/main/java/com/xcong/excoin/modules/okxNewPrice/indicator/strategy/TechnicalIndicatorStrategy.java         |   44 +
 CoreTechnicalStrategy_Usage_Guide.md                                                                          |  150 +++
 src/main/java/com/xcong/excoin/modules/okxNewPrice/indicator/MA.java                                          |  151 +++
 src/main/java/com/xcong/excoin/modules/okxNewPrice/indicator/BOLL.java                                        |  143 +++
 src/main/java/com/xcong/excoin/modules/okxNewPrice/indicator/RSI.java                                         |  119 ++
 src/main/java/com/xcong/excoin/modules/okxNewPrice/indicator/KDJ.java                                         |  120 ++
 src/main/java/com/xcong/excoin/modules/okxNewPrice/indicator/strategy/ComprehensiveTechnicalStrategy.java     |  351 ++++++++
 src/main/java/com/xcong/excoin/modules/okxNewPrice/indicator/MACD.java                                        |   80 +
 src/main/java/com/xcong/excoin/modules/okxNewPrice/indicator/strategy/AbstractTechnicalIndicatorStrategy.java |   89 ++
 src/main/java/com/xcong/excoin/modules/okxNewPrice/indicator/strategy/CoreTechnicalStrategy.java              |  589 +++++++++++++
 src/main/java/com/xcong/excoin/modules/okxNewPrice/indicator/AdvancedMA.java                                  |  104 ++
 src/main/java/com/xcong/excoin/modules/okxNewPrice/indicator/strategy/CoreTechnicalStrategyUsageGuide.md      |  198 ++++
 src/main/java/com/xcong/excoin/modules/okxNewPrice/indicator/IndicatorBase.java                               |   94 ++
 15 files changed, 2,574 insertions(+), 0 deletions(-)

diff --git a/CoreTechnicalStrategy_Usage_Guide.md b/CoreTechnicalStrategy_Usage_Guide.md
new file mode 100644
index 0000000..ace716c
--- /dev/null
+++ b/CoreTechnicalStrategy_Usage_Guide.md
@@ -0,0 +1,150 @@
+# CoreTechnicalStrategy 使用指南
+
+## 功能概述
+CoreTechnicalStrategy 是一个集成了多种技术指标的交易策略类,用于生成做多、做空、买入和卖出信号。它整合了以下核心指标:
+- 三重 EMA 交叉系统 (9/21/55 周期)
+- 波动率自适应布林带
+- MACD 能量柱分级策略
+- RSI (相对强弱指标)
+- KDJ 指标
+
+## 所需参数
+
+### 1. 初始化参数
+```java
+CoreTechnicalStrategy strategy = new CoreTechnicalStrategy();
+```
+
+### 2. 初始化价格历史
+在使用策略之前,需要先初始化价格历史数据:
+```java
+List<BigDecimal> historicalPrices = Arrays.asList(
+    new BigDecimal(30000),
+    new BigDecimal(30100),
+    new BigDecimal(30200),
+    // 添加更多历史价格数据,建议至少包含 60 个数据点
+);
+strategy.init(historicalPrices);
+```
+
+### 3. 获取交易信号参数
+调用 `getSignal` 方法获取交易信号,需要传入以下参数:
+
+| 参数名 | 类型 | 描述 | 示例值 |
+|--------|------|------|--------|
+| accountName | String | 账户名称 | "main_account" |
+| markPx | String | 当前标记价格 | "30500.50" |
+| posSide | String | 当前持仓方向 | "long" 或 "short" 或 "net" |
+
+### 4. 持仓方向说明
+- `"long"`: 多头持仓
+- `"short"`: 空头持仓
+- `"net"`: 净持仓(无方向)
+
+## 使用示例
+
+```java
+import com.xcong.excoin.modules.okxNewPrice.indicator.strategy.CoreTechnicalStrategy;
+import com.xcong.excoin.modules.okxNewPrice.okxWs.param.TradeRequestParam;
+import com.xcong.excoin.modules.okxNewPrice.okxWs.param.TradeSignal;
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+public class CoreTechnicalStrategyExample {
+    public static void main(String[] args) {
+        // 1. 创建策略实例
+        CoreTechnicalStrategy strategy = new CoreTechnicalStrategy();
+
+        // 2. 准备历史价格数据
+        List<BigDecimal> historicalPrices = new ArrayList<>();
+        // 假设我们有过去 100 个价格数据
+        for (int i = 0; i < 100; i++) {
+            historicalPrices.add(new BigDecimal(30000 + i * 10));
+        }
+
+        // 3. 初始化策略
+        strategy.initialize();
+
+        // 4. 更新初始价格历史
+        strategy.updatePrices(historicalPrices);
+
+        // 5. 定期更新价格(例如每分钟获取一次最新价格)
+        // 这里的价格是指交易资产的当前市场价格,如加密货币的标记价格或股票的实时价格
+        BigDecimal newMarketPrice = new BigDecimal("31050.75");
+        List<BigDecimal> newPrices = Collections.singletonList(newMarketPrice);
+        strategy.updatePrices(newPrices);
+
+        // 6. 获取交易信号
+        String accountName = "trading_account";
+        String currentPrice = newMarketPrice.toString();
+        String currentPosition = "net"; // 当前无持仓
+
+        TradeRequestParam tradeParam = strategy.getSignal(accountName, currentPrice, currentPosition);
+
+        // 7. 处理交易信号
+        if (tradeParam.getSignal() == TradeSignal.BUY) {
+            System.out.println("执行买入操作");
+            // 调用交易API执行买入
+        } else if (tradeParam.getSignal() == TradeSignal.SELL) {
+            System.out.println("执行卖出操作");
+            // 调用交易API执行卖出
+        } else {
+            System.out.println("无交易信号");
+        }
+    }
+}
+
+## 返回值说明
+
+`getSignal` 方法返回 `TradeRequestParam` 对象,包含以下主要属性:
+
+| 属性名 | 类型 | 描述 |
+|--------|------|------|
+| accountName | String | 账户名称 |
+| markPx | String | 当前标记价格 |
+| posSide | String | 持仓方向 |
+| signal | TradeSignal | 交易信号:BUY、SELL 或 NO_SIGNAL |
+| side | String | 交易方向:"buy" 或 "sell" |
+| tradeType | String | 交易类型:"open"(开仓)或 "close"(平仓) |
+
+## 核心指标逻辑说明
+
+### 1. 三重 EMA 交叉系统
+- **多头排列**:9EMA > 21EMA > 55EMA
+- **空头排列**:9EMA < 21EMA < 55EMA
+- **震荡过滤**:当三线粘合度 < 2% 时暂停交易
+
+### 2. 波动率自适应布林带
+- **动态标准差倍数**:根据 ATR(平均真实范围)自动调整
+  - ATR < 0.5% 时,使用 2 倍标准差
+  - 0.5% ≤ ATR < 1% 时,使用 2.5 倍标准差
+  - ATR ≥ 1% 时,使用 3 倍标准差
+- **做空信号**:价格突破上轨 + 成交量放大
+- **做多信号**:价格触及下轨 + 正资金费率
+
+### 3. MACD 能量柱分级策略
+- **多头入场**:当前能量柱 > 0 且面积增速 > 前周期 20%
+- **空头反转**:能量柱顶背离 + RSI > 70 区域死叉
+
+## 注意事项
+
+1. **数据充足性**:确保提供足够的历史价格数据(至少 60 个数据点),以便所有指标能准确计算
+
+2. **价格更新**:策略不会自动更新价格历史,需要外部定期调用 `updatePrices` 方法添加新价格。这里的价格是指交易资产的市场价格(如加密货币的当前标记价格、股票的实时价格等),用于计算技术指标。
+
+3. **参数调整**:可以根据市场情况调整指标参数,如 EMA 周期、布林带参数等
+
+4. **风险控制**:本策略仅提供交易信号,实际交易时应结合风险控制措施
+
+## 错误处理
+
+- 如果策略未初始化或价格历史为空,将返回 NO_SIGNAL
+- 如果计算过程中发生异常,将返回 NO_SIGNAL 并记录错误日志
+
+## 依赖关系
+
+- Java 8 或更高版本
+- Lombok 库(用于自动生成 getter/setter 方法)
+- Apache Commons Math 库(用于数学计算)
\ No newline at end of file
diff --git a/indicator_package_documentation.md b/indicator_package_documentation.md
new file mode 100644
index 0000000..280a23a
--- /dev/null
+++ b/indicator_package_documentation.md
@@ -0,0 +1,288 @@
+# com.xcong.excoin.modules.okxNewPrice.indicator 包文档
+
+## 1. 包概述
+
+该包实现了一套完整的技术指标分析系统,包含基础指标计算、高级指标策略以及信号生成功能。主要用于加密货币交易中的技术分析和策略决策,支持三重EMA交叉系统、波动率自适应布林带、MACD能量柱分级策略等高级分析方法。
+
+## 2. 类层次结构
+
+```
+├── IndicatorBase (抽象基类)
+│   ├── MA (简单移动平均线)
+│   ├── AdvancedMA (三重EMA交叉系统)
+│   ├── BOLL (波动率自适应布林带)
+│   ├── MACD (移动平均线收敛发散)
+│   ├── RSI (相对强弱指标)
+│   └── KDJ (随机指标)
+└── strategy/
+    ├── TechnicalIndicatorStrategy (策略接口)
+    ├── AbstractTechnicalIndicatorStrategy (策略抽象基类)
+    ├── CoreTechnicalStrategy (核心技术指标策略)
+    ├── ComprehensiveTechnicalStrategy (综合技术指标策略)
+    └── TradeSignal (交易信号枚举)
+```
+
+## 3. 核心类详解
+
+### 3.1 IndicatorBase (指标基类)
+
+**功能**:提供所有技术指标的通用计算方法
+
+**核心方法**:
+- `calculateMA(List<BigDecimal> prices, int period)` - 计算移动平均值
+- `calculateEMA(List<BigDecimal> prices, int period, BigDecimal prevEMA)` - 计算指数移动平均值
+- `calculateStdDev(List<BigDecimal> prices, int period)` - 计算标准差
+- `getRecentPrices(List<BigDecimal> prices, int period)` - 获取最近N个价格数据
+
+**使用场景**:作为所有指标类的父类,提供基础计算功能
+
+### 3.2 MA (移动平均线)
+
+**功能**:实现标准周期的移动平均线指标
+
+**支持的周期**:
+- MA5/MA10/MA20/MA30/MA60 (简单移动平均线)
+- EMA5/EMA10/EMA20/EMA30/EMA60 (指数移动平均线)
+
+**核心方法**:
+- `calculate(List<BigDecimal> prices)` - 计算所有周期的移动平均线
+- `isGoldenCross()` - 判断金叉信号
+- `isDeathCross()` - 判断死叉信号
+
+**使用场景**:用于基本趋势判断和交叉信号分析
+
+### 3.3 AdvancedMA (高级移动平均线)
+
+**功能**:实现三重EMA交叉系统,用于高级趋势分析
+
+**支持的周期**:EMA9/EMA21/EMA55 (三重EMA交叉系统)
+
+**核心方法**:
+- `calculateTripleEMA(List<BigDecimal> prices)` - 计算三重EMA指标
+- `isBullish()` - 判断多头排列 (9EMA > 21EMA > 55EMA)
+- `isBearish()` - 判断空头排列 (9EMA < 21EMA < 55EMA)
+- `calculatePercent()` - 计算三线粘合度
+- `isUpAndDown()` - 判断震荡行情 (粘合度 < 2%)
+
+**使用场景**:用于判断市场趋势强度和过滤震荡行情
+
+### 3.4 BOLL (布林带)
+
+**功能**:实现波动率自适应布林带指标
+
+**计算逻辑**:
+- 中轨(MB)= N日移动平均线
+- 上轨(UP)= 中轨 + K倍标准差
+- 下轨(DN)= 中轨 - K倍标准差
+
+**核心方法**:
+- `calculate(List<BigDecimal> prices)` - 计算布林带指标
+- `isBreakUpper()` - 判断价格突破上轨
+- `isBreakLower()` - 判断价格跌破下轨
+- `isReturnFromUpper()` - 判断价格回归上轨下方
+- `isReturnFromLower()` - 判断价格回归下轨上方
+- `calculateBandWidth()` - 计算布林带宽度
+
+**使用场景**:用于判断价格波动范围和突破信号
+
+### 3.5 MACD (移动平均线收敛发散)
+
+**功能**:实现MACD指标,包括DIF、DEA和柱状图
+
+**计算逻辑**:
+- DIF = EMA(12) - EMA(26)
+- DEA = EMA(DIF, 9)
+- MACD柱状图 = (DIF - DEA) * 2
+
+**核心方法**:
+- `calculate(List<BigDecimal> prices)` - 计算MACD指标
+- `isGoldenCross()` - 判断金叉信号(DIF上穿DEA)
+- `isDeathCross()` - 判断死叉信号(DIF下穿DEA)
+
+**使用场景**:用于判断价格动量和趋势强度
+
+### 3.6 RSI (相对强弱指标)
+
+**功能**:实现相对强弱指标,用于判断超买超卖
+
+**计算逻辑**:
+- RSI = 100 - (100 / (1 + (平均上涨幅度 / 平均下跌幅度)))
+
+**核心方法**:
+- `calculate(List<BigDecimal> prices)` - 计算RSI指标
+- `isOverbought()` - 判断超买 (RSI > 70)
+- `isOversold()` - 判断超卖 (RSI < 30)
+- `isExtremelyOverbought()` - 判断严重超买 (RSI > 80)
+- `isExtremelyOversold()` - 判断严重超卖 (RSI < 20)
+
+**使用场景**:用于判断市场情绪和价格反转点
+
+### 3.7 KDJ (随机指标)
+
+**功能**:实现KDJ指标,用于判断价格反转和超买超卖
+
+**计算逻辑**:
+- RSV = (收盘价 - N日内最低价) / (N日内最高价 - N日内最低价) * 100
+- K = 2/3 * 前一日K值 + 1/3 * 当日RSV
+- D = 2/3 * 前一日D值 + 1/3 * 当日K值
+- J = 3*K - 2*D
+
+**核心方法**:
+- `calculate(List<BigDecimal> prices)` - 计算KDJ指标
+- `isOverbought()` - 判断超买 (K > 80)
+- `isOversold()` - 判断超卖 (K < 20)
+- `isGoldenCross()` - 判断金叉信号(K线上穿D线)
+- `isDeathCross()` - 判断死叉信号(K线下穿D线)
+
+**使用场景**:用于判断价格短期反转和超买超卖
+
+## 4. 策略相关类
+
+### 4.1 TechnicalIndicatorStrategy (策略接口)
+
+**功能**:定义技术指标策略的基本方法
+
+**核心方法**:
+- `initialize()` - 初始化策略
+- `updatePrices(List<BigDecimal> prices)` - 更新价格数据
+- `getSignal()` - 获取交易信号
+- `getStrategyName()` - 获取策略名称
+- `isValid()` - 判断策略是否有效
+
+**使用场景**:作为所有技术指标策略的接口,定义统一的方法规范
+
+### 4.2 AbstractTechnicalIndicatorStrategy (策略抽象基类)
+
+**功能**:提供技术指标策略的通用功能
+
+**核心功能**:
+- 价格历史管理(最多保存100条记录)
+- 策略初始化
+- 价格更新
+- 交易请求参数创建
+
+**使用场景**:作为所有具体策略的父类,提供基础功能
+
+### 4.3 TradeSignal (交易信号枚举)
+
+**功能**:定义所有可能的交易信号类型
+
+**信号类型**:
+- NO_SIGNAL (无信号)
+- BUY (买入)
+- SELL (卖出)
+- OPEN_LONG (开多)
+- CLOSE_LONG (平多)
+- OPEN_SHORT (开空)
+- CLOSE_SHORT (平空)
+- STOP_LOSS (止损)
+- TAKE_PROFIT (止盈)
+
+**使用场景**:用于策略生成和传递交易信号
+
+### 4.4 CoreTechnicalStrategy (核心技术指标策略)
+
+**功能**:整合三重EMA交叉系统、波动率自适应布林带、MACD能量柱分级策略等高级指标
+
+**核心特点**:
+- 波动率自适应布林带(根据ATR动态调整标准差倍数)
+- MACD能量柱面积指标(累计过去5根柱体积分)
+- 多重指标综合分析(EMA、MACD、RSI、KDJ、BOLL)
+- 震荡行情过滤(三线粘合度 < 2%)
+
+**交易信号生成规则**:
+- 多头入场:当前柱体>0且面积增速>前周期20%
+- 空头入场:当前柱体<0且面积增速>前周期20%
+- 突破上轨+成交量放大3倍=做空信号
+- 触及下轨+期货资金费率转正=做多信号
+- 空头反转:柱体顶背离+RSI>70区域死叉
+- 多头反转:柱体底背离+RSI<30区域金叉
+
+**使用场景**:用于复杂的技术分析和交易决策
+
+### 4.5 ComprehensiveTechnicalStrategy (综合技术指标策略)
+
+**功能**:整合MACD、KDJ、RSI、BOLL等指标生成交易信号
+
+**核心特点**:
+- 基于多空方向分别分析信号
+- 结合超买超卖条件和指标交叉信号
+- 简化的信号生成逻辑
+
+**交易信号生成规则**:
+- 多头方向:RSI超卖+KDJ金叉或布林带下轨突破+MACD金叉=买入信号
+- 多头方向:RSI超买+KDJ死叉或布林带上轨突破+MACD死叉=卖出信号
+- 空头方向:RSI超买+KDJ死叉或布林带上轨突破+MACD死叉=卖出信号
+- 空头方向:RSI超卖+KDJ金叉或布林带下轨突破+MACD金叉=买入信号
+
+**使用场景**:用于较为简单的技术分析和交易决策
+
+## 5. 工作流程
+
+```
+1. 初始化策略(initialize())
+2. 更新价格数据(updatePrices())
+3. 计算技术指标(calculate())
+4. 分析交易信号(analyzeSignal())
+5. 生成交易请求参数(createTradeRequestParam())
+6. 执行交易操作
+```
+
+## 6. 如何使用
+
+### 6.1 基本使用示例
+
+```java
+// 创建策略实例
+CoreTechnicalStrategy strategy = new CoreTechnicalStrategy();
+
+// 初始化策略
+strategy.initialize();
+
+// 更新价格数据(需要外部定期调用)
+List<BigDecimal> prices = new ArrayList<>();
+// 添加价格数据...
+strategy.updatePrices(prices);
+
+// 获取交易信号
+TradeRequestParam param = strategy.getSignal("account1", "45000.0", "long");
+
+// 处理交易信号
+if (TradeSignal.BUY.equals(param.getSignal())) {
+    // 执行买入操作
+} else if (TradeSignal.SELL.equals(param.getSignal())) {
+    // 执行卖出操作
+}
+```
+
+### 6.2 参数说明
+
+- `accountName`:账户名称,用于标识交易账户
+- `markPx`:当前标记价格,用于计算指标和生成信号
+- `posSide`:仓位方向,取值为"long"(多头)或"short"(空头)
+
+### 6.3 价格更新说明
+
+策略不会自动更新价格历史,需要外部定期调用`updatePrices()`方法添加新价格。价格历史最多保存100条记录,超过时会自动移除最旧的价格记录。
+
+## 7. 代码优化建议
+
+1. **性能优化**:
+   - 考虑使用缓存机制存储已计算的指标值
+   - 对于高频更新的场景,可实现增量计算
+
+2. **功能扩展**:
+   - 添加更多技术指标(如ATR、OBV等)
+   - 实现回测功能,支持历史数据验证
+
+3. **鲁棒性提升**:
+   - 增加异常处理和参数验证
+   - 实现策略监控和告警机制
+
+4. **可维护性**:
+   - 提取常量到配置文件
+   - 增强日志记录,便于调试和分析
+
+## 8. 总结
+
+该包提供了一套完整的技术指标分析系统,支持从基础指标计算到高级策略分析的全流程。通过整合多种技术指标,实现了复杂的交易信号生成逻辑,可用于加密货币交易中的技术分析和策略决策。系统设计遵循面向对象原则,具有良好的可扩展性和可维护性。
\ No newline at end of file
diff --git a/src/main/java/com/xcong/excoin/modules/okxNewPrice/indicator/AdvancedMA.java b/src/main/java/com/xcong/excoin/modules/okxNewPrice/indicator/AdvancedMA.java
new file mode 100644
index 0000000..a7e3aad
--- /dev/null
+++ b/src/main/java/com/xcong/excoin/modules/okxNewPrice/indicator/AdvancedMA.java
@@ -0,0 +1,104 @@
+package com.xcong.excoin.modules.okxNewPrice.indicator;
+
+import lombok.Getter;
+import lombok.Setter;
+import lombok.extern.slf4j.Slf4j;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.util.List;
+
+/**
+ * Advanced MA (Moving Average) 指标实现
+ * 支持扩展周期的指数移动平均线(EMA),用于三重EMA交叉系统
+ */
+@Slf4j
+@Getter
+@Setter
+public class AdvancedMA extends IndicatorBase {
+
+    // 扩展周期 - 三重EMA交叉系统
+    public static final int EMA9 = 9;
+    public static final int EMA21 = 21;
+    public static final int EMA55 = 55;
+
+    private BigDecimal ema9 = BigDecimal.ZERO;
+    private BigDecimal ema21 = BigDecimal.ZERO;
+    private BigDecimal ema55 = BigDecimal.ZERO;
+
+    private BigDecimal prevEma9 = null;
+    private BigDecimal prevEma21 = null;
+    private BigDecimal prevEma55 = null;
+
+    /**
+     * 计算三重EMA交叉系统的指标
+     * @param prices 价格列表
+     */
+    public void calculateTripleEMA(List<BigDecimal> prices) {
+        if (prices == null || prices.isEmpty()) {
+            return;
+        }
+
+        // 计算三重EMA
+        prevEma9 = calculateEMA(prices, EMA9, prevEma9);
+        ema9 = prevEma9;
+        
+        prevEma21 = calculateEMA(prices, EMA21, prevEma21);
+        ema21 = prevEma21;
+        
+        prevEma55 = calculateEMA(prices, EMA55, prevEma55);
+        ema55 = prevEma55;
+
+        log.debug("三重EMA计算结果 - EMA9: {}, EMA21: {}, EMA55: {}", 
+                ema9, ema21, ema55);
+    }
+
+    /**
+     * 判断三重EMA多头排列
+     * 当9EMA > 21EMA > 55EMA时触发多头条件
+     * @return 是否形成多头排列
+     */
+    public boolean isBullish() {
+        return ema9.compareTo(ema21) > 0 && ema21.compareTo(ema55) > 0;
+    }
+
+    /**
+     * 判断三重EMA空头排列
+     * 当9EMA < 21EMA < 55EMA时触发空头条件
+     * @return 是否形成空头排列
+     */
+    public boolean isBearish() {
+        return ema9.compareTo(ema21) < 0 && ema21.compareTo(ema55) < 0;
+    }
+
+    /**
+     * 计算三线粘合度
+     * 用于自动过滤震荡行情
+     * @return 粘合度百分比,值越小表示越粘合
+     */
+    public BigDecimal calculatePercent() {
+        // 计算最大值和最小值
+        BigDecimal max = ema9.max(ema21).max(ema55);
+        BigDecimal min = ema9.min(ema21).min(ema55);
+        
+        // 计算平均价
+        BigDecimal avg = ema9.add(ema21).add(ema55).divide(new BigDecimal(3), 8, RoundingMode.HALF_UP);
+        
+        // 计算粘合度: (最大值 - 最小值) / 平均值 * 100%
+        if (avg.compareTo(BigDecimal.ZERO) == 0) {
+            return BigDecimal.ZERO;
+        }
+        
+        return max.subtract(min).divide(avg, 8, RoundingMode.HALF_UP).multiply(new BigDecimal(100));
+    }
+
+    /**
+     * 检查是否处于震荡行情(三线粘合)
+     * 当三线粘合度 < 2% 时判定为震荡行情
+     * @return 是否处于震荡行情
+     */
+    public boolean isUpAndDown() {
+        BigDecimal bigDecimal = calculatePercent();
+        return bigDecimal.compareTo(new BigDecimal(2)) < 0;
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/xcong/excoin/modules/okxNewPrice/indicator/BOLL.java b/src/main/java/com/xcong/excoin/modules/okxNewPrice/indicator/BOLL.java
new file mode 100644
index 0000000..8f00e0c
--- /dev/null
+++ b/src/main/java/com/xcong/excoin/modules/okxNewPrice/indicator/BOLL.java
@@ -0,0 +1,143 @@
+package com.xcong.excoin.modules.okxNewPrice.indicator;
+
+import lombok.Getter;
+import lombok.Setter;
+import lombok.extern.slf4j.Slf4j;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.util.List;
+
+/**
+ * BOLL (Bollinger Bands) 指标实现
+ * 计算逻辑:
+ * 1. 中轨(MB)= N日移动平均线
+ * 2. 上轨(UP)= 中轨 + K倍标准差
+ * 3. 下轨(DN)= 中轨 - K倍标准差
+ */
+@Slf4j
+@Getter
+@Setter
+public class BOLL extends IndicatorBase {
+
+    private static final int DEFAULT_PERIOD = 20;
+    private static final double DEFAULT_K = 2.0;
+
+    private int period = DEFAULT_PERIOD;
+    private BigDecimal k = new BigDecimal(DEFAULT_K);
+    private BigDecimal mid = BigDecimal.ZERO;
+    private BigDecimal upper = BigDecimal.ZERO;
+    private BigDecimal lower = BigDecimal.ZERO;
+
+    public BOLL() {}
+
+    public BOLL(int period, double k) {
+        this.period = period;
+        this.k = new BigDecimal(k);
+    }
+
+    /**
+     * 计算BOLL指标
+     * @param prices 价格列表
+     */
+    public void calculate(List<BigDecimal> prices) {
+        if (prices == null || prices.size() < period) {
+            return;
+        }
+
+        // 计算中轨(MB)= N日移动平均线
+        mid = calculateMA(prices, period);
+        
+        // 计算标准差
+        BigDecimal stdDev = calculateStdDev(prices, period);
+        
+        // 计算上轨(UP)和下轨(DN)
+        BigDecimal bandWidth = k.multiply(stdDev);
+        upper = mid.add(bandWidth).setScale(8, RoundingMode.HALF_UP);
+        lower = mid.subtract(bandWidth).setScale(8, RoundingMode.HALF_UP);
+        
+        log.debug("BOLL计算结果 - 中轨: {}, 上轨: {}, 下轨: {}", mid, upper, lower);
+    }
+
+    /**
+     * 判断价格是否突破上轨
+     * @param price 当前价格
+     * @return 是否突破上轨
+     */
+    public boolean isBreakUpper(BigDecimal price) {
+        return price.compareTo(upper) > 0;
+    }
+
+    /**
+     * 判断价格是否跌破下轨
+     * @param price 当前价格
+     * @return 是否跌破下轨
+     */
+    public boolean isBreakLower(BigDecimal price) {
+        return price.compareTo(lower) < 0;
+    }
+
+    /**
+     * 判断价格是否回归上轨下方
+     * @param price 当前价格
+     * @param prevPrice 前一期价格
+     * @return 是否回归上轨下方
+     */
+    public boolean isReturnFromUpper(BigDecimal price, BigDecimal prevPrice) {
+        return prevPrice.compareTo(upper) > 0 && price.compareTo(upper) <= 0;
+    }
+
+    /**
+     * 判断价格是否回归下轨上方
+     * @param price 当前价格
+     * @param prevPrice 前一期价格
+     * @return 是否回归下轨上方
+     */
+    public boolean isReturnFromLower(BigDecimal price, BigDecimal prevPrice) {
+        return prevPrice.compareTo(lower) < 0 && price.compareTo(lower) >= 0;
+    }
+
+    /**
+     * 判断价格是否在中轨上方
+     * @param price 当前价格
+     * @return 是否在中轨上方
+     */
+    public boolean isAboveMid(BigDecimal price) {
+        return price.compareTo(mid) > 0;
+    }
+
+    /**
+     * 判断价格是否在中轨下方
+     * @param price 当前价格
+     * @return 是否在中轨下方
+     */
+    public boolean isBelowMid(BigDecimal price) {
+        return price.compareTo(mid) < 0;
+    }
+
+    /**
+     * 计算布林带宽度
+     * @return 布林带宽度
+     */
+    public BigDecimal calculateBandWidth() {
+        if (mid.compareTo(BigDecimal.ZERO) == 0) {
+            return BigDecimal.ZERO;
+        }
+        return upper.subtract(lower).divide(mid, 8, RoundingMode.HALF_UP);
+    }
+
+    /**
+     * 计算价格相对于布林带的位置
+     * @param price 当前价格
+     * @return 价格位置指标 (-1: 下轨外, 0: 轨道内, 1: 上轨外)
+     */
+    public int getPricePosition(BigDecimal price) {
+        if (price.compareTo(upper) > 0) {
+            return 1;
+        } else if (price.compareTo(lower) < 0) {
+            return -1;
+        } else {
+            return 0;
+        }
+    }
+}
diff --git a/src/main/java/com/xcong/excoin/modules/okxNewPrice/indicator/IndicatorBase.java b/src/main/java/com/xcong/excoin/modules/okxNewPrice/indicator/IndicatorBase.java
new file mode 100644
index 0000000..6872bfd
--- /dev/null
+++ b/src/main/java/com/xcong/excoin/modules/okxNewPrice/indicator/IndicatorBase.java
@@ -0,0 +1,94 @@
+package com.xcong.excoin.modules.okxNewPrice.indicator;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 技术指标基础类,提供通用计算方法
+ */
+public abstract class IndicatorBase {
+
+    /**
+     * 计算移动平均值
+     * @param prices 价格列表
+     * @param period 周期
+     * @return 移动平均值
+     */
+    protected BigDecimal calculateMA(List<BigDecimal> prices, int period) {
+        if (prices == null || prices.size() < period) {
+            return BigDecimal.ZERO;
+        }
+        BigDecimal sum = BigDecimal.ZERO;
+        for (int i = prices.size() - period; i < prices.size(); i++) {
+            sum = sum.add(prices.get(i));
+        }
+        return sum.divide(new BigDecimal(period), 8, RoundingMode.HALF_UP);
+    }
+
+    /**
+     * 计算指数移动平均值
+     * @param prices 价格列表
+     * @param period 周期
+     * @param prevEMA 前一个EMA值
+     * @return 指数移动平均值
+     */
+    protected BigDecimal calculateEMA(List<BigDecimal> prices, int period, BigDecimal prevEMA) {
+        if (prices == null || prices.size() == 0) {
+            return BigDecimal.ZERO;
+        }
+        if (prevEMA == null || prevEMA.compareTo(BigDecimal.ZERO) == 0) {
+            return calculateMA(prices, Math.min(period, prices.size()));
+        }
+        BigDecimal k = new BigDecimal(2).divide(new BigDecimal(period + 1), 8, RoundingMode.HALF_UP);
+        BigDecimal currentPrice = prices.get(prices.size() - 1);
+        return currentPrice.multiply(k).add(prevEMA.multiply(BigDecimal.ONE.subtract(k)));
+    }
+
+    /**
+     * 计算标准差
+     * @param prices 价格列表
+     * @param period 周期
+     * @return 标准差
+     */
+    protected BigDecimal calculateStdDev(List<BigDecimal> prices, int period) {
+        if (prices == null || prices.size() < period) {
+            return BigDecimal.ZERO;
+        }
+        BigDecimal ma = calculateMA(prices, period);
+        BigDecimal sumSquares = BigDecimal.ZERO;
+        for (int i = prices.size() - period; i < prices.size(); i++) {
+            BigDecimal diff = prices.get(i).subtract(ma);
+            sumSquares = sumSquares.add(diff.multiply(diff));
+        }
+        BigDecimal variance = sumSquares.divide(new BigDecimal(period), 8, RoundingMode.HALF_UP);
+        return sqrt(variance);
+    }
+
+    /**
+     * 计算平方根(简化实现)
+     * @param value 输入值
+     * @return 平方根
+     */
+    protected BigDecimal sqrt(BigDecimal value) {
+        if (value.compareTo(BigDecimal.ZERO) < 0) {
+            return BigDecimal.ZERO;
+        }
+        return new BigDecimal(Math.sqrt(value.doubleValue())).setScale(8, RoundingMode.HALF_UP);
+    }
+
+    /**
+     * 获取最近的价格数据
+     * @param prices 所有价格数据
+     * @param period 周期
+     * @return 最近period个价格数据
+     */
+    protected List<BigDecimal> getRecentPrices(List<BigDecimal> prices, int period) {
+        if (prices == null || prices.size() == 0) {
+            return new ArrayList<>();
+        }
+        int startIndex = Math.max(0, prices.size() - period);
+        return prices.subList(startIndex, prices.size());
+    }
+}
diff --git a/src/main/java/com/xcong/excoin/modules/okxNewPrice/indicator/KDJ.java b/src/main/java/com/xcong/excoin/modules/okxNewPrice/indicator/KDJ.java
new file mode 100644
index 0000000..6651871
--- /dev/null
+++ b/src/main/java/com/xcong/excoin/modules/okxNewPrice/indicator/KDJ.java
@@ -0,0 +1,120 @@
+package com.xcong.excoin.modules.okxNewPrice.indicator;
+
+import lombok.Getter;
+import lombok.Setter;
+import lombok.extern.slf4j.Slf4j;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.util.List;
+
+/**
+ * KDJ (Stochastic Oscillator) 指标实现
+ * 计算逻辑:
+ * 1. RSV = (收盘价 - N日内最低价) / (N日内最高价 - N日内最低价) * 100
+ * 2. K = 2/3 * 前一日K值 + 1/3 * 当日RSV
+ * 3. D = 2/3 * 前一日D值 + 1/3 * 当日K值
+ * 4. J = 3*K - 2*D
+ */
+@Slf4j
+@Getter
+@Setter
+public class KDJ extends IndicatorBase {
+
+    private static final int DEFAULT_PERIOD = 9;
+    private static final int K_PERIOD = 3;
+    private static final int D_PERIOD = 3;
+
+    private int period = DEFAULT_PERIOD;
+    private BigDecimal k = new BigDecimal(50);
+    private BigDecimal d = new BigDecimal(50);
+    private BigDecimal j = new BigDecimal(50);
+    private BigDecimal prevK = new BigDecimal(50);
+    private BigDecimal prevD = new BigDecimal(50);
+
+    public KDJ() {}
+
+    public KDJ(int period) {
+        this.period = period;
+    }
+
+    /**
+     * 计算KDJ指标
+     * @param prices 价格列表
+     */
+    public void calculate(List<BigDecimal> prices) {
+        if (prices == null || prices.size() < period) {
+            return;
+        }
+
+        // 获取最近N天的价格
+        List<BigDecimal> recentPrices = getRecentPrices(prices, period);
+        
+        // 计算最高价和最低价
+        BigDecimal high = recentPrices.stream().max(BigDecimal::compareTo).orElse(BigDecimal.ZERO);
+        BigDecimal low = recentPrices.stream().min(BigDecimal::compareTo).orElse(BigDecimal.ZERO);
+        BigDecimal close = recentPrices.get(recentPrices.size() - 1);
+        
+        // 计算RSV
+        BigDecimal rsv;
+        if (high.compareTo(low) == 0) {
+            rsv = new BigDecimal(50);
+        } else {
+            rsv = close.subtract(low)
+                    .divide(high.subtract(low), 8, RoundingMode.HALF_UP)
+                    .multiply(new BigDecimal(100))
+                    .setScale(8, RoundingMode.HALF_UP);
+        }
+        
+        // 计算K值
+        prevK = k;
+        k = new BigDecimal(2).multiply(prevK)
+                .add(rsv)
+                .divide(new BigDecimal(3), 8, RoundingMode.HALF_UP);
+        
+        // 计算D值
+        prevD = d;
+        d = new BigDecimal(2).multiply(prevD)
+                .add(k)
+                .divide(new BigDecimal(3), 8, RoundingMode.HALF_UP);
+        
+        // 计算J值
+        j = k.multiply(new BigDecimal(3))
+                .subtract(d.multiply(new BigDecimal(2)))
+                .setScale(8, RoundingMode.HALF_UP);
+        
+        log.debug("KDJ计算结果 - K: {}, D: {}, J: {}", k, d, j);
+    }
+
+    /**
+     * 判断超买(K > 80)
+     * @return 是否超买
+     */
+    public boolean isOverbought() {
+        return k.compareTo(new BigDecimal(80)) > 0;
+    }
+
+    /**
+     * 判断超卖(K < 20)
+     * @return 是否超卖
+     */
+    public boolean isOversold() {
+        return k.compareTo(new BigDecimal(20)) < 0;
+    }
+
+    /**
+     * 判断金叉信号(K线上穿D线)
+     * @return 是否形成金叉
+     */
+    public boolean isGoldenCross() {
+        return prevK.compareTo(prevD) < 0 && k.compareTo(d) > 0;
+    }
+
+    /**
+     * 判断死叉信号(K线下穿D线)
+     * @return 是否形成死叉
+     */
+    public boolean isDeathCross() {
+        return prevK.compareTo(prevD) > 0 && k.compareTo(d) < 0;
+    }
+}
diff --git a/src/main/java/com/xcong/excoin/modules/okxNewPrice/indicator/MA.java b/src/main/java/com/xcong/excoin/modules/okxNewPrice/indicator/MA.java
new file mode 100644
index 0000000..25cba55
--- /dev/null
+++ b/src/main/java/com/xcong/excoin/modules/okxNewPrice/indicator/MA.java
@@ -0,0 +1,151 @@
+package com.xcong.excoin.modules.okxNewPrice.indicator;
+
+import lombok.Getter;
+import lombok.Setter;
+import lombok.extern.slf4j.Slf4j;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+/**
+ * MA (Moving Average) 指标实现
+ * 支持不同周期的简单移动平均线(SMA)和指数移动平均线(EMA)
+ */
+@Slf4j
+@Getter
+@Setter
+public class MA extends IndicatorBase {
+
+    // 常用周期
+    public static final int MA5 = 5;
+    public static final int MA10 = 10;
+    public static final int MA20 = 20;
+    public static final int MA30 = 30;
+    public static final int MA60 = 60;
+
+    private BigDecimal ma5 = BigDecimal.ZERO;
+    private BigDecimal ma10 = BigDecimal.ZERO;
+    private BigDecimal ma20 = BigDecimal.ZERO;
+    private BigDecimal ma30 = BigDecimal.ZERO;
+    private BigDecimal ma60 = BigDecimal.ZERO;
+
+    private BigDecimal ema5 = BigDecimal.ZERO;
+    private BigDecimal ema10 = BigDecimal.ZERO;
+    private BigDecimal ema20 = BigDecimal.ZERO;
+    private BigDecimal ema30 = BigDecimal.ZERO;
+    private BigDecimal ema60 = BigDecimal.ZERO;
+
+    private BigDecimal prevEma5 = null;
+    private BigDecimal prevEma10 = null;
+    private BigDecimal prevEma20 = null;
+    private BigDecimal prevEma30 = null;
+    private BigDecimal prevEma60 = null;
+
+    /**
+     * 计算所有周期的MA指标
+     * @param prices 价格列表
+     */
+    public void calculate(List<BigDecimal> prices) {
+        if (prices == null || prices.size() < 1) {
+            return;
+        }
+
+        // 计算SMA
+        if (prices.size() >= MA5) {
+            ma5 = calculateMA(prices, MA5);
+        }
+        if (prices.size() >= MA10) {
+            ma10 = calculateMA(prices, MA10);
+        }
+        if (prices.size() >= MA20) {
+            ma20 = calculateMA(prices, MA20);
+        }
+        if (prices.size() >= MA30) {
+            ma30 = calculateMA(prices, MA30);
+        }
+        if (prices.size() >= MA60) {
+            ma60 = calculateMA(prices, MA60);
+        }
+
+        // 计算EMA
+        prevEma5 = calculateEMA(prices, MA5, prevEma5);
+        ema5 = prevEma5;
+        
+        prevEma10 = calculateEMA(prices, MA10, prevEma10);
+        ema10 = prevEma10;
+        
+        prevEma20 = calculateEMA(prices, MA20, prevEma20);
+        ema20 = prevEma20;
+        
+        prevEma30 = calculateEMA(prices, MA30, prevEma30);
+        ema30 = prevEma30;
+        
+        prevEma60 = calculateEMA(prices, MA60, prevEma60);
+        ema60 = prevEma60;
+
+        log.debug("MA计算结果 - MA5: {}, MA10: {}, MA20: {}, MA30: {}, MA60: {}", 
+                ma5, ma10, ma20, ma30, ma60);
+        log.debug("EMA计算结果 - EMA5: {}, EMA10: {}, EMA20: {}, EMA30: {}, EMA60: {}", 
+                ema5, ema10, ema20, ema30, ema60);
+    }
+
+    /**
+     * 判断短期均线是否上穿长期均线(金叉)
+     * @param shortMA 短期均线
+     * @param longMA 长期均线
+     * @param prevShortMA 前一期短期均线
+     * @param prevLongMA 前一期长期均线
+     * @return 是否形成金叉
+     */
+    public boolean isGoldenCross(BigDecimal shortMA, BigDecimal longMA, 
+                                BigDecimal prevShortMA, BigDecimal prevLongMA) {
+        return prevShortMA != null && prevLongMA != null &&
+                prevShortMA.compareTo(prevLongMA) < 0 && 
+                shortMA.compareTo(longMA) > 0;
+    }
+
+    /**
+     * 判断短期均线是否下穿长期均线(死叉)
+     * @param shortMA 短期均线
+     * @param longMA 长期均线
+     * @param prevShortMA 前一期短期均线
+     * @param prevLongMA 前一期长期均线
+     * @return 是否形成死叉
+     */
+    public boolean isDeathCross(BigDecimal shortMA, BigDecimal longMA, 
+                               BigDecimal prevShortMA, BigDecimal prevLongMA) {
+        return prevShortMA != null && prevLongMA != null &&
+                prevShortMA.compareTo(prevLongMA) > 0 && 
+                shortMA.compareTo(longMA) < 0;
+    }
+
+    /**
+     * 判断价格是否上穿均线
+     * @param price 当前价格
+     * @param ma 均线值
+     * @param prevPrice 前一期价格
+     * @param prevMA 前一期均线值
+     * @return 是否上穿
+     */
+    public boolean isPriceCrossUp(BigDecimal price, BigDecimal ma, 
+                                 BigDecimal prevPrice, BigDecimal prevMA) {
+        return prevPrice != null && prevMA != null &&
+                prevPrice.compareTo(prevMA) < 0 && 
+                price.compareTo(ma) > 0;
+    }
+
+    /**
+     * 判断价格是否下穿均线
+     * @param price 当前价格
+     * @param ma 均线值
+     * @param prevPrice 前一期价格
+     * @param prevMA 前一期均线值
+     * @return 是否下穿
+     */
+    public boolean isPriceCrossDown(BigDecimal price, BigDecimal ma, 
+                                   BigDecimal prevPrice, BigDecimal prevMA) {
+        return prevPrice != null && prevMA != null &&
+                prevPrice.compareTo(prevMA) > 0 && 
+                price.compareTo(ma) < 0;
+    }
+}
diff --git a/src/main/java/com/xcong/excoin/modules/okxNewPrice/indicator/MACD.java b/src/main/java/com/xcong/excoin/modules/okxNewPrice/indicator/MACD.java
new file mode 100644
index 0000000..92c91b9
--- /dev/null
+++ b/src/main/java/com/xcong/excoin/modules/okxNewPrice/indicator/MACD.java
@@ -0,0 +1,80 @@
+package com.xcong.excoin.modules.okxNewPrice.indicator;
+
+import lombok.Getter;
+import lombok.Setter;
+import lombok.extern.slf4j.Slf4j;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * MACD (Moving Average Convergence Divergence) 指标实现
+ * 计算逻辑:
+ * 1. DIF = EMA(12) - EMA(26)
+ * 2. DEA = EMA(DIF, 9)
+ * 3. MACD柱状图 = (DIF - DEA) * 2
+ */
+@Slf4j
+@Getter
+@Setter
+public class MACD extends IndicatorBase {
+
+    private static final int FAST_PERIOD = 12;
+    private static final int SLOW_PERIOD = 26;
+    private static final int SIGNAL_PERIOD = 9;
+
+    private BigDecimal dif = BigDecimal.ZERO;
+    private BigDecimal dea = BigDecimal.ZERO;
+    private BigDecimal macdBar = BigDecimal.ZERO;
+    private BigDecimal prevFastEMA = null;
+    private BigDecimal prevSlowEMA = null;
+    private BigDecimal prevDea = null;
+
+    /**
+     * 计算MACD指标
+     * @param prices 价格列表
+     */
+    public void calculate(List<BigDecimal> prices) {
+        if (prices == null || prices.size() < 2) {
+            return;
+        }
+
+        // 计算快速EMA
+        prevFastEMA = calculateEMA(prices, FAST_PERIOD, prevFastEMA);
+        
+        // 计算慢速EMA
+        prevSlowEMA = calculateEMA(prices, SLOW_PERIOD, prevSlowEMA);
+        
+        // 计算DIF
+        dif = prevFastEMA.subtract(prevSlowEMA).setScale(8, RoundingMode.HALF_UP);
+        
+        // 计算DEA
+        List<BigDecimal> difList = new ArrayList<>();
+        difList.add(dif);
+        prevDea = calculateEMA(difList, SIGNAL_PERIOD, prevDea);
+        dea = prevDea.setScale(8, RoundingMode.HALF_UP);
+        
+        // 计算MACD柱状图
+        macdBar = dif.subtract(dea).multiply(new BigDecimal(2)).setScale(8, RoundingMode.HALF_UP);
+        
+        log.debug("MACD计算结果 - DIF: {}, DEA: {}, MACD柱状图: {}", dif, dea, macdBar);
+    }
+
+    /**
+     * 判断金叉信号(DIF上穿DEA)
+     * @return 是否形成金叉
+     */
+    public boolean isGoldenCross(BigDecimal previousDIF, BigDecimal previousDEA) {
+        return previousDIF.compareTo(previousDEA) < 0 && dif.compareTo(dea) > 0;
+    }
+
+    /**
+     * 判断死叉信号(DIF下穿DEA)
+     * @return 是否形成死叉
+     */
+    public boolean isDeathCross(BigDecimal previousDIF, BigDecimal previousDEA) {
+        return previousDIF.compareTo(previousDEA) > 0 && dif.compareTo(dea) < 0;
+    }
+}
diff --git a/src/main/java/com/xcong/excoin/modules/okxNewPrice/indicator/RSI.java b/src/main/java/com/xcong/excoin/modules/okxNewPrice/indicator/RSI.java
new file mode 100644
index 0000000..b289d1c
--- /dev/null
+++ b/src/main/java/com/xcong/excoin/modules/okxNewPrice/indicator/RSI.java
@@ -0,0 +1,119 @@
+package com.xcong.excoin.modules.okxNewPrice.indicator;
+
+import lombok.Getter;
+import lombok.Setter;
+import lombok.extern.slf4j.Slf4j;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.util.List;
+
+/**
+ * RSI (Relative Strength Index) 指标实现
+ * 计算逻辑:
+ * 1. 计算N天内的上涨幅度和下跌幅度
+ * 2. 计算平均上涨幅度和平均下跌幅度
+ * 3. RSI = 100 - (100 / (1 + (平均上涨幅度 / 平均下跌幅度)))
+ */
+@Slf4j
+@Getter
+@Setter
+public class RSI extends IndicatorBase {
+
+    private static final int DEFAULT_PERIOD = 14;
+
+    private int period = DEFAULT_PERIOD;
+    private BigDecimal rsi = BigDecimal.ZERO;
+    private BigDecimal prevAvgGain = BigDecimal.ZERO;
+    private BigDecimal prevAvgLoss = BigDecimal.ZERO;
+
+    public RSI() {}
+
+    public RSI(int period) {
+        this.period = period;
+    }
+
+    /**
+     * 计算RSI指标
+     * @param prices 价格列表
+     */
+    public void calculate(List<BigDecimal> prices) {
+        if (prices == null || prices.size() < period + 1) {
+            return;
+        }
+
+        if (prevAvgGain.compareTo(BigDecimal.ZERO) == 0 && prevAvgLoss.compareTo(BigDecimal.ZERO) == 0) {
+            // 首次计算
+            BigDecimal totalGain = BigDecimal.ZERO;
+            BigDecimal totalLoss = BigDecimal.ZERO;
+
+            for (int i = prices.size() - period; i < prices.size(); i++) {
+                BigDecimal change = prices.get(i).subtract(prices.get(i - 1));
+                if (change.compareTo(BigDecimal.ZERO) > 0) {
+                    totalGain = totalGain.add(change);
+                } else {
+                    totalLoss = totalLoss.add(change.abs());
+                }
+            }
+
+            prevAvgGain = totalGain.divide(new BigDecimal(period), 8, RoundingMode.HALF_UP);
+            prevAvgLoss = totalLoss.divide(new BigDecimal(period), 8, RoundingMode.HALF_UP);
+        } else {
+            // 后续计算
+            BigDecimal change = prices.get(prices.size() - 1).subtract(prices.get(prices.size() - 2));
+            BigDecimal gain = change.compareTo(BigDecimal.ZERO) > 0 ? change : BigDecimal.ZERO;
+            BigDecimal loss = change.compareTo(BigDecimal.ZERO) < 0 ? change.abs() : BigDecimal.ZERO;
+
+            prevAvgGain = prevAvgGain.multiply(new BigDecimal(period - 1))
+                    .add(gain)
+                    .divide(new BigDecimal(period), 8, RoundingMode.HALF_UP);
+            prevAvgLoss = prevAvgLoss.multiply(new BigDecimal(period - 1))
+                    .add(loss)
+                    .divide(new BigDecimal(period), 8, RoundingMode.HALF_UP);
+        }
+
+        // 计算RSI
+        if (prevAvgLoss.compareTo(BigDecimal.ZERO) == 0) {
+            rsi = new BigDecimal(100);
+        } else {
+            BigDecimal rs = prevAvgGain.divide(prevAvgLoss, 8, RoundingMode.HALF_UP);
+            rsi = new BigDecimal(100)
+                    .subtract(new BigDecimal(100).divide(BigDecimal.ONE.add(rs), 8, RoundingMode.HALF_UP))
+                    .setScale(8, RoundingMode.HALF_UP);
+        }
+
+        log.debug("RSI计算结果 - RSI({}): {}", period, rsi);
+    }
+
+    /**
+     * 判断超买(RSI > 70)
+     * @return 是否超买
+     */
+    public boolean isOverbought() {
+        return rsi.compareTo(new BigDecimal(70)) > 0;
+    }
+
+    /**
+     * 判断超卖(RSI < 30)
+     * @return 是否超卖
+     */
+    public boolean isOversold() {
+        return rsi.compareTo(new BigDecimal(30)) < 0;
+    }
+
+    /**
+     * 判断超买(RSI > 80)
+     * @return 是否严重超买
+     */
+    public boolean isExtremelyOverbought() {
+        return rsi.compareTo(new BigDecimal(80)) > 0;
+    }
+
+    /**
+     * 判断超卖(RSI < 20)
+     * @return 是否严重超卖
+     */
+    public boolean isExtremelyOversold() {
+        return rsi.compareTo(new BigDecimal(20)) < 0;
+    }
+}
diff --git a/src/main/java/com/xcong/excoin/modules/okxNewPrice/indicator/strategy/AbstractTechnicalIndicatorStrategy.java b/src/main/java/com/xcong/excoin/modules/okxNewPrice/indicator/strategy/AbstractTechnicalIndicatorStrategy.java
new file mode 100644
index 0000000..a853473
--- /dev/null
+++ b/src/main/java/com/xcong/excoin/modules/okxNewPrice/indicator/strategy/AbstractTechnicalIndicatorStrategy.java
@@ -0,0 +1,89 @@
+package com.xcong.excoin.modules.okxNewPrice.indicator.strategy;
+
+import com.xcong.excoin.modules.okxNewPrice.okxWs.param.TradeRequestParam;
+import com.xcong.excoin.modules.okxNewPrice.utils.WsMapBuild;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.extern.slf4j.Slf4j;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 技术指标策略抽象基类,提供通用功能
+ */
+@Slf4j
+@Getter
+@Setter
+public abstract class AbstractTechnicalIndicatorStrategy implements TechnicalIndicatorStrategy {
+
+    protected static final int MAX_PRICE_HISTORY = 100; // 最大价格历史记录数量
+    protected List<BigDecimal> priceHistory = new ArrayList<>();
+    protected boolean initialized = false;
+    protected String strategyName = ""; // 策略名称
+
+    @Override
+    public void initialize() {
+        priceHistory.clear();
+        initialized = true;
+        log.info("策略初始化完成: {}", strategyName);
+    }
+
+    @Override
+    public void updatePrices(List<BigDecimal> prices) {
+        if (!initialized) {
+            initialize();
+        }
+        
+        if (prices == null || prices.isEmpty()) {
+            return;
+        }
+        
+        // 更新价格历史记录
+        priceHistory.addAll(prices);
+        
+        // 限制价格历史记录数量
+        if (priceHistory.size() > MAX_PRICE_HISTORY) {
+            priceHistory = priceHistory.subList(priceHistory.size() - MAX_PRICE_HISTORY, priceHistory.size());
+        }
+        
+        log.debug("价格历史记录更新完成,当前数量: {}", priceHistory.size());
+    }
+
+    @Override
+    public boolean isValid() {
+        return initialized;
+    }
+
+    /**
+     * 创建交易请求参数
+     * @param accountName 账户名称
+     * @param markPx 当前标记价格
+     * @param posSide 仓位方向
+     * @param signal 交易信号
+     * @return 交易请求参数
+     */
+    protected TradeRequestParam createTradeRequestParam(String accountName, String markPx, String posSide, TradeSignal signal) {
+        TradeRequestParam param = new TradeRequestParam();
+        param.setAccountName(accountName);
+        param.setMarkPx(markPx);
+        param.setPosSide(posSide);
+        
+        log.info("账户: {}, 价格: {}, 仓位方向: {}, 信号: {}", 
+                accountName, markPx, posSide, signal.getName());
+        
+        return param;
+    }
+
+    /**
+     * 日志记录交易信号
+     * @param accountName 账户名称
+     * @param markPx 当前标记价格
+     * @param signal 交易信号
+     */
+    protected void logSignal(String accountName, String markPx, TradeSignal signal) {
+        log.info("策略: {}, 账户: {}, 价格: {}, 信号: {}", 
+                strategyName, accountName, markPx, signal.getName());
+    }
+}
diff --git a/src/main/java/com/xcong/excoin/modules/okxNewPrice/indicator/strategy/ComprehensiveTechnicalStrategy.java b/src/main/java/com/xcong/excoin/modules/okxNewPrice/indicator/strategy/ComprehensiveTechnicalStrategy.java
new file mode 100644
index 0000000..a6c320c
--- /dev/null
+++ b/src/main/java/com/xcong/excoin/modules/okxNewPrice/indicator/strategy/ComprehensiveTechnicalStrategy.java
@@ -0,0 +1,351 @@
+package com.xcong.excoin.modules.okxNewPrice.indicator.strategy;
+
+import com.xcong.excoin.modules.okxNewPrice.indicator.BOLL;
+import com.xcong.excoin.modules.okxNewPrice.indicator.KDJ;
+import com.xcong.excoin.modules.okxNewPrice.indicator.MACD;
+import com.xcong.excoin.modules.okxNewPrice.indicator.RSI;
+import com.xcong.excoin.modules.okxNewPrice.okxWs.enums.CoinEnums;
+import com.xcong.excoin.modules.okxNewPrice.okxWs.enums.OrderParamEnums;
+import com.xcong.excoin.modules.okxNewPrice.okxWs.param.TradeRequestParam;
+import com.xcong.excoin.modules.okxNewPrice.utils.WsMapBuild;
+import lombok.extern.slf4j.Slf4j;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+/**
+ * 综合技术指标策略实现类,整合MACD、KDJ、RSI、BOLL等指标生成交易信号
+ */
+@Slf4j
+public class ComprehensiveTechnicalStrategy extends AbstractTechnicalIndicatorStrategy {
+
+    private final MACD macd;
+    private final KDJ kdj;
+    private final RSI rsi;
+    private final BOLL boll;
+    
+    private BigDecimal prevDif;
+    private BigDecimal prevDea;
+    private BigDecimal prevK;
+    private BigDecimal prevD;
+
+    public ComprehensiveTechnicalStrategy() {
+        super();
+        this.strategyName = "综合技术指标策略";
+        this.macd = new MACD();
+        this.kdj = new KDJ();
+        this.rsi = new RSI();
+        this.boll = new BOLL();
+        this.prevDif = BigDecimal.ZERO;
+        this.prevDea = BigDecimal.ZERO;
+        this.prevK = new BigDecimal(50);
+        this.prevD = new BigDecimal(50);
+    }
+
+    @Override
+    public void initialize() {
+        super.initialize();
+        macd.setDif(BigDecimal.ZERO);
+        macd.setDea(BigDecimal.ZERO);
+        macd.setMacdBar(BigDecimal.ZERO);
+        macd.setPrevFastEMA(null);
+        macd.setPrevSlowEMA(null);
+        macd.setPrevDea(null);
+        
+        kdj.setK(new BigDecimal(50));
+        kdj.setD(new BigDecimal(50));
+        kdj.setJ(new BigDecimal(50));
+        kdj.setPrevK(new BigDecimal(50));
+        kdj.setPrevD(new BigDecimal(50));
+        
+        rsi.setRsi(BigDecimal.ZERO);
+        rsi.setPrevAvgGain(BigDecimal.ZERO);
+        rsi.setPrevAvgLoss(BigDecimal.ZERO);
+        
+        boll.setMid(BigDecimal.ZERO);
+        boll.setUpper(BigDecimal.ZERO);
+        boll.setLower(BigDecimal.ZERO);
+        
+        prevDif = BigDecimal.ZERO;
+        prevDea = BigDecimal.ZERO;
+        prevK = new BigDecimal(50);
+        prevD = new BigDecimal(50);
+        
+        log.info("综合技术指标策略初始化完成");
+    }
+
+    @Override
+    public TradeRequestParam getSignal(String accountName, String markPx, String posSide) {
+        if (!initialized || priceHistory.isEmpty()) {
+            log.warn("策略未初始化或价格历史为空");
+            return createTradeRequestParam(accountName, markPx, posSide, TradeSignal.NO_SIGNAL);
+        }
+
+        try {
+            BigDecimal currentPrice = new BigDecimal(markPx);
+            
+            // 计算所有技术指标
+            macd.calculate(priceHistory);
+            kdj.calculate(priceHistory);
+            rsi.calculate(priceHistory);
+            boll.calculate(priceHistory);
+            
+            // 生成交易信号
+            TradeRequestParam param = analyzeSignal(accountName, markPx, posSide, currentPrice);
+            
+            // 更新历史指标值
+            updateHistoricalIndicatorValues();
+            
+            return param;
+        } catch (Exception e) {
+            log.error("计算交易信号时发生异常", e);
+            return createTradeRequestParam(accountName, markPx, posSide, TradeSignal.NO_SIGNAL);
+        }
+    }
+
+    /**
+     * 分析技术指标生成交易信号
+     */
+    private TradeRequestParam analyzeSignal(String accountName, String markPx, String posSide, BigDecimal currentPrice) {
+        TradeRequestParam param = createTradeRequestParam(accountName, markPx, posSide, TradeSignal.NO_SIGNAL);
+        param.setTradeType(OrderParamEnums.TRADE_YES.getValue());
+        param.setInstId(CoinEnums.HE_YUE.getCode());
+        param.setTdMode(CoinEnums.CROSS.getCode());
+        param.setOrdType(CoinEnums.ORDTYPE_MARKET.getCode());
+        
+        // 检查冷静期
+        String outStr = getAccountConfig(accountName, CoinEnums.OUT.name());
+        if (OrderParamEnums.OUT_YES.getValue().equals(outStr)) {
+            log.error("冷静中,不允许下单......");
+            param.setTradeType(OrderParamEnums.TRADE_NO.getValue());
+            return param;
+        }
+        
+        TradeSignal signal = TradeSignal.NO_SIGNAL;
+        
+        // 根据多空方向分别分析信号
+        if (CoinEnums.POSSIDE_LONG.getCode().equals(posSide)) {
+            signal = analyzeLongSignal(currentPrice, posSide);
+        } else if (CoinEnums.POSSIDE_SHORT.getCode().equals(posSide)) {
+            signal = analyzeShortSignal(currentPrice, posSide);
+        } else {
+            // 如果没有指定仓位方向,同时分析多头和空头信号
+            TradeSignal longSignal = analyzeLongSignal(currentPrice, posSide);
+            TradeSignal shortSignal = analyzeShortSignal(currentPrice, posSide);
+            
+            // 优先选择非NO_SIGNAL的信号
+            if (longSignal != TradeSignal.NO_SIGNAL) {
+                signal = longSignal;
+            } else {
+                signal = shortSignal;
+            }
+        }
+        
+        log.info("账户: {}, 价格: {}, 方向: {}, 生成信号: {}", 
+                accountName, markPx, posSide, signal.getName());
+        
+        // 设置信号参数
+        setSignalParameters(param, signal);
+        
+        return param;
+    }
+
+    /**
+     * 分析多头信号
+     */
+    private TradeSignal analyzeLongSignal(BigDecimal currentPrice, String posSide) {
+        // 检查超卖条件
+        if (rsi.isOversold() || rsi.isExtremelyOversold()) {
+            // KDJ超卖且金叉
+            if ((kdj.isOversold() && kdj.isGoldenCross()) || 
+                (boll.isBreakLower(currentPrice) && macd.isGoldenCross(prevDif, prevDea))) {
+                // 如果当前没有仓位,则开多
+                if (posSide == null || posSide.isEmpty()) {
+                    return TradeSignal.OPEN_LONG;
+                }
+                // 如果当前是空头仓位,则平空
+                if (CoinEnums.POSSIDE_SHORT.getCode().equals(posSide)) {
+                    return TradeSignal.CLOSE_SHORT;
+                }
+                // 如果当前已经是多头仓位,则保持观望
+                return TradeSignal.NO_SIGNAL;
+            }
+        }
+        
+        // 检查超买条件
+        if (rsi.isOverbought() || rsi.isExtremelyOverbought()) {
+            // KDJ超买且死叉
+            if ((kdj.isOverbought() && kdj.isDeathCross()) || 
+                (boll.isBreakUpper(currentPrice) && macd.isDeathCross(prevDif, prevDea))) {
+                // 如果当前是多头仓位,则平多
+                if (CoinEnums.POSSIDE_LONG.getCode().equals(posSide)) {
+                    return TradeSignal.CLOSE_LONG;
+                }
+                // 如果当前没有仓位,则开空
+                if (posSide == null || posSide.isEmpty()) {
+                    return TradeSignal.OPEN_SHORT;
+                }
+                // 如果当前已经是空头仓位,则保持观望
+                return TradeSignal.NO_SIGNAL;
+            }
+        }
+        
+        // 检查MACD金叉死叉
+        if (macd.isGoldenCross(prevDif, prevDea)) {
+            // 如果当前没有仓位,则开多
+            if (posSide == null || posSide.isEmpty()) {
+                return TradeSignal.OPEN_LONG;
+            }
+            // 如果当前是空头仓位,则平空
+            if (CoinEnums.POSSIDE_SHORT.getCode().equals(posSide)) {
+                return TradeSignal.CLOSE_SHORT;
+            }
+            // 如果当前已经是多头仓位,则保持观望
+            return TradeSignal.NO_SIGNAL;
+        } else if (macd.isDeathCross(prevDif, prevDea)) {
+            // 如果当前是多头仓位,则平多
+            if (CoinEnums.POSSIDE_LONG.getCode().equals(posSide)) {
+                return TradeSignal.CLOSE_LONG;
+            }
+            // 如果当前没有仓位,则开空
+            if (posSide == null || posSide.isEmpty()) {
+                return TradeSignal.OPEN_SHORT;
+            }
+            // 如果当前已经是空头仓位,则保持观望
+            return TradeSignal.NO_SIGNAL;
+        }
+        
+        return TradeSignal.NO_SIGNAL;
+    }
+
+    /**
+     * 分析空头信号
+     */
+    private TradeSignal analyzeShortSignal(BigDecimal currentPrice, String posSide) {
+        // 检查超买条件
+        if (rsi.isOverbought() || rsi.isExtremelyOverbought()) {
+            // KDJ超买且死叉
+            if ((kdj.isOverbought() && kdj.isDeathCross()) || 
+                (boll.isBreakUpper(currentPrice) && macd.isDeathCross(prevDif, prevDea))) {
+                // 如果当前没有仓位,则开空
+                if (posSide == null || posSide.isEmpty()) {
+                    return TradeSignal.OPEN_SHORT;
+                }
+                // 如果当前是多头仓位,则平多
+                if (CoinEnums.POSSIDE_LONG.getCode().equals(posSide)) {
+                    return TradeSignal.CLOSE_LONG;
+                }
+                // 如果当前已经是空头仓位,则保持观望
+                return TradeSignal.NO_SIGNAL;
+            }
+        }
+        
+        // 检查超卖条件
+        if (rsi.isOversold() || rsi.isExtremelyOversold()) {
+            // KDJ超卖且金叉
+            if ((kdj.isOversold() && kdj.isGoldenCross()) || 
+                (boll.isBreakLower(currentPrice) && macd.isGoldenCross(prevDif, prevDea))) {
+                // 如果当前是空头仓位,则平空
+                if (CoinEnums.POSSIDE_SHORT.getCode().equals(posSide)) {
+                    return TradeSignal.CLOSE_SHORT;
+                }
+                // 如果当前没有仓位,则开多
+                if (posSide == null || posSide.isEmpty()) {
+                    return TradeSignal.OPEN_LONG;
+                }
+                // 如果当前已经是多头仓位,则保持观望
+                return TradeSignal.NO_SIGNAL;
+            }
+        }
+        
+        // 检查MACD金叉死叉
+        if (macd.isGoldenCross(prevDif, prevDea)) {
+            // 如果当前是空头仓位,则平空
+            if (CoinEnums.POSSIDE_SHORT.getCode().equals(posSide)) {
+                return TradeSignal.CLOSE_SHORT;
+            }
+            // 如果当前没有仓位,则开多
+            if (posSide == null || posSide.isEmpty()) {
+                return TradeSignal.OPEN_LONG;
+            }
+            // 如果当前已经是多头仓位,则保持观望
+            return TradeSignal.NO_SIGNAL;
+        } else if (macd.isDeathCross(prevDif, prevDea)) {
+            // 如果当前没有仓位,则开空
+            if (posSide == null || posSide.isEmpty()) {
+                return TradeSignal.OPEN_SHORT;
+            }
+            // 如果当前是多头仓位,则平多
+            if (CoinEnums.POSSIDE_LONG.getCode().equals(posSide)) {
+                return TradeSignal.CLOSE_LONG;
+            }
+            // 如果当前已经是空头仓位,则保持观望
+            return TradeSignal.NO_SIGNAL;
+        }
+        
+        return TradeSignal.NO_SIGNAL;
+    }
+
+    /**
+     * 设置信号参数
+     */
+    private void setSignalParameters(TradeRequestParam param, TradeSignal signal) {
+        String side = null;
+        
+        switch (signal) {
+            case BUY:
+                side = CoinEnums.SIDE_BUY.getCode();
+                break;
+            case SELL:
+                side = CoinEnums.SIDE_SELL.getCode();
+                break;
+            case OPEN_LONG:
+                side = CoinEnums.SIDE_BUY.getCode();
+                break;
+            case CLOSE_LONG:
+                side = CoinEnums.SIDE_SELL.getCode();
+                break;
+            case OPEN_SHORT:
+                side = CoinEnums.SIDE_SELL.getCode();
+                break;
+            case CLOSE_SHORT:
+                side = CoinEnums.SIDE_BUY.getCode();
+                break;
+            case STOP_LOSS:
+                // 止损操作,根据当前仓位方向决定买卖方向
+                side = CoinEnums.POSSIDE_LONG.getCode().equals(param.getPosSide()) ? 
+                       CoinEnums.SIDE_SELL.getCode() : CoinEnums.SIDE_BUY.getCode();
+                break;
+            default:
+                param.setTradeType(OrderParamEnums.TRADE_NO.getValue());
+                return;
+        }
+        
+        param.setSide(side);
+        log.info("设置交易方向: {}", side);
+    }
+
+    /**
+     * 更新历史指标值
+     */
+    private void updateHistoricalIndicatorValues() {
+        prevDif = macd.getDif();
+        prevDea = macd.getDea();
+        prevK = kdj.getK();
+        prevD = kdj.getD();
+    }
+
+    /**
+     * 获取账户配置信息
+     */
+    private String getAccountConfig(String accountName, String key) {
+        try {
+            // 这里需要根据实际情况获取账户配置信息
+            // 暂时返回默认值,实际应该从InstrumentsWs或其他配置类中获取
+            return "NO";
+        } catch (Exception e) {
+            log.error("获取账户配置信息失败", e);
+            return "NO";
+        }
+    }
+}
diff --git a/src/main/java/com/xcong/excoin/modules/okxNewPrice/indicator/strategy/CoreTechnicalStrategy.java b/src/main/java/com/xcong/excoin/modules/okxNewPrice/indicator/strategy/CoreTechnicalStrategy.java
new file mode 100644
index 0000000..61469c5
--- /dev/null
+++ b/src/main/java/com/xcong/excoin/modules/okxNewPrice/indicator/strategy/CoreTechnicalStrategy.java
@@ -0,0 +1,589 @@
+package com.xcong.excoin.modules.okxNewPrice.indicator.strategy;
+
+import com.xcong.excoin.modules.okxNewPrice.indicator.AdvancedMA;
+import com.xcong.excoin.modules.okxNewPrice.indicator.BOLL;
+import com.xcong.excoin.modules.okxNewPrice.indicator.KDJ;
+import com.xcong.excoin.modules.okxNewPrice.indicator.MACD;
+import com.xcong.excoin.modules.okxNewPrice.indicator.RSI;
+import com.xcong.excoin.modules.okxNewPrice.okxWs.enums.CoinEnums;
+import com.xcong.excoin.modules.okxNewPrice.okxWs.enums.OrderParamEnums;
+import com.xcong.excoin.modules.okxNewPrice.okxWs.param.TradeRequestParam;
+import lombok.extern.slf4j.Slf4j;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 核心技术指标策略实现类
+ * 整合三重EMA交叉系统、波动率自适应布林带、MACD能量柱分级策略等核心指标
+ */
+@Slf4j
+public class CoreTechnicalStrategy extends AbstractTechnicalIndicatorStrategy {
+
+    private static final int MACD_HISTOGRAM_PERIOD = 5; // MACD能量柱计算周期
+    private static final BigDecimal VOLUME_MULTIPLIER = new BigDecimal(3); // 成交量放大倍数
+    private static final BigDecimal GLUE_THRESHOLD = new BigDecimal(2); // 三线粘合度阈值(%)
+
+    private final AdvancedMA advancedMA;
+    private final BOLL boll;
+    private final MACD macd;
+    private final RSI rsi;
+    private final KDJ kdj;
+
+    private List<BigDecimal> macdHistogramHistory; // MACD能量柱历史
+    private BigDecimal prevEma9;
+    private BigDecimal prevEma21;
+    private BigDecimal prevEma55;
+    private BigDecimal prevDif;
+    private BigDecimal prevDea;
+    private BigDecimal prevK;
+    private BigDecimal prevD;
+    private BigDecimal prevJ;
+
+    public CoreTechnicalStrategy() {
+        super();
+        this.strategyName = "核心技术指标策略";
+        this.advancedMA = new AdvancedMA();
+        this.boll = new BOLL();
+        this.macd = new MACD();
+        this.rsi = new RSI();
+        this.kdj = new KDJ();
+        this.macdHistogramHistory = new ArrayList<>();
+        this.prevEma9 = BigDecimal.ZERO;
+        this.prevEma21 = BigDecimal.ZERO;
+        this.prevEma55 = BigDecimal.ZERO;
+        this.prevDif = BigDecimal.ZERO;
+        this.prevDea = BigDecimal.ZERO;
+        this.prevK = new BigDecimal(50);
+        this.prevD = new BigDecimal(50);
+        this.prevJ = new BigDecimal(50);
+    }
+
+    @Override
+    public void initialize() {
+        super.initialize();
+        macdHistogramHistory.clear();
+        
+        // 初始化技术指标
+        advancedMA.setPrevEma9(null);
+        advancedMA.setPrevEma21(null);
+        advancedMA.setPrevEma55(null);
+        
+        macd.setDif(BigDecimal.ZERO);
+        macd.setDea(BigDecimal.ZERO);
+        macd.setMacdBar(BigDecimal.ZERO);
+        macd.setPrevFastEMA(null);
+        macd.setPrevSlowEMA(null);
+        macd.setPrevDea(null);
+        
+        rsi.setRsi(BigDecimal.ZERO);
+        rsi.setPrevAvgGain(BigDecimal.ZERO);
+        rsi.setPrevAvgLoss(BigDecimal.ZERO);
+        
+        kdj.setK(new BigDecimal(50));
+        kdj.setD(new BigDecimal(50));
+        kdj.setJ(new BigDecimal(50));
+        kdj.setPrevK(new BigDecimal(50));
+        kdj.setPrevD(new BigDecimal(50));
+        
+        boll.setMid(BigDecimal.ZERO);
+        boll.setUpper(BigDecimal.ZERO);
+        boll.setLower(BigDecimal.ZERO);
+        
+        prevEma9 = BigDecimal.ZERO;
+        prevEma21 = BigDecimal.ZERO;
+        prevEma55 = BigDecimal.ZERO;
+        prevDif = BigDecimal.ZERO;
+        prevDea = BigDecimal.ZERO;
+        prevK = new BigDecimal(50);
+        prevD = new BigDecimal(50);
+        prevJ = new BigDecimal(50);
+        
+        log.info("核心技术指标策略初始化完成");
+    }
+
+    @Override
+    public TradeRequestParam getSignal(String accountName, String markPx, String posSide) {
+        if (!initialized || priceHistory.isEmpty()) {
+            log.warn("策略未初始化或价格历史为空");
+            return createTradeRequestParam(accountName, markPx, posSide, TradeSignal.NO_SIGNAL);
+        }
+
+        try {
+            BigDecimal currentPrice = new BigDecimal(markPx);
+            
+            // 计算所有技术指标
+            calculateIndicators(currentPrice);
+            
+            // 生成交易信号
+            TradeRequestParam param = analyzeSignal(accountName, markPx, posSide, currentPrice);
+            
+            // 更新历史指标值
+            updateHistoricalIndicatorValues();
+            
+            return param;
+        } catch (Exception e) {
+            log.error("计算交易信号时发生异常", e);
+            return createTradeRequestParam(accountName, markPx, posSide, TradeSignal.NO_SIGNAL);
+        }
+    }
+
+    /**
+     * 计算所有技术指标
+     */
+    private void calculateIndicators(BigDecimal currentPrice) {
+        // 计算三重EMA交叉系统
+        advancedMA.calculateTripleEMA(priceHistory);
+        
+        // 计算MACD
+        macd.calculate(priceHistory);
+        
+        // 维护MACD能量柱历史
+        updateMacdHistogramHistory();
+        
+        // 计算RSI
+        rsi.calculate(priceHistory);
+        
+        // 计算KDJ
+        kdj.calculate(priceHistory);
+        
+        // 计算波动率自适应布林带
+        calculateAdaptiveBollingerBands();
+    }
+
+    /**
+     * 计算波动率自适应布林带
+     */
+    private void calculateAdaptiveBollingerBands() {
+        // 动态调整布林带的标准差倍数
+        BigDecimal atr = calculateATR(priceHistory, 14);
+        
+        // 根据ATR动态计算标准差倍数
+        BigDecimal stdDevMultiplier;
+        if (atr.compareTo(new BigDecimal(0.5)) < 0) {
+            stdDevMultiplier = new BigDecimal(2);
+        } else if (atr.compareTo(new BigDecimal(1)) < 0) {
+            stdDevMultiplier = new BigDecimal(2.5);
+        } else {
+            stdDevMultiplier = new BigDecimal(3);
+        }
+        
+        boll.setK(stdDevMultiplier);
+        boll.calculate(priceHistory);
+        
+        log.debug("ATR: {}, 布林带标准差倍数: {}", atr, stdDevMultiplier);
+    }
+
+    /**
+     * 计算ATR (平均真实范围)
+     */
+    private BigDecimal calculateATR(List<BigDecimal> prices, int period) {
+        if (prices == null || prices.size() < period + 1) {
+            return new BigDecimal(0.5); // 默认值
+        }
+        
+        List<BigDecimal> trList = new ArrayList<>();
+        
+        for (int i = 1; i < prices.size(); i++) {
+            BigDecimal high = prices.get(i);
+            BigDecimal low = prices.get(i);
+            BigDecimal prevClose = prices.get(i - 1);
+            
+            BigDecimal tr1 = high.subtract(low);
+            BigDecimal tr2 = high.subtract(prevClose).abs();
+            BigDecimal tr3 = prevClose.subtract(low).abs();
+            
+            trList.add(tr1.max(tr2).max(tr3));
+        }
+        
+        // 计算ATR
+        BigDecimal sum = trList.stream().reduce(BigDecimal.ZERO, BigDecimal::add);
+        return sum.divide(new BigDecimal(trList.size()), 8, RoundingMode.HALF_UP);
+    }
+
+    /**
+     * 更新MACD能量柱历史
+     */
+    private void updateMacdHistogramHistory() {
+        macdHistogramHistory.add(macd.getMacdBar());
+        
+        // 限制历史记录数量
+        if (macdHistogramHistory.size() > MACD_HISTOGRAM_PERIOD) {
+            macdHistogramHistory = macdHistogramHistory.subList(
+                macdHistogramHistory.size() - MACD_HISTOGRAM_PERIOD, 
+                macdHistogramHistory.size());
+        }
+    }
+
+    /**
+     * 计算MACD能量柱面积指标(累计过去5根柱体积分)
+     */
+    private BigDecimal calculateMacdHistogramArea() {
+        return macdHistogramHistory.stream()
+            .reduce(BigDecimal.ZERO, BigDecimal::add)
+            .abs(); // 使用绝对值表示面积
+    }
+
+    /**
+     * 分析技术指标生成交易信号
+     */
+    private TradeRequestParam analyzeSignal(String accountName, String markPx, String posSide, BigDecimal currentPrice) {
+        TradeRequestParam param = createTradeRequestParam(accountName, markPx, posSide, TradeSignal.NO_SIGNAL);
+        param.setTradeType(OrderParamEnums.TRADE_YES.getValue());
+        param.setInstId(CoinEnums.HE_YUE.getCode());
+        param.setTdMode(CoinEnums.CROSS.getCode());
+        param.setOrdType(CoinEnums.ORDTYPE_MARKET.getCode());
+        
+        // 检查冷静期
+        String outStr = getAccountConfig(accountName, CoinEnums.OUT.name());
+        if (OrderParamEnums.OUT_YES.getValue().equals(outStr)) {
+            log.error("冷静中,不允许下单......");
+            param.setTradeType(OrderParamEnums.TRADE_NO.getValue());
+            return param;
+        }
+        
+        // 检查震荡行情
+        if (advancedMA.isUpAndDown()) {
+            log.info("处于震荡行情(三线粘合度<{}%),暂停交易", GLUE_THRESHOLD);
+            param.setTradeType(OrderParamEnums.TRADE_NO.getValue());
+            return param;
+        }
+        
+        TradeSignal signal = TradeSignal.NO_SIGNAL;
+        
+        // 分析多空信号
+        signal = analyzeCoreSignal(currentPrice, posSide);
+        
+        log.info("账户: {}, 价格: {}, 方向: {}, 生成信号: {}", 
+                accountName, markPx, posSide, signal.getName());
+        
+        // 设置信号参数
+        setSignalParameters(param, signal);
+        
+        return param;
+    }
+
+    /**
+     * 分析核心技术指标信号
+     */
+    private TradeSignal analyzeCoreSignal(BigDecimal currentPrice, String posSide) {
+        // 计算MACD能量柱面积
+        BigDecimal macdArea = calculateMacdHistogramArea();
+        BigDecimal prevMacdArea = calculateMacdHistogramAreaPrevious();
+        
+        // 多头入场条件:当前柱体>0且面积增速>前周期20%
+        if (isBullishEntry(macdArea, prevMacdArea)) {
+            // 如果当前没有仓位或仓位为空头,则开多
+            if (posSide == null || posSide.isEmpty() || CoinEnums.POSSIDE_SHORT.getCode().equals(posSide)) {
+                return posSide == null || posSide.isEmpty() ? TradeSignal.OPEN_LONG : TradeSignal.CLOSE_SHORT;
+            }
+            // 如果当前已经是多头仓位,则保持观望
+            return TradeSignal.NO_SIGNAL;
+        }
+        
+        // 空头入场条件:当前柱体<0且面积增速>前周期20%
+        if (isBearishEntry(macdArea, prevMacdArea)) {
+            // 如果当前没有仓位或仓位为多头,则开空
+            if (posSide == null || posSide.isEmpty() || CoinEnums.POSSIDE_LONG.getCode().equals(posSide)) {
+                return posSide == null || posSide.isEmpty() ? TradeSignal.OPEN_SHORT : TradeSignal.CLOSE_LONG;
+            }
+            // 如果当前已经是空头仓位,则保持观望
+            return TradeSignal.NO_SIGNAL;
+        }
+        
+        // 突破上轨+成交量放大3倍=做空信号
+        if (isBollingerUpperBreak(currentPrice) && isVolumeIncreased()) {
+            // 如果当前没有仓位或仓位为多头,则开空
+            if (posSide == null || posSide.isEmpty() || CoinEnums.POSSIDE_LONG.getCode().equals(posSide)) {
+                return posSide == null || posSide.isEmpty() ? TradeSignal.OPEN_SHORT : TradeSignal.CLOSE_LONG;
+            }
+            // 如果当前已经是空头仓位,则保持观望
+            return TradeSignal.NO_SIGNAL;
+        }
+        
+        // 触及下轨+期货资金费率转正=做多信号
+        if (isBollingerLowerTouch(currentPrice) && isFundingRatePositive()) {
+            // 如果当前没有仓位或仓位为空头,则开多
+            if (posSide == null || posSide.isEmpty() || CoinEnums.POSSIDE_SHORT.getCode().equals(posSide)) {
+                return posSide == null || posSide.isEmpty() ? TradeSignal.OPEN_LONG : TradeSignal.CLOSE_SHORT;
+            }
+            // 如果当前已经是多头仓位,则保持观望
+            return TradeSignal.NO_SIGNAL;
+        }
+        
+        // 空头反转:柱体顶背离+RSI>70区域死叉
+        if (isBearishReversal(currentPrice)) {
+            // 如果当前没有仓位或仓位为多头,则开空或平多
+            if (posSide == null || posSide.isEmpty() || CoinEnums.POSSIDE_LONG.getCode().equals(posSide)) {
+                return posSide == null || posSide.isEmpty() ? TradeSignal.OPEN_SHORT : TradeSignal.CLOSE_LONG;
+            }
+            // 如果当前已经是空头仓位,则保持观望
+            return TradeSignal.NO_SIGNAL;
+        }
+        
+        // 多头反转:柱体底背离+RSI<30区域金叉
+        if (isBullishReversal(currentPrice)) {
+            // 如果当前没有仓位或仓位为空头,则开多或平空
+            if (posSide == null || posSide.isEmpty() || CoinEnums.POSSIDE_SHORT.getCode().equals(posSide)) {
+                return posSide == null || posSide.isEmpty() ? TradeSignal.OPEN_LONG : TradeSignal.CLOSE_SHORT;
+            }
+            // 如果当前已经是多头仓位,则保持观望
+            return TradeSignal.NO_SIGNAL;
+        }
+        
+        return TradeSignal.NO_SIGNAL;
+    }
+
+    /**
+     * 多头入场条件判断
+     */
+    private boolean isBullishEntry(BigDecimal currentArea, BigDecimal prevArea) {
+        // 当前柱体>0
+        boolean currentBarPositive = macd.getMacdBar().compareTo(BigDecimal.ZERO) > 0;
+        
+        // 面积增速>前周期20%
+        boolean areaGrowth = prevArea != null && prevArea.compareTo(BigDecimal.ZERO) > 0 &&
+                currentArea.divide(prevArea, 8, RoundingMode.HALF_UP)
+                .compareTo(new BigDecimal(1.2)) > 0;
+        
+        // 三重EMA多头排列
+        boolean emaBullish = advancedMA.isBullish();
+        
+        return currentBarPositive && areaGrowth && emaBullish;
+    }
+
+    /**
+     * 空头入场条件判断
+     */
+    private boolean isBearishEntry(BigDecimal currentArea, BigDecimal prevArea) {
+        // 当前柱体<0
+        boolean currentBarNegative = macd.getMacdBar().compareTo(BigDecimal.ZERO) < 0;
+        
+        // 面积增速>前周期20%
+        boolean areaGrowth = prevArea != null && prevArea.compareTo(BigDecimal.ZERO) > 0 &&
+                currentArea.divide(prevArea, 8, RoundingMode.HALF_UP)
+                .compareTo(new BigDecimal(1.2)) > 0;
+        
+        // 三重EMA空头排列
+        boolean emaBearish = advancedMA.isBearish();
+        
+        return currentBarNegative && areaGrowth && emaBearish;
+    }
+
+    /**
+     * 突破上轨判断
+     */
+    private boolean isBollingerUpperBreak(BigDecimal currentPrice) {
+        return currentPrice.compareTo(boll.getUpper()) > 0;
+    }
+
+    /**
+     * 触及下轨判断
+     */
+    private boolean isBollingerLowerTouch(BigDecimal currentPrice) {
+        return currentPrice.compareTo(boll.getLower()) < 0;
+    }
+
+    /**
+     * 成交量放大判断(模拟)
+     */
+    private boolean isVolumeIncreased() {
+        // 这里使用价格波动率模拟成交量
+        return calculateVolatility(priceHistory, 5)
+                .compareTo(calculateVolatility(priceHistory, 20).multiply(VOLUME_MULTIPLIER)) > 0;
+    }
+
+    /**
+     * 期货资金费率转正判断(模拟)
+     */
+    private boolean isFundingRatePositive() {
+        // 这里使用MACD柱状图模拟资金费率
+        return macd.getMacdBar().compareTo(BigDecimal.ZERO) > 0;
+    }
+
+    /**
+     * 计算价格波动率
+     */
+    private BigDecimal calculateVolatility(List<BigDecimal> prices, int period) {
+        if (prices.size() < period) {
+            return BigDecimal.ZERO;
+        }
+        
+        List<BigDecimal> returns = new ArrayList<>();
+        for (int i = 1; i < prices.size(); i++) {
+            BigDecimal current = prices.get(i);
+            BigDecimal previous = prices.get(i - 1);
+            returns.add(current.divide(previous, 8, RoundingMode.HALF_UP).subtract(BigDecimal.ONE));
+        }
+        
+        return calculateStandardDeviation(returns);
+    }
+
+    /**
+     * 计算标准差
+     */
+    private BigDecimal calculateStandardDeviation(List<BigDecimal> values) {
+        if (values.isEmpty()) {
+            return BigDecimal.ZERO;
+        }
+        
+        // 计算平均值
+        BigDecimal sum = values.stream().reduce(BigDecimal.ZERO, BigDecimal::add);
+        BigDecimal mean = sum.divide(new BigDecimal(values.size()), 8, RoundingMode.HALF_UP);
+        
+        // 计算方差
+        BigDecimal variance = values.stream()
+            .map(val -> val.subtract(mean).pow(2))
+            .reduce(BigDecimal.ZERO, BigDecimal::add)
+            .divide(new BigDecimal(values.size()), 8, RoundingMode.HALF_UP);
+        
+        // 计算标准差
+        return sqrt(variance);
+    }
+
+    /**
+     * 计算平方根
+     */
+    private BigDecimal sqrt(BigDecimal value) {
+        return new BigDecimal(Math.sqrt(value.doubleValue()));
+    }
+
+    /**
+     * 空头反转判断
+     */
+    private boolean isBearishReversal(BigDecimal currentPrice) {
+        // 柱体顶背离
+        boolean topDivergence = isMacdTopDivergence(currentPrice);
+        
+        // RSI>70区域死叉
+        boolean rsiOverbought = rsi.getRsi().compareTo(new BigDecimal(70)) > 0;
+        boolean kdjDeathCross = kdj.isDeathCross();
+        
+        return topDivergence && rsiOverbought && kdjDeathCross;
+    }
+
+    /**
+     * 多头反转判断
+     */
+    private boolean isBullishReversal(BigDecimal currentPrice) {
+        // 柱体底背离
+        boolean bottomDivergence = isMacdBottomDivergence(currentPrice);
+        
+        // RSI<30区域金叉
+        boolean rsiOversold = rsi.getRsi().compareTo(new BigDecimal(30)) < 0;
+        boolean kdjGoldenCross = kdj.isGoldenCross();
+        
+        return bottomDivergence && rsiOversold && kdjGoldenCross;
+    }
+
+    /**
+     * 判断MACD顶背离
+     */
+    private boolean isMacdTopDivergence(BigDecimal currentPrice) {
+        // 简化的顶背离判断:价格创新高但MACD未创新高
+        if (priceHistory.size() < 2) {
+            return false;
+        }
+        
+        BigDecimal previousPrice = priceHistory.get(priceHistory.size() - 2);
+        return currentPrice.compareTo(previousPrice) > 0 &&
+               macd.getMacdBar().compareTo(prevDea) < 0;
+    }
+
+    /**
+     * 判断MACD底背离
+     */
+    private boolean isMacdBottomDivergence(BigDecimal currentPrice) {
+        // 简化的底背离判断:价格创新低但MACD未创新低
+        if (priceHistory.size() < 2) {
+            return false;
+        }
+        
+        BigDecimal previousPrice = priceHistory.get(priceHistory.size() - 2);
+        return currentPrice.compareTo(previousPrice) < 0 &&
+               macd.getMacdBar().compareTo(prevDea) > 0;
+    }
+
+    /**
+     * 计算前一期MACD能量柱面积
+     */
+    private BigDecimal calculateMacdHistogramAreaPrevious() {
+        if (macdHistogramHistory.size() < 2) {
+            return BigDecimal.ZERO;
+        }
+        
+        List<BigDecimal> prevHistory = macdHistogramHistory.subList(
+            0, macdHistogramHistory.size() - 1);
+        
+        return prevHistory.stream()
+            .reduce(BigDecimal.ZERO, BigDecimal::add)
+            .abs();
+    }
+
+    /**
+     * 设置信号参数
+     */
+    private void setSignalParameters(TradeRequestParam param, TradeSignal signal) {
+        String side = null;
+        
+        switch (signal) {
+            case BUY:
+                side = CoinEnums.SIDE_BUY.getCode();
+                param.setPosSide(CoinEnums.POSSIDE_LONG.getCode());
+                break;
+            case SELL:
+                side = CoinEnums.SIDE_SELL.getCode();
+                param.setPosSide(CoinEnums.POSSIDE_SHORT.getCode());
+                break;
+            case OPEN_LONG:
+                side = CoinEnums.SIDE_BUY.getCode();
+                param.setPosSide(CoinEnums.POSSIDE_LONG.getCode());
+                break;
+            case CLOSE_LONG:
+                side = CoinEnums.SIDE_SELL.getCode();
+                break;
+            case OPEN_SHORT:
+                side = CoinEnums.SIDE_SELL.getCode();
+                param.setPosSide(CoinEnums.POSSIDE_SHORT.getCode());
+                break;
+            case CLOSE_SHORT:
+                side = CoinEnums.SIDE_BUY.getCode();
+                break;
+            case STOP_LOSS:
+                // 止损操作
+                side = CoinEnums.POSSIDE_LONG.getCode().equals(param.getPosSide()) ? 
+                       CoinEnums.SIDE_SELL.getCode() : CoinEnums.SIDE_BUY.getCode();
+                break;
+            default:
+                param.setTradeType(OrderParamEnums.TRADE_NO.getValue());
+                return;
+        }
+        
+        param.setSide(side);
+        log.info("设置交易方向: {}, 仓位方向: {}", side, param.getPosSide());
+    }
+
+    /**
+     * 更新历史指标值
+     */
+    private void updateHistoricalIndicatorValues() {
+        prevEma9 = advancedMA.getEma9();
+        prevEma21 = advancedMA.getEma21();
+        prevEma55 = advancedMA.getEma55();
+        prevDif = macd.getDif();
+        prevDea = macd.getDea();
+        prevK = kdj.getK();
+        prevD = kdj.getD();
+        prevJ = kdj.getJ();
+    }
+
+    /**
+     * 获取账户配置
+     */
+    private String getAccountConfig(String accountName, String key) {
+        // 模拟获取账户配置
+        return OrderParamEnums.OUT_NO.getValue();
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/xcong/excoin/modules/okxNewPrice/indicator/strategy/CoreTechnicalStrategyUsageGuide.md b/src/main/java/com/xcong/excoin/modules/okxNewPrice/indicator/strategy/CoreTechnicalStrategyUsageGuide.md
new file mode 100644
index 0000000..0e56433
--- /dev/null
+++ b/src/main/java/com/xcong/excoin/modules/okxNewPrice/indicator/strategy/CoreTechnicalStrategyUsageGuide.md
@@ -0,0 +1,198 @@
+# CoreTechnicalStrategy 使用指南
+
+## 1. 概述
+CoreTechnicalStrategy 是一个综合技术指标策略类,整合了以下核心技术指标:
+- 三重EMA交叉系统(9/21/55周期)
+- 波动率自适应布林带
+- MACD能量柱分级策略
+
+## 2. 类结构
+
+### 2.1 AdvancedMA 类
+用于计算三重EMA交叉系统的指标。
+
+**主要方法:**
+- `calculateTripleEMA(List<BigDecimal> prices)`: 计算9EMA、21EMA、55EMA
+- `isBullish排列()`: 判断是否多头排列(9EMA>21EMA>55EMA)
+- `isBearish排列()`: 判断是否空头排列(9EMA<21EMA<55EMA)
+- `calculate粘合度()`: 计算三线粘合度
+- `is震荡行情()`: 判断是否处于震荡行情(粘合度<2%)
+
+### 2.2 CoreTechnicalStrategy 类
+综合所有技术指标生成交易信号的策略类。
+
+**主要方法:**
+- `initialize()`: 初始化策略
+- `updatePrices(List<BigDecimal> prices)`: 更新价格数据
+- `getSignal(String accountName, String markPx, String posSide)`: 获取交易信号
+
+## 3. 使用步骤
+
+### 3.1 初始化策略
+```java
+// 创建策略实例
+CoreTechnicalStrategy strategy = new CoreTechnicalStrategy();
+
+// 初始化策略
+strategy.initialize();
+```
+
+### 3.2 更新价格数据
+```java
+// 准备价格数据列表
+List<BigDecimal> prices = new ArrayList<>();
+prices.add(new BigDecimal(30000));
+prices.add(new BigDecimal(30500));
+prices.add(new BigDecimal(31000));
+// 添加更多价格数据...
+
+// 更新价格数据
+strategy.updatePrices(prices);
+```
+
+### 3.3 获取交易信号
+```java
+// 调用getSignal方法获取交易信号
+TradeRequestParam param = strategy.getSignal(
+    "account1",           // 账户名称
+    "31500",              // 当前标记价格
+    "long"                // 当前仓位方向("long"或"short")
+);
+
+// 获取交易方向
+String side = param.getSide(); // "buy"或"sell"
+String tradeType = param.getTradeType(); // "yes"或"no"
+```
+
+## 4. 参数说明
+
+### 4.1 getSignal 方法参数
+
+| 参数名 | 类型 | 说明 | 示例 |
+|-------|------|------|------|
+| accountName | String | 账户名称,用于日志记录和配置获取 | "account1", "myAccount" |
+| markPx | String | 当前标记价格,作为交易决策的基础价格 | "31500", "32000.5" |
+| posSide | String | 当前仓位方向,决定多空信号的生成逻辑 | "long"(多头), "short"(空头) |
+
+### 4.2 返回值 TradeRequestParam 说明
+
+| 属性名 | 类型 | 说明 |
+|-------|------|------|
+| accountName | String | 账户名称 |
+| markPx | String | 当前标记价格 |
+| posSide | String | 仓位方向 |
+| side | String | 交易方向:"buy"(买入/做多)或"sell"(卖出/做空) |
+| tradeType | String | 交易类型:"yes"(执行交易)或"no"(不执行交易) |
+| instId | String | 交易对ID |
+| tdMode | String | 交易模式 |
+| ordType | String | 订单类型 |
+
+## 5. 核心指标逻辑
+
+### 5.1 三重EMA交叉系统
+- **多头条件**:9EMA > 21EMA > 55EMA
+- **空头条件**:9EMA < 21EMA < 55EMA
+- **震荡过滤**:三线粘合度 < 2% 时暂停交易
+
+### 5.2 波动率自适应布林带
+- **动态通道宽度**:标准差倍数根据ATR调整
+- **做空信号**:突破上轨 + 成交量放大3倍
+- **做多信号**:触及下轨 + 期货资金费率转正
+
+### 5.3 MACD能量柱分级策略
+- **能量柱面积**:累计过去5根柱体积分
+- **多头入场**:当前柱体 > 0 且面积增速 > 前周期20%
+- **空头反转**:柱体顶背离 + RSI > 70区域死叉
+
+## 6. 示例代码
+
+```java
+public class StrategyExample {
+    public static void main(String[] args) {
+        // 初始化策略
+        CoreTechnicalStrategy strategy = new CoreTechnicalStrategy();
+        strategy.initialize();
+        
+        // 准备历史价格数据
+        List<BigDecimal> historicalPrices = new ArrayList<>();
+        for (int i = 0; i < 100; i++) {
+            // 模拟价格数据
+            BigDecimal price = new BigDecimal(30000 + i * 100 + Math.random() * 500);
+            historicalPrices.add(price);
+        }
+        
+        // 更新价格数据
+        strategy.updatePrices(historicalPrices);
+        
+        // 获取当前价格
+        String currentPrice = "35000";
+        
+        // 获取多头信号
+        TradeRequestParam longSignal = strategy.getSignal("myAccount", currentPrice, "long");
+        System.out.println("多头信号: " + longSignal.getSide() + ", 交易类型: " + longSignal.getTradeType());
+        
+        // 获取空头信号
+        TradeRequestParam shortSignal = strategy.getSignal("myAccount", currentPrice, "short");
+        System.out.println("空头信号: " + shortSignal.getSide() + ", 交易类型: " + shortSignal.getTradeType());
+    }
+}
+```
+
+## 7. 注意事项
+
+1. **价格数据长度**:建议至少提供55个以上的价格数据点,以确保所有指标都能正确计算
+2. **初始化顺序**:必须先调用`initialize()`方法,再调用`updatePrices()`和`getSignal()`
+3. **仓位方向**:传入的`posSide`参数会影响信号生成逻辑,请确保传入正确的当前仓位方向
+4. **日志记录**:策略会输出详细的日志信息,可通过日志级别控制输出内容
+5. **震荡过滤**:当处于震荡行情时,`tradeType`会返回"no",建议暂停交易
+
+## 8. 错误处理
+
+策略内部包含完善的错误处理机制:
+- 价格数据为空或无效时,会返回`NO_SIGNAL`
+- 计算过程中发生异常时,会捕获并记录日志,返回`NO_SIGNAL`
+- 冷静期内会返回`tradeType="no"`
+- 震荡行情会返回`tradeType="no"`
+
+## 9. 扩展与定制
+
+### 9.1 修改指标参数
+可以在`CoreTechnicalStrategy`类中修改以下常量来调整策略参数:
+
+```java
+// MACD能量柱计算周期
+private static final int MACD_HISTOGRAM_PERIOD = 5;
+
+// 成交量放大倍数
+private static final BigDecimal VOLUME_MULTIPLIER = new BigDecimal(3);
+
+// 三线粘合度阈值(%)
+private static final BigDecimal GLUE_THRESHOLD = new BigDecimal(2);
+```
+
+### 9.2 自定义信号逻辑
+可以重写`analyzeCoreSignal`方法来自定义信号生成逻辑:
+
+```java
+@Override
+protected TradeSignal analyzeCoreSignal(BigDecimal currentPrice) {
+    // 自定义信号逻辑
+    // ...
+}
+```
+
+## 10. 整合到现有系统
+
+要将CoreTechnicalStrategy整合到现有系统中,只需将其替换或补充现有的策略类即可:
+
+```java
+// 在OkxWebSocketClientManager或其他适当位置
+CoreTechnicalStrategy coreStrategy = new CoreTechnicalStrategy();
+coreStrategy.initialize();
+
+// 在价格更新时
+coreStrategy.updatePrices(priceList);
+
+// 在需要交易信号时
+TradeRequestParam signal = coreStrategy.getSignal(accountName, markPx, posSide);
+```
diff --git a/src/main/java/com/xcong/excoin/modules/okxNewPrice/indicator/strategy/TechnicalIndicatorStrategy.java b/src/main/java/com/xcong/excoin/modules/okxNewPrice/indicator/strategy/TechnicalIndicatorStrategy.java
new file mode 100644
index 0000000..65b4d95
--- /dev/null
+++ b/src/main/java/com/xcong/excoin/modules/okxNewPrice/indicator/strategy/TechnicalIndicatorStrategy.java
@@ -0,0 +1,44 @@
+package com.xcong.excoin.modules.okxNewPrice.indicator.strategy;
+
+import com.xcong.excoin.modules.okxNewPrice.okxWs.param.TradeRequestParam;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+/**
+ * 技术指标策略接口,定义技术指标策略的基本方法
+ */
+public interface TechnicalIndicatorStrategy {
+
+    /**
+     * 初始化策略
+     */
+    void initialize();
+
+    /**
+     * 更新价格数据
+     * @param prices 价格列表
+     */
+    void updatePrices(List<BigDecimal> prices);
+
+    /**
+     * 获取交易信号
+     * @param accountName 账户名称
+     * @param markPx 当前标记价格
+     * @param posSide 仓位方向
+     * @return 交易请求参数,包含交易信号和相关信息
+     */
+    TradeRequestParam getSignal(String accountName, String markPx, String posSide);
+
+    /**
+     * 获取策略名称
+     * @return 策略名称
+     */
+    String getStrategyName();
+
+    /**
+     * 判断策略是否有效
+     * @return 是否有效
+     */
+    boolean isValid();
+}
diff --git a/src/main/java/com/xcong/excoin/modules/okxNewPrice/indicator/strategy/TradeSignal.java b/src/main/java/com/xcong/excoin/modules/okxNewPrice/indicator/strategy/TradeSignal.java
new file mode 100644
index 0000000..e1c05da
--- /dev/null
+++ b/src/main/java/com/xcong/excoin/modules/okxNewPrice/indicator/strategy/TradeSignal.java
@@ -0,0 +1,54 @@
+package com.xcong.excoin.modules.okxNewPrice.indicator.strategy;
+
+import lombok.Getter;
+
+/**
+ * 交易信号枚举
+ */
+@Getter
+public enum TradeSignal {
+    
+    /** 无信号,保持观望 */
+    NO_SIGNAL("NO_SIGNAL", "无信号"),
+    
+    /** 买入信号 */
+    BUY("BUY", "买入"),
+    
+    /** 卖出信号 */
+    SELL("SELL", "卖出"),
+    
+    /** 开多信号 */
+    OPEN_LONG("OPEN_LONG", "开多"),
+    
+    /** 平多信号 */
+    CLOSE_LONG("CLOSE_LONG", "平多"),
+    
+    /** 开空信号 */
+    OPEN_SHORT("OPEN_SHORT", "开空"),
+    
+    /** 平空信号 */
+    CLOSE_SHORT("CLOSE_SHORT", "平空"),
+    
+    /** 止损信号 */
+    STOP_LOSS("STOP_LOSS", "止损"),
+    
+    /** 止盈信号 */
+    TAKE_PROFIT("TAKE_PROFIT", "止盈");
+    
+    private final String value;
+    private final String name;
+    
+    TradeSignal(String value, String name) {
+        this.value = value;
+        this.name = name;
+    }
+    
+    public static TradeSignal fromValue(String value) {
+        for (TradeSignal signal : values()) {
+            if (signal.getValue().equals(value)) {
+                return signal;
+            }
+        }
+        return NO_SIGNAL;
+    }
+}

--
Gitblit v1.9.1