| | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * 技术指标基础类,提供通用计算方法 |
| | | * Technical indicators base class, provides common calculation methods |
| | | * |
| | | * Indicator combination strategy: |
| | | * 1. Trend judgment (MA/AdvancedMA/MACD): Determine the overall trend direction of prices |
| | | * 2. Momentum confirmation (RSI/KDJ): Confirm the strength and sustainability of the current trend |
| | | * 3. Volatility reference (BOLL): Determine reasonable price volatility range and breakthrough timing |
| | | * |
| | | * Long/Short direction selection logic: |
| | | * - Long signal: MA bullish arrangement + MACD golden cross + RSI(30-70) + BOLL price between upper and middle band |
| | | * - Short signal: MA bearish arrangement + MACD death cross + RSI(30-70) + BOLL price between lower and middle band |
| | | * - Consolidation signal: AdvancedMA three-line convergence + RSI(40-60) + BOLL bandwidth narrowing |
| | | * |
| | | * Open and close position strategies: |
| | | * - Open long: MA golden cross + MACD golden cross + KDJ golden cross + RSI(30-70) + price breaks through BOLL middle band |
| | | * - Open short: MA death cross + MACD death cross + KDJ death cross + RSI(30-70) + price breaks below BOLL middle band |
| | | * - Close long: MA death cross + MACD death cross + RSI overbought(>70) + price breaks below BOLL middle band |
| | | * - Close short: MA golden cross + MACD golden cross + RSI oversold(<30) + price breaks through BOLL middle band |
| | | */ |
| | | public abstract class IndicatorBase { |
| | | |
| | | /** |
| | | * 计算移动平均值 |
| | | * @param prices 价格列表 |
| | | * @param period 周期 |
| | | * @return 移动平均值 |
| | | * Calculate moving average |
| | | * @param prices Price list |
| | | * @param period Period |
| | | * @return Moving average value |
| | | */ |
| | | protected BigDecimal calculateMA(List<BigDecimal> prices, int period) { |
| | | if (prices == null || prices.size() < period) { |
| | |
| | | } |
| | | |
| | | /** |
| | | * 计算指数移动平均值 |
| | | * @param prices 价格列表 |
| | | * @param period 周期 |
| | | * @param prevEMA 前一个EMA值 |
| | | * @return 指数移动平均值 |
| | | * Calculate exponential moving average |
| | | * @param prices Price list |
| | | * @param period Period |
| | | * @param prevEMA Previous EMA value |
| | | * @return Exponential moving average value |
| | | */ |
| | | protected BigDecimal calculateEMA(List<BigDecimal> prices, int period, BigDecimal prevEMA) { |
| | | if (prices == null || prices.size() == 0) { |
| | |
| | | } |
| | | |
| | | /** |
| | | * 计算标准差 |
| | | * @param prices 价格列表 |
| | | * @param period 周期 |
| | | * @return 标准差 |
| | | * Calculate standard deviation |
| | | * @param prices Price list |
| | | * @param period Period |
| | | * @return Standard deviation |
| | | */ |
| | | protected BigDecimal calculateStdDev(List<BigDecimal> prices, int period) { |
| | | if (prices == null || prices.size() < period) { |
| | |
| | | } |
| | | |
| | | /** |
| | | * 计算平方根(简化实现) |
| | | * @param value 输入值 |
| | | * @return 平方根 |
| | | * Calculate square root (simplified implementation) |
| | | * @param value Input value |
| | | * @return Square root |
| | | */ |
| | | protected BigDecimal sqrt(BigDecimal value) { |
| | | if (value.compareTo(BigDecimal.ZERO) < 0) { |
| | |
| | | } |
| | | |
| | | /** |
| | | * 获取最近的价格数据 |
| | | * @param prices 所有价格数据 |
| | | * @param period 周期 |
| | | * @return 最近period个价格数据 |
| | | * Get recent price data |
| | | * @param prices All price data |
| | | * @param period Period |
| | | * @return Recent period price data |
| | | */ |
| | | protected List<BigDecimal> getRecentPrices(List<BigDecimal> prices, int period) { |
| | | if (prices == null || prices.size() == 0) { |
| | |
| | | int startIndex = Math.max(0, prices.size() - period); |
| | | return prices.subList(startIndex, prices.size()); |
| | | } |
| | | |
| | | /** |
| | | * Calculate ATR (Average True Range) |
| | | * @param high High price list |
| | | * @param low Low price list |
| | | * @param close Close price list |
| | | * @param period Period |
| | | * @return ATR value |
| | | */ |
| | | protected BigDecimal calculateATR(List<BigDecimal> high, List<BigDecimal> low, List<BigDecimal> close, int period) { |
| | | if (high == null || low == null || close == null || |
| | | high.size() < period || low.size() < period || close.size() < period) { |
| | | return BigDecimal.ZERO; |
| | | } |
| | | |
| | | List<BigDecimal> trList = new ArrayList<>(); |
| | | for (int i = 1; i < high.size(); i++) { |
| | | BigDecimal trueRange = calculateTrueRange(high.get(i), low.get(i), close.get(i - 1)); |
| | | trList.add(trueRange); |
| | | } |
| | | |
| | | // Use simple moving average to calculate ATR |
| | | return calculateMA(trList, Math.min(period, trList.size())); |
| | | } |
| | | |
| | | /** |
| | | * Calculate True Range |
| | | * @param high Current high price |
| | | * @param low Current low price |
| | | * @param prevClose Previous close price |
| | | * @return True range |
| | | */ |
| | | protected BigDecimal calculateTrueRange(BigDecimal high, BigDecimal low, BigDecimal prevClose) { |
| | | BigDecimal h1 = high.subtract(low); |
| | | BigDecimal h2 = high.subtract(prevClose).abs(); |
| | | BigDecimal h3 = low.subtract(prevClose).abs(); |
| | | return h1.max(h2).max(h3); |
| | | } |
| | | |
| | | /** |
| | | * Calculate normalized volatility (based on ATR) |
| | | * @param close Close price list |
| | | * @param atr ATR value |
| | | * @return Normalized volatility (percentage) |
| | | */ |
| | | protected BigDecimal normalizeVolatility(List<BigDecimal> close, BigDecimal atr) { |
| | | if (close == null || close.size() == 0 || atr.compareTo(BigDecimal.ZERO) == 0) { |
| | | return BigDecimal.ZERO; |
| | | } |
| | | return atr.divide(close.get(close.size() - 1), 4, RoundingMode.HALF_UP).multiply(new BigDecimal(100)); |
| | | } |
| | | } |