Open Forex4you Account

Server รัน EA 1000 / ปี

สั่งชื้อคู่มือการโปรแรกม MQL4

Author Topic: [ถาม] จะเปิด order แบบกำหนดจำนวนของแต่ละเงื่อนไขต้องเขียน code ยังไงคับ  (Read 17612 times)

dataxdata

  • Newbie
  • *
  • Posts: 35
มือใหม่ครับ เพิ่งลองเขียน EA โดยพยายามอ่านๆ จากในเวปต่างๆดู พอมีสกิลเขียนโปรแกรมนิดหน่อย(ค่อนไปทางน้อยมากๆ)ครับ

ขอเริ่มคำถามเลยนะครับ อยากถามผู้รู้ว่าสมมติผมมีเงื่อนไขในการเปิด order อยู่ 2 เงื่อนไขด้วยการรับค่าจาก indicator ที่ต่างกัน 2 ตัว
ถ้ากำหนดให้เปิด order ได้ทั้งหมดไม่เกิน 4 order แต่อยากให้แต่ละเงื่อนไขเปิดได้ไม่เกิดเงื่อนไขละ 2 order ถ้าเงื่อนไขไหนเปิด order ไปแล้วห้ามเปิด order อีก
และเวลาจะปิด order ให้ไล่ปิดให้หมดโดยดูว่ามาจาก order ของ indicator ตัวไหนก่อนที่จะเช็คเงื่อนไขเพื่อปิด จะต้องเขียนอย่างไรครับ ในหัวนึกออกคร่าวๆ ได้แบบนี้ครับ

   if(OrdersTotal()<4)
      {
         for(int j = 0; j<4; j++)
            {
               bool condition1buy=false;
               bool condition1sell=false;
               bool condition2buy=false;
               bool condition2sell=false;
               countcondition1=0;
               countcondition2=0;
               if(เงื่อนไขของ indicator ตัวที่1 ==true && countcondition1<=2)
                  {
                     OrderSend(Symbol(),OP_BUY,0.1,Ask,3,0,0,"Buy",12345,0,Green);
                     countcondition1++;
                     condition1_buy=true;
                  }
               else
                  {
                     OrderSend(Symbol(),OP_SELL,0.1,Bid,3,0,0,"Sell",12345,0,Red);
                     countcondition1++;
                     condition1_sell=true;
                  }
               if(เงื่อนไขของ indicator ตัวที่2 ==true && countcondition2<=2)
                  {
                     OrderSend(Symbol(),OP_BUY,0.1,Ask,3,0,0,"Buy",12345,0,Green);
                     countcondition2++;
                     condition2_buy=true;
                  }
               else
                  {
                     OrderSend(Symbol(),OP_SELL,0.1,Bid,3,0,0,"Sell",12345,0,Red);
                     countcondition2++;
                     condition2_sell=true;
                  }
            }   
                 
      }

for(int i = (OrdersTotal()-1); i>=0; i--)
      {
         OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
         if(OrderType()== OP_BUY)
            {
               if(condition1_buy==true)
                  {
                     if(เงื่อนไขเพื่อปิด indicator ตัวที่1 ==true) OrderClose(OrderTicket(),OrderLots(),Bid,3,Green);
                  }
               if(condition2_buy==true)
                  {
                     if(เงื่อนไขเพื่อปิด indicator ตัวที่2 ==true) OrderClose(OrderTicket(),OrderLots(),Bid,3,Red);
                  }
            }
         if(OrderType()== OP_SELL)
            {
               if(condition1_sell==true)
                  {
                     if(closecondition1==true) OrderClose(OrderTicket(),OrderLots(),Ask,3,Green);
                  }
               if(condition2_sell==true)
                  {
                     if(closecondition2==true) OrderClose(OrderTicket(),OrderLots(),Ask,3,Red);
                  }
            }
      }

ลองรันดูแล้วผิดตั้งแต่การเปิด order จนถึงปิด order เลยครับไม่ทราบว่าผมเขียนผิดตรงไหนรึเปล่าครับ รบกวนผู้รู้ด้วยครับ

ขอบคุณครับ ^^
Name: Ataporn.Tap
Rank : Newbie Trader (- -,)

admin

  • Administrator
  • Hero Member
  • *****
  • Posts: 2386
คุณต้องใช้ magic number ในการกำหนดว่า order ใดเปิดด้วยเงื่อนไขอะไร วิธีการเช็กจำนวน order ของคุณมี 2 ชั้น ชั้นแรกคือจำนวน order ทั้งหมด ใช้ Ordertotal ได้ ส่วน Order ที่เปิดจากเงื่อนไขต่างใช้การวน loop แล้วใช้เงื่อนไขกรอง แล้วนับจำนวน order ที่มี Magic number ตรงกับที่เรากำหนด

