利用深度强化学习优化Ilan智能交易系统
概述
在算法交易领域,有些策略宛如金融星空中不灭的恒星,在交易史上留下了深刻的印记。其中,Ilan便是2010年代曾风靡一时的传奇网格智能交易系统(EA)。它以看似简单的逻辑和低波动期潜在的有效性,吸引了无数交易者的注意。
然而,时间从未停滞。在量子计算、神经网络与机器学习主导的新时代,传统策略亟需根本性革新。如果将Ilan网格加仓的经典机制与前沿人工智能(AI)算法相结合,会擦出怎样的火花?假如摒弃硬编码规则,让系统自主适应并持续优化,能否突破瓶颈?
本文旨在颠覆对传统交易模型的认知,我们大胆尝试将深度强化学习与动态Q-table技术融入经典llan,使其具备“自我进化”能力。我们并非简单修改既有代码,而是构建一个能从自身经验中学习、实时适应市场变化并优化交易决策的全新智能模型。
这段探索之旅将带您深入算法交易的迷宫。在这里,数学的严谨与计算的流畅完美融合,创新的机器学习方法让经典的马丁格尔策略焕发新生。无论您是资深算法交易者、交易架构开发者,还是金融科技爱好者,本文都将提供关于自动化交易未来的独特视角。
准备好了吗?我们即将开启llan3.0AI的构建之旅,见证传统与创新的碰撞,看过去的经验如何演化为未来的趋势。
解构经典Ilan的内在逻辑
在踏入AI领域之前,需先理解Ilan在2010年代风靡的核心原因。其核心机制是仓位平均化。当价格反向波动时,EA不会止损离场,而是反向加仓,通过拉低平均入场价实现潜在盈利。
以下简化的代码段说明了这一逻辑:
// Simplified averaging logic in the original Ilan if(positionCount == 0) { // Opening first position on signal if(OpenSignal()) { OpenPosition(ORDER_TYPE_BUY, StartLot); } } else { // Calculating level for averaging double averagePrice = CalculateAveragePrice(); double gridLevel = averagePrice - GridSize * Point(); // If price has reached grid level, add position if(Bid <= gridLevel) { double newLot = StartLot * MathPow(LotMultiplier, positionCount); OpenPosition(ORDER_TYPE_BUY, newLot); } // Checking for closing of all TP positions if(Bid >= averagePrice + TakeProfit * Point()) { CloseAllPositions(); } }
马丁格尔的魔力:交易者为何痴迷于Ilan
Ilan的流行可归因于多重因素。首先,其运作逻辑对新手交易者而言直观易懂。在震荡行情中,该系统展现出近乎神奇的效果——每一次价格波动都转化为盈利来源。通过仓位平均化机制,初始亏损的交易得以"拯救",让交易者产生策略架构无懈可击的错觉。
另一个极具吸引力的特质在于其极简的参数定制功能:
// Key parameters of Ilan Expert Advisor input double StartLot = 0.01; // Initial lot size input double LotMultiplier = 1.5; // Lot multiplier for each new position input int GridSize = 30; // Grid size in points input int TakeProfit = 40; // Profit for closing all positions input int MaxPositions = 10; // Maximum number of positions to open
这种简易的参数配置营造了掌控全局的错觉。交易者可以通过调整不同参数组合,在历史数据回测中收获令人惊叹的成果。
进化之路:Ilan 2.0的革新尝试
在Ilan 2.0版本中,开发者试图解决初代版本的部分缺陷。已添加基于市场波动性的网格步长动态计算、多货币对交易及其相关性分析、新增开仓的条件过滤以及防止过度亏损的保护机制。
// Dynamic calculation of grid step in Ilan 2.0 double CalculateGridStep(string symbol) { double atr = iATR(symbol, PERIOD_CURRENT, ATR_Period, 0); return atr * ATR_Multiplier; } // Protective mechanism to limit losses bool EquityProtection() { double currentEquity = AccountInfoDouble(ACCOUNT_EQUITY); double maxAllowedDrawdown = AccountInfoDouble(ACCOUNT_BALANCE) * MaxDrawdownPercent / 100.0; if(AccountInfoDouble(ACCOUNT_BALANCE) - currentEquity > maxAllowedDrawdown) { CloseAllPositions(); return true; } return false; }
这些改进确实提升了系统的抗风险能力,但未能解决缺乏自适应性的根本问题。Ilan 2.0仍基于静态规则运行,无法从历史经验中学习,更无法适应瞬息万变的市场环境。
为何交易者仍对Ilan趋之若鹜?
尽管缺陷明显,众多交易者仍持续使用Ilan及其变种。这背后存在多重心理诱因。亏损者往往沉默不语,而成功案例却被大肆宣扬。交易者只关注盈利阶段,而忽视风险信号。坚信通过微调参数即可解决所有的问题。马丁格尔策略触发了与赌博相同的心理快感机制。
客观来说,在特定市场条件下(尤其是低波动震荡行情),该EA确实能长期展现惊人的表现。问题在于,市场状态终将改变,而EA却无法随之进化。
Ilan为何不可避免地失控并导致爆仓?
长期运行后,Ilan的致命缺陷暴露无遗。在震荡市中表现完美的策略,面对长期趋势行情时却极具灾难性。以典型的失控场景为例。
首先开立第一个买入仓位。然后市场开始稳步下跌。EA按照指数级增加手数来加仓。经数轮平均后,仓位规模变得如此之大,以至于即使是小幅度的进一步波动也会导致追加保证金通知。
从数学上讲,该问题的表述如下:采用1.5倍倍增系数的马丁格尔策略,初始仓位0.01手时,第10次连续加仓的仓位规模将达0.57手(初始的57倍),所有持仓总和约1.1手。在1000美元账户、1:100杠杆条件下,这相当于使用近全部可用保证金。
// Calculation of total size of martingale positions double totalVolume = 0; double currentLot = StartLot; for(int i = 0; i < MaxPositions; i++) { totalVolume += currentLot; currentLot *= LotMultiplier; } // At StartLot = 0.01 and LotMultiplier = 1.5 after 10 positions // totalVolume will be about 1.1 lots!
核心问题在于缺乏终止平均化策略的判断机制。Ilan如同不知止损的赌徒,在亏损时不断加倍下注,妄图通过一次胜利挽回所有损失。
为何Ilan需要AI?
剖析llan的优劣可知,其致命缺陷在于缺乏自主学习和动态适应能力。无论过往盈亏如何,EA始终机械地执行既定规则。
这正是AI的用武之地。如果我们保留Ilan的基本运行机制,但为其添加分析操作结果并调整策略的功能会怎样?如果我们不用硬编码规则,而是让模型根据积累的经验独立找到最优参数和入场点又会怎样?
这一想法正是我们 Ilan 3.0 AI项目的核心,我们将久经考验的平均策略与先进的机器学习方法相结合。在下一章节中,我们将探讨Q-learning技术如何使这一概念成为现实。
Q-learning将如何改进Ilan EA
从经典Ilan模型向能够学习的智能系统转变,需要从根本上改变EA的架构。Q-learning算法成为Ilan 3.0 AI的核心。它是强化学习领域中最重要的技术之一。
基于您行为的Q-learning基础
Q-learning因"质量函数"而得名,该函数用于确定特定条件下某个操作的价值。在实现中,我们通过维护Q-table这种数据结构,存储每个"状态—操作"对的评分:
// Structure for Q-table struct QEntry { string state; // Discretized state of market int action; // Action (0-nothing, 1-buy, 2-sell) double value; // Q-value }; // Global array for Q-table QEntry QTable[]; int QTableSize = 0;Q-learning的核心特性在于系统具备从自身经验中学习的能力。每次执行操作后,算法会基于获得的奖励(盈利)或惩罚(亏损),动态调整对该操作在特定市场状况下价值的评估:
// Updating Q-value using Bellman formula void UpdateQValue(string stateStr, int action, double reward, string nextStateStr, bool done) { double currentQ = GetQValue(stateStr, action); double nextMaxQ = 0; if(!done) { // Find maximum Q for following state nextMaxQ = GetMaxQValue(nextStateStr); } // Updating Q-value double newQ = currentQ + LearningRate * (reward + DiscountFactor * nextMaxQ - currentQ); // Saving updated value SetQValue(stateStr, action, newQ); }
这一公式被称为贝尔曼方程,是我们方法的核心基石。其中,学习率参数控制每次经验更新的权重,折扣因子则决定未来收益相对于当前收益的重要程度。
探索与利用的平衡之道
强化学习中的关键挑战之一,在于如何平衡探索新策略与利用已知最优解。为解决这一问题,我们采用ε-贪婪策略。
// Choosing action with balance between exploration and exploiting int SelectAction(string stateStr) { // With epsilon probability choose random action (research) if(MathRand() / (double)32767 < currentEpsilon) { return MathRand() % ActionCount; } // Otherwise, choose action with maximum Q-value (exploiting) int bestAction = 0; double maxQ = GetQValue(stateStr, 0); for(int a = 1; a < ActionCount; a++) { double q = GetQValue(stateStr, a); if(q > maxQ) { maxQ = q; bestAction = a; } } return bestAction; }当前ε值(currentEpsilon)参数决定了系统随机选择操作的概率。随着时间的推移,该参数值会逐渐减小,使系统从主动探索新策略转向优先利用已积累的知识:
// Reducing epsilon for a gradual transition from exploration to exploiting if(currentEpsilon > MinExplorationRate) currentEpsilon *= ExplorationDecay;
数字感知:算法如何“读懂”市场
为了有效训练算法,必须赋予其市场“感知”能力,即对当前市场状态建立结构化认知。在Ilan 3.0 AI中,我们采用多维状态向量,其中包括技术指标、持仓数据和其他市场信息:
// Getting current market state for Q-learning void GetCurrentState(string symbol, double &state[]) { ArrayResize(state, StateDimension); // Technical indicators double rsi = iRSI(symbol, PERIOD_CURRENT, RSI_Period, PRICE_CLOSE, 0); double cci = iCCI(symbol, PERIOD_CURRENT, CCI_Period, PRICE_TYPICAL, 0); double macd = iMACD(symbol, PERIOD_CURRENT, 12, 26, 9, PRICE_CLOSE, MODE_MAIN, 0); // Normalization of indicators double normalized_rsi = rsi / 100.0; double normalized_cci = (cci + 500) / 1000.0; // Metrics of positions int positions = (symbol == "EURUSD") ? euroUsdPositions : audUsdPositions; double normalized_positions = (double)positions / MaxTrades; // Calculating price difference double point = SymbolInfoDouble(symbol, SYMBOL_POINT); double currentBid = SymbolInfoDouble(symbol, SYMBOL_BID); double avgPrice = CalculateAveragePrice(symbol); double price_diff = (currentBid - avgPrice) / (100 * point); // Filling in state vector state[0] = normalized_rsi; state[1] = normalized_cci; state[2] = normalized_positions; state[3] = price_diff; state[4] = macd / (100 * point); state[5] = AccountInfoDouble(ACCOUNT_EQUITY) / AccountInfoDouble(ACCOUNT_BALANCE); }为适配Q-table,连续状态值必须进行离散化处理——即将其转换为具有有限选项的字符串表示形式:
// Converting state to string for Q-table string StateToString(double &state[]) { string stateStr = ""; for(int i = 0; i < ArraySize(state); i++) { // Rounding to 2 decimal places for discretization double discretized = MathRound(state[i] * 100) / 100.0; stateStr += DoubleToString(discretized, 2); if(i < ArraySize(state) - 1) stateStr += ","; } return stateStr; }
离散化处理使系统能够通过迁移经验实现泛化——将过往经验应用于相似但非完全相同的市场状况。
激励机制:AI世界的"胡萝卜加大棒"在强化学习系统中,奖励机制的设计至关重要,直接决定了算法的学习效率。在Ilan 3.0AI 中,我们开发了一个多层激励系统,引导算法向正确的方向发展。
奖励经济学:如何激励算法
当以盈利平仓时,模型会获得与盈利金额成正比的正向奖励:
// Reward at closing profitable positions if(shouldClose) { if(ClosePositions(symbol, magic)) { if(isTraining) { double reward = profit; // Reward is equal to profit UpdateQValue(stateStr, action, reward, stateStr, true); // Learning statistics episodeCount++; totalReward += reward; Print(“Episode ", episodeCount, " completed with reward: ", reward, ". Average reward: ", totalReward / episodeCount); } } }当对亏损仓位进行加仓平摊成本时,系统会受到轻微惩罚,以此引导算法寻找最优入场点并规避需要加仓的被动局面:
// Penalty at averaging positions if(OpenPosition(symbol, ORDER_TYPE_BUY, CalculateLot(positionsCount, symbol), StopLoss, TakeProfit, magic)) { if(isTraining) { double reward = -1; // Small penalty for averaging UpdateQValue(stateStr, action, reward, stateStr, false); } }
在首次建仓时未设置即时奖励,迫使系统聚焦长期收益而非短期操作。
模型参数的精细调优
Q-learning系统的效能高度依赖其核心参数的精准配置。在Ilan 3.0 AI中,我们开发了全维度学习参数调优模块:
// Reinforcement learning parameters input double LearningRate = 0.01; // Learning rate input double DiscountFactor = 0.95; // Discount factor input double ExplorationRate = 0.3; // Initial probability of exploration input double ExplorationDecay = 0.995; // Exploration reduction factor input double MinExplorationRate = 0.01;// Minimal probability of exploration
学习率决定Q值的更新速率。Q值较高可加速学习进程,但容易导致策略不稳定。Q值较低虽确保学习稳定性,却会降低收敛速度。
折扣因子权衡未来收益的重要性。值越接近1,模型越倾向于追求长期利润最大化,甚至可能牺牲短期收益。
探索参数调控新策略探索与已知最优解利用之间的平衡。随着时间的推移,探索概率逐步衰减,使得系统逐渐依赖积累的经验进行决策。
从理论到实践:系统实现
Ilan 3.0 AI的实现需将Q-learning机制与传统EA逻辑深度融合。其核心模块为基于Q-learning的交易管理函数,该函数通过以下机制实现决策:// Trade management function using Q-learning void ManagePairWithDQN(string symbol, int &positionsCount, CArrayDouble &trades, int magic, datetime &firstTradeTime) { // Getting current market data double currentBid = SymbolInfoDouble(symbol, SYMBOL_BID); double currentAsk = SymbolInfoDouble(symbol, SYMBOL_ASK); double point = SymbolInfoDouble(symbol, SYMBOL_POINT); // Forming current state double state[]; GetCurrentState(symbol, state); string stateStr = StateToString(state); // Selecting action using Q-table int action = SelectAction(stateStr); // Converting action into trading operation bool shouldTrade = (action > 0); ENUM_ORDER_TYPE orderType = (action == 1) ? ORDER_TYPE_BUY : ORDER_TYPE_SELL; // Logic of opening and managing positions if(shouldTrade) { // Logic of opening first position or averaging // ... } // Checking need to close positions double profit = CalculatePositionsPnL(symbol, magic); if(profit > 0 && positionsCount > 0) { // Logic of closing profitable positions // ... } }
系统经验存储
为了保存积累的经验,我们实现了在会话之间保存和加载Q-table的机制:
// Saving Q-table to file bool SaveQTable(string filename) { int handle = FileOpen(filename, FILE_WRITE|FILE_BIN); if(handle == INVALID_HANDLE) { Print("Error when opening file for writing Q-table: ", GetLastError()); return false; } // Writing table size FileWriteInteger(handle, QTableSize); // Writing values for(int i = 0; i < QTableSize; i++) { FileWriteString(handle, QTable[i].state); FileWriteInteger(handle, QTable[i].action); FileWriteDouble(handle, QTable[i].value); } FileClose(handle); return true; } // Downloading Q-table from file bool LoadQTable(string filename) { if(!FileIsExist(filename)) { Print("Q-table file does not exist: ", filename); return false; } int handle = FileOpen(filename, FILE_READ|FILE_BIN); if(handle == INVALID_HANDLE) { Print("Error when opening file to read Q-table: ", GetLastError()); return false; } // Reading table size int size = FileReadInteger(handle); // Allocating memory for table if(size > ArraySize(QTable)) { ArrayResize(QTable, size); } // Reading values for(int i = 0; i < size; i++) { QTable[i].state = FileReadString(handle); QTable[i].action = FileReadInteger(handle); QTable[i].value = FileReadDouble(handle); QTableSize++; } FileClose(handle); return true; }
让我们考察该EA的测试表现。测试基于15分钟K线图的OHLC建模方法,对2020-2025年期间的AUDUSD和EURUSD货币对进行回测(主测试标的为EURUSD,但EA同时加载了AUDUSD数据作为辅助分析)。

