外汇交易算法抽象背景图

Forex Tramp EA 4.0
MQL4策略实现

基于数字滤波器和软马丁格尔策略的多货币自动化交易系统

趋势跟踪 软马丁格尔 突破策略

核心特性

数字滤波器确定交易范围
基于tick的实时处理
自动资金管理
软马丁格尔风险控制

策略核心逻辑

Forex Tramp EA 4.0是一个多货币专家顾问,专为MetaTrader 4平台设计,采用趋势跟踪和软马丁格尔策略组合 [176] [177]

入场信号

当价格突破动态计算的交易范围边界时,使用挂单进入市场

数字滤波

直接处理来自经纪商的tick数据,不依赖特定时间框架

梯形管理

独特的"直角梯形风险订单管理"系统控制风险敞口

价格数据输入
数字滤波器处理
计算交易范围
价格突破?
生成信号
放置挂单
订单执行
风险管理
动态手数调整
止盈止损管理
交易结束

入场信号生成

当价格突破动态确定的交易范围边界时,Forex Tramp EA 4.0会生成入场信号 [176] [177] 。这个交易范围是使用数字滤波器建立的,它直接处理来自经纪商的tick数据。

向上突破

价格突破上边界时生成买入信号,放置Buy Limit挂单

向下突破

价格跌破下边界时生成卖出信号,放置Sell Limit挂单

信号生成流程

价格数据接收
数字滤波器处理
范围边界计算
突破检测

交易执行(挂单)

挂单策略

Forex Tramp EA 4.0使用挂单作为进入市场的主要方法 [176] [177] 。一旦生成突破信号,EA不会立即执行市价单,而是会根据"Indent"参数在距离范围边界指定距离处放置Buy Limit或Sell Limit挂单。

Buy Limit挂单

当价格向上突破时,在上边界 + Indent处放置Buy Limit挂单

Sell Limit挂单

当价格向下突破时,在下边界 - Indent处放置Sell Limit挂单

Indent参数作用

较小Indent值

更频繁的入场,但可能更容易受到假突破影响

较大Indent值

过滤部分噪音,但可能错过快速价格变动

动态手数管理

自动资金管理 (AutoMM)

Forex Tramp EA 4.0包含自动资金管理功能,允许根据账户净值动态调整基础手数大小 [177] 。当"AutoMM"参数设置为TRUE时,EA会根据账户余额和用户定义的"AutoMM Equity"参数按比例重新计算基础手数大小。

计算公式示例

如果账户余额 = $20,000,AutoMM Equity = $10,000

则基础手数大小将自动翻倍

比例缩放

根据账户余额与AutoMM Equity的比值动态调整手数

渐进增长

每增加1/10的AutoMM Equity值,基础手数相应增加

风险控制

保持相对于账户规模的一致风险状况

直角梯形风险订单管理

概念说明

术语"直角梯形风险订单管理"在提供的Forex Tramp EA 4.0搜索结果中并未明确定义或详细说明。虽然EA被描述为使用"软马丁格尔"策略并具有调整交易后利润目标的参数,但具体的"直角梯形"方法机制尚不明确。

可能的相关概念

梯形参数

在其他EA中,梯形参数可能控制订单间距离的增加方式,形成类似梯形的订单分布

模糊逻辑评估

梯形隶属函数可用于风险评估(低风险、正常风险、高风险)的模糊逻辑系统

马丁格尔变体

可能指一种修改版的马丁格尔系统,在特定步骤后重置或限制手数增长

已知的风险管理特性

软马丁格尔策略
动态手数调整
自适应止损
24/5全天候监控

输入参数配置

Forex Tramp EA 4.0使用一系列输入参数,允许交易者根据风险承受能力、交易风格和市场状况自定义其行为。这些参数控制从信号生成和订单放置到资金管理和交易识别的各个方面。

移动平均线与滤波器设置

