1赞

12评论

1收藏

希望来一个高手(有偿)帮我完成以下指标(价格可商量)

 

评论|共 12 个

臭宝很深情

发表于 2025-7-27 00:46:53 | 显示全部楼层

//+------------------------------------------------------------------+
//|                                                  AdvancedSignals |
//|                        Copyright 2023, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2023, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
#property indicator_chart_window
#property indicator_buffers 14
#property indicator_plots   11

//--- 输入参数
input int      MA1_Period = 5;       // 快速均线周期
input int      MA2_Period = 20;      // 中期均线周期
input int      MA3_Period = 60;      // 慢速均线周期
input int      RSI_Period = 14;      // RSI周期
input int      BB_Period = 20;       // 布林带周期
input double   BB_Deviation = 2.0;   // 布林带标准差
input int      MACD_Fast = 12;       // MACD快线
input int      MACD_Slow = 26;       // MACD慢线
input int      MACD_Signal = 9;      // MACD信号线
input int      Box_Lookback = 50;    // 箱体回溯周期
input bool     Draw_Trendline = true;// 绘制趋势线
input bool     Draw_Fibonacci = true;// 绘制黄金分割

//--- 指标缓冲区
double MA1Buffer[], MA2Buffer[], MA3Buffer[];
double RSIBuffer[], UpperBB[], LowerBB[], MiddleBB[];
double MACDBuffer[], SignalBuffer[], HistogramBuffer[];
double BuySignal[], SellSignal[];

//--- 全局变量
double boxHigh, boxLow;
datetime lastAlertTime;
int trendStart, trendEnd;

//+------------------------------------------------------------------+
//| 自定义指标初始化函数                                              |
//+------------------------------------------------------------------+
int OnInit()
{
   //--- 设置指标缓冲区
   SetIndexBuffer(0, MA1Buffer);
   SetIndexBuffer(1, MA2Buffer);
   SetIndexBuffer(2, MA3Buffer);
   SetIndexBuffer(3, RSIBuffer);
   SetIndexBuffer(4, UpperBB);
   SetIndexBuffer(5, LowerBB);
   SetIndexBuffer(6, MiddleBB);
   SetIndexBuffer(7, MACDBuffer);
   SetIndexBuffer(8, SignalBuffer);
   SetIndexBuffer(9, HistogramBuffer);
   SetIndexBuffer(10, BuySignal);
   SetIndexBuffer(11, SellSignal);
   
   //--- 设置指标样式
   SetIndexStyle(0, DRAW_LINE, STYLE_SOLID, 1, clrBlue);
   SetIndexStyle(1, DRAW_LINE, STYLE_SOLID, 1, clrOrange);
   SetIndexStyle(2, DRAW_LINE, STYLE_SOLID, 1, clrRed);
   SetIndexStyle(3, DRAW_LINE, STYLE_DOT, 1, clrGold);
   SetIndexStyle(4, DRAW_LINE, STYLE_DOT, 1, clrGreen);
   SetIndexStyle(5, DRAW_LINE, STYLE_DOT, 1, clrGreen);
   SetIndexStyle(6, DRAW_LINE, STYLE_SOLID, 1, clrGreen);
   SetIndexStyle(7, DRAW_LINE, STYLE_SOLID, 1, clrBlue);
   SetIndexStyle(8, DRAW_LINE, STYLE_SOLID, 1, clrRed);
   SetIndexStyle(9, DRAW_HISTOGRAM, STYLE_SOLID, 1, clrSilver);
   SetIndexStyle(10, DRAW_ARROW, 0, 1, clrYellow);
   SetIndexStyle(11, DRAW_ARROW, 0, 1, clrGreen);
   
   //--- 设置箭头代码
   SetIndexArrow(10, 233); // 黄色向上箭头
   SetIndexArrow(11, 234); // 绿色向下箭头
   
   //--- 设置指标标签
   IndicatorSetString(INDICATOR_SHORTNAME, "AdvancedSignals");
   IndicatorSetInteger(INDICATOR_DIGITS, _Digits);
   
   return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| 自定义指标迭代函数                                                |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
{
   int limit = rates_total - prev_calculated;
   if(prev_calculated > 0) limit++;
   
   //--- 计算移动平均线
   for(int i = limit - 1; i >= 0; i--)
   {
      MA1Buffer = iMA(NULL, 0, MA1_Period, 0, MODE_SMA, PRICE_CLOSE, i);
      MA2Buffer = iMA(NULL, 0, MA2_Period, 0, MODE_SMA, PRICE_CLOSE, i);
      MA3Buffer = iMA(NULL, 0, MA3_Period, 0, MODE_SMA, PRICE_CLOSE, i);
   }
   
   //--- 计算RSI
   for(int i = limit - 1; i >= 0; i--)
   {
      RSIBuffer = iRSI(NULL, 0, RSI_Period, PRICE_CLOSE, i);
   }
   
   //--- 计算布林带
   for(int i = limit - 1; i >= 0; i--)
   {
      MiddleBB = iMA(NULL, 0, BB_Period, 0, MODE_SMA, PRICE_CLOSE, i);
      double deviation = iStdDev(NULL, 0, BB_Period, 0, MODE_SMA, PRICE_CLOSE, i);
      UpperBB = MiddleBB + BB_Deviation * deviation;
      LowerBB = MiddleBB - BB_Deviation * deviation;
   }
   
   //--- 计算MACD
   for(int i = limit - 1; i >= 0; i--)
   {
      MACDBuffer = iMACD(NULL, 0, MACD_Fast, MACD_Slow, MACD_Signal, PRICE_CLOSE, MODE_MAIN, i);
      SignalBuffer = iMACD(NULL, 0, MACD_Fast, MACD_Slow, MACD_Signal, PRICE_CLOSE, MODE_SIGNAL, i);
      HistogramBuffer = MACDBuffer - SignalBuffer;
   }
   
   //--- 计算箱体
   CalculateBox(Box_Lookback);
   
   //--- 绘制趋势线
   if(Draw_Trendline) DrawTrendLines();
   
   //--- 绘制黄金分割
   if(Draw_Fibonacci) DrawFibonacci();
   
   //--- 交易信号判断
   for(int i = limit - 1; i >= 1; i--) // 从第1根开始避免数组越界
   {
      BuySignal = EMPTY_VALUE;
      SellSignal = EMPTY_VALUE;
      
      // 组合条件示例:金叉+RSI超卖+价格突破布林下轨
      bool buyCondition =
          (MA1Buffer > MA2Buffer && MA1Buffer[i-1] <= MA2Buffer[i-1]) &&
          (RSIBuffer < 30) &&
          (close < LowerBB && close[i-1] >= LowerBB[i-1]);
      
      // 组合条件示例:死叉+RSI超买+价格突破布林上轨
      bool sellCondition =
          (MA1Buffer < MA2Buffer && MA1Buffer[i-1] >= MA2Buffer[i-1]) &&
          (RSIBuffer > 70) &&
          (close > UpperBB && close[i-1] <= UpperBB[i-1]);
      
      if(buyCondition)
      {
         BuySignal = low - 10 * _Point;
         if(SellSignal[i-1] != EMPTY_VALUE || BuySignal[i-1] == EMPTY_VALUE)
            TriggerAlert("BUY", i, time);
      }
      else if(sellCondition)
      {
         SellSignal = high + 10 * _Point;
         if(BuySignal[i-1] != EMPTY_VALUE || SellSignal[i-1] == EMPTY_VALUE)
            TriggerAlert("SELL", i, time);
      }
   }
   
   return(rates_total);
}

//+------------------------------------------------------------------+
//| 计算箱体范围                                                     |
//+------------------------------------------------------------------+
void CalculateBox(int lookback)
{
   int highest = iHighest(NULL, 0, MODE_HIGH, lookback, 1);
   int lowest = iLowest(NULL, 0, MODE_LOW, lookback, 1);
   
   boxHigh = High[highest];
   boxLow = Low[lowest];
   
   // 绘制箱体
   DrawHorizontalLine("BoxUpper", boxHigh, clrDodgerBlue);
   DrawHorizontalLine("BoxLower", boxLow, clrDodgerBlue);
}

//+------------------------------------------------------------------+
//| 绘制趋势线                                                       |
//+------------------------------------------------------------------+
void DrawTrendLines()
{
   // 简化示例:连接最近两个低点
   int low1 = iLowest(NULL, 0, MODE_LOW, 20, 1);
   int low2 = iLowest(NULL, 0, MODE_LOW, 20, low1 + 5);
   
   if(low1 != -1 && low2 != -1 && low1 != low2)
   {
      trendStart = MathMin(low1, low2);
      trendEnd = MathMax(low1, low2);
      DrawTrendLine("TrendLine", Time[trendStart], Low[trendStart], Time[trendEnd], Low[trendEnd], clrDeepPink);
   }
}

//+------------------------------------------------------------------+
//| 绘制黄金分割线                                                   |
//+------------------------------------------------------------------+
void DrawFibonacci()
{
   int highest = iHighest(NULL, 0, MODE_HIGH, 50, 0);
   int lowest = iLowest(NULL, 0, MODE_LOW, 50, 0);
   
   if(highest != -1 && lowest != -1)
   {
      double fibLevels[] = {0.0, 0.236, 0.382, 0.5, 0.618, 1.0};
      double priceRange = High[highest] - Low[lowest];
      
      for(int i = 0; i < ArraySize(fibLevels); i++)
      {
         double levelPrice = Low[lowest] + priceRange * fibLevels;
         string name = "FibLevel_" + DoubleToString(fibLevels, 3);
         DrawHorizontalLine(name, levelPrice, clrGoldenrod);
      }
   }
}

//+------------------------------------------------------------------+
//| 触发交易警报                                                     |
//+------------------------------------------------------------------+
void TriggerAlert(string type, int barIndex, datetime time)
{
   if(time != lastAlertTime)
   {
      string symbol = Symbol();
      string message = symbol + " " + TimeToString(time) + " " + type + " Signal";
      Alert(message);
      lastAlertTime = time;
   }
}

//+------------------------------------------------------------------+
//| 绘制水平线辅助函数                                               |
//+------------------------------------------------------------------+
void DrawHorizontalLine(string name, double price, color clr)
{
   if(ObjectFind(0, name) < 0)
      ObjectCreate(0, name, OBJ_HLINE, 0, 0, price);
   else
      ObjectMove(0, name, 0, 0, price);
   
   ObjectSetInteger(0, name, OBJPROP_COLOR, clr);
   ObjectSetInteger(0, name, OBJPROP_STYLE, STYLE_DASHDOT);
   ObjectSetInteger(0, name, OBJPROP_WIDTH, 1);
}

//+------------------------------------------------------------------+
//| 绘制趋势线辅助函数                                               |
//+------------------------------------------------------------------+
void DrawTrendLine(string name, datetime t1, double p1, datetime t2, double p2, color clr)
{
   if(ObjectFind(0, name) < 0)
      ObjectCreate(0, name, OBJ_TRENDLINE, 0, t1, p1, t2, p2);
   else
   {
      ObjectMove(0, name, 0, t1, p1);
      ObjectMove(0, name, 1, t2, p2);
   }
   
   ObjectSetInteger(0, name, OBJPROP_COLOR, clr);
   ObjectSetInteger(0, name, OBJPROP_WIDTH, 2);
}
//+------------------------------------------------------------------+

臭宝很深情

发表于 2025-8-17 23:12:49 | 显示全部楼层

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
from matplotlib.patches import Rectangle
import matplotlib.ticker as mticker
import seaborn as sns
from datetime import datetime, timedelta
import warnings
warnings.filterwarnings('ignore')

# 设置样式
plt.style.use('seaborn-darkgrid')
sns.set_palette("deep")

# 生成模拟金融数据
def generate_market_data(start_date, periods=500, freq='5T'):
    np.random.seed(42)
    date_range = pd.date_range(start=start_date, periods=periods, freq=freq)
    base_price = 100
    prices = [base_price]
    volatility = 0.008
   
    for _ in range(1, periods):
        change = np.random.normal(0, volatility)
        if np.random.rand() < 0.2:  # 20% 的概率出现大幅波动
            change *= 3
        new_price = prices[-1] * (1 + change)
        prices.append(new_price)
   
    df = pd.DataFrame(index=date_range)
    df['close'] = prices
    df['open'] = df['close'].shift(1) * (1 + np.random.normal(0, volatility/2, periods))
    df['high'] = df[['open', 'close']].max(axis=1) * (1 + abs(np.random.normal(0, volatility/3, periods)))
    df['low'] = df[['open', 'close']].min(axis=1) * (1 - abs(np.random.normal(0, volatility/3, periods)))
   
    df.iloc[0, 0] = df.iloc[0, 1]  # 修正第一行的open值
    return df.dropna()

# 技术指标计算
def calculate_technical_indicators(df, timeframes=['5T', '15T', '30T', '1H', '4H']):
    # 计算简单移动平均线
    df['MA5'] = df['close'].rolling(window=5).mean()
    df['MA20'] = df['close'].rolling(window=20).mean()
    df['MA60'] = df['close'].rolling(window=60).mean()
   
    # 计算RSI
    delta = df['close'].diff()
    gain = (delta.where(delta > 0, 0)).rolling(window=14).mean()
    loss = (-delta.where(delta < 0, 0)).rolling(window=14).mean()
    rs = gain / loss
    df['RSI'] = 100 - (100 / (1 + rs))
   
    # 计算布林带
    df['SMA20'] = df['close'].rolling(window=20).mean()
    df['stddev'] = df['close'].rolling(window=20).std()
    df['UpperBand'] = df['SMA20'] + (df['stddev'] * 2)
    df['LowerBand'] = df['SMA20'] - (df['stddev'] * 2)
   
    # 计算MACD
    exp12 = df['close'].ewm(span=12, adjust=False).mean()
    exp26 = df['close'].ewm(span=26, adjust=False).mean()
    df['MACD'] = exp12 - exp26
    df['Signal'] = df['MACD'].ewm(span=9, adjust=False).mean()
    df['Histogram'] = df['MACD'] - df['Signal']
   
    # 多时间级别指标
    for tf in timeframes:
        resampled = df.resample(tf).agg({'open': 'first',
                                         'high': 'max',
                                         'low': 'min',
                                         'close': 'last'})
        resampled[f'MA20_{tf}'] = resampled['close'].rolling(window=20).mean()
        resampled[f'RSI_{tf}'] = 100 - (100 / (1 + (resampled['close'].diff().where(lambda x: x>0, 0).rolling(14).mean() /
                                                 resampled['close'].diff().where(lambda x: x<0, 0).abs().rolling(14).mean())))
        df = df.join(resampled[[f'MA20_{tf}', f'RSI_{tf}']], how='left')
   
    return df.dropna()

# 交易信号判断
def generate_trading_signals(df):
    df['Signal'] = 0  # 0: 无信号, 1: 买入, -1: 卖出
   
    # 均线交叉信号
    df.loc[(df['MA5'] > df['MA20']) & (df['MA5'].shift(1) <= df['MA20'].shift(1)), 'Signal'] = 1
    df.loc[(df['MA5'] < df['MA20']) & (df['MA5'].shift(1) >= df['MA20'].shift(1)), 'Signal'] = -1
   
    # RSI超买超卖信号
    df.loc[(df['RSI'] < 30) & (df['RSI'].shift(1) >= 30), 'Signal'] = 1
    df.loc[(df['RSI'] > 70) & (df['RSI'].shift(1) <= 70), 'Signal'] = -1
   
    # MACD交叉信号
    df.loc[(df['MACD'] > df['Signal']) & (df['MACD'].shift(1) <= df['Signal'].shift(1)), 'Signal'] = 1
    df.loc[(df['MACD'] < df['Signal']) & (df['MACD'].shift(1) >= df['Signal'].shift(1)), 'Signal'] = -1
   
    # 布林带突破信号
    df.loc[(df['close'] < df['LowerBand']) & (df['close'].shift(1) >= df['LowerBand'].shift(1)), 'Signal'] = 1
    df.loc[(df['close'] > df['UpperBand']) & (df['close'].shift(1) <= df['UpperBand'].shift(1)), 'Signal'] = -1
   
    # 避免连续信号
    df.loc[df['Signal'] == df['Signal'].shift(1), 'Signal'] = 0
   
    return df

# 绘制技术图表
def plot_technical_analysis(df):
    fig = plt.figure(figsize=(16, 14))
    gs = fig.add_gridspec(6, 1)
   
    # K线图区域
    ax1 = fig.add_subplot(gs[0:4, 0])
   
    # 计算箱体范围
    box_start = df.index[-100]
    box_df = df.loc[box_start:]
    box_high = box_df['high'].max()
    box_low = box_df['low'].min()
    box_range = box_high - box_low
   
    # 绘制箱体
    rect = Rectangle((mdates.date2num(box_start), box_high - box_low, box_low,
                     width=len(box_df)*0.8, alpha=0.1, color='blue')
    ax1.add_patch(rect)
   
    # 绘制K线
    for idx, row in df[-200:].iterrows():
        color = 'green' if row['close'] >= row['open'] else 'red'
        ax1.plot([idx, idx], [row['low'], row['high']], color=color, linewidth=1)
        ax1.plot([idx, idx], [row['open'], row['close']], color=color, linewidth=4)
   
    # 绘制移动平均线
    ax1.plot(df.index[-200:], df['MA5'][-200:], label='MA5', color='orange', alpha=0.8)
    ax1.plot(df.index[-200:], df['MA20'][-200:], label='MA20', color='blue', alpha=0.8)
    ax1.plot(df.index[-200:], df['MA60'][-200:], label='MA60', color='purple', alpha=0.8)
   
    # 绘制布林带
    ax1.plot(df.index[-200:], df['UpperBand'][-200:], label='Upper Band', color='red', linestyle='--', alpha=0.7)
    ax1.plot(df.index[-200:], df['SMA20'][-200:], label='SMA20', color='green', alpha=0.7)
    ax1.plot(df.index[-200:], df['LowerBand'][-200:], label='Lower Band', color='blue', linestyle='--', alpha=0.7)
    ax1.fill_between(df.index[-200:], df['UpperBand'][-200:], df['LowerBand'][-200:], color='gray', alpha=0.1)
   
    # 绘制趋势线
    low_points = df['low'][-100:].nsmallest(3).index
    if len(low_points) >= 2:
        x = mdates.date2num(low_points.sort_values()[:2])
        y = df.loc[low_points.sort_values()[:2], 'low']
        coeffs = np.polyfit(x, y, 1)
        trend_x = np.linspace(min(x), max(df.index[-100:].map(mdates.date2num)), 100)
        trend_y = np.polyval(coeffs, trend_x)
        ax1.plot(trend_x, trend_y, 'c--', linewidth=2, label='Trend Line')
   
    # 绘制黄金分割线
    swing_high = df['high'][-100:].max()
    swing_low = df['low'][-100:].min()
    levels = [0, 0.236, 0.382, 0.5, 0.618, 1]
    for level in levels:
        price_level = swing_low + (swing_high - swing_low) * level
        ax1.axhline(y=price_level, color='gold' if level in [0.382, 0.618] else 'goldenrod',
                    linestyle='--', alpha=0.7)
        ax1.text(df.index[-1], price_level, f'{level*100:.1f}%',
                 verticalalignment='bottom', fontsize=8, color='goldenrod')
   
    # 绘制交易信号
    buy_signals = df[df['Signal'] == 1][-200:]
    sell_signals = df[df['Signal'] == -1][-200:]
   
    ax1.scatter(buy_signals.index, buy_signals['low']*0.98,
                marker='^', color='gold', s=150, label='Buy Signal', zorder=10)
    ax1.scatter(sell_signals.index, sell_signals['high']*1.02,
                marker='v', color='lime', s=150, label='Sell Signal', zorder=10)
   
    ax1.set_title('Technical Analysis Dashboard', fontsize=16)
    ax1.set_ylabel('Price', fontsize=12)
    ax1.legend(loc='upper left')
    ax1.grid(True, linestyle='--', alpha=0.7)
   
    # 格式化x轴日期
    ax1.xaxis.set_major_formatter(mdates.DateFormatter('%m-%d %H:%M'))
   
    # MACD区域
    ax2 = fig.add_subplot(gs[4, 0], sharex=ax1)
    ax2.plot(df.index[-200:], df['MACD'][-200:], label='MACD', color='blue')
    ax2.plot(df.index[-200:], df['Signal'][-200:], label='Signal', color='red')
   
    # 绘制MACD柱状图
    colors = ['green' if h >= 0 else 'red' for h in df['Histogram'][-200:]]
    ax2.bar(df.index[-200:], df['Histogram'][-200:], width=0.8, color=colors, alpha=0.6)
   
    ax2.axhline(0, color='gray', linestyle='--', alpha=0.7)
    ax2.set_ylabel('MACD', fontsize=12)
    ax2.legend(loc='upper left')
    ax2.grid(True, linestyle='--', alpha=0.7)
   
    # RSI区域
    ax3 = fig.add_subplot(gs[5, 0], sharex=ax1)
    ax3.plot(df.index[-200:], df['RSI'][-200:], label='RSI', color='purple')
    ax3.axhline(70, color='red', linestyle='--', alpha=0.7)
    ax3.axhline(30, color='green', linestyle='--', alpha=0.7)
    ax3.fill_between(df.index[-200:], 70, 30, color='gray', alpha=0.1)
    ax3.set_ylabel('RSI', fontsize=12)
    ax3.set_xlabel('Date', fontsize=12)
    ax3.set_ylim(0, 100)
    ax3.grid(True, linestyle='--', alpha=0.7)
   
    plt.tight_layout()
    return fig

# 警报系统
def alert_system(df):
    last_signal = df['Signal'].iloc[-1]
    prev_signal = df['Signal'].iloc[-2]
   
    if last_signal != prev_signal:
        if last_signal == 1:
            print(f"\n\033[93mALERT: BUY SIGNAL at {df.index[-1]}\033[0m")
            print("Recommended Action: Consider entering a long position")
        elif last_signal == -1:
            print(f"\n\033[92mALERT: SELL SIGNAL at {df.index[-1]}\033[0m")
            print("Recommended Action: Consider exiting long positions or shorting")
    else:
        print(f"\nNo new trading signals at {df.index[-1]}")

# 多时间框架分析
def plot_multi_timeframe_analysis(df):
    fig, axes = plt.subplots(5, 1, figsize=(14, 12))
    timeframes = ['5T', '15T', '30T', '1H', '4H']
    colors = plt.cm.viridis(np.linspace(0, 1, len(timeframes)))
   
    for i, tf in enumerate(timeframes):
        resampled = df.resample(tf).agg({'open': 'first',
                                         'high': 'max',
                                         'low': 'min',
                                         'close': 'last'})
        resampled['MA20'] = resampled['close'].rolling(window=20).mean()
        
        axes[i].plot(resampled.index, resampled['close'], label=f'{tf} Close', color=colors[i], alpha=0.7)
        axes[i].plot(resampled.index, resampled['MA20'], label=f'{tf} MA20', color='red', linestyle='--')
        axes[i].set_title(f'{tf} Timeframe Analysis', fontsize=10)
        axes[i].legend(loc='upper left', fontsize=8)
        axes[i].grid(True, linestyle='--', alpha=0.5)
   
    plt.tight_layout()
    return fig

# 主函数
def main():
    # 生成模拟数据
    start_date = datetime.now() - timedelta(days=30)
    df = generate_market_data(start_date, periods=1000, freq='5T')
   
    # 计算技术指标
    df = calculate_technical_indicators(df)
   
    # 生成交易信号
    df = generate_trading_signals(df)
   
    # 警报系统
    alert_system(df)
   
    # 绘制主图表
    main_fig = plot_technical_analysis(df)
   
    # 绘制多时间框架分析
    multi_fig = plot_multi_timeframe_analysis(df)
   
    plt.show()

if __name__ == "__main__":
    main()

长城学校

发表于 3 天前 | 显示全部楼层

12
您需要登录后才可以回帖 登录 | 注册 微信登录

EA之家评论守则