做了一个2个EMA交叉的EA,需要建议

 

你好!我是mql 4的新手。

我是mql 4的新手,我做了一个简单的2 EMA交叉顾问,我已经在模拟账户 上测试过了,但有点害怕在真实账户上使用它。

在1小时范围内用小手测试它需要太多的时间,而在分钟范围内测试它是昂贵的,因为我的经纪人的最小手数大约是7美元。

所以,如果您能看一下,并指出一些我可能犯的明显错误,我将非常感激。

这个顾问应该在比特币/美元市场上进行交易,这个市场是非常不稳定的(价格可以在一天内+ - 30%),所以止损和止盈不是以点为单位,而是以买入或卖出的百分比为单位。

变量和东西。

#property copyright "me"
#property link      "killnosock.net"
extern int SlowEma = 21;
extern int FastEma = 10;
extern int MaxRisk = 100;// % of Depo to be traded per order
extern int  TakeProfit=100;
extern int  StopLoss=100;
extern int Slippage = 10;

int LastBars = 0;

int init(){return(0);}
int deinit() {return(0);}

这个函数是用来确定手数的,根据每个订单允许使用的百分比(int Risk)。

double GetLot(int Risk)
{double Free    =AccountFreeMargin();
 double One_Lot =MarketInfo(Symbol(),MODE_MARGINREQUIRED);
 double Min_Lot =MarketInfo(Symbol(),MODE_MINLOT);
 double Max_Lot =MarketInfo(Symbol(),MODE_MAXLOT);
 double Step    =MarketInfo(Symbol(),MODE_LOTSTEP);
 double Lot     =MathFloor(Free*Risk/100/One_Lot/Step)*Step;
 if(Lot<Min_Lot) Lot=Min_Lot;
 if(Lot>Max_Lot) Lot=Max_Lot;
 if(Lot*One_Lot>Free) {
 Alert(" free= ", AccountFreeMargin()," for one lot= ", MarketInfo(Symbol(),MODE_MARGINREQUIRED)," lot= ", Lot);
 return(0.0);}
return(Lot);}

这是打开新订单的函数,指令是买入或卖出。

int NewOrder(int Cmd,double Lot)
{double TP=0; //takeprofit
 double SL=0; //stoploss
 double PR=0; //price
 color clr = CLR_NONE;
 while(!IsTradeAllowed()) Sleep(10);
 RefreshRates();
 if(Cmd==OP_BUY)
   {PR=Ask;
    if(TakeProfit>0) TP=Ask + Ask*TakeProfit/100;
    if(StopLoss>0) SL=Ask - Ask*StopLoss/100;
    if(SL<0) SL = 0;
    if(TP<0) TP = 0;
    clr = Green;}
 if(Cmd==OP_SELL)
   {PR=Bid;
    if(TakeProfit>0) TP=Bid - Bid*TakeProfit/100;
    if(StopLoss>0) SL=Bid + Bid*StopLoss/100;
    if(SL<0) SL = 0;
    if(TP<0) TP = 0;
    clr = Red;}
 int tic=OrderSend(Symbol(),Cmd,Lot,PR,Slippage,SL,TP,"",0,0,clr);
 if(tic<0) Print("Open order error: ",GetLastError());
return(tic);}

这里我关闭一个订单或关闭所有订单。

//CloseOrder
void CloseOrder()
{double PR=0;
 while(!IsTradeAllowed()) Sleep(10);
 RefreshRates();
 if(OrderType()==OP_BUY)  PR=Bid;
 if(OrderType()==OP_SELL) PR=Ask;
 if(!OrderClose(OrderTicket(),OrderLots(),PR,Slippage,CLR_NONE))
   Print("Order close error: ",GetLastError());
return;}
//Close all Orders
void CloseAllOrders()
{
  for(int i=OrdersTotal()-1;i>=0;i--)
   if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
     {
      CloseOrder();
     }
return;}

这个函数用于计算快速和慢速EMA的差异(快速EMA-慢速EMA)。

double EmaDiff(int shift)
   {
      double difference;
      difference = iMA(Symbol(),0,FastEma,0,MODE_EMA,PRICE_CLOSE,shift)
                 - iMA(Symbol(),0,SlowEma,0,MODE_EMA,PRICE_CLOSE,shift);
      return(difference);
   }

这里是主体。

