Sponsored Ads

วันจันทร์ที่ 31 กรกฎาคม พ.ศ. 2560

เขียน EA แบบง่ายๆ ผ่าน Moving average

วันนี้เราลองมาเขียน EA  แบบง่ายๆ กันครับ ผ่าน indicator คือ EMA 

ผมเอา Code มาแปะให้ เพื่อให้เพื่อนๆได้ทำความเข้าใจว่าขั้นตอนในการเขียนมันมีหลักการเช็ค loop ยังไงบ้าง ผมเองตอนหัดเขียนใหม่ๆ ก็เจอปัญหาคือ มันส่ง Order ซ้ำ ลองเอา Code นี้ไปศึกษาดูนะครับ ผมไปเอามาจากตัวอย่างในหนังสือ แล้วพิมพ์หมายเหตุเป็นภาษาไทย เพื่อให้เข้าใจง่ายๆ ลองหัดเขียนแล้วเอาไปปรับใช้กันดูนะครับ




extern double TakeProfit = 250; 
extern double Lots = 0.1; 
extern double TrailingStop = 35.0; 

int Crossed(double line1, double line2) // ไว้เช็ค up / down trend
   {
      static int last_direction = 0 ; // ค่า direction เริ่มต้น = 0 
      static int current_direction = 0; 
      
      //สร้างเงื่อนไข Cross 
      
     // ถ้า line 1 > line 2 ให้ค่า current direction = 1 หมายถึง up 
           if(line1>line2) current_direction = 1; 
            if(line1<line2) current_direction = 2; // down
            
      // แก้ค่าตัวแปร ให้ curent = last direction
      
      if(current_direction != last_direction)
      {
         last_direction = current_direction; 
         return(last_direction); 
         
       }
       else 
       {
         return(0); 
       }
    } 
      
 //-----------------------------------------------------------------
 
 int start()
   {
      int cnt,ticket ,total; 
      double shortEma , longEma; 
      
      if(Bars<100)
         {
            Print("bar Less than 100") ; // bar น้อยกว่า 100 ข้อมูลน้อยไป 
         }
       // set ค่า EMA 
       
       shortEma = iMA(NULL,0,8,0,MODE_EMA,PRICE_CLOSE,0);  //set EMA 8 
       longEma = iMA(NULL,0,13,0,MODE_EMA,PRICE_CLOSE,0); 
       
       //ใช้ฟังก์ชั่น cross ที่เขียนไว้ก่อนหน้า เพื่อดู trend 
       
       
       int isCrossed = Crossed(shortEma , longEma); 
       
       //เช็ค Order ทั้งหมด 
       
       total = OrdersTotal(); 
       if(total <1) // ถ้ายังไม่เปิด order  
       
         {  
            if(isCrossed ==1)  //ถ้า up 
            
              {
                //ส่ง Order 
                ticket = OrderSend(Symbol(),OP_BUY,Lots,Ask,3,0,Ask+TakeProfit*Point,"My EA",0,Green); 
                
                
                   if(ticket>0) // ถ้าส่ง order ผ่าน 
                   
                    { 
                       if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))// เลือก order ได้ไหม 
                           Print("Buy Order Opened : ",OrderOpenPrice()); //ถ้าได้ให้ print เลข Order 
                    }
                    else // ถ้าไม่ได้ 
                        Print("error opening Buy");
                        return(0);
             }
            
              if(isCrossed == 2) // ถ้าลง เขียนเหมือน up
            {
               ticket=OrderSend(Symbol(),OP_SELL,Lots,Bid,3,0,Bid-TakeProfit*Point,"My EA",12345,0,Red);
                  
                    if(ticket>0)
                        
                        {

                              if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))
                                 Print("SELL order opened : ",OrderOpenPrice());

                        }
                              else 
                                 Print("Error opening SELL order : ",GetLastError());
                              return(0);
            }
            return(0);
            
       }
       
       
       //-------------------------------------------------------------------------------
       // เช้ค Order 
       
       for(cnt=0;cnt<total;cnt++)
            {
               OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
               
                  if(OrderType()<=OP_SELL && OrderSymbol()==Symbol())   // ถ้าเป็น Order Buy or Sell 
                     
                     { 
                                 if(OrderType()==OP_BUY) // ถ้า Buy เปิดไว้ให้ปิด 
                        
                                       {

                                             if(isCrossed == 2)    // สัญญา downมา
                                          
                                                {
                                                         OrderClose(OrderTicket(),OrderLots(),Bid,3,Violet);   // ปิด
                                                         
                                                         return(0); // จบ
                                                 }
                                       }
                                      
                                 
                         else // go to short position
                             {
                                       // ถ้าขึ้น
                                       if(isCrossed == 1)
                                       {
                                                OrderClose(OrderTicket(),OrderLots(),Ask,3,Violet); // ปิด long 
                                       
                                                  return(0); // จบ
                                        }
                                        
                               }
                       }
                       
                 
                  
                 }
                 
        return;
        
   }

วันอังคารที่ 4 กรกฎาคม พ.ศ. 2560

การปิด Order แบบ Auto ผ่่านการใช้ OrderSelect()

จากตอนที่แล้ว เราได้พูดถึงเรื่องการใช้ OrderClose() ไว้เพื่อใช้ปิด Order แต่ตอนนี้เราจะมาพูดถึงกาารใช้ฟังก์ชั่น OrderSelect() ไว้เพื่อเลือก Order ที่เราต้องการเอง โดยไม่ต้องมานั่งจดเลข Ticket

Function OrderSelect()


โครงสร้าง 

bool OrderSelect(int index, int select , int pool=MODE_TRADES) 

int select คือ เราพูดถึง select ก่อน index เพราะค่า index มันขึ้นอยู่กับการเลือก select  ซึ่งค่า select สามารถเลือกได้ 2 ค่า คือ 

SELECT_BY_POS  หมายถึง Order Number จะถูก return ค่าออกไป ในค่า Parameter index  
SELECT_BY_TICKET หมายถึง ค่า ticket number จะถูก return ค่าออกไป 

int index คือ ค่าซึ่งถูก return ค่าออกมาจากการเลือก select  

pool  คือ ข้อมูลที่เราต้องการจะเลือกเอามาจากชุดข้อมูลไหน ซึ่งมันขึ้นอยู่กับการเลือก select 

ตัวแปร pool จะถูกใช้เมื่อ เราเลือก select เป็น SELECT_BY_POS 

ตัวแปร pool จะไม่ถูกใช้หากเลือก select เป็น SELECT_BY_TICKET

ตัวแปร pool เลือกได้ 2 ค่า คือ 

MODE_TRADES  หมายถึง เลือก Order ที่เป็น open หรือ pending position 

MODE_HISTORY หมายถึง Order ที่ปิดไปแล้ว หรือ Order ที่ลบไปแล้ว ที่เกิดขึ้นในอดีต 


ก่อนจะเขียนโปรแกรมทั้งหมดมาทำความเข้าใจโครงสร้างแต่ละส่วนกันก่อน

for(int i = 1 ; i<= OrdersTotal(); i++)
   {
      if(OrderSelect(i-1,SELECT_BY_POS)==true)
      {
           //
          //
       }
   }

จากบล็อคด้านบน เป็นวิธีการเลือก Order ครับ ซึ่งเขียนอยู่ในลูป For โดยเลือก Order ทั้งหมดผ่าน OrderTotal จากนั้นค่อยกรองเอาแต่ Order ที่ยังเปิดอยู่เท่านั้นผ่านเงื่อนไข if  ซึ่งเมื้่อกรอง Order มาได้แล้วก็ขึ้นอยู่กับว่าเราต้องการจะเอาไปทำอะไรต่อ


ด้านล่างนี้เป็น Code ที่เอามาจากตัวอย่าง ในหนังสือ


int start()                                     //
  {
   string Symb=Symbol();                      // symbol
   double Dist=1000000.0;                     // กำหนดระยะ
   int Real_Order=-1;                         // -1 คือ Order ที่ไม่ใช่ market order
   double Win_Price=WindowPriceOnDropped();     // หากลากไปที่ราคาไหน เก็บราคาไว้ในตัวแปร Win price
//--------------------------------------------------------------- 2 --
   for(int i=1; i<=OrdersTotal(); i++)         // ดึงข้อมูลทั้งหมด
     {
      if (OrderSelect(i-1,SELECT_BY_POS)==true) //  เลือกเฉพาะ Order ที่เปิดอยู่
        {                                      //
         //------------------------------------------------------ 3 --
         if (OrderSymbol()!= Symb) continue;    // ถ้า order ที่เปิดไม่ตรงกับ Symbol ของกราฟ ให้ข้ามไป
         int Tip=OrderType();                 //ดึงค่า Ordertype ใส่ใน Tip
         if (Tip>1) continue;                   // ถ้า Tip > 1 แสดงว่าเป้น pending order ให้ข้ามไปดู order ใหม่
         //------------------------------------------------------ 4 --
         double Price=OrderOpenPrice();       // เก็บค่าราคาลงไปในตัวแปร Price
         if (NormalizeDouble(MathAbs(Price-Win_Price),Digits)<  NormalizeDouble(Dist,Digits))// เงื่อนไข ถ้าราคาเปิด - ราคาที่เราเอาเมาส์ลาก script ไปวาง แล้วน้อยกว่า Dist
           {
            Dist=MathAbs(Price-Win_Price);      //ให้กำหนดค่า dist ใหม่   = ค่าบวกของ Price - win_Price
            Real_Order=Tip;                   // กำหนดค่า real_orde = Tip
            int Ticket=OrderTicket();         // ดึงค่า OrderTicket มาใส่ใสนตัวแปร Ticket
            double Lot=OrderLots();           // ดึงค่า จำนวน Lot มาใส่ใน Lot
           }
         //------------------------------------------------------ 5 --
        }                                      //จบเงื่อนไข If
     }                                         // จบ loop .
//--------------------------------------------------------------- 6 --
   while(true)                                 // ถ้าเป็นจริงให้ทำต่อไป
     {
      if (Real_Order==-1)                     // ถ้า real_Order = - 1
        {
         Alert("For ",Symb,"no market order aviable");
         break;                                 //
        }
      //--------------------------------------------------------- 7 --
      switch(Real_Order)                       //By order type ใช้คำสั่ง switch ดูทางเลือก
        {
         case 0: double Price_Cls=Bid;        // หาก Real_Order =0 ให้ดึงค่า Bid ใส่ตัวแปร Price_Cls
            string Text="Buy ";          // กำหนดค่า "Buy" เก็บไว้ในตัวแปร Text
            break;                         // ออกจาก switch
         case 1: Price_Cls=Ask;               // หากเป็น 1 ดึงค่า Ask มาเก็บใน Price_Cls
            Text="Sell ";                // กำหนดค่า "Sell" ไว้ใน Text
        }
      Alert("Attempt to close",Text," ",Ticket,"Awaiting.."); // แจ้ง alert ว่ากำลังจะปิด Order
      bool Ans=OrderClose(Ticket,Lot,Price_Cls,2);//ส่งคำสั่งปิด Order ตามค่าตัวแปรที่เราเขียนโปรแกรม ถ้าปิดได้ จะ return true
      //--------------------------------------------------------- 8 --
      if (Ans==true)                            // หากปิดได้
        {
         Alert ("close order ",Text," ",Ticket);
         break;                                 // แจ้งปิด Order เลขที่
        }
      //--------------------------------------------------------- 9 --

     }
//-------------------------------------------------------------- 10 --
   Alert ("The script has finished operations  -----------------------------");
   return;                                      // จบโปรแกรม
  }
//-------------------------------------------------------------- 11 --

ที่มา https://book.mql4.com/trading/orderclose

ลอองไปหัดเขียนแล้วทำความเข้าใจดูนะครับ










วันพฤหัสบดีที่ 22 มิถุนายน พ.ศ. 2560

การเขียนคำสั่ง Close Order

Closing and Deleting Orders


เวลาที่เราต้องการจะปิด position เราจะใช้ฟังก์ชั่น OrderClose() เพื่อใช้ส่งคำสั่งปิด position 

