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

 
deVries:


如果你用目前的点差进行测试,那就不是了,这是非常疯狂的移动,所以点差会变得非常大。

那么,你是如何进行测试的呢?

固定点差还是当前点差?


好吧,这就是我去谷歌 "价差 "的时候了

我很感谢你能回答我的愚蠢问题))

我将在一段时间内回来

 
prupru:


好的,所以这是我去谷歌 "传播 "的时间。

我很感激你能回答我的愚蠢问题))

我将在一段时间内回来

价差=卖价-买价
 

每一次打勾,这个值都会改变

我之所以问这个方法,是因为你是怎么做测试的?

 
deVries:

每一次打勾,这个值都会改变

我之所以问这个方法,是因为你是怎么做测试的?

正是如此!

我的差异是由于当前的点差测试,当我用固定点差进行测试时,它们是完全一样的!

非常感谢你们!

我真的提高了我的知识。

如果代码中还有什么需要改进的地方,请让我知道。

 
prupru:

完全正确!我的差异是由于目前的传播测试,当我用固定的传播进行测试时,它们完全相同

我的差异是由于当前的点差测试,当我用固定点差进行测试时,它们是完全一样的!

非常感谢你们!

我真的提高了我的知识。

如果代码中还有什么需要改进的地方,请告诉我。


如果你展示你的代码现在变成了什么

也希望看到一个新的错误处理,见评论RaptorUKhttps://www.mql5.com/en/forum/148529

 
deVries:


如果你显示你的代码现在变成了什么

希望看到一个新的错误处理,见评论RaptorUKhttps://www.mql5.com/en/forum/148529

好了,我们开始吧。

#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=0;
extern int  StopLoss=0;
extern int TrailingStop=0;
extern int Slippage = 10;

extern double MinDiff = 0.002;

int LastBars = 0;
//0 - undefined, 1 - bullish cross (fast MA above slow MA), -1 - bearish cross (fast MA below slow MA)
int PrevCross = 0;

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

价格规范化。

double NormPrice(double g_price)
{
   return (NormalizeDouble(g_price,MarketInfo(Symbol(),MODE_DIGITS)));
}

GetLot函数,我想它没有改变。

//function GetLot, get size of the lot according to MaxRisk
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);}

新的订单功能,现在使用规范化的价格。

//function NewOrder, place new order
int NewOrder(int Cmd,double Lot)
{double TP=0; //тейкпрофит
 double SL=0; //стоплосс
 double PR=0; //Цена
 color clr = CLR_NONE;
 while(!IsTradeAllowed()) Sleep(10);
 RefreshRates();
 if(Cmd==OP_BUY)
   {PR=Ask;
    if(TakeProfit>0) TP=NormPrice(Ask + Ask*TakeProfit/100);
    if(StopLoss>0) SL=NormPrice(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=NormPrice(Bid - Bid*TakeProfit/100);
    if(StopLoss>0) SL=NormPrice(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());
   Print("cmd ", Cmd, " Lot ", Lot, " PR ", PR, " Slip ", Slippage, " SL ", SL, " TP ", TP, " Ask ", Ask, " Bid ", Bid);
  }
return(tic);}

关闭1个或所有订单

我没有改变订单关闭功能,以检查符号和魔法数字,因为我只打算在一个符号上交易,而且每个账户只有一个EA。但我将在处理完其他更重要的问题和调整后再做。

//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("Close order error: ",GetLastError());
   Print("Type ", OrderType()," PR ",PR, " Ask ", Ask, " Bid ", Bid, " OrderTicket ", OrderTicket(), " OrderLots ", OrderLots());
  }
return;}
//--------------------------- end of close order

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

我已经改变了EMA交叉检测,从比较EmaDiff[2]和EmaDiff[1]到比较EmaDiff[0]到零,并使用一个额外的标志(所有这些都来自我发现的一些例子)。

在一分钟规模的模拟账户中,当价差过大,买入交易使EMAs相交,然后在同一分钟内的卖出交易又使它们分开时,会产生错误的触发。