int start()
  {
double Lot;
    // check if new bar opened
    if (LastBars == Bars) return(0);
    else LastBars = Bars;
      {         
         if ((EmaDiff(1) > 0) && (EmaDiff(2) < 0))
            {
               CloseAllOrders();
               Lot = GetLot(MaxRisk);
               NewOrder(OP_BUY,Lot);
            }
            
         if ((EmaDiff(2) > 0) && (EmaDiff(1) < 0))
            {
               CloseAllOrders();
               Lot = GetLot(MaxRisk);
               NewOrder(OP_SELL,Lot);
            }                    
      }
   return(0);
  }

我打算添加一个跟踪止损,并考虑将EMA差值不是零,而是一些小的波段,当慢速和快速EMA非常接近并在每个柱子上相交时,不会被砍掉。

 
 //CloseOrder
void CloseOrder()
{double PR=0;
 while(!IsTradeAllowed()) Sleep(10);
 RefreshRates();
 if(OrderType()==OP_BUY)  PR=Bid;
 if(OrderType()==OP_SELL) PR=Ask;
 if(!OrderClose(OrderTicket(),OrderLots(),PR,Slippage,CLR_NONE))
   Print("Order close error: ",GetLastError());
return;}



//Close all Orders
void CloseAllOrders()
{
  for(int i=OrdersTotal()-1;i>=0;i--)
   if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
     {
      CloseOrder();
     }
return;}

检查 符号不检查magicnumber....

那么用不同的EA实战会发生什么?

 
deVries:

不检查符号不检查magicnumber....

那么用不同的EA实战会发生什么?


你是说在一个账户上运行两个EA吗?
 
prupru:

你是指在一个账户中运行两个EA吗?
两个EA还是一个EA和手动交易...或者只是手动交易。
 
prupru:

你好!我是mql 4的新手。

我是mql 4的新手,我做了一个简单的2 EMA交叉顾问,我已经在模拟账户上测试过了,但有点害怕在真实账户上使用它。

在1小时范围内用小手测试它需要太多的时间,而在分钟范围内测试它是昂贵的,因为我的经纪人的最小手数大约是7美元。

所以,如果你能看一下,并指出我可能犯的一些明显的错误,我将非常感激。

很高兴看到有人在没有提示的情况下检查交易函数的返回值......但如果你得到一个错误,你需要更多的信息,以便你能诊断出是什么导致了这个问题,你不能在活着的情况下回到过去,检查当时的Spread是什么或者Freeze水平 是什么。

if(tic < 0) Print("Open order error: ", GetLastError());

这很好,但你需要更多,你需要打印哪些变量,以便你能确定你得到的任何错误的原因? 当你确定你可能需要什么时,将它们全部添加到你的Print()调用中,确保你对任何双变量如Ask、Bid等使用正确的小数(DoubeToStr(value, digits)

 
RaptorUK:

很高兴看到有人在没有提示的情况下检查交易函数的返回值 . .

对不起,我没有理解这部分。我唯一明白的是,我需要在Print()调用 中加入尽可能多的变量。有道理,谢谢。

deVries, 也谢谢你的建议,现在我明白你的意思了。

还有什么需要解决的吗?

 

当然有

    // check if new bar opened
    if (LastBars == Bars) return(0);
    else LastBars = Bars;

假设你已经有了最大的酒吧(有一个限制).....

 
deVries:

当然有

假设你已经有了最大的酒吧(有一个限制).....


好吧,那么我怎样才能更好地捕捉到新蜡烛打开的那一刻?
 
prupru:

好的,那么我怎样才能更好地抓住新蜡烛打开的时刻呢?


检查 最新条形图的时间 Time[0]

搜索NewBar,你会发现一些例子

 
deVries:


检查最新条形图的时间 Time[0] 。

搜索NewBar,你会发现一些例子


谢谢,我找到了这个https://www.mql5.com/en/code/10370

 
 if(Cmd==OP_BUY)
   {PR=Ask;
    if(TakeProfit>0) TP=Ask + Ask*TakeProfit/100;
    if(StopLoss>0) SL=Ask - Ask*StopLoss/100;
    if(SL<0) SL = 0;
    if(TP<0) TP = 0;
    clr = Green;}

我认为这是不对的

你是如何得到100点的止盈和150点的止损的?

更新看到"所以止损和止盈 不是以点为单位,而是以买入或卖出的百分比为单位"。

这样你还能得到一个有效的价格吗......如果你的符号有5位数,结果往往是2位数以上。