โครงสร้างฟังก์ชั่น OrderClose()

bool OrderClose(int ticket , double lots,double price,int slippage,color Colr = CLR_NONE)

อธิบายฟังก์ชั่น 

int ticket คือ หมายเลข ticket order ที่ต้องการจะปิด 

doublt lot คือ ขนาด lot ที่ต้องกาสรปิด 

double price คือ ราคาที่ต้องการปิด  สามารถดูเงื่อนไขเพิ่มเติมได้ที่ https://book.mql4.com/appendix/limits

int slippage คือ ค่ามากที่สุดที่สามารถเบี่ยงเบนได้จากราคาตลาด เพราะบาง Broker มีปัญหาเรื่อง requote  หน่วยเป็น point 

Color คือ สีลูกศรที่แสดงบนกราฟหากมีการปิด Order 


ตัวอย่างการใช้ฟังก์ชั่น 

OrderClose(12345,0.5,Bid,2); 

OrderClose คือ ฟังก์ชั่น OrderClose ส่งคำสั่งเพื่อปิด Order 

12345          คือ  หมายเลข ticket 

0.5               คือ ขนาดของ lot 

Bid               คือ ราคาที่ต้องการใช้ปิด 

2                   คือ ค่า Slippage หน่วยเป็น point มีค่าคือ 2 point 



ตัวอย่างเราต้องการปิด Order ที่เปิดอยู่ สิ่งแรกเราต้องรู้หมายเลข Order ก่อน เอาแบบง่ายๆ เราก็ไปดูเลข ticket ใน Tab Order มันจะแสดงหมายเลขไว้ 


คำสั่งปิด Order 

int start()
   {
      OrderClose(40149595,0.10,Bid,1000,Red);
     return;
   }

ก่อน Compile เรามี Order ค้างไว้อยู่





หลังจากเรา Compile แล้วลาก script มาวางไว้บนกราฟ เราก็จะปิด Order ได้ ซึ่งบนกราฟจะแสดงลูกศรสีแดงขึ้นมาให้เห็นด้วย 

เพื่อนๆสามารถอ่านเนื้อหาเพิ่มเติมได้ที่ https://book.mql4.com/trading/orderclose




วันอังคารที่ 13 มิถุนายน พ.ศ. 2560

การใช้ Marketinfo กับการส่ง Order

ตัวอย่างการใช้ MatketInfo กับการส่ง Order 

ในบทความนี้เราจะเอาฟังชั่นทั้ง 2 ตัว เอามาเขียนประยุกต์ใช้ด้วยกัน 

โดยเราจะดึงราคา Bid และ Ask รวมถึงค่า Point เพื่อเอาไว้ใช้ในการเปิด Order นั่นเอง 

int start()
{
   double bid = MarketInfo(Symbol(),MODE_BID); 
   double ask = MarketInfo(Symbol(),MODE_ASK);
   double point = MarketInfo(Symbol(),MODE_POINT);
   double SL = MarketInfo(Symbol(),MODE_STOPLEVEL); 
   
   
   OrderSend(Symbol(),OP_BUY,0.01,ask,10,bid-SL*Point,bid+SL*Point); 
   Alert(GetLastError()); 
   
   return; 
   
}   

****  Code นี้ หากเราไปเขียนใน EA มันจะส่งคำสั่งทุกครั้งที่มีการเคลื่อนที่ของราคา ดังนั้นควรเขียนลงใน script น่าจะดีกว่าหากต้องการส่งคำสั่งครั้งเดียว 

มาอธิบายทีละบรรทัดกันครับ

   double bid = MarketInfo(Symbol(),MODE_BID); 

ดึงค่า Bid มาใส่ในตัวแปร bid   (  Ask ก็เหมือนกัน )

   double point = MarketInfo(Symbol(),MODE_POINT);

ดึงค่า Point มาเก็บไว้ในตัวแปร point 


  double SL = MarketInfo(Symbol(),MODE_STOPLEVEL); 

