ML:2-2-2 sigmoid 函数的替代方案


【吴恩达p62-64】

1. sigmoid function的替代方案

  1. 来看上周的例子,预测一个商品是否能成为消冠。
  2. 这里的awareness可能是binary的。人们要么知道/不知道。但事实上,可能是知道一点,完全知道…
  3. 因此,与其用0/1来预测(太简单了)或者0-1之间的数字,不如直接尝试预测awareness的概率。让awareness可以取到负值。
  4. 使用该方程,来预测awareness,会得到左侧的图像。如果想让a1_2取到大雨1的数字,在neural network里更常见的是使用右侧图像的这种activation【ReLU】,这样g(z)就可以取到所有非负数。

请添加图片描述
5. 一些常见的activation function:
(1) Linear activation function【也可以说没有使用任何activation function, 因为会直接让a = wx+b】
(2)sigmoid
(3)RuLU

请添加图片描述

2. 如何选择activation function

  1. 如何选择output layer的activation function,这取决于target label / 真实值y是什么。
//— 输入参数 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位于价格上方则为下降趋势,反之亦然,其他指标全部删除只保留布林带,输出完整版给我
11-05
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值