dataxdata

  • Newbie
  • *
  • Posts: 35
นึกภาพไม่ค่อยออกครับ รบกวนช่วยเขียน structure เป็นตัวอย่างคร่าวๆได้ไหมครับท่าน Admin ^^
Name: Ataporn.Tap
Rank : Newbie Trader (- -,)

D_Diamond

  • Hero Member
  • *****
  • Posts: 673
    • Expert Forex Trading
แนะนำแบบนี้ครับ  แบบที่ท่านเขียนมีบั๊ก
ใช้ magic 1 หรือ 2 ตัวก็ได้ แต่จำเป็นต้องมีเอาไว้นับออเดอร์
สร้างตัวแปรก่อน ไว้ข้างนอก

s1count  เอาไว้นับจำนวนออเดอร์เงื่อนไข 1 ทั้งบายและเซล
s2count นับเงื่อนไข 2
count นับออเดอร์ทั้งหมดของอีเอตัวนี้

start()
{

เคลียร์ค่า
s1count  = 0
s2count  = 0
count   = 0

for นับออเดอร์ให้ถูกต้อง
{
s1count  ++
s2count  ++
count  ++
}

ตอนนี้เราจะรู้แล้วว่าเงื่อนไขไหนเปิดไปแล้วกี่ออเดอร์  และทั้งหมดของอีเอตัวนี้เปิดกี่ออเดอร์

ต่อไปก็ปิดออเดอร์
if(  s1count  >0 )
{
  if(เงื่อนไข)
  {
   if(orderclose )
   s1count --

   เมื่อปิดออเดอร์ก็ลบจำนวนนับไป 1
   ตรงนี้ตอนปิดออเดอร์ต้องใช้ if คร่อม  เพื่อให้แน่ใจว่าปิดออเดอร์ได้จริง  ไม่งั้นมีโอกาสพลาด
  }
}


ต่อไปเปิดออเดอร์

if( count < 4 )
{
   if ( เงื่อนไข && s1count<2 ) ordersend
}

}


การเขียนอีเอจะเรียงลำดับจาก  นับออเดอร์->modify->close->send  ครับ
ท่านขึ้น send มาก่อนเพื่อน มันก็ผิดเลย  มันนับออเดอร์ไม่ได้  เพราะมันเปิดออเดอร์ครั้งเดียวแล้วรอปิดทีหลัง  ไม่ได้เปิดแล้วปิดทุกวิครับ

dataxdata

  • Newbie
  • *
  • Posts: 35
ขอบคุณท่าน D_Diamond มากครับสำหรับแนวทางและคำแนะนำ ดูแล้วเห็นภาพเลยครับ ^^

ปล. ขอบคุณท่าน Admin เช่นกันครับ
Name: Ataporn.Tap
Rank : Newbie Trader (- -,)

dataxdata

  • Newbie
  • *
  • Posts: 35
ลองเอาคำแนะนำท่าน D_Daimond ไปลองเขียนดูแต่ EA ไม่เปิดออร์เดอร์เลยคับ รบกวนช่วยตรวจให้หน่อยครับว่าผิดตรงไหน ขอบคุณครับท่าน







extern double MagicNumber1 = 12345;
extern double MagicNumber2 = 56789;
extern double MaximumOrder = 4;
extern double TimePeriod   = 1;