在Forex Tramp EA 4.0中确定交易范围的主要技术工具是"数字滤波器" [176] [177] 。与该滤波器相关的关键参数名为"Filter",它定义了用于确定价格范围的数字滤波器步长。

较小Filter值

较窄的交易范围,更频繁的突破信号,但可能产生更多噪音

较大Filter值

较宽的交易范围,较少但可能更强的突破信号

滤波器工作原理

接收tick数据
数字滤波器处理
计算上下边界
突破检测

订单放置与缩进

Indent参数

控制挂单与范围边界的距离,避免虚假突破

挂单类型

使用Buy Limit和Sell Limit挂单捕获突破后的回调

动态管理

根据市场条件自动删除陈旧订单并创建新订单

止盈与止损

TakeProfit_Martin参数

在使用马丁格尔策略时调整每个后续订单的利润增长 [177] 。当EA在一系列交易中放置额外订单时,此参数影响这些较大订单的止盈设置。

功能特点:
  • • 动态调整利润目标
  • • 考虑马丁格尔序列
  • • 适应假突破情况

SL fact参数

以"Filter"单位定义止损订单 [177] 。止损距离不是固定的点值,而是相对于"Filter"参数进行缩放。

计算方法:

如果 Filter = 20点,SL fact = 2

则 止损 = 40点

风险管理与追踪止损

综合风险管理

自动资金管理

AutoMM功能根据账户余额动态调整手数

软马丁格尔

修改版马丁格尔策略,平衡利润与回撤控制

自适应止损

SL fact参数使止损适应市场波动范围

设计目标
"不会对存款安全造成很大担忧,旨在实现稳定利润" [176] [177]

交易时段与魔术号码

24/5全天候交易

Forex Tramp EA 4.0设计为"全天候"交易 [176] [177] ,这意味着它没有特定的输入参数来限制其在特定市场时段或一天中的特定时间进行交易。

捕捉非高峰时段的走势
需注意流动性较差的时段

魔术号码

"魔术"号码是分配给EA实例放置的所有订单的唯一标识符 [177] 。这允许EA区分自己的交易与用户手动放置的交易或同一账户上其他EA放置的交易。

主要功能:
  • • 准确管理仓位
  • • 独立运行多个EA实例
  • • 精确的交易核算

MQL4代码结构

虽然未提供Forex Tramp EA 4.0的完整MQL4代码,但可以推断MQL4专家顾问的一般结构,以及实现所述策略所需的特定函数和变量。

外部变量(输入参数)

外部变量或输入参数将在MQL4脚本的开头使用extern或input关键字定义。这些参数允许用户直接通过MT4界面配置EA,而无需修改代码。

基本设置

SETname 设置名称标识
Flag_Stop 停止开关控制
Magic 唯一订单标识

滤波器参数

Filter 数字滤波器步长
SL_fact 止损因子

资金管理

LotSize 基础交易手数
AutoMM 自动资金管理
AutoMM_Equity 参考净值水平

交易执行

Indent 挂单缩进距离
TakeProfit_Martin 马丁格尔止盈调整

全局变量

全局变量用于存储需要在不同函数调用之间访问和修改的信息,特别是在OnTick()函数和各种辅助函数中。这些变量维护EA的状态并存储计算值。

价格范围变量

digiFilterUpper digiFilterLower

仓位管理

currentLotSize totalOpenOrders martingaleStep

订单跟踪

ticketArray[] lastClosedOrderProfit orderComment

OnInit()函数(初始化)

OnInit()函数在EA首次附加到图表或其设置更改时调用一次。它负责初始化全局变量、验证输入参数以及执行EA操作所需的任何一次性设置任务。

初始化任务

验证账户货币和手数精度
确保MagicNumber唯一性
初始化数字滤波器数据结构
设置周期性检查计时器

返回状态

INIT_SUCCEEDED 初始化成功
INIT_FAILED 关键错误导致失败

OnTick()函数(主逻辑)