[url=http://postimg.org/image/udq4ufmqf/][img]http://s15.postimg.org/udq4ufmqf/mess.jpg[/img][/url]

我现在正在考虑如何处理这个问题

// check cross
void CheckCross()
{
   double FMA_Current = iMA(Symbol(),0,FastEma,0,MODE_EMA,PRICE_CLOSE,0);
   double SMA_Current = iMA(Symbol(),0,SlowEma,0,MODE_EMA,PRICE_CLOSE,0);
   double Poin = (FMA_Current + SMA_Current)/2;
   double Lot;
   if (PrevCross == 0) //Was undefined
   {
      if ((FMA_Current - SMA_Current) >= MinDiff * Poin) PrevCross = 1; //Bullish state
      else if ((SMA_Current - FMA_Current) >= MinDiff * Poin) PrevCross = -1; //Bearish state
      return;
   }
   else if (PrevCross == 1) //Was bullish
   {
      if ((SMA_Current - FMA_Current) >= MinDiff * Poin) //Became bearish
      {
         CloseAllOrders();
         Lot = GetLot(MaxRisk);
         NewOrder(OP_SELL,Lot);
         PrevCross = -1;
      }
   }
   else if (PrevCross == -1) //Was bearish
   {
      if ((FMA_Current - SMA_Current) >= MinDiff * Poin) //Became bullish
      {
         CloseAllOrders();
         Lot = GetLot(MaxRisk);
         NewOrder(OP_BUY,Lot);
         PrevCross = 1;
      }
   }
}

追踪止损功能。

// trailing stop
void DoTrailing()
{
   int total = OrdersTotal();
   for (int pos = 0; pos < total; pos++)
   {
      if (OrderSelect(pos, SELECT_BY_POS) == false) continue;
      if (OrderSymbol() == Symbol())
      {
         if (OrderType() == OP_BUY)
         {
            RefreshRates();
            if (Bid - OrderOpenPrice() >= TrailingStop * Bid/100) //If profit is greater or equal to the desired Trailing Stop value
            {
               if (OrderStopLoss() < (Bid - TrailingStop * Bid/100)) //If the current stop-loss is below the desired trailing stop level
                  OrderModify(OrderTicket(), OrderOpenPrice(), NormPrice(Bid - TrailingStop * Bid/100), OrderTakeProfit(), 0);
            }
         }
         else if (OrderType() == OP_SELL)
         {
            RefreshRates();
            if (OrderOpenPrice() - Ask >= TrailingStop * Ask/100) //If profit is greater or equal to the desired Trailing Stop value
            {
                      if ((OrderStopLoss() > (Ask + TrailingStop * Ask/100)) || (OrderStopLoss() == 0)) //If the current stop-loss is below the desired trailing stop level
                  OrderModify(OrderTicket(), OrderOpenPrice(), NormPrice(Ask + TrailingStop * Ask/100), OrderTakeProfit(), 0);
            }
         }
      }
   }   
}

和主体本身。

//main program
int start()
  {

   if (TrailingStop > 0) DoTrailing();
          
        static datetime Time0;
        if (Time0 == Time[0]) return;
        Time0 = Time[0];
      {
       CheckCross();     
              
      }

   return(0);
  }

谢谢你的关注!



 
prupru:


我还没有改变订单关闭功能,以检查符号和魔法数字,因为我只打算在一个符号上进行交易,而且每个账户只有一个EA。但我会在处理完其他更重要的问题和调整后再做。


不要偷懒,直接做!!!!。

这是一个重要的 事情,你总是必须包括

如果你想修复你的程序,我们给你建议需要做什么

那么,如果你不想工作来修复它,那么我们还帮助你什么呢?

 
deVries:


不要偷懒,直接做 !!!!

这是很重要的事情,你必须要包括

如果你想修复你的程序,我们给你建议需要做什么?

那么,如果你不想修改它,我们还帮你干什么呢?


好了,好了,别紧张)

在这里,我想这应该是个好办法。

打开订单功能。

OrderSend(Symbol(),Cmd,Lot,PR,Slippage,SL,TP,"",Expert_ID,0,clr);

关闭所有订单功能。

//Close all Orders
void CloseAllOrders()
{
  for(int i=OrdersTotal()-1;i>=0;i--)
   {
    if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
     {
      if ((OrderSymbol() == Symbol()) && (OrderMagicNumber() == Expert_ID))  CloseOrder();
     }
    else
     {
      Print("Error selecting order: ",GetLastError());
      Print(" i= ", i, " Symbol= ", OrderSymbol());
     }
   }
return;}
 

我现在有一个更大的问题,我的经纪人倾向于部分执行订单。

亲爱的客户。

请注意,您的交易已被部分打开(15.84中的2.32手),价格为587.318。

如果您对这个问题有任何其他问题,不要犹豫,请联系我们。

亲切的问候。

经理。

这里是支持说的。

请注意,在高波动性或低流动性期间,限价订单可能被部分执行。这意味着,如果价格得到满足,该仓位将立即得到全部或部分填补。在您的情况下,您的订单被部分执行,这就是您收到通知信的原因。

我知道如何关闭所有订单,尽管它们被部分关闭,我只需要在OrdersTotal()>0 时关闭所有订单,但我不知道当订单部分打开时该怎么办。

编辑。

我刚刚意识到,我必须检查适当的Symbol和magicnumber订单,这就有点困难了

编辑:这里是关闭所有订单的函数,即使是部分关闭的订单也应该关闭。

//Close all my Orders
void CloseAllOrders()
{
int notMyOrders = 0;

for(int j=OrdersTotal()-1;j>=0;j--)
{
    if(OrderSelect(j,SELECT_BY_POS,MODE_TRADES))
      {
       if ((OrderSymbol() != Symbol()) || (OrderMagicNumber() != Expert_ID)) notMyOrders++;
      }
    else
      {
       Print("Error selecting order: ",GetLastError());
       Print(" j= ", j, " Symbol= ", OrderSymbol());
      }    
}

 while (OrdersTotal()>notMyOrders)
 {
  for(int i=OrdersTotal()-1;i>=0;i--)
   {
    if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
     {
      if ((OrderSymbol() == Symbol()) && (OrderMagicNumber() == Expert_ID))  CloseOrder();
     }
    else
     {
      Print("Error selecting order: ",GetLastError());
      Print(" i= ", i, " Symbol= ", OrderSymbol());
     }
   }
 }


return;}
 

下面是我将如何解决部分执行未结订单的问题。

打开订单将不再用NewOrder函数 来执行,而是用这个函数来执行。

//OpenOrders in case of partial execution
int OpenPartOrders(int Cmd, double Lot)
{
 int NumOrders = 0;
 int LastTic = -1;
 double Step = MarketInfo(Symbol(),MODE_LOTSTEP);
 double LotRemains = Lot;
 
 //MathFloor( /Step)*Step;;
while (LotRemains>0)
 {
  LastTic = NewOrder(Cmd, LotRemains);
  NumOrders++;
  if(OrderSelect(LastTic, SELECT_BY_TICKET)==true)
     {
      LotRemains = LotRemains - OrderLots();
      Print("NumberOfOrders ", NumOrders, " Ticket ", LastTic, " LotRemains ", LotRemains, " initial Lot ", Lot);          
     }
  else
   {
    Print("OrderSelect returned the error of ",GetLastError());
    LotRemains = 0;//not to create an endless loop opening new orders again and again
   }
 } 
return(NumOrders);}
原因: