//— 输入参数
input int MagicNumber = 8888; // 唯一魔术码
input int Default_BB_Period = 12; // 布林带周期
input double Bollinger_Deviation = 1.8; // 标准差
input int Default_KDJ_Period = 14; // KDJ周期
input int KDJ_Smooth = 3; // KDJ平滑周期
input double TakeProfit = 15.0; // 止盈(USD)
input double StopLoss = 10.0; // 止损(USD)
input double LotSize = 0.1; // 基础手数
input double MaxDrawdown = 20.0; // 最大回撤(%)
input int PanelX = 5; // 面板X坐标
input int PanelY = 20; // 面板Y坐标
input color PanelColor = clrDimGray; // 面板背景色
//— 趋势参数
input bool EnableTrendMode = true; // 启用趋势策略
input int TrendMA_Period = 50; // 趋势均线周期
input double TrendThreshold = 0.0020; // 趋势阈值(20点)
//— 追踪止损参数
input bool EnableTrailing = true; // 启用追踪止损
input double TrailingStart = 5.0; // 追踪启动点(USD)
input double TrailingStep = 3.0; // 追踪步长(USD)
//— 交易间隔控制
input int TradeIntervalMinutes=15; // 交易间隔(分钟)
input int BuyOrderDistance = 30; // 多单间隔点数
input int SellOrderDistance = 30; // 空单间隔点数
//— 市场状态参数
input int ADX_Period = 14; // ADX周期
input int ATR_Period = 14; // ATR周期
input double ExtremeRangeThreshold = 0.6; // 极端震荡布林带宽度阈值
input double LowVolatilityThreshold = 0.8; // 低波动率阈值(ATR%)
//— 全新循环手数系统参数
input bool EnableCycleLot = true; // 启用循环手数系统
input double CycleBaseLot = 0.1; // 循环基础手数
input double CycleMaxLot = 5.0; // 最大循环手数
input double CycleLotStep = 0.1; // 每盈利一次增加的手数
input int CycleResetAfter = 3; // 盈利多少次后重置
input bool CycleUseMartingale = false; // 使用马丁格尔模式(亏损后加倍)
//— 连亏暂停机制参数
input bool EnableLossPause = true; // 启用连亏暂停机制
input int ConsecutiveLosses = 4; // 连亏次数阈值
input int PauseMinutes = 60; // 暂停时间(分钟)
//— 自动学习参数
input bool EnableAutoLearning = true; // 启用自动学习功能
input int LearningPeriod = 100; // 学习周期(交易次数)
input double LearningRate = 0.01; // 学习率
input int RetrainingInterval = 24; // 重新训练间隔(小时)
input double MinConfidence = 0.6; // 最小置信度阈值
//— 全局变量
int directionMode = 0; // 0:双向 1:只多 2:只空
bool tradingEnabled = true;
double pointValue;
datetime lastTradeTime = 0;
double equityPeak = 0;
int adjusted_BB_Period;
int adjusted_KDJ_Period;
double trendMA;
//— 循环手数系统变量
int cycleWinCount = 0; // 当前连续盈利次数
int cycleLossCount = 0; // 当前连续亏损次数
double currentCycleLot = 0.1; // 当前循环手数
//— 连亏暂停机制变量
int consecutiveLossCount = 0; // 当前连续亏损次数
datetime pauseStartTime = 0; // 暂停开始时间
bool isPaused = false; // 是否处于暂停状态
//— 自动学习系统变量
double learningWeights[10]; // 学习权重数组
double lastFeatures[10]; // 上次交易时的特征值
int trainingSamples = 0; // 训练样本数量
datetime lastRetrainingTime = 0; // 上次重新训练时间
double modelConfidence = 0.5; // 模型置信度
int successfulPredictions = 0; // 成功预测次数
int totalPredictions = 0; // 总预测次数
//— 市场状态变量
enum ENUM_MARKET_STATE {
MARKET_STATE_TREND_STRONG, // 趋势强劲
MARKET_STATE_RANGE_SOLID, // 震荡稳固
MARKET_STATE_RANGE_EXTREME, // 震荡极端(波动率极度收缩)
MARKET_STATE_BREAKOUT_POTENTIAL, // 突破在即
MARKET_STATE_UNKNOWN // 未知
};
ENUM_MARKET_STATE marketState = MARKET_STATE_UNKNOWN;
//— 指标变量
double adxValue;
double pdiValue;
double ndiValue;
double atrValue;
double atrPercent;
double atrPercentMA;
double atrPercentArray[];
//±-----------------------------------------------------------------+
//| 手数标准化函数 |
//±-----------------------------------------------------------------+
double NormalizeLots(double lots)
{
double minLot = MarketInfo(Symbol(), MODE_MINLOT);
double maxLot = MarketInfo(Symbol(), MODE_MAXLOT);
double lotStep = MarketInfo(Symbol(), MODE_LOTSTEP);
lots = MathMax(lots, minLot);
lots = MathMin(lots, maxLot);
lots = MathRound(lots / lotStep) * lotStep;
return NormalizeDouble(lots, 2);
}
//±-----------------------------------------------------------------+
//| 专家初始化函数 |
//±-----------------------------------------------------------------+
int OnInit()
{
ObjectsDeleteAll(0, “GTS_*”);
pointValue = MarketInfo(Symbol(), MODE_TICKVALUE);
CreateControlPanel();
EventSetMillisecondTimer(200);
AdjustParametersByTF();
equityPeak = AccountEquity();
ArraySetAsSeries(atrPercentArray, true);
// 初始化循环手数系统
currentCycleLot = CycleBaseLot;
cycleWinCount = 0;
cycleLossCount = 0;
// 初始化连亏暂停机制
consecutiveLossCount = 0;
pauseStartTime = 0;
isPaused = false;
// 初始化自动学习系统
InitializeLearningSystem();
return(INIT_SUCCEEDED);
}
//±-----------------------------------------------------------------+
//| 初始化自动学习系统 |
//±-----------------------------------------------------------------+
void InitializeLearningSystem()
{
// 随机初始化权重
for(int i = 0; i < 10; i++)
{
learningWeights[i] = MathRand() / 32767.0 - 0.5;
}
trainingSamples = 0;
lastRetrainingTime = TimeCurrent();
modelConfidence = 0.5;
successfulPredictions = 0;
totalPredictions = 0;
}
//±-----------------------------------------------------------------+
//| 提取交易特征 |
//±-----------------------------------------------------------------+
void ExtractFeatures(double &features[])
{
ArrayResize(features, 10);
// 特征1: 布林带位置 (0-1)
double upperBand = iBands(Symbol(), 0, adjusted_BB_Period, Bollinger_Deviation, 0, PRICE_CLOSE, MODE_UPPER, 0);
double lowerBand = iBands(Symbol(), 0, adjusted_BB_Period, Bollinger_Deviation, 0, PRICE_CLOSE, MODE_LOWER, 0);
features[0] = (Close[0] - lowerBand) / (upperBand - lowerBand);
// 特征2: KDJ指标的J值 (归一化)
double K, D, J;
CalculateKDJ(adjusted_KDJ_Period, KDJ_Smooth, K, D, J);
features[1] = J / 100.0;
// 特征3: ADX强度
features[2] = iADX(Symbol(), 0, ADX_Period, PRICE_CLOSE, MODE_MAIN, 0) / 100.0;
// 特征4: 价格与趋势MA的距离
features[3] = (Close[0] - iMA(Symbol(), 0, TrendMA_Period, 0, MODE_EMA, PRICE_CLOSE, 0)) / Close[0];
// 特征5: ATR百分比 (波动率)
features[4] = iATR(Symbol(), 0, ATR_Period, 0) / Close[0];
// 特征6: RSI
features[5] = iRSI(Symbol(), 0, 14, PRICE_CLOSE, 0) / 100.0;
// 特征7: 成交量变化
// 特征8: 市场状态 (编码为0-1)
features[7] = marketState / 4.0;
// 特征9: 时间特征 (小时归一化)
features[8] = Hour() / 24.0;
// 特征10: 价格动量
features[9] = (Close[0] - Close[20]) / Close[20];
// 保存特征用于后续学习
for(int i = 0; i < 10; i++)
{
lastFeatures[i] = features[i];
}
}
//±-----------------------------------------------------------------+
//| 机器学习预测函数 |
//±-----------------------------------------------------------------+
double PredictWithLearning(double &features[])
{
if(!EnableAutoLearning) return 0.5;
double prediction = 0;
for(int i = 0; i < 10; i++)
{
prediction += learningWeights[i] * features[i];
}
// Sigmoid函数转换为概率
return 1.0 / (1.0 + MathExp(-prediction));
}
//±-----------------------------------------------------------------+
//| 更新机器学习模型 |
//±-----------------------------------------------------------------+
void UpdateLearningModel(double actualOutcome, double predictedOutcome, double &features[])
{
if(!EnableAutoLearning) return;
// 计算误差
double error = actualOutcome - predictedOutcome;
// 更新权重 (随机梯度下降)
for(int i = 0; i < 10; i++)
{
learningWeights[i] += LearningRate * error * features[i];
}
trainingSamples++;
// 更新置信度 - 修复第207行的错误
if((actualOutcome > 0.5 && predictedOutcome > 0.5) || (actualOutcome <= 0.5 && predictedOutcome <= 0.5))
{
successfulPredictions++;
}
totalPredictions++;
if(totalPredictions > 0)
{
modelConfidence = (double)successfulPredictions / totalPredictions;
}
// 定期重新训练
if(TimeCurrent() - lastRetrainingTime >= RetrainingInterval * 3600)
{
RetrainModel();
lastRetrainingTime = TimeCurrent();
}
}
//±-----------------------------------------------------------------+
//| 重新训练模型 |
//±-----------------------------------------------------------------+
void RetrainModel()
{
// 在实际应用中,这里可以使用更复杂的重新训练逻辑
// 例如使用历史数据进行批量训练
Print("模型重新训练已完成。当前置信度: ", DoubleToString(modelConfidence, 2));
}
//±-----------------------------------------------------------------+
//| 周期参数调整 |
//±-----------------------------------------------------------------+
void AdjustParametersByTF()
{
switch(_Period)
{
case PERIOD_M1:
case PERIOD_M5:
adjusted_BB_Period = 10;
adjusted_KDJ_Period = 9;
break;
case PERIOD_M15:
case PERIOD_M30:
adjusted_BB_Period = Default_BB_Period;
adjusted_KDJ_Period = Default_KDJ_Period;
break;
case PERIOD_H1:
case PERIOD_H4:
adjusted_BB_Period = 20;
adjusted_KDJ_Period = 21;
break;
default:
adjusted_BB_Period = Default_BB_Period;
adjusted_KDJ_Period = Default_KDJ_Period;
}
}
//±-----------------------------------------------------------------+
//| 更新循环手数系统 |
//±-----------------------------------------------------------------+
void UpdateCycleLotSystem(double lastProfit)
{
if(!EnableCycleLot) return;
// 盈利处理
if(lastProfit > 0)
{
cycleWinCount++;
cycleLossCount = 0; // 重置亏损计数
// 检查是否需要重置 if(cycleWinCount >= CycleResetAfter) { currentCycleLot = CycleBaseLot; cycleWinCount = 0; } else { // 增加手数 currentCycleLot += CycleLotStep; if(currentCycleLot > CycleMaxLot) currentCycleLot = CycleMaxLot; }
}
// 亏损处理
else if(lastProfit < 0)
{
cycleWinCount = 0; // 重置盈利计数
cycleLossCount++;
if(CycleUseMartingale) { // 马丁格尔模式:亏损后加倍 currentCycleLot *= 2; if(currentCycleLot > CycleMaxLot) currentCycleLot = CycleMaxLot; } else { // 普通模式:亏损后重置 currentCycleLot = CycleBaseLot; cycleLossCount = 0; }
}
currentCycleLot = NormalizeLots(currentCycleLot);
}
//±-----------------------------------------------------------------+
//| 更新连亏暂停机制 |
//±-----------------------------------------------------------------+
void UpdateLossPauseSystem(double lastProfit)
{
if(!EnableLossPause) return;
// 盈利处理 - 重置连亏计数
if(lastProfit > 0)
{
consecutiveLossCount = 0;
isPaused = false;
pauseStartTime = 0;
}
// 亏损处理 - 增加连亏计数
else if(lastProfit < 0)
{
consecutiveLossCount++;
// 检查是否达到连亏阈值 if(consecutiveLossCount >= ConsecutiveLosses && !isPaused) { isPaused = true; pauseStartTime = TimeCurrent(); Print("连续亏损 ", ConsecutiveLosses, " 次,交易暂停 ", PauseMinutes, " 分钟"); }
}
// 检查暂停是否结束
if(isPaused && (TimeCurrent() - pauseStartTime >= PauseMinutes * 60))
{
isPaused = false;
consecutiveLossCount = 0;
pauseStartTime = 0;
Print(“暂停结束,恢复交易”);
}
}
//±-----------------------------------------------------------------+
//| 检查是否处于暂停状态 |
//±-----------------------------------------------------------------+
bool IsTradingPaused()
{
if(!EnableLossPause) return false;
if(isPaused)
{
// 计算剩余暂停时间
int remainingSeconds = PauseMinutes * 60 - (int)(TimeCurrent() - pauseStartTime);
int remainingMinutes = remainingSeconds / 60;
remainingSeconds = remainingSeconds % 60;
// 每分钟更新一次状态 static datetime lastUpdate = 0; if(TimeCurrent() - lastUpdate >= 60) { Print("交易暂停中,剩余时间: ", remainingMinutes, "分", remainingSeconds, "秒"); lastUpdate = TimeCurrent(); } return true;
}
return false;
}
//±-----------------------------------------------------------------+
//| 市场状态判断函数 |
//±-----------------------------------------------------------------+
void CheckMarketCondition()
{
// 计算布林带带宽比率
static double bbWidthArray[];
double upperBand = iBands(Symbol(),0,adjusted_BB_Period,Bollinger_Deviation,0,PRICE_CLOSE,MODE_UPPER,0);
double lowerBand = iBands(Symbol(),0,adjusted_BB_Period,Bollinger_Deviation,0,PRICE_CLOSE,MODE_LOWER,0);
double currentBBWidth = (upperBand - lowerBand)/Close[0];
ArraySetAsSeries(bbWidthArray, true);
ArrayResize(bbWidthArray, 14);
for(int i=0; i<14; i++) bbWidthArray[i] = (iBands(Symbol(),0,adjusted_BB_Period,Bollinger_Deviation,0,PRICE_CLOSE,MODE_UPPER,i) -
iBands(Symbol(),0,adjusted_BB_Period,Bollinger_Deviation,0,PRICE_CLOSE,MODE_LOWER,i))/Close[i];
double avgBBWidth = iMAOnArray(bbWidthArray,0,14,0,MODE_SMA,0);
double bbWidthRatio = currentBBWidth/avgBBWidth;
// 计算趋势MA
trendMA = iMA(Symbol(),0,TrendMA_Period,0,MODE_EMA,PRICE_CLOSE,0);
// 计算ADX指标
adxValue = iADX(Symbol(), 0, ADX_Period, PRICE_CLOSE, MODE_MAIN, 0);
pdiValue = iADX(Symbol(), 0, ADX_Period, PRICE_CLOSE, MODE_PLUSDI, 0);
ndiValue = iADX(Symbol(), 0, ADX_Period, PRICE_CLOSE, MODE_MINUSDI, 0);
// 计算ATR百分比
atrValue = iATR(Symbol(), 0, ATR_Period, 0);
atrPercent = (atrValue / Close[0]) * 100;
// 更新ATR百分比数组并计算其MA
ArrayResize(atrPercentArray, 20);
for(int i = 0; i < 20; i++) {
double atr = iATR(Symbol(), 0, ATR_Period, i);
atrPercentArray[i] = (atr / Close[i]) * 100;
}
atrPercentMA = iMAOnArray(atrPercentArray, 0, 20, 0, MODE_SMA, 0);
// 判断市场状态
if (adxValue > 25 && bbWidthRatio > 1.2) {
marketState = MARKET_STATE_TREND_STRONG; // 强势趋势
}
else if (bbWidthRatio < 0.7 && atrPercent > atrPercentMA * LowVolatilityThreshold) {
marketState = MARKET_STATE_RANGE_SOLID; // 稳固震荡
}
else if (bbWidthRatio < ExtremeRangeThreshold && atrPercent < atrPercentMA * LowVolatilityThreshold) {
marketState = MARKET_STATE_RANGE_EXTREME; // 极端震荡(波动率极度收缩)
}
else {
marketState = MARKET_STATE_UNKNOWN;
}
}
//±-----------------------------------------------------------------+
//| 核心交易逻辑 |
//±-----------------------------------------------------------------+
void OnTick()
{
if(!tradingEnabled) return;
// 检查是否处于连亏暂停状态
if(IsTradingPaused())
{
UpdatePanel();
return;
}
if(EnableTrailing) TrailingStop();
if(AccountEquity() > equityPeak) equityPeak = AccountEquity();
if(CalculateDrawdown() > MaxDrawdown){
CloseAllTrades();
tradingEnabled = false;
UpdatePanel();
return;
}
CheckMarketCondition(); // 市场状态判断 - 修复第262行的拼写错误
//— 震荡策略信号
double upperBand = iBands(Symbol(),0,adjusted_BB_Period,Bollinger_Deviation,0,PRICE_CLOSE,MODE_UPPER,0);
double lowerBand = iBands(Symbol(),0,adjusted_BB_Period,Bollinger_Deviation,0,PRICE_CLOSE,MODE_LOWER,0);
double K,D,J;
CalculateKDJ(adjusted_KDJ_Period, KDJ_Smooth, K, D, J);
bool buySignal = false;
bool sellSignal = false;
bool trendBuy = false;
bool trendSell = false;
//=== 趋势策略信号 ===
if(EnableTrendMode){
trendBuy = (Close[0] > trendMA + TrendThreshold) && (directionMode!=2);
trendSell = (Close[0] < trendMA - TrendThreshold) && (directionMode!=1);
}
//=== 震荡策略信号 ===
double pivot = (upperBand + lowerBand)/2;
double rangeHigh = pivot + 0.5*(upperBand - lowerBand);
double rangeLow = pivot - 0.5*(upperBand - lowerBand);
buySignal = (Close[0] < rangeLow) && (J < 35) && (directionMode!=2);
sellSignal = (Close[0] > rangeHigh) && (J > 65) && (directionMode!=1);
//=== 自动学习增强 ===
double mlBuyConfidence = 0.5;
double mlSellConfidence = 0.5;
if(EnableAutoLearning)
{
// 提取特征
double features[];
ExtractFeatures(features);
// 获取机器学习预测 mlBuyConfidence = PredictWithLearning(features); mlSellConfidence = 1.0 - mlBuyConfidence; // 根据置信度调整信号 if(mlBuyConfidence > MinConfidence && mlBuyConfidence > mlSellConfidence) { buySignal = buySignal || true; // 增强买入信号 if(!buySignal) // 如果没有原始信号,但ML强烈预测 buySignal = (mlBuyConfidence > 0.7); } else if(mlSellConfidence > MinConfidence && mlSellConfidence > mlBuyConfidence) { sellSignal = sellSignal || true; // 增强卖出信号 if(!sellSignal) // 如果没有原始信号,但ML强烈预测 sellSignal = (mlSellConfidence > 0.7); }
}
//=== 根据市场状态动态调整策略 ===
double proposedLotSize = CalculateLotSize();
double proposedStopLoss = StopLoss;
double proposedTakeProfit = TakeProfit;
switch(marketState) {
case MARKET_STATE_TREND_STRONG:
// 强势趋势:正常执行趋势策略,可以略微激进
proposedLotSize *= 1.1;
break;
case MARKET_STATE_RANGE_SOLID: // 稳固震荡:正常执行震荡策略,但更谨慎 proposedLotSize *= 0.7; proposedStopLoss *= 1.2; break; case MARKET_STATE_RANGE_EXTREME: // 极端震荡:暂停震荡策略,为趋势突破做准备 buySignal = false; sellSignal = false; proposedStopLoss *= 0.7; // 使用更紧的止损 break; case MARKET_STATE_UNKNOWN: // 未知状态:保持极度谨慎 proposedLotSize *= 0.5; break;
}
// 综合信号处理
if((buySignal || trendBuy) && CheckRisk() && CheckTrendCondition(OP_BUY) && CheckTradeInterval() && CheckOrderDistance(OP_BUY))
ExecuteTrade(OP_BUY, proposedLotSize, proposedStopLoss, proposedTakeProfit, mlBuyConfidence);
if((sellSignal || trendSell) && CheckRisk() && CheckTrendCondition(OP_SELL) && CheckTradeInterval() && CheckOrderDistance(OP_SELL))
ExecuteTrade(OP_SELL, proposedLotSize, proposedStopLoss, proposedTakeProfit, mlSellConfidence);
UpdatePanel();
}
//±-----------------------------------------------------------------+
//| 手数计算函数 |
//±-----------------------------------------------------------------+
double CalculateLotSize()
{
if(EnableCycleLot)
{
return currentCycleLot;
}
return LotSize;
}
//±-----------------------------------------------------------------+
//| 订单间隔检查函数 |
//±-----------------------------------------------------------------+
bool CheckOrderDistance(int type)
{
datetime lastOrderTime = 0;
double lastOrderPrice = 0;
for(int i=OrdersHistoryTotal()-1; i>=0; i–){
if(OrderSelect(i, SELECT_BY_POS, MODE_HISTORY) &&
OrderMagicNumber() == MagicNumber &&
OrderSymbol() == Symbol() &&
OrderType() == type)
{
lastOrderTime = OrderOpenTime();
lastOrderPrice = OrderOpenPrice();
break;
}
}
for(int i=OrdersTotal()-1; i>=0; i–){
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES) &&
OrderMagicNumber() == MagicNumber &&
OrderSymbol() == Symbol() &&
OrderType() == type)
{
if(OrderOpenTime() > lastOrderTime)
{
lastOrderTime = OrderOpenTime();
lastOrderPrice = OrderOpenPrice();
}
}
}
if(lastOrderTime == 0) return true;
double currentPrice = (type == OP_BUY) ? Ask : Bid;
double distancePoints = MathAbs(currentPrice - lastOrderPrice) / Point;
if(type == OP_BUY && distancePoints < BuyOrderDistance) return false;
if(type == OP_SELL && distancePoints < SellOrderDistance) return false;
return true;
}
//±-----------------------------------------------------------------+
//| 交易间隔检查函数 |
//±-----------------------------------------------------------------+
bool CheckTradeInterval()
{
if(TimeCurrent() - lastTradeTime >= TradeIntervalMinutes*60)
return true;
return false;
}
//±-----------------------------------------------------------------+
//| 趋势条件检查 |
//±-----------------------------------------------------------------+
bool CheckTrendCondition(int type)
{
if(!EnableTrendMode) return true;
static double lastMA = 0;
bool maRising = trendMA > lastMA;
bool maFalling = trendMA < lastMA;
lastMA = trendMA;
if(type == OP_BUY)
return maRising;
else if(type == OP_SELL)
return maFalling;
return true;
}
//±-----------------------------------------------------------------+
//| KDJ计算函数 |
//±-----------------------------------------------------------------+
void CalculateKDJ(int period, int smooth, double &K, double &D, double &J)
{
static double prevK=50, prevD=50;
double rsvArray[];
ArraySetAsSeries(rsvArray, true);
int bars = MathMin(Bars-1, period*3);
ArrayResize(rsvArray, bars);
for(int i=0; i<bars; i++){
int shift = i+1;
double high = High[iHighest(Symbol(),0,MODE_HIGH,period,shift)];
double low = Low[iLowest(Symbol(),0,MODE_LOW,period,shift)];
if(high != low)
rsvArray[i] = (Close[shift]-low)/(high-low)*100;
else
rsvArray[i] = 50;
}
// 修正KDJ计算:先计算K值,再用K值计算D值
K = iMAOnArray(rsvArray,0,smooth,0,MODE_EMA,0);
K = 0.3K + 0.7prevK; // 平滑K值
// 使用K值数组计算D值
double kArray[];
ArrayResize(kArray, smooth);
for(int j=0; j<smooth; j++) {
kArray[j] = iMAOnArray(rsvArray,0,smooth,0,MODE_EMA,j);
}
D = iMAOnArray(kArray,0,smooth,0,MODE_EMA,0);
D = 0.3D + 0.7prevD; // 平滑D值
J = 3K - 2D;
prevK = K;
prevD = D;
}
//±-----------------------------------------------------------------+
//| 订单执行函数 |
//±-----------------------------------------------------------------+
void ExecuteTrade(int type, double lot, double sl, double tp, double mlConfidence)
{
if(!IsTradeAllowed()) return;
// 根据机器学习置信度调整手数
if(EnableAutoLearning && mlConfidence > MinConfidence)
{
// 置信度越高,手数调整越大 (0.5-1.5倍)
double lotMultiplier = 0.5 + mlConfidence;
lot *= lotMultiplier;
lot = NormalizeLots(lot);
}
double price = (type==OP_BUY) ? Ask : Bid;
double stopLoss = CalculateStopLoss(type, sl);
double takeProfit = CalculateTakeProfit(type, tp);
for(int i=0; i<3; i++){
int ticket = OrderSend(Symbol(),type,lot,price,3,stopLoss,takeProfit,“”,MagicNumber,0,clrNONE);
if(ticket > 0){
lastTradeTime = TimeCurrent();
// 保存交易时的特征和预测,用于后续学习 if(EnableAutoLearning) { // 特征已在ExtractFeatures中保存到lastFeatures // 我们将在订单关闭时更新模型 } break; } else Print("订单发送失败 错误:", GetLastError()); Sleep(500);
}
}
//±-----------------------------------------------------------------+
//| 计算止损函数 |
//±-----------------------------------------------------------------+
double CalculateStopLoss(int type, double sl)
{
if(sl <= 0) return 0;
double price = (type == OP_BUY) ? Bid : Ask;
double tickValue = MarketInfo(Symbol(), MODE_TICKVALUE);
if(tickValue == 0) return 0;
double points = sl / (tickValue * LotSize);
return NormalizeDouble(price + ((type == OP_BUY) ? -points : points) * Point, Digits);
}
//±-----------------------------------------------------------------+
//| 计算止盈函数 |
//±-----------------------------------------------------------------+
double CalculateTakeProfit(int type, double tp)
{
if(tp <= 0) return 0;
double price = (type == OP_BUY) ? Ask : Bid;
double tickValue = MarketInfo(Symbol(), MODE_TICKVALUE);
if(tickValue == 0) return 0;
double points = tp / (tickValue * LotSize);
return NormalizeDouble(price + ((type == OP_BUY) ? points : -points) * Point, Digits);
}
//±-----------------------------------------------------------------+
//| 风控函数组 |
//±-----------------------------------------------------------------+
bool CheckRisk()
{
double marginRatio = AccountMargin()/AccountEquity()*100;
return (marginRatio <= 50);
}
//±-----------------------------------------------------------------+
//| 追踪止损函数 |
//±-----------------------------------------------------------------+
void TrailingStop()
{
for(int i=0; i<OrdersTotal(); i++){
if(OrderSelect(i, SELECT_BY_POS) && OrderMagicNumber() == MagicNumber && OrderSymbol() == Symbol()){
int type = OrderType();
if(type != OP_BUY && type != OP_SELL) continue;
double currentProfit = OrderProfit() + OrderSwap() + OrderCommission(); double openPrice = OrderOpenPrice(); double currentStop = OrderStopLoss(); double currentTP = OrderTakeProfit(); double point = MarketInfo(Symbol(), MODE_POINT); double pipValue = MarketInfo(Symbol(), MODE_TICKVALUE) * OrderLots(); if(pipValue <= 0) continue; double trailingStartPips = TrailingStart / pipValue; double trailingStepPips = TrailingStep / pipValue; if(type == OP_BUY){ double currentPrice = Bid; if(currentPrice - openPrice >= trailingStartPips * point){ double newStop = currentPrice - trailingStepPips * point; if(newStop > currentStop || currentStop == 0){ if(!OrderModify(OrderTicket(), OrderOpenPrice(), newStop, currentTP, 0, clrNONE)) Print("追踪止损修改失败,错误:", GetLastError()); } } } else if(type == OP_SELL){ double currentPrice = Ask; if(openPrice - currentPrice >= trailingStartPips * point){ double newStop = currentPrice + trailingStepPips * point; if(newStop < currentStop || currentStop == 0){ if(!OrderModify(OrderTicket(), OrderOpenPrice(), newStop, currentTP, 0, clrNONE)) Print("追踪止损修改失败,错误:", GetLastError()); } } } }
}
}
//±-----------------------------------------------------------------+
//| 检查订单历史并更新循环手数系统和连亏暂停机制 |
//±-----------------------------------------------------------------+
void CheckOrderHistory()
{
int lastClosedTicket = -1;
datetime lastClosedTime = 0;
double lastProfit = 0;
// 遍历历史订单,找到最近关闭的订单
for(int i = OrdersHistoryTotal()-1; i >= 0; i–)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_HISTORY) &&
OrderMagicNumber() == MagicNumber &&
OrderSymbol() == Symbol())
{
if(OrderCloseTime() > lastClosedTime)
{
lastClosedTime = OrderCloseTime();
lastClosedTicket = OrderTicket();
lastProfit = OrderProfit() + OrderSwap() + OrderCommission();
// 自动学习: 使用交易结果更新模型 if(EnableAutoLearning) { // 计算实际结果 (1为盈利, 0为亏损) double actualOutcome = (lastProfit > 0) ? 1.0 : 0.0; // 更新学习模型 double features[10]; ArrayCopy(features, lastFeatures); // 获取交易方向 (1为买入, 0为卖出) int orderType = OrderType(); double predictedOutcome = (orderType == OP_BUY) ? PredictWithLearning(features) : 1.0 - PredictWithLearning(features); UpdateLearningModel(actualOutcome, predictedOutcome, features); } } }
}
// 如果没有找到历史订单,则重置
if(lastClosedTicket == -1)
{
return;
}
// 更新循环手数系统
UpdateCycleLotSystem(lastProfit);
// 更新连亏暂停机制
UpdateLossPauseSystem(lastProfit);
}
//±-----------------------------------------------------------------+
//| 控制面板系统 |
//±-----------------------------------------------------------------+
void CreateControlPanel()
{
ObjectCreate(0,“GTS_MainPanel”,OBJ_RECTANGLE_LABEL,0,0,0);
ObjectSetInteger(0,“GTS_MainPanel”,OBJPROP_XDISTANCE,PanelX);
ObjectSetInteger(0,“GTS_MainPanel”,OBJPROP_YDISTANCE,PanelY);
ObjectSetInteger(0,“GTS_MainPanel”,OBJPROP_XSIZE,300);
ObjectSetInteger(0,“GTS_MainPanel”,OBJPROP_YSIZE,500);
ObjectSetInteger(0,“GTS_MainPanel”,OBJPROP_BGCOLOR,PanelColor);
CreateButton(“BtnBoth”,“双向”,PanelX+10,PanelY+20,80,25,directionMode0?clrGold:clrDimGray);
CreateButton(“BtnLong”,“只多”,PanelX+100,PanelY+20,80,25,directionMode1?clrGold:clrDimGray);
CreateButton(“BtnShort”,“只空”,PanelX+190,PanelY+20,80,25,directionMode==2?clrGold:clrDimGray);
CreateButton(“BtnBuy”,“手工开多”,PanelX+10,PanelY+60,80,25,clrLime);
CreateButton(“BtnSell”,“手工开空”,PanelX+100,PanelY+60,80,25,clrRed);
CreateButton(“BtnCloseAll”,“全部平仓”,PanelX+190,PanelY+60,80,25,clrDodgerBlue);
CreateButton(“BtnCloseProfit”,“平盈利单”,PanelX+10,PanelY+100,120,25,clrLime);
CreateButton(“BtnCloseLoss”,“平亏损单”,PanelX+140,PanelY+100,120,25,clrRed);
CreateLabel(“LblTrend”,PanelX+10,PanelY+140,“趋势状态:”,clrGold);
CreateLabel(“LblMAValue”,PanelX+80,PanelY+140,“MA:0.00”,clrWhite);
CreateLabel(“LblTrendSignal”,PanelX+180,PanelY+140,“趋势:无”,clrSilver);
CreateLabel(“LblADX”,PanelX+10,PanelY+160,“ADX:0.00”,clrYellow);
CreateLabel(“LblATR”,PanelX+100,PanelY+160,“ATR%:0.00”,clrOrange);
CreateLabel(“LblEquity”,PanelX+10,PanelY+180,“净值: N/A”,clrWhite);
CreateLabel(“LblDrawdown”,PanelX+10,PanelY+200,“回撤: N/A”,clrTomato);
CreateLabel(“LblMargin”,PanelX+10,PanelY+220,“保证金: N/A”,clrOrange);
CreateLabel(“LblWinRate”,PanelX+10,PanelY+260,“胜率: N/A”,clrLawnGreen);
CreateLabel(“LblTrades”,PanelX+10,PanelY+280,“总交易: N/A”,clrSkyBlue);
CreateLabel(“LblStatus”,PanelX+10,PanelY+320,“状态: 运行中”,clrWhite);
CreateLabel(“LblTime”,PanelX+10,PanelY+340,“最后交易: N/A”,clrSilver);
CreateLabel(“LblTrailing”,PanelX+10,PanelY+360,“追踪状态:”+(EnableTrailing?“激活”:“关闭”),EnableTrailing?clrLime:clrRed);
// 市场状态显示
CreateLabel(“LblMarketState”,PanelX+10,PanelY+400,“市场状态: 未知”, clrYellow);
// 循环手数系统显示
CreateLabel(“LblCycleLot”,PanelX+10,PanelY+420,“循环手数:”+(EnableCycleLot?“激活”:“关闭”),EnableCycleLot?clrLime:clrRed);
CreateLabel(“LblCycleStats”,PanelX+120,PanelY+420,“盈利:”+IntegerToString(cycleWinCount)+" 亏损:"+IntegerToString(cycleLossCount),clrWhite);
CreateLabel(“LblCurrentLot”,PanelX+10,PanelY+440,“当前手数:”+DoubleToString(currentCycleLot,2),clrWhite);
// 连亏暂停机制显示
CreateLabel(“LblLossPause”,PanelX+10,PanelY+460,“连亏暂停:”+(EnableLossPause?“激活”:“关闭”),EnableLossPause?clrLime:clrRed);
CreateLabel(“LblLossStats”,PanelX+120,PanelY+460,“连亏:”+IntegerToString(consecutiveLossCount)+“/”+IntegerToString(ConsecutiveLosses),clrWhite);
CreateLabel(“LblPauseStatus”,PanelX+10,PanelY+480,“暂停状态:”+(isPaused?“是”:“否”),isPaused?clrRed:clrLime);
// 自动学习系统显示
CreateLabel(“LblAutoLearning”,PanelX+10,PanelY+500,“自动学习:”+(EnableAutoLearning?“激活”:“关闭”),EnableAutoLearning?clrLime:clrRed);
CreateLabel(“LblMLConfidence”,PanelX+120,PanelY+500,“置信度:”+DoubleToString(modelConfidence*100,1)+“%”,clrWhite);
CreateLabel(“LblMLPredictions”,PanelX+10,PanelY+520,“预测:”+IntegerToString(successfulPredictions)+“/”+IntegerToString(totalPredictions),clrWhite);
}
//±-----------------------------------------------------------------+
//| 面板更新函数 |
//±-----------------------------------------------------------------+
void UpdatePanel()
{
// 检查订单历史并更新循环手数系统和连亏暂停机制
CheckOrderHistory();
ObjectSetInteger(0,“GTS_BtnBoth”,OBJPROP_BGCOLOR,directionMode0?clrGold:clrDimGray);
ObjectSetInteger(0,“GTS_BtnLong”,OBJPROP_BGCOLOR,directionMode1?clrGold:clrDimGray);
ObjectSetInteger(0,“GTS_BtnShort”,OBJPROP_BGCOLOR,directionMode==2?clrGold:clrDimGray);
ObjectSetString(0,“GTS_LblEquity”,OBJPROP_TEXT,"净值: "+DoubleToString(AccountEquity(),2));
ObjectSetString(0,“GTS_LblDrawdown”,OBJPROP_TEXT,“回撤: “+DoubleToString(CalculateDrawdown(),1)+”%”);
ObjectSetString(0,“GTS_LblMargin”,OBJPROP_TEXT,“保证金: “+DoubleToString(AccountMargin()/AccountEquity()*100,1)+”%”);
ObjectSetString(0,“GTS_LblWinRate”,OBJPROP_TEXT,“胜率: “+DoubleToString(CalculateWinRate(),1)+”%”);
ObjectSetString(0,“GTS_LblTrades”,OBJPROP_TEXT,"总交易: "+IntegerToString(OrdersHistoryTotal()));
ObjectSetString(0,“GTS_LblStatus”,OBJPROP_TEXT,"状态: "+(tradingEnabled?“运行中”:“已停止”));
ObjectSetString(0,“GTS_LblTime”,OBJPROP_TEXT,"最后交易: "+TimeToString(lastTradeTime));
// 更新指标值
ObjectSetString(0,“GTS_LblADX”,OBJPROP_TEXT,“ADX:”+DoubleToString(adxValue,2));
ObjectSetString(0,“GTS_LblATR”,OBJPROP_TEXT,“ATR%:”+DoubleToString(atrPercent,2));
string trendStatus = “震荡”;
color trendColor = clrSilver;
if(Close[0] > trendMA + TrendThreshold){
trendStatus = “上升趋势”;
trendColor = clrLime;
}
else if(Close[0] < trendMA - TrendThreshold){
trendStatus = “下降趋势”;
trendColor = clrRed;
}
ObjectSetString(0,“GTS_LblMAValue”,OBJPROP_TEXT,“MA:”+DoubleToString(trendMA,2));
ObjectSetString(0,“GTS_LblTrendSignal”,OBJPROP_TEXT,“趋势:”+trendStatus);
ObjectSetInteger(0,“GTS_LblTrendSignal”,OBJPROP_COLOR,trendColor);
// 更新市场状态显示
string stateText;
color stateColor;
switch(marketState) {
case MARKET_STATE_TREND_STRONG:
stateText = “强势趋势”;
stateColor = clrLime;
break;
case MARKET_STATE_RANGE_SOLID:
stateText = “稳固震荡”;
stateColor = clrYellow;
break;
case MARKET_STATE_RANGE_EXTREME:
stateText = “极端震荡(突破前兆)”;
stateColor = clrOrange;
break;
case MARKET_STATE_BREAKOUT_POTENTIAL:
stateText = “突破在即”;
stateColor = clrRed;
break;
default:
stateText = “未知状态”;
stateColor = clrGray;
}
ObjectSetString(0,“GTS_LblMarketState”,OBJPROP_TEXT,"市场状态: "+stateText);
ObjectSetInteger(0,“GTS_LblMarketState”,OBJPROP_COLOR,stateColor);
// 更新循环手数系统信息
ObjectSetString(0,“GTS_LblCycleLot”,OBJPROP_TEXT,“循环手数:”+(EnableCycleLot?“激活”:“关闭”));
ObjectSetInteger(0,“GTS_LblCycleLot”,OBJPROP_COLOR,EnableCycleLot?clrLime:clrRed);
ObjectSetString(0,“GTS_LblCycleStats”,OBJPROP_TEXT,“盈利:”+IntegerToString(cycleWinCount)+" 亏损:"+IntegerToString(cycleLossCount));
ObjectSetString(0,“GTS_LblCurrentLot”,OBJPROP_TEXT,“当前手数:”+DoubleToString(currentCycleLot,2));
// 更新连亏暂停机制信息
ObjectSetString(0,“GTS_LblLossPause”,OBJPROP_TEXT,“连亏暂停:”+(EnableLossPause?“激活”:“关闭”));
ObjectSetInteger(0,“GTS_LblLossPause”,OBJPROP_COLOR,EnableLossPause?clrLime:clrRed);
ObjectSetString(0,“GTS_LblLossStats”,OBJPROP_TEXT,“连亏:”+IntegerToString(consecutiveLossCount)+“/”+IntegerToString(ConsecutiveLosses));
ObjectSetString(0,“GTS_LblPauseStatus”,OBJPROP_TEXT,“暂停状态:”+(isPaused?“是”:“否”));
ObjectSetInteger(0,“GTS_LblPauseStatus”,OBJPROP_COLOR,isPaused?clrRed:clrLime);
// 如果处于暂停状态,显示剩余时间
if(isPaused)
{
int remainingSeconds = PauseMinutes * 60 - (int)(TimeCurrent() - pauseStartTime);
int remainingMinutes = remainingSeconds / 60;
remainingSeconds = remainingSeconds % 60;
ObjectSetString(0,"GTS_LblPauseStatus",OBJPROP_TEXT,"暂停状态:剩余"+IntegerToString(remainingMinutes)+"分"+IntegerToString(remainingSeconds)+"秒");
}
// 更新自动学习系统信息
ObjectSetString(0,“GTS_LblAutoLearning”,OBJPROP_TEXT,“自动学习:”+(EnableAutoLearning?“激活”:“关闭”));
ObjectSetInteger(0,“GTS_LblAutoLearning”,OBJPROP_COLOR,EnableAutoLearning?clrLime:clrRed);
ObjectSetString(0,“GTS_LblMLConfidence”,OBJPROP_TEXT,“置信度:”+DoubleToString(modelConfidence*100,1)+“%”);
ObjectSetString(0,“GTS_LblMLPredictions”,OBJPROP_TEXT,“预测:”+IntegerToString(successfulPredictions)+“/”+IntegerToString(totalPredictions));
ChartRedraw();
}
//±-----------------------------------------------------------------+
//| 公用工具函数 |
//±-----------------------------------------------------------------+
void CreateButton(string name,string text,int x,int y,int w,int h,color bg)
{
string objName = “GTS_”+name;
ObjectCreate(0,objName,OBJ_BUTTON,0,0,0);
ObjectSetInteger(0,objName,OBJPROP_XDISTANCE,x);
ObjectSetInteger(0,objName,OBJPROP_YDISTANCE,y);
ObjectSetInteger(0,objName,OBJPROP_XSIZE,w);
ObjectSetInteger(0,objName,OBJPROP_YSIZE,h);
ObjectSetString(0,objName,OBJPROP_TEXT,text);
ObjectSetInteger(0,objName,OBJPROP_BGCOLOR,bg);
ObjectSetInteger(0,objName,OBJPROP_FONTSIZE,8);
}
void CreateLabel(string name,int x,int y,string text,color clr)
{
string objName = “GTS_”+name;
ObjectCreate(0,objName,OBJ_LABEL,0,0,0);
ObjectSetInteger(0,objName,OBJPROP_XDISTANCE,x);
ObjectSetInteger(0,objName,OBJPROP_YDISTANCE,y);
ObjectSetString(0,objName,OBJPROP_TEXT,text);
ObjectSetInteger(0,objName,OBJPROP_COLOR,clr);
ObjectSetInteger(0,objName,OBJPROP_FONTSIZE,8);
}
void CloseAllTrades()
{
for(int i=OrdersTotal()-1; i>=0; i–){
if(OrderSelect(i,SELECT_BY_POS) && OrderMagicNumber()==MagicNumber){
bool result = OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),3);
if(!result) Print(“平仓失败 错误:”,GetLastError());
}
}
}
void CloseProfitTrades()
{
for(int i=OrdersTotal()-1; i>=0; i–){
if(OrderSelect(i,SELECT_BY_POS) && OrderMagicNumber()==MagicNumber){
if(OrderProfit() > 0){
bool result = OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),3);
if(!result) Print(“平盈利单失败 错误:”,GetLastError());
}
}
}
}
void CloseLossTrades()
{
for(int i=OrdersTotal()-1; i>=0; i–){
if(OrderSelect(i,SELECT_BY_POS) && OrderMagicNumber()==MagicNumber){
if(OrderProfit() < 0){
bool result = OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),3);
if(!result) Print(“平亏损单失败 错误:”,GetLastError());
}
}
}
}
double CalculateDrawdown()
{
return (equityPeak > 0) ? (equityPeak - AccountEquity())/equityPeak*100 : 0;
}
double CalculateWinRate()
{
int total=0, wins=0;
for(int i=0;i<OrdersHistoryTotal();i++){
if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY) && OrderMagicNumber()==MagicNumber){
total++;
if(OrderProfit()>0) wins++;
}
}
return (total>0) ? NormalizeDouble(wins*100.0/total,1) : 0;
}
//±-----------------------------------------------------------------+
//| 事件处理函数 |
//±-----------------------------------------------------------------+
void OnChartEvent(const int id,const long& lparam,const double& dparam,const string& sparam)
{
if(id == CHARTEVENT_OBJECT_CLICK)
{
if(StringFind(sparam, “GTS_”) != 0) return;
string buttonName = StringSubstr(sparam, 4); if(buttonName == "BtnBoth") directionMode=0; else if(buttonName == "BtnLong") directionMode=1; else if(buttonName == "BtnShort") directionMode=2; else if(buttonName == "BtnBuy") ExecuteTrade(OP_BUY, CalculateLotSize(), StopLoss, TakeProfit, 0.5); else if(buttonName == "BtnSell") ExecuteTrade(OP_SELL, CalculateLotSize(), StopLoss, TakeProfit, 0.5); else if(buttonName == "BtnCloseAll") CloseAllTrades(); else if(buttonName == "BtnCloseProfit") CloseProfitTrades(); else if(buttonName == "BtnCloseLoss") CloseLossTrades(); UpdatePanel();
}
}
//±-----------------------------------------------------------------+
//| 定时器事件 |
//±-----------------------------------------------------------------+
void OnTimer()
{
UpdatePanel();
}
//±-----------------------------------------------------------------+
//| 程序卸载函数 |
//±-----------------------------------------------------------------+
void OnDeinit(const int reason)
{
ObjectsDeleteAll(0, “GTS_*”);
EventKillTimer();
}
//±-----------------------------------------------------------------+将以上EA里的趋势判断改为SAR指标,指标设置为 0.01,0.5当SAR位于价格上方则为下降趋势,反之亦然,其他指标全部删除只保留布林带,输出完整版给我