当前位置: > 财经>正文

MT4 EA编程入门,自带移动平均线策略,代码解析与回测 外汇平仓策略

2023-08-15 01:51:35 互联网 未知 财经

:

 

mt4软件自带两个ea交易策略,macd和moving average(ma),这里解析的是ma。

一、策略思路

K线上穿均线时,如果无仓,则开多仓,如果有空仓,则平仓;

K线下穿均线时,如果无仓,则开空仓,如果有多仓,则平仓。

二、代码解析

//双斜线后为注释内容,对程序执行没影响。注:绿色字体为我的注释,黑色注释为原程序自带。

#define MAGICMA 20230201//全局标识,用于区分该策略与别的策略,在对单子进行筛选时会用到,确保该策略不会操作其它策略的单子

//--- Inputs(输入变量,这些变量允许用户输入,也可以加载、保存,如下图所示)

 

input double Lots =0.1;//下单手数

input double MaximumRisk =0.02;//可用的最大资金比例2%

input double DecreaseFactor=3;//作者自己定义的数据,通过下文可以看到,影响下单量

input int MovingPeriod =12;//移动平均线周期

input int MovingShift =6;//均线向左的偏移量

//| Calculate open positions |

//计算当前开单的数量,包括买单和卖单,不考虑锁单的情况,只有买单、卖单、空仓三种情况

int CalculateCurrentOrders(string symbol)

{

int buys=0,sells=0;(初始化买单数和卖单数为0)

for(int i=0;i

if(OrderType()==OP_BUY) buys++;

if(OrderType()==OP_SELL) sells++;

//订单类型为整数型,0-BUY,1-SELL,2-BUYLIMT,3-BUYSTOP,4-SELLLIMT,5-SELLSTOP,下文中还会用到“>OP_SELL”代表挂单

}

}

if(buys>0) return(buys);

else return(-sells);

(如果买单数大于0,返回买单数,否则返回卖单数的负数,如果空仓就会返回0。)

}

//| Calculate optimal lot size |//计算下单的数量

double LotsOptimized()

{

double lot=Lots;

int orders=HistoryTotal(); // history orders total

int losses=0; // number of losses orders without a break亏损的单量

//--- select lot size

lot=NormalizeDouble(AccountFreeMargin()*MaximumRisk/1000.0,1);

//--- calcuulate number of losses orders without a break

if(DecreaseFactor>0)

{

for(int i=orders-1;i>=0;i--)

{

if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)==false)

{

Print("Error in history!");

break;

}

if(OrderSymbol()!=Symbol() || OrderType()>OP_SELL)

continue;

//---当不是买单和卖单时(比如挂单),继续

if(OrderProfit()>0) break;

if(OrderProfit()1)

lot=NormalizeDouble(lot-lot*losses/DecreaseFactor,1);

//修正下单量, 如果 亏损单数>1时,则重新计算下单量,并保留小数点后1位,其计算公式为:下单量=(lot-lot*losses/DecreaseFactor(=3))。

}

//--- return lot size

if(lot

res=OrderSend(Symbol(),OP_SELL,LotsOptimized(),Bid,3,0,0,"",MAGICMA,0,Red);

// 发送仓单(当前货币对,卖出方向,开仓量计算(),买价,滑点=3,无止损,无止赢,订单编号,标上红色箭头)

return;

}

//--- buy conditions

if(Open[1]ma)

// 如果前1根K线上穿均线(即K线的开盘价小于均线值、收盘价大于均线值)

{

res=OrderSend(Symbol(),OP_BUY,LotsOptimized(),Ask,3,0,0,"",MAGICMA,0,Blue);

// 发送仓单(当前货币对,买入方向,开仓量计算(),卖价,滑点=3,无止损,无止赢,订单编号,标上蓝色箭头)

return;

}

}

//| Check for close order conditions |(平仓函数)

void CheckForClose()

{

double ma;

//--- go trading only for first tiks of new bar

if(Volume[0]>1) return;

//--- get Moving Average

ma=iMA(NULL,0,MovingPeriod,MovingShift,MODE_SMA,PRICE_CLOSE,0);

//---

for(int i=0;i

if(Open[1]>ma && Close[1]

if(Open[1]ma)

{

if(!OrderClose(OrderTicket(),OrderLots(),Ask,3,White))

// 如果第1根K线开盘价上穿均线(即开盘价低于均价而收盘价高于均价),则进行空头平仓(仓单编号,持仓数量,卖价,滑点=3,用白色箭头显示)

Print("OrderClose error ",GetLastError());

}

break;

}

}

}

//| OnTick function |(循环函数,每更新一次数据执行一次函数)

void OnTick()

{

//--- check for history and trading

if(Bars

版权声明: 本站仅提供信息存储空间服务,旨在传递更多信息,不拥有所有权,不承担相关法律责任,不代表本网赞同其观点和对其真实性负责。如因作品内容、版权和其它问题需要同本网联系的,请发送邮件至 举报,一经查实,本站将立刻删除。