#define MAGICMA 20160610 
//宏定义命令#define用法,定义本EA操作的订单的唯一标识号码,由此可以实现在同一账户上多系统操作,各操作EA的订单标识码不同,就不会互相误操作。凡是EA皆不可缺少,非常非常重要! 
extern double Lots = 0.01; //每单的交易量 
extern double MaximumRisk = 0.02;//本系统最大风险系数,即可以动用总资金的2% 
extern double DecreaseFactor = 3; //下跌因素个数 
extern double MovingPeriod = 20; //均线的计算周期为MA必须的参数之一; 
extern double MovingShift = 0; //均线转移量=6,为MA必须的参数之一; 
//extern 确定从外部程序输入的变量, 会直接显现输入数据窗口。数列本身不能作为外部变量。注意:iMA中的MovingShift(均线偏移量)是指均线指标在图上绘制时向左、右移动的K线个数,主要为了使图中结果更好看,并不会对MA的计算数值产生变化。其中,该参数为正时,代表向右移动;为负值,则代表向左移动。 
//+------------------------------------------------------------------+ 
//| Calculate open positions自定义函数(返回-整数型数据) 仓单查询与统计 | 
//+------------------------------------------------------------------+ 
int CalculateCurrentOrders(string symbol)//函数作用,计算当前持仓单的数量 
{ 
int buys=0,sells=0; 
//定义两个局部变量,整数型,buys——多单数,sells——空单数,用于订单的统计 
//---- 
for(int i=0;i0) return(buys); 
//如果 多单>0,则返回(多单数) 
else return(-sells); 
//否则,返回(-空单数) 
//本函数返回查询计算结束时的持仓单的个数.这种模式返回是假设不存在锁单的。 
} 
//+------------------------------------------------------------------+ 
//| Calculate optimal lot size自定义函数(返回-小数型数据) 资金管理 | 
//+------------------------------------------------------------------+ 
double LotsOptimized()//开仓量计算函数(根据要求计算出订单交易量,小数型) 
{ 
double lot=Lots; //定义局部变量los 小数型 
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); 
//计算 开仓下单量=帐户可用资金*最大风险系数(=2%)/1000.0,并将结果保留小数点1位(通过风险系数的计算获得当前入场单应该采用的交易量,除以1000是因为大多货币对汇价都在这个附近。) 
//---- calcuulate number of losses orders without a break-计算亏损单数目 
 if(DecreaseFactor>0) //如果 下跌因素个数(=3)>0 
{ 
for(int i=orders-1;i>=0;i--) 
//计次循环(i=历史平仓单数-1,到i=0, 递减1) 
{ 
if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)==false) { Print("Error in history!"); 
break; } 
//如果 没有本系统交易记录,输出“无交易历史!” 
if(OrderSymbol()!=Symbol() || OrderType()>OP_SELL) continue; 
//如果 订单的货币对不是当前货币对,或者 订单类型为挂单时,继续运行 
//订单类型为整数型,0-BUY,1-SELL,2-BUYLIMT,3-BUYSTOP,4-SELLLIMT,5-SELLSTOP,其中“>OP_SELL”代表挂单 
if(OrderProfit()>0) break; 
//如果 盈利单数目>0,跳出循环 
if(OrderProfit()1) lot=NormalizeDouble(lot-lot*losses/DecreaseFactor,1); 
//如果 亏损单数>1时,则重新计算下单量,并保留小数点后1位,其计算公式为:下单量=(lot-lot*losses/DecreaseFactor(=3))。 
} 
//---- return lot size-返回下单量 
if(lot1) return; 
//如果当前K线的成交价次数大于1时,返回(不是K线的开盘时间点,即当前k线还没收盘确定,则直接返回;否则,如果是K线第一个成交价,则向下继续运行) 
//---- get Moving Average –获取均线数值 
ma=iMA(NULL,0,MovingPeriod,MovingShift,MODE_SMA,PRICE_CLOSE,0); 
//获取当前以收盘价为基准计算出的均线数值 
//---- sell conditions-卖出条件 
if(Open[1]>ma && Close[1]ma) 
//如果前1根K线上穿均线(即K线的开盘价小于均线值、收盘价大于均线值) 
{ 
res=OrderSend(Symbol(),OP_BUY,LotsOptimized(),Ask,3,0,0,"B",MAGICMA,0,Blue); 
//发送仓单(当前货币对,买入方向,开仓量计算(),卖价,滑点=3,无止损,无止赢,订单编号,标上蓝色箭头) 
return;//返回 
} 
//---- 
} 
//+------------------------------------------------------------------+ 
//| Check for close order conditions 
//自定义函数(无返回值) 平仓策略 | 
//+------------------------------------------------------------------+ 
void CheckForClose()//平仓检查(判断平仓条件及其处理) 
{ 
double ma;//定义局部变量ma小数型 
//---- 只在一个k收盘另一个新出现时交易 
if(Volume[0]>1) return;//如果当前K线的成交价次数>1时,则返回 
//---- get Moving Average //获取均线数值 
ma=iMA(NULL,0,MovingPeriod,MovingShift,MODE_SMA,PRICE_CLOSE,0); 
//获取当前以收盘价为基准计算出的均线数值 
for(int i=0;ima && Close[1]ma) OrderClose(OrderTicket(),OrderLots(),Ask,3,Red); 
//如果第1根K线开盘价上穿均线时(即开盘价低于均价而收盘价高于均价时),则进行空头平仓(仓单编号,持仓数量,卖价,滑点=3,用白色箭头显示) 
break;//跳出循环 
} 
} 
//---- 
} 
//+------------------------------------------------------------------+ 
//| Start function | 
//+------------------------------------------------------------------+ 
void start()//主程序—-每次成交价所驱动的运算过程 
{ 
//---- check for history and trading—对交易历史进行检查 
if(Bars<100 || IsTradeAllowed()==false) return; 
//如果K线数少于100根,或者如果允许智能交易交易=假时,返回 
//---- calculate open orders by current symbol-计算当前货币对的开仓订单 
if(CalculateCurrentOrders(Symbol())==0) CheckForOpen(); 
//如果 计算出当前货币对开仓订单数=0 (即没有仓单),则进行开仓检查。 
else CheckForClose(); 
//否则(即当前已经有仓单时),则进行平仓检查。 
//---- 
} |