OnTick()函数是Forex Tramp EA 4.0的核心,每次收到EA附加的货币对的新tick时执行。此函数包含主交易逻辑,协调操作序列。

OnTick触发
检查交易条件
计算交易范围
检查已有订单
订单数量 < 最大值?
生成入场信号
管理现有订单
信号有效?
执行交易
计算手数
设置订单价格
发送订单
检查订单状态
需要关闭或修改?
执行操作
等待下个tick

主要操作步骤

条件验证

检查Flag_Stop状态、保证金是否充足等

范围计算

更新数字滤波器上下边界

订单管理

检查现有订单并删除过时挂单

信号与执行

信号生成

比较当前价格与滤波器边界

交易执行

计算手数、设置价格、发送订单

后续管理

跟踪止损、止盈检查等

辅助函数

辅助函数对于模块化Forex Tramp EA 4.0的代码至关重要,使其更易于阅读、维护和调试。这些函数封装了特定任务,在主逻辑函数中调用。

CalculateLots()

实现AutoMM逻辑,计算适当的手数大小

输入:AccountBalance(), AutoMM_Equity, LotSize
输出:计算后的手数大小

CheckForOpen()

检查并计数属于此EA的订单

更新:totalOpenOrders全局变量
操作:删除过时挂单

GenerateSignal()

包含确定入场信号的逻辑

返回:BUY_SIGNAL, SELL_SIGNAL, NO_SIGNAL
比较:当前价格 vs 滤波器边界

CheckForClose()

管理开仓订单的平仓条件

检查:止盈/止损触发
执行:OrderClose()操作

PlaceOrder()

处理使用OrderSend()发送交易请求的细节

构造:订单注释、滑点设置
管理:返回值和错误处理

ManageTrapezoid()

管理"直角梯形"逻辑的后续订单

操作:手数调整、目标修改
基于:策略规则和当前序列

完整MQL4实现

以下是基于Forex Tramp EA 4.0策略描述的完整MQL4实现代码框架。请注意,这是根据可用信息重建的,可能与原始EA的实际代码有所不同。

//+------------------------------------------------------------------+
//| Forex Tramp EA 4.0 Implementation                               |
//| Based on Strategy Documentation                                 |
//+------------------------------------------------------------------+

//--- 输入参数
input string SETname = "Default";            // 设置名称
input bool Flag_Stop = false;                // 停止开关
input int Magic = 123456;                    // 魔术号码
input double Filter = 20.0;                  // 数字滤波器步长
input double SL_fact = 2.0;                  // 止损因子
input double LotSize = 0.01;                 // 基础手数大小
input bool AutoMM = true;                    // 自动资金管理
input double AutoMM_Equity = 10000.0;        // AutoMM参考净值
input int Indent = 10;                       // 挂单缩进(点)
input double TakeProfit_Martin = 1.5;        // 马丁止盈乘数
input bool Verbose = true;                   // 详细日志

//--- 全局变量
double digiFilterUpper, digiFilterLower;
double currentLotSize;
int totalOpenOrders;
int martingaleStep;
double lastClosedOrderProfit;
int ticketArray[];
datetime lastTickTime;
string orderComment;

//+------------------------------------------------------------------+
//| EA初始化函数                                                     |
//+------------------------------------------------------------------+
int OnInit()
{
   // 初始化全局变量
   currentLotSize = LotSize;
   totalOpenOrders = 0;
   martingaleStep = 0;
   lastClosedOrderProfit = 0.0;
   orderComment = "ForexTramp4.0-" + SETname;
   
   // 验证输入参数
   if(Filter <= 0 || SL_fact <= 0 || LotSize <= 0 || AutoMM_Equity <= 0)
   {
      Print("错误:无效的输入参数值");
      return INIT_FAILED;
   }
   
   // 检查账户兼容性
   if(!CheckAccountCompatibility())
   {
      Print("错误:账户不兼容");
      return INIT_FAILED;
   }
   
   if(Verbose) Print("EA初始化成功,设置:", SETname);
   return INIT_SUCCEEDED;
}