//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
   {
      double s1count, s2count, count;
      double GetRSI = iRSI(NULL,PERIOD_H1,14,PRICE_CLOSE,0);
      double PreRSI = iRSI(NULL,PERIOD_H1,14,PRICE_CLOSE,1);

      //----- Clear Value -----//
      s1count  = 0;
      s2count  = 0;
      count    = 0;

      for(int i = 0; i < MaximumOrder; i++)
         {   
            if(OrderMagicNumber()==MagicNumber1) s1count++;
            if(OrderMagicNumber()==MagicNumber2) s2count++;
            count++;
         }

      //----- Close Order -----//
      if(s1count>0 )
         {
            //----- Close Order with Condition1 -----//
            if(OrderMagicNumber()==MagicNumber1)   
               {
                  double OBid = MarketInfo("EURUSD",MODE_BID);
                  double OAsk = MarketInfo("EURUSD",MODE_ASK);
                  if(PreRSI > 70.0000 && (OrderOpenPrice()+(10*Point)) < OBid)
                     {
                        OrderClose(OrderTicket(),OrderLots(),Bid,4,Green);
                        s1count--;
                     }
                  if(PreRSI < 30.0000 && (OrderOpenPrice()-(20*Point)) > OAsk)
                     {
                        OrderClose(OrderTicket(),OrderLots(),Ask,4,Red);
                        s1count--;
                     }
               }
         }
      if(s2count>0 )
         {
            if(OrderMagicNumber()==MagicNumber2)   
               {
                  double CurMA5 = iMA(NULL,TimePeriod,5,0,MODE_EMA,PRICE_CLOSE,0);
                  double PreMA5 = iMA(NULL,TimePeriod,5,0,MODE_EMA,PRICE_CLOSE,1);
                  double CurMA34 = iMA(NULL,TimePeriod,34,0,MODE_EMA,PRICE_CLOSE,0);
                  double PreMA34 = iMA(NULL,TimePeriod,34,0,MODE_EMA,PRICE_CLOSE,1);
                  double CurMA50 = iMA(NULL,TimePeriod,50,0,MODE_EMA,PRICE_CLOSE,0);
                  double PreMA50 = iMA(NULL,TimePeriod,50,0,MODE_EMA,PRICE_CLOSE,1);
                  if(CurMA5 < CurMA34 && PreMA5 > PreMA34)
                     {
                        OrderClose(OrderTicket(),OrderLots(),Bid,4,Green); // close position
                        s2count--;
                     }
                  if(CurMA5 > CurMA34 && PreMA5 < PreMA34)
                     {
                        OrderClose(OrderTicket(),OrderLots(),Ask,4,Red);
                        s2count--;
                     }
               }
         }
     
      //----- Open Order -----//   
      if(count < MaximumOrder )
         {
            if(GetRSI < 30.0000 && PreRSI < 30.0000 && s1count < 2) OrderSend(Symbol(),OP_BUY,0.1,Ask,4,0,0,"Buy",12345,0,Green);
            if(GetRSI > 70.0000 && PreRSI > 70.0000 && s1count < 2) OrderSend(Symbol(),OP_SELL,0.1,Bid,4,0,0,"Sell",12345,0,Red);
            if(CurMA5 > CurMA50 && PreMA5 < PreMA50 && MarketInfo(TimePeriod,MODE_ASK) < PreMA34 && s2count < 2) OrderSend(Symbol(),OP_BUY,0.1,Ask,4,0,0,"Buy",56789,0,Green);
            if(CurMA5 < CurMA50 && PreMA5 > PreMA50 && MarketInfo(TimePeriod,MODE_BID) > PreMA34 && s2count < 2) OrderSend(Symbol(),OP_SELL,0.1,Bid,4,0,0,"Sell",56789,0,Red);
         }

      return(0);
   }
Name: Ataporn.Tap
Rank : Newbie Trader (- -,)

D_Diamond

  • Hero Member
  • *****
  • Posts: 673
    • Expert Forex Trading
ลองเพิ่มโค้ดนี้ไว้ก่อน open order ดูครับ

Comment("RSI = ",GetRSI,
"\nRSI1 = ",PreRSI,
"\ns1count = ",s1count,
"\ns2count = ",s2count,
"\ncount = ",count);

แล้วแบคเทสเปิด visual mode จะเห็นว่าทำไมมันถึงไม่เทรด

เท่าที่ดูท่านเขียนโค้ดเป็นแล้ว  แต่ยังไม่เข้าใจหลักการของอีเอเท่าไร
แนะนำให้ซื้อหนังสือท่านแอดมิน  หรือลองโหลดอีเอของคนอื่นมาดูเยอะๆครับ  http://codebase.mql4.com/experts

      for(int i = 0; i < MaximumOrder; i++)
         {   
            if(OrderMagicNumber()==MagicNumber1) s1count++;
            if(OrderMagicNumber()==MagicNumber2) s2count++;
            count++;
         }

แก้เป็น

int total=OrdersTotal();
   
   for(int pos=0;pos<total;pos++)
         {
            OrderSelect(pos,SELECT_BY_POS,MODE_TRADES);
                       
            if( OrderSymbol()==Symbol() && (OrderMagicNumber() == MagicNumber1 || OrderMagicNumber() == MagicNumber2) )
               {
                  count++;
                  if ( OrderMagicNumber() == MagicNumber1 ) s1count++;
                  if ( OrderMagicNumber() == MagicNumber2 ) s2count++;
               }
         }

และ

OrderClose(OrderTicket(),OrderLots(),Bid,4,Green);

แก้เป็น

if ( OrderClose(OrderTicket(),OrderLots(),Bid,4,Green) )