ดึงค่า Stop Level มาเก็บไว้ในตัวแปร SL  เนื่องจากในการส่งคำสั่ง TP หรือ Stop loss มันจะมีระยะต่ำที่สุดที่สามารถให้ใส่ค่าได้ ดังนั้นเราก็ดึงค่านั้นจาก MarketInFo มาใช้นั้นเอง 

   OrderSend(Symbol(),OP_BUY,0.01,ask,10,bid-SL*Point,bid+SL*Point); 


เป็นคำสั่งไว้ส่ง Order ครับ ก็ใส่ค่าตามตัวแปรที่ฟังช์่นต้องการ โดยเอาตัวแปรที่เราดึงค่ามาใส่ในฟังก์ชั่นนั้นเอง 


   Alert(GetLastError()); 


เป็นการแสดงผลค่า Error ที่เกิดขึ้น มันจะแสดงเป็นตัวเลข หากเกิดปัญหาอะไรก็สามารถเช็คได้ที่ 

https://book.mql4.com/appendix/errors


เพื่อนๆสามารถดูคำอธิบายเพิ่มเติมได้ที่ https://book.mql4.com/trading/ordersend 



คำสั่งไว้เช็ค AccountMargin

Account Margin

ในบทความนี้ผมจะมาแนะนำการใช้ฟังก์ชั่นเพื่อใช้ในการเช็คมาร์จิ้นกันครับ

หากเพื่อนๆต้องการที่จะรู้ว่า Free Margin ในพอร์ทมีอยู่เท่าไหร่าสามารถใช้ฟังก์ชั่น AccountFreeMargin () เพื่อดึงค่า Free Margin ออกมาแสดงผล หรือเอามาคำนวณความเสี่ยง หรือ Money management ได้

ตัวอย่างการเขียน

int start()

{
     double x = AccountFreeMargin();
   
     Alert("Account Free Margin =" , x );
   
     return;
   
   
}

หาเพื่อนๆ ต้องการหากต้องการเปิด Order Buy  1 lot จะเหลือมาร์จิ้นอยู่เท่าไหร่  ลองเขียนตามนี้

int start()

{
     double x = AccountFreeMarginCheck(Symbol(),OP_BUY,1);
   
     Alert("Account Free Margin =" , x );
   
     return;
   
   
}


หากต้องการรู้ว่ามาร์จิ้นเพืื่อใช้ Buy 1 Lot ใช้ไปเท่าไหร่สามารถนำเอา  Code ด้านบนมาประยุกต์ใช้ได้ครับ


int start()

{
     double x = AccountFreeMarginCheck(Symbol(),OP_BUY,1);
   
     double y = AccountFreeMargin();
   
     Alert("Account Free Margin =" , y-x );
   
     return;
   
   
}

เพื่อนๆสามารถดูตัวอย่างพร้อมคำอธิบายเพิ่มเติมได้ที่ https://book.mql4.com/trading/ordersend

นอกจากนี้ยังมีคำสั่ง Account ที่น่าสนใจเพิ่มเติมเผื่อใครสนใจไปอ่านเพิ่มได้ที่ https://docs.mql4.com/account

ฟังก์ชั่น MarketInfo เพื่อดึงข้อมูลจาก Broker

Function MarketInfo()


เราสามารถดึงข้อมูลต่างๆจาก Broker นำมาใช้ในการเขียน EA ได้ โดยใช้ฟังก์ชั่น MarketInfo()

เช่น  อยากรู้ Margin required , Stop Level , Lot step จะทำยังไง 

วันนี้ผมมาแนะนำฟังก์ชั่น MarketInfo() 

โดยเพื่อนๆ สามารถอ่านข้อมูลเพิ่มเติมได้ที่ 

https://book.mql4.com/trading/ordersend

ตัวฟังก์ชั่นเขียนดังนี้ 

double MarketInfo(string symbol, int type)

ค่าที่ส่งออกจาก MarketInfo จะเป็นค่าที่เป็นตัวเลขทศนิยม  ซึ่งต้องใส่ค่า 2 ตัวได้แก่ Symbol และ Type 

Symbol หมายถึง คู่สกุลเงินที่เราต้องการจะดูข้อมูล 

