MT4 EA编程模板

这里 https://www.earnforex.com/metatrader-expert-advisors/expert-advisor-template/ 有一个 EA 编程模板,注释也很全,定义了相关状态的枚举,没有使用魔数。

OnTick 函数:

//The OnTick function is triggered every time MT4 receives a price change for the symbol in the chart
void OnTick(){
   //Re-initialize the values of the global variables at every run
   InitializeVariables();
   //ScanOrders scans all the open orders and collect statistics, if an error occurs it skips to the next price change
   if(!ScanOrders()) return;
   //CheckNewBar checks if the price change happened at the start of a new bar
   CheckNewBar();
   //CheckOperationHours checks if the current time is in the operating hours
   CheckOperationHours();
   //CheckSpread checks if the spread is above the maximum spread allowed
   CheckSpread();
   //CheckTradedThisBar checks if there was already a trade executed in the current candle
   CheckTradedThisBar();
   //EvaluateExit contains the code to decide if there is an exit signal
   EvaluateExit();
   //ExecuteExit executes the exit in case there is an exit signal
   ExecuteExit();
   //Scan orders again in case some where closed, if an error occurs it skips to the next price change
   if(!ScanOrders()) return;
   //Execute Trailing Stop
   ExecuteTrailingStop();
   //EvaluateEntry contains the code to decide if there is an entry signal
   EvaluateEntry();
   //ExecuteEntry executes the entry in case there is an entry signal
   ExecuteEntry();
}
  • 首先,重新初始化全局变量的值。
  • 然后,扫描所有已开立的订单并收集统计数据。如果出现错误,跳过到下一个价格变动。
  • 检查价格变动是否发生在新的K线(蜡烛)开始时。
  • 检查当前时间是否在交易操作时间范围内。
  • 检查当前的点差是否超过允许的最大点差。
  • 检查当前K线内是否已经执行了交易。
  • 根据特定的条件判断是否存在退出信号。
  • 如果存在退出信号,执行退出操作。
  • 再次扫描订单,以防有订单被关闭。如果出现错误,跳过到下一个价格变动。
  • 执行追踪止损操作。
  • 根据特定的条件判断是否存在入场信号。
  • 如果存在入场信号,执行入场操作。

EvaluateEntry 函数

//Evaluate if there is an entry signal
void EvaluateEntry(){
   SignalEntry=SIGNAL_ENTRY_NEUTRAL;
   //if(!IsSpreadOK) return;    //If the spread is too high don't give an entry signal
   //if(UseTradingHours && !IsOperatingHours) return;      //If you are using trading hours and it's not a trading hour don't give an entry signal
   //if(!IsNewCandle) return;      //If you want to provide a signal only if it's a new candle opening
   //if(IsTradedThisBar) return;   //If you don't want to execute multiple trades in the same bar
   //if(TotalOpenOrders>0) return; //If there are already open orders and you don't want to open more

   //This is where you should insert your Entry Signal for BUY orders
   //Include a condition to open a buy order, the condition will have to set SignalEntry=SIGNAL_ENTRY_BUY

   //This is where you should insert your Entry Signal for SELL orders
   //Include a condition to open a sell order, the condition will have to set SignalEntry=SIGNAL_ENTRY_SELL
}
  1. EvaluateEntry 函数:此函数用于判断是否存在入场信号。
  2. 函数内部的逻辑:
    • 首先,将 SignalEntry 设置为中性(SIGNAL_ENTRY_NEUTRAL)。
    • 然后,根据一系列条件判断是否应该提供入场信号:
      • 如果点差过高,不提供入场信号。
      • 如果使用交易时间限制且当前不在交易时间内,不提供入场信号。
      • 如果不是新的K线(蜡烛)开盘,不提供入场信号。
      • 如果当前K线内已经执行了交易,不提供入场信号。
      • 如果已经存在其他开放订单且不希望再开立更多订单,不提供入场信号。
    • 在注释中,作者提醒您在以下位置插入具体的入场信号逻辑:
      • 对于买入订单,设置 SignalEntry=SIGNAL_ENTRY_BUY
      • 对于卖出订单,设置 SignalEntry=SIGNAL_ENTRY_SELL

LotsOptimized 函数

double LotsOptimized()
{
    if (!MM) return (Lots);

   double Size, RiskMoney, PositionSize = 0;

   if (AccountCurrency() == "") return(0);

   if (FixedBalance > 0)
   {
      Size = FixedBalance;
   }
   else if (UseEquityInsteadOfBalance)
   {
      Size = AccountEquity();
   }
   else
   {
      Size = AccountBalance();
   }

   if (!UseMoneyInsteadOfPercentage) RiskMoney = Size * Risk / 100;
   else RiskMoney = MoneyRisk;

   double UnitCost = MarketInfo(Symbol(), MODE_TICKVALUE);
   double TickSize = MarketInfo(Symbol(), MODE_TICKSIZE);

   if ((StopLoss != 0) && (UnitCost != 0) && (TickSize != 0)) PositionSize = NormalizeDouble(RiskMoney / (StopLoss * UnitCost / TickSize), LotDigits);

   if (PositionSize < MarketInfo(Symbol(), MODE_MINLOT)) PositionSize = MarketInfo(Symbol(), MODE_MINLOT);
   else if (PositionSize > MarketInfo(Symbol(), MODE_MAXLOT)) PositionSize = MarketInfo(Symbol(), MODE_MAXLOT);

   return(PositionSize);
} 
  1. 首先,这是一个函数定义,名为LotsOptimized
  2. 函数内部的逻辑如下:
    • 如果不使用资金管理(MM),则直接返回已设定的交易手数(Lots)。
    • 否则,根据不同情况计算交易手数:
      • 如果账户货币为空,返回0。
      • 如果设置了固定余额(FixedBalance),则使用该余额。
      • 否则,如果选择使用权益而不是余额(UseEquityInsteadOfBalance),则使用账户权益(AccountEquity())。
      • 否则,使用账户余额(AccountBalance())。
    • 根据风险管理设置计算风险金额(RiskMoney):
      • 如果不使用资金百分比而是直接使用金额(UseMoneyInsteadOfPercentage),则使用预设的风险金额(MoneyRisk)。
      • 否则,根据账户大小和风险百分比计算风险金额。
    • 获取交易品种的单价(UnitCost)和最小价格变动(TickSize)。
    • 如果设置了止损(StopLoss)且单价和价格变动不为零,则计算交易手数(PositionSize):
      • 根据风险金额、止损点数和价格变动计算交易手数。
      • 确保交易手数不低于最小手数(MODE_MINLOT)且不高于最大手数(MODE_MAXLOT)。
    • 返回计算得到的交易手数。
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