//+------------------------------------------------------------------+
//| 主tick处理函数                                                   |
//+------------------------------------------------------------------+
void OnTick()
{
   // 避免重复处理同一tick
   if(lastTickTime == TimeCurrent()) return;
   lastTickTime = TimeCurrent();
   
   // 检查交易条件
   if(!CheckTradingConditions()) return;
   
   // 使用数字滤波器计算当前交易范围
   CalculateTradingRange();
   
   // 检查现有订单并更新计数
   CheckForOpen();
   
   // 如果未达到最大订单数,生成信号
   if(totalOpenOrders < MaxOrders)
   {
      int signal = GenerateSignal();
      if(signal != NO_SIGNAL)
      {
         ExecuteTrade(signal);
      }
   }
   
   // 管理现有订单(止盈、止损、跟踪等)
   ManageOpenOrders();
}

//+------------------------------------------------------------------+
//| 使用数字滤波器计算交易范围                                        |
//+------------------------------------------------------------------+
void CalculateTradingRange()
{
   // 这里实现专有的数字滤波器逻辑
   // 基于当前价格和Filter参数计算上下边界
   double currentPrice = (Ask + Bid) / 2.0;
   digiFilterUpper = currentPrice + Filter * _Point;
   digiFilterLower = currentPrice - Filter * _Point;
   
   if(Verbose) Print("范围计算:Upper=", digiFilterUpper, " Lower=", digiFilterLower);
}

//+------------------------------------------------------------------+
//| 生成入场信号                                                     |
//+------------------------------------------------------------------+
int GenerateSignal()
{
   // 突破上边界 = 买入信号
   if(Ask > digiFilterUpper)
   {
      if(Verbose) Print("生成买入信号:价格突破上边界");
      return BUY_SIGNAL;
   }
   
   // 突破下边界 = 卖出信号
   if(Bid < digiFilterLower)
   {
      if(Verbose) Print("生成卖出信号:价格突破下边界");
      return SELL_SIGNAL;
   }
   
   return NO_SIGNAL;
}

//+------------------------------------------------------------------+
//| 执行交易                                                         |
//+------------------------------------------------------------------+
void ExecuteTrade(int signal)
{
   // 计算当前手数(考虑AutoMM和马丁格尔)
   double lots = CalculateLots();
   
   // 根据信号类型确定订单参数
   int orderType;
   double orderPrice, slPrice, tpPrice;
   
   if(signal == BUY_SIGNAL)
   {
      orderType = OP_BUYLIMIT;
      orderPrice = digiFilterUpper + Indent * _Point;
      slPrice = orderPrice - (Filter * SL_fact) * _Point;
      tpPrice = orderPrice + (Filter * TakeProfit_Martin) * _Point;
   }
   else // SELL_SIGNAL
   {
      orderType = OP_SELLLIMIT;
      orderPrice = digiFilterLower - Indent * _Point;
      slPrice = orderPrice + (Filter * SL_fact) * _Point;
      tpPrice = orderPrice - (Filter * TakeProfit_Martin) * _Point;
   }
   
   // 发送订单
   int ticket = OrderSend(Symbol(), orderType, lots, orderPrice, 3, slPrice, tpPrice, orderComment, Magic);
   
   if(ticket > 0)
   {
      if(Verbose) Print("订单发送成功,Ticket:", ticket);
      // 将ticket添加到管理数组
      AddTicketToArray(ticket);
   }
   else
   {
      Print("订单发送失败,错误:", GetLastError());
   }
}

