//+------------------------------------------------------------------+
//| StarSkyGoldenAge.mq5 |
//| Copyright 2026, 星禾科技 |
//| Version 2.20 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2026, 星禾科技"
#property link ""
#property version "2.20"
//+------------------------------------------------------------------+
//| 包含文件 |
//+------------------------------------------------------------------+
#include <Trade/Trade.mqh>
#include <Trade/PositionInfo.mqh>
#include <Trade/AccountInfo.mqh>
#include <Trade/SymbolInfo.mqh>
//+------------------------------------------------------------------+
//| 输入参数(完全对应图片面板) |
//+------------------------------------------------------------------+
//=== 系统信息 ===
sinput string RiskWarning = "<<交易有风险,使用者盈亏自行承担>>"; // 风险提示
//=== 仓位配置 ===
sinput double InitialLots = 0.01; // 下单手数(首单)
sinput double MaxLot = 1.0; // 最大手数限制
//=== 网格与间距 ===
sinput double BaselineInterval = 100.0; // 基准网格间距(点)
//=== 止盈策略 ===
sinput double SingleOrderTP = 100.0; // 单一单量止盈点
sinput double CrossExitTP = 100.0; // 交叉出场止盈点
sinput double OverSevenAvgTP = 50.0; // 超过七单平均出场点
//=== 风控止盈计划 ===
sinput double RiskLotsThreshold = 0.3; // 风控触发手数阈值
sinput double RiskProfitTarget = 15.0; // 风控触发止盈金额
//=== 止损保护 ===
sinput double StopLossAmount = 200000.0; // 止损金额
//=== 监控开关 ===
sinput bool EnableMonitor = false; // 是否启动监控
//=== 止盈同步策略 ===
sinput int SyncTPMinInterval = 2; // 止盈同步最小间隔(秒)
//=== 系统与显示 ===
sinput bool OfficialAuth = true; // 官方授权标识
sinput string AuthorID = "星天科技"; // 作者标识
sinput bool ShowFooterInfo = true; // 面板底部显示说明
//+------------------------------------------------------------------+
//| 全局变量 |
//+------------------------------------------------------------------+
CTrade m_trade; // 交易对象
CPositionInfo m_position; // 持仓信息
CAccountInfo m_account; // 账户信息
CSymbolInfo m_symbol; // 品种信息
// 指标句柄
int m_ema_handle;
int m_rsi_handle;
int m_macd_handle;
int m_bb_handle;
// 网格管理
double m_grid_price[]; // 网格价格数组
double m_grid_lots[]; // 网格手数数组
int m_grid_count; // 网格层数
// 状态变量
datetime m_last_sync_time; // 上次止盈同步时间
double m_total_lots; // 总持仓手数
double m_total_profit; // 总浮动盈亏
//+------------------------------------------------------------------+
//| 初始化函数 |
//+------------------------------------------------------------------+
int OnInit()
{
// 初始化交易对象
m_trade.SetExpertMagicNumber(20260803);
m_trade.SetDeviationInPoints(10);
// 初始化品种信息
m_symbol.Name(Symbol());
m_symbol.Refresh();
// 创建技术指标
m_ema_handle = iMA(Symbol(), Period(), 20, 0, MODE_EMA, PRICE_CLOSE);
m_rsi_handle = iRSI(Symbol(), Period(), 14, PRICE_CLOSE);
m_macd_handle = iMACD(Symbol(), Period(), 12, 26, 9, PRICE_CLOSE);
m_bb_handle = iBands(Symbol(), Period(), 20, 2, 0, PRICE_CLOSE);
if(m_ema_handle == INVALID_HANDLE || m_rsi_handle == INVALID_HANDLE ||
m_macd_handle == INVALID_HANDLE || m_bb_handle == INVALID_HANDLE)
{
Print("指标创建失败");
return(INIT_FAILED);
}
// 初始化网格序列
InitializeGrid();
// 设置定时器用于止盈同步
EventSetTimer(SyncTPMinInterval);
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| 反初始化函数 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
// 释放指标句柄
if(m_ema_handle != INVALID_HANDLE) IndicatorRelease(m_ema_handle);
if(m_rsi_handle != INVALID_HANDLE) IndicatorRelease(m_rsi_handle);
if(m_macd_handle != INVALID_HANDLE) IndicatorRelease(m_macd_handle);
if(m_bb_handle != INVALID_HANDLE) IndicatorRelease(m_bb_handle);
// 删除定时器
EventKillTimer();
}
//+------------------------------------------------------------------+
//| 定时器函数(止盈同步) |
//+------------------------------------------------------------------+
void OnTimer()
{
// 止盈同步逻辑
if(TimeCurrent() - m_last_sync_time >= SyncTPMinInterval)
{
SyncTakeProfit();
m_last_sync_time = TimeCurrent();
}
}
//+------------------------------------------------------------------+
//| 新K线触发函数 |
//+------------------------------------------------------------------+
void OnTick()
{
// 检查是否为新K线
static datetime last_bar_time = 0;
datetime current_bar_time = iTime(Symbol(), Period(), 0);
if(current_bar_time == last_bar_time) return;
last_bar_time = current_bar_time;
// 更新持仓信息
UpdatePositionInfo();
// 风险控制检查
if(CheckRiskControl()) return;
// 获取交易信号
int signal = GetTradingSignal();
// 执行交易
if(signal > 0) ExecuteBuy();
else if(signal < 0) ExecuteSell();
// 如果开启监控,输出状态信息
if(EnableMonitor) PrintStatus();
}
//+------------------------------------------------------------------+
//| 初始化网格序列 |
//+------------------------------------------------------------------+
void InitializeGrid()
{
// 根据图片中的手数序列:0.01,0.01,0.01,0.01,0.01,0.01,...,0.02,0.02...
// 这里简化为动态生成,实际可按复杂序列
double lots[] = {0.01, 0.01, 0.01, 0.01, 0.01, 0.01,
0.02, 0.02, 0.02, 0.02, 0.02,
0.03, 0.03, 0.04, 0.05, 0.06, 0.08, 0.10};
m_grid_count = ArraySize(lots);
ArrayResize(m_grid_lots, m_grid_count);
ArrayResize(m_grid_price, m_grid_count);
for(int i = 0; i < m_grid_count; i++)
{
m_grid_lots[i] = lots[i];
// 网格价格在开仓时动态计算
}
}
//+------------------------------------------------------------------+
//| 获取交易信号(EMA/RSI/MACD/布林综合) |
//+------------------------------------------------------------------+
int GetTradingSignal()
{
double ema[3], rsi[3], macd[3], signal[3], bb[3];
double bb_upper[3], bb_lower[3], bb_middle[3];
// 获取指标数据
CopyBuffer(m_ema_handle, 0, 0, 3, ema);
CopyBuffer(m_rsi_handle, 0, 0, 3, rsi);
CopyBuffer(m_macd_handle, 0, 0, 3, macd);
CopyBuffer(m_macd_handle, 1, 0, 3, signal);
CopyBuffer(m_bb_handle, 0, 0, 3, bb_middle);
CopyBuffer(m_bb_handle, 1, 0, 3, bb_upper);
CopyBuffer(m_bb_handle, 2, 0, 3, bb_lower);
double close = SymbolInfoDouble(Symbol(), SYMBOL_BID);
double open = SymbolInfoDouble(Symbol(), SYMBOL_ASK);
// ---- 多空信号评分 ----
int buy_score = 0, sell_score = 0;
// 1. EMA信号(价格与EMA20比较)
if(close > ema[0]) buy_score++;
else if(close < ema[0]) sell_score++;
// 2. RSI信号(超买超卖)
if(rsi[0] < 30) buy_score++;
else if(rsi[0] > 70) sell_score++;
// 3. MACD信号(金叉死叉)
if(macd[0] > signal[0] && macd[1] <= signal[1]) buy_score++;
else if(macd[0] < signal[0] && macd[1] >= signal[1]) sell_score++;
// 4. 布林带信号(触及上下轨)
if(close <= bb_lower[0]) buy_score++;
else if(close >= bb_upper[0]) sell_score++;
// 综合判断:得分>=3则开仓
if(buy_score >= 3 && buy_score > sell_score) return 1;
if(sell_score >= 3 && sell_score > buy_score) return -1;
return 0;
}
//+------------------------------------------------------------------+
//| 执行买入(网格加仓) |
//+------------------------------------------------------------------+
void ExecuteBuy()
{
double price = SymbolInfoDouble(Symbol(), SYMBOL_ASK);
int total_positions = PositionsTotal();
// 计算当前持仓手数
double current_lot = GetGridLot(total_positions);
if(current_lot > MaxLot) current_lot = MaxLot;
// 计算止损止盈
double sl = price - 200 * SymbolInfoDouble(Symbol(), SYMBOL_POINT); // 200点止损
double tp = 0;
// 根据持仓数量选择止盈方式
if(total_positions == 0)
tp = price + SingleOrderTP * SymbolInfoDouble(Symbol(), SYMBOL_POINT);
else if(total_positions < 7)
tp = price + CrossExitTP * SymbolInfoDouble(Symbol(), SYMBOL_POINT);
else
tp = price + OverSevenAvgTP * SymbolInfoDouble(Symbol(), SYMBOL_POINT);
// 开仓
m_trade.Buy(current_lot, Symbol(), price, sl, tp, "星天网格多单");
}
//+------------------------------------------------------------------+
//| 执行卖出(网格加仓) |
//+------------------------------------------------------------------+
void ExecuteSell()
{
double price = SymbolInfoDouble(Symbol(), SYMBOL_BID);
int total_positions = PositionsTotal();
double current_lot = GetGridLot(total_positions);
if(current_lot > MaxLot) current_lot = MaxLot;
double sl = price + 200 * SymbolInfoDouble(Symbol(), SYMBOL_POINT);
double tp = 0;
if(total_positions == 0)
tp = price - SingleOrderTP * SymbolInfoDouble(Symbol(), SYMBOL_POINT);
else if(total_positions < 7)
tp = price - CrossExitTP * SymbolInfoDouble(Symbol(), SYMBOL_POINT);
else
tp = price - OverSevenAvgTP * SymbolInfoDouble(Symbol(), SYMBOL_POINT);
m_trade.Sell(current_lot, Symbol(), price, sl, tp, "星天网格空单");
}
//+------------------------------------------------------------------+
//| 获取网格手数 |
//+------------------------------------------------------------------+
double GetGridLot(int position_count)
{
if(position_count < m_grid_count)
return m_grid_lots[position_count];
else
return m_grid_lots[m_grid_count - 1];
}
//+------------------------------------------------------------------+
//| 更新持仓信息 |
//+------------------------------------------------------------------+
void UpdatePositionInfo()
{
m_total_lots = 0;
m_total_profit = 0;
for(int i = PositionsTotal() - 1; i >= 0; i--)
{
if(m_position.SelectByIndex(i) && m_position.Symbol() == Symbol())
{
m_total_lots += m_position.Volume();
m_total_profit += m_position.Profit();
}
}
}
//+------------------------------------------------------------------+
//| 风险控制检查 |
//+------------------------------------------------------------------+
bool CheckRiskControl()
{
// 1. 止损金额检查
if(m_total_profit <= -StopLossAmount)
{
CloseAllPositions();
Print("触发止损保护,平仓所有仓位");
return true;
}
// 2. 风控止盈检查
if(m_total_lots >= RiskLotsThreshold && m_total_profit >= RiskProfitTarget)
{
CloseAllPositions();
Print("触发风控止盈,平仓所有仓位");
return true;
}
return false;
}
//+------------------------------------------------------------------+
//| 平仓所有持仓 |
//+------------------------------------------------------------------+
void CloseAllPositions()
{
for(int i = PositionsTotal() - 1; i >= 0; i--)
{
if(m_position.SelectByIndex(i) && m_position.Symbol() == Symbol())
{
m_trade.PositionClose(m_position.Ticket());
}
}
}
//+------------------------------------------------------------------+
//| 止盈同步策略 |
//+------------------------------------------------------------------+
void SyncTakeProfit()
{
if(PositionsTotal() < 2) return;
// 将所有持仓的止盈价同步到统一的水平
// 计算平均开仓价
double avg_price = 0;
double total_vol = 0;
for(int i = PositionsTotal() - 1; i >= 0; i--)
{
if(m_position.SelectByIndex(i) && m_position.Symbol() == Symbol())
{
avg_price += m_position.PriceOpen() * m_position.Volume();
total_vol += m_position.Volume();
}
}
if(total_vol == 0) return;
avg_price /= total_vol;
// 设置统一的止盈
double tp_price = 0;
if(m_total_profit > 0)
{
// 盈利时,根据总持仓数决定止盈距离
if(PositionsTotal() <= 7)
tp_price = avg_price + CrossExitTP * SymbolInfoDouble(Symbol(), SYMBOL_POINT);
else
tp_price = avg_price + OverSevenAvgTP * SymbolInfoDouble(Symbol(), SYMBOL_POINT);
}
// 修改所有持仓的止盈
for(int i = PositionsTotal() - 1; i >= 0; i--)
{
if(m_position.SelectByIndex(i) && m_position.Symbol() == Symbol())
{
if(m_position.PositionType() == POSITION_TYPE_BUY)
m_trade.PositionModify(m_position.Ticket(), m_position.StopLoss(), tp_price);
else
m_trade.PositionModify(m_position.Ticket(), m_position.StopLoss(),
m_position.PriceOpen() - (tp_price - avg_price));
}
}
}
//+------------------------------------------------------------------+
//| 打印状态信息(监控用) |
//+------------------------------------------------------------------+
void PrintStatus()
{
if(!EnableMonitor) return;
string status = "===== 星天黄金时代 状态监控 =====\n";
status += "总持仓: " + IntegerToString(PositionsTotal()) + "\n";
status += "总手数: " + DoubleToString(m_total_lots, 2) + "\n";
status += "总盈亏: " + DoubleToString(m_total_profit, 2) + "\n";
status += "风控阈值: " + DoubleToString(RiskLotsThreshold, 2) + "手 / " +
DoubleToString(RiskProfitTarget, 2) + "$\n";
status += "止损金额: " + DoubleToString(StopLossAmount, 2) + "\n";
status += "====================================\n";
Comment(status);
}
//+------------------------------------------------------------------+
//| 图表事件处理(面板按钮) |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
const long &lparam,
const double &dparam,
const string &sparam)
{
if(id == CHARTEVENT_CLICK)
{
// 处理按钮点击事件:确定、取消、重置
// 实际可根据需要添加功能
Print("按钮点击: ", sparam);
}
}
//+------------------------------------------------------------------+ |