type หมายถึง ข้อมูลที่ต้องการจะได้ 

ตัวอย่าง 

หากเราต้องการดูมาร์จิ้น 1 lot ของ EURUSD ของ Broker ที่เราใช้อยู่ ให้เขียนคำสั่งดังนี้ 

int start()
{   
    double m ;
      m = MarketInfo("EURUSD",MODE_MARGINREQUIRED);
      Alert(m);
      return;
   
}


หากเราต้องการดูจำนวน Lot ที่ต่ำที่สุดของ "EURUSD" ให้เขียนดังนี้ 


int start()
{   
    double m ;
      m = MarketInfo("EURUSD",MODE_MINLOT);
      Alert(m);
      return;
   
}

เพื่อนๆสามารถลองทำตาม แล้วเปลี่ยน Type เพื่อใช้ดูข้อมูลอื่นๆได้อีกมากเลยครับ 

ซึ่งสามารถดูได้ตามลิงค์ด้านล่างนี้เลย 

https://book.mql4.com/appendix/marketinfo

Open Order

Opening and Placing Orders


การส่งคำสั่งเพื่อ Open Order หรือ Placing Order สามารถใช้ฟังก์ชั่น OrderSend() เพื่อใช้ในการส่งคำสั่ง

Function OrderSend()

int OrderSend(string symbol, int cmd, double volume , double price , int slippage , double stoploss , double takeprofit , string comment=NULL, int magic=0, datetime expiration=0,color arrow_color=CLR_NONE) 


อย่าเพิ่งตกใจกับฟังก์ชั่นทำไมมันเขียนยาวขนาดนี้ มาดูความหมายของมันก่อน 

OrderSend คือ ชื่อฟังก์ชั่นจะ return ค่ากลับมาเป็นเลข ticket ของ order หากส่ง Order ไม่ผ่าน มันจะ return ค่าเป็น -1 (ซึ่งเราสามารถใช้้ฟังก์ชั่น getLastError() ไว้เพื่อเช็คดุสาเหตุอีกที ไว้ตอนต่อไปเราจะอธิบายเพิ่มเติม) 

symbol คือ ชื่อสกุลเงินที่เราต้องการจะส่งไป ปกติเราจะใช่ฟังก์ชั่น Symbol() มากกว่าที่จะระบุสกุลเงินไปตรงๆ เพื่อให้ง่ายต่อการปรับเปลี่ยนนั่นเอง 

volume คือ ขนาดของ lot ที่เราต้องการจะส่ง Order ไป 

Price คือ ราคาที่เราต้่องการจะส่ง Order ไป อาจจะระบุเป็นตัวเลขตรงๆไปเลย หรือเลือกที่ Bid , Ask เป็นต้น 

Slippage คือ ค่าเบี่ยงเบนจากราคา open price สามารถยอมรับได้เท่าไหร่ เพื่อให้ได้ order  

stoploss คือ ราคาที่เราต้องการ stoploss 

takeprofit คือ ราคาที่เราต้องการ take profit 

comment คือ เราอยากหมายเหตุอะไรก็ใส่ไป 

magic คือ หมายเหตุที่เป็นเฉพาะตัวเลข 

expiration คือ ช่วงเวลาสิ้นสุดของการส่ง Order  จะใช้กับ pending order 

arrow _ color  คือ สีของลูกศร เมื่อมีการเปิด Order 


เมื่อเรารู้ว่าฟังก์ชั่นนี้ต้องการค่าอะไรแล้ว ทีนี้เรามาลองเขียน code ส่งคำสั่งกันครับ 




int start() 
   {
 OrderSend(Symbol(),OP_BUY,0.1,Ask,10,Bid-150*Point,Bid+150*Point,NULL,1234,0,"Green");
      Alert(GetLastError());
      return; 
   }



หากต้องการเลือกส่งรายการ GBPUSD  


int start() 
   {
 OrderSend(GBPUSD,OP_BUY,0.1,Ask,10,Bid-150*Point,Bid+150*Point,NULL,1234,0,"Green");
      Alert(GetLastError());
      return; 

   }