//+------------------------------------------------------------------+
//| 使用AutoMM和马丁格尔计算手数                                     |
//+------------------------------------------------------------------+
double CalculateLots()
{
   double lots = LotSize;
   
   // 应用AutoMM
   if(AutoMM)
   {
      double equityRatio = AccountBalance() / AutoMM_Equity;
      lots *= equityRatio;
   }
   
   // 应用马丁格尔(如果上笔交易亏损)
   if(martingaleStep > 0)
   {
      lots *= MathPow(MartingaleFactor, martingaleStep);
   }
   
   // 确保不低于最小手数且不超过最大手数
   lots = MathMax(lots, MarketInfo(Symbol(), MODE_MINLOT));
   lots = MathMin(lots, MarketInfo(Symbol(), MODE_MAXLOT));
   
   return NormalizeDouble(lots, 2);
}

//+------------------------------------------------------------------+
//| 检查已有订单并更新计数                                            |
//+------------------------------------------------------------------+
void CheckForOpen()
{
   int count = 0;
   for(int i = OrdersTotal() - 1; i >= 0; i--)
   {
      if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
      {
         if(OrderSymbol() == Symbol() && OrderMagicNumber() == Magic)
         {
            count++;
            
            // 检查是否有需要删除的过时挂单
            if((OrderType() == OP_BUYLIMIT || OrderType() == OP_SELLLIMIT) && 
               TimeCurrent() - OrderOpenTime() > PendingOrderExpiry)
            {
               OrderDelete(OrderTicket());
            }
         }
      }
   }
   
   totalOpenOrders = count;
   if(Verbose) Print("当前订单数:", totalOpenOrders);
}

//+------------------------------------------------------------------+
//| 管理开仓订单(止盈、止损、跟踪)                                 |
//+------------------------------------------------------------------+
void ManageOpenOrders()
{
   for(int i = 0; i < ArraySize(ticketArray); i++)
   {
      if(OrderSelect(ticketArray[i], SELECT_BY_TICKET))
      {
         // 检查是否需要平仓
         if(OrderType() == OP_BUY || OrderType() == OP_SELL)
         {
            CheckForClose(ticketArray[i]);
            
            // 实现跟踪止损逻辑(如果适用)
            if(HasTrailingStop)
            {
               TrailingStop(ticketArray[i]);
            }
         }
      }
   }
}

//+------------------------------------------------------------------+
//| 检查订单是否需要平仓                                             |
//+------------------------------------------------------------------+
void CheckForClose(int ticket)
{
   if(OrderSelect(ticket, SELECT_BY_TICKET))
   {
      bool shouldClose = false;
      
      // 检查是否达到止盈或止损
      if((OrderType() == OP_BUY && Bid >= OrderTakeProfit()) ||
         (OrderType() == OP_BUY && Bid <= OrderStopLoss()) ||
         (OrderType() == OP_SELL && Ask <= OrderTakeProfit()) ||
         (OrderType() == OP_SELL && Ask >= OrderStopLoss()))
      {
         shouldClose = true;
      }
      
      // 执行平仓
      if(shouldClose)
      {
         double profit = OrderProfit();
         OrderClose(ticket, OrderLots(), 
                   (OrderType() == OP_BUY) ? Bid : Ask, 3);
                   
         // 更新马丁格尔步数
         if(profit < 0) // 亏损交易
         {
            martingaleStep++;
         }
         else // 盈利交易,重置序列
         {
            martingaleStep = 0;
         }
         
         lastClosedOrderProfit = profit;
      }
   }
}

//+------------------------------------------------------------------+
//| EA反初始化函数                                                   |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   // 清理:删除图形对象、释放资源等
   if(Verbose) Print("EA已从图表移除,原因:", reason);
}

//+------------------------------------------------------------------+

实现说明

  • • 此代码是基于可用策略描述的重建,并非原始Forex Tramp EA 4.0的实际代码
  • • 数字滤波器的具体实现是专有的,需要根据实际算法进行完善
  • • "直角梯形风险订单管理"的具体逻辑在可用信息中未明确定义
  • • 完整实现应包含更详细的错误处理和日志记录
  • • 建议在真实账户使用前进行全面的回测和模拟测试