但"全Ticks数据"回测无情地揭示了马丁格尔策略导致的巨额回撤。尽管系统设置了惩罚机制,模型仍会偶尔陷入连续加仓平摊成本的被动局面。未来的版本中,我们计划通过DQN风险管理体系彻底消除此类回撤风险:

需要注意的是,该交易EA采用超大仓位操作,此设计有助于根据经纪商的返佣机制获取佣金。
算法优化方向
尽管Ilan 3.0 AI已实现显著改进,但其仅代表智能交易系统演进的第一步。未来值得探索的优化路径包括:
- 将Q-table替换为完备的神经网络架构,提升策略对市场模式的泛化能力
- 实现深度强化学习(DQN、DDPG、PPO)算法
- 采用元学习技术,构建快速适应市场状况的机制
- 整合新闻事件与基本面分析架构
结论
llan3.0Al的问世,标志着算法交易方式的根本变革。我们正走出基于固定规则的静态系统,迈向具备自主学习与进化能力的自适应算法新时代。
通过经典Ilan策略与现代机器学习的融合,为交易系统的开发开辟了新天地。不再局限于无休止的参数调优,我们构建的系统能够自主探索最优策略,并适应变化的市场状况。
算法交易的未来,在于将久经考验的交易策略与创新的Al技术深度融合。Ilan 3.0 AI不仅是经典EA的升级版,更是开创了全新的智能交易系统类别 —— 此类系统能够与市场同步学习、自适应进化并持续发展。
我们正站在算法交易新时代的门槛上 —— 一个模型不再机械地执行预设的规则,而是通过持续进化,在瞬息万变的金融市场中自主探寻最优策略。
本文由MetaQuotes Ltd译自俄文
原文地址: https://www.mql5.com/ru/articles/17455
注意: MetaQuotes Ltd.将保留所有关于这些材料的权利。全部或部分复制或者转载这些材料将被禁止。
本文由网站的一位用户撰写,反映了他们的个人观点。MetaQuotes Ltd 不对所提供信息的准确性负责,也不对因使用所述解决方案、策略或建议而产生的任何后果负责。
MQL5 交易策略自动化(第二十七部分):创建带可视化反馈的价格行为螃蟹谐波形态
新手在交易中的10个基本错误
价格行为分析工具包开发(第三十六部分):实现Python直接读取MetaTrader 5行情数据流
目前只是粗略浏览了一下——乍一看这篇文章——太棒了!
得仔细观察并比较不同符号——哪些更适合伊拉诺的“训练”,哪些则不太适合!!!
马丁欠了很多人的人情……
能获得一款具有发展前景的先进产品,这将是一件很有意思的事。
你好,叶夫根尼,
CalculateAveragePrice(symbol) 的代码在哪里?
另外,如何预先计算两个或多个仓位平均价格的止损(SL)和止盈(TP)?
谢谢,萨比诺。