//| 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 <= MA2Buffer) &&
(RSIBuffer < 30) &&
(close < LowerBB && close >= LowerBB);
// 组合条件示例:死叉+RSI超买+价格突破布林上轨
bool sellCondition =
(MA1Buffer < MA2Buffer && MA1Buffer >= MA2Buffer) &&
(RSIBuffer > 70) &&
(close > UpperBB && close <= UpperBB);
if(buyCondition)
{
BuySignal = low - 10 * _Point;
if(SellSignal != EMPTY_VALUE || BuySignal == EMPTY_VALUE)
TriggerAlert("BUY", i, time);
}
else if(sellCondition)
{
SellSignal = high + 10 * _Point;
if(BuySignal != EMPTY_VALUE || SellSignal == 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;
boxLow = Low;
// 绘制箱体
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, Low, Time, Low, 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 - Low;
for(int i = 0; i < ArraySize(fibLevels); i++)
{
double levelPrice = Low + 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);
}
//+------------------------------------------------------------------+ 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 =
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 = df.iloc# 修正第一行的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 = resampled['close'].rolling(window=20).mean()
resampled = 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[], 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'].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)
# 计算箱体范围
box_start = df.index[-100]
box_df = df.loc
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(, , row['high']], color=color, linewidth=1)
ax1.plot(, , 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']
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 =
for level in levels:
price_level = swing_low + (swing_high - swing_low) * level
ax1.axhline(y=price_level, color='gold' if level in 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 == 1][-200:]
sell_signals = df == -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, 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, 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}\033[0m")
print("Recommended Action: Consider entering a long position")
elif last_signal == -1:
print(f"\n\033}\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.plot(resampled.index, resampled['close'], label=f'{tf} Close', color=colors, alpha=0.7)
axes.plot(resampled.index, resampled['MA20'], label=f'{tf} MA20', color='red', linestyle='--')
axes.set_title(f'{tf} Timeframe Analysis', fontsize=10)
axes.legend(loc='upper left', fontsize=8)
axes.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() {:1_180:}
页:
1
[2]