หน้าแรก ตัวชี้วัดทางเทคนิค โพสต์

แสดงแนวโน้มในทุกช่วงเวลาในพาแนลเดียว - อินดิเคเตอร์สำหรับ MetaTrader 4

ไฟล์แนบ
15620.zip (2.17 KB, ดาวน์โหลด 0 ครั้ง)

วันนี้เรามาพูดคุยเกี่ยวกับอินดิเคเตอร์ที่ช่วยให้คุณสามารถแสดงแนวโน้มปัจจุบันในทุกช่วงเวลาได้ในพาแนลเดียวกัน ซึ่งเป็นเครื่องมือที่ดีสำหรับนักเทรดที่ต้องการมองเห็นภาพรวมของตลาดอย่างรวดเร็ว

อินดิเคเตอร์นี้เป็นกราฟฟิกที่อิงจาก Slope-Direction-Trend Indicator ที่มีการเผยแพร่ในรูปแบบต่าง ๆ มาแล้วมากมาย แต่ไม่มีรุ่นไหนที่สามารถแสดงทุกช่วงเวลาในพาแนลกราฟฟิกเดียวกันบนหน้าจอของคุณ

คุณสามารถค้นหาได้ที่ https://www.mql5.com/en/search#!keyword=slope%20direction%20line เพื่อดูผลลัพธ์ต่าง ๆ

ผมได้ทำการดัดแปลงอินดิเคเตอร์นี้ให้สามารถแสดงผลในพาแนลกราฟฟิกที่แสดงทุกช่วงเวลา และได้ทำการปรับเปลี่ยนโค้ดต้นฉบับเล็กน้อย หนึ่งในฟีเจอร์ที่เพิ่มเข้ามาคือการให้ผู้ใช้เลือกวิธีการคำนวณค่าเฉลี่ยเคลื่อนที่ที่สองสำหรับการปรับเรียบ โค้ดต้นฉบับใช้ Linear Weighted สำหรับการประมวลผลครั้งที่สอง แต่ผมได้ให้ผู้ใช้เลือกวิธีการปรับเรียบตามที่ต้องการ เมื่อใช้ Linear Weighted สำหรับการคำนวณทั้งสองครั้ง มันอาจทำให้การอ่านค่าแนวโน้มปัจจุบันไม่แม่นยำ แต่ถ้าเราใช้ Simple เป็นวิธีการเฉลี่ยที่สอง เราจะได้แนวโน้มที่แสดงถึงทิศทางราคาที่ถูกต้องมากขึ้น

อีกหนึ่งการเปลี่ยนแปลงที่ผมได้ทำคือ การไม่เพียงแค่แสดงทิศทางของแนวโน้ม (ขึ้น, ลง หรือ แฟลต) แต่ยังสามารถแสดงค่าของมันได้ด้วย สำหรับรายละเอียดเพิ่มเติมเกี่ยวกับการใช้ Double SlopeDirection Indicator และการสร้าง Expert Advisor ด้วยมัน ผมจะเขียนในบทความถัดไป

SlopeDirection

มาดูโค้ดกันเลยนะครับ ผมจะเริ่มต้นด้วยการกำหนดชื่อวัตถุทั้งหมดที่ผมจะใช้ การทำเช่นนี้เป็นการปฏิบัติที่ดีเพราะแต่ละครั้งที่เรากำหนดชื่อวัตถุในเครื่องหมายคำพูด มันจะใช้พื้นที่ในโปรแกรม ดังนั้นถ้ามันถูกกำหนดเพียงครั้งเดียว (โดยใช้คำสั่ง define) คุณจะใช้พื้นที่ในโค้ดแค่ครั้งเดียว

// กำหนดทิศทางแนวโน้ม
#define     UPTREND           1
#define     DOWNTREND         -1
#define     FLATTREND         0

// กำหนดวัตถุ
#define     TrendPanel        "TrendPanel"
#define     InfoLine1         "InfoLine1"
#define     InfoLine2         "InfoLine2"
#define     TrendLabel        "แนวโน้ม:  M1  M5  M15  M30  H1  H4  D1  W1  MN"
#define     TrendUp           "\233"
#define     TrendDown         "\234"
#define     TrendFlat         "\232"
#define     TrendUnknown      "\251"
#define     StatObjectError   "%s(%d) สร้าง '%s' ไม่สำเร็จ.  Error = %d"

ถัดไปผมจะกำหนดอาร์เรย์สองตัว หนึ่งสำหรับตำแหน่งพิกเซลสำหรับช่วงเวลาทั้ง 9 และอีกตัวสำหรับช่วงเวลา ซึ่งถูกกำหนดเป็นตัวแปรทั่วโลก

// กำหนดตัวแปรทั่วโลก
int      TrendPosition[] = { 44, 64, 88, 114, 136, 156, 174, 194, 216 };
int      TrendPeriods[] = { PERIOD_M1, PERIOD_M5, PERIOD_M15, PERIOD_M30, PERIOD_H1, PERIOD_H4, PERIOD_D1, PERIOD_W1, PERIOD_MN1 };

ฟังก์ชั่น OnInit() ของเราจะเรียกฟังก์ชั่นเพื่อสร้างพาแนลและวัตถุภายในพาแนล นอกจากนี้ยังทำการตรวจสอบ "Dumn Dumn" เร็ว ๆ ที่บาร์ที่ใช้ในการคำนวณแนวโน้ม หากน้อยกว่า 3 ก็แทบจะไร้ประโยชน์

//+------------------------------------------------------------------+
//| ฟังก์ชั่นเริ่มต้นของอินดิเคเตอร์                         |
//+------------------------------------------------------------------+
int   OnInit()
{
   // ไปสร้างวัตถุสำหรับพาแนลอินดิเคเตอร์
   if(Create_Panel() && BarCount >= 3)
      return(INIT_SUCCEEDED);
   else
      return(INIT_FAILED);
}

ผมจะไม่ลงรายละเอียดเกี่ยวกับการทำงานของฟังก์ชั่น GetTrend() จะมีเอกสารดี ๆ อยู่แล้วที่นี่สำหรับเรื่องนั้น เรามาดูฟังก์ชั่น DisplayTrend() ที่แสดงกราฟิกกันดีกว่า

//+------------------------------------------------------------------+
//| แสดงแนวโน้มปัจจุบันสำหรับทุกช่วงเวลา
//+------------------------------------------------------------------+
void  DisplayTrend(void)
{
   int      i, cntr, Trend, LastTrend;
   string   str;
   
   for(i=1; i<10; i++)
   {
      str = "Trend" + DoubleToStr(i, 0);
      Trend = (int)GetTrend(TrendPeriods[i-1], BarCount, Method);
      if(Trend == FLATTREND)
      {
         // แฟลต, หาแนวโน้มสุดท้าย
         cntr = 1;
         do 
         { 
            LastTrend = (int)GetTrend(TrendPeriods[i-1], BarCount, Method, false, cntr++);
         } while(LastTrend == Trend);
         ObjectSetText(str, TrendFlat, 8, "WingDings", (LastTrend == UPTREND ? Green : Red));
         ObjectSetInteger(0, str, OBJPROP_YDISTANCE, 6);
      }
      else
      {
         ObjectSetText(str, (Trend == UPTREND ? TrendUp : TrendDown), 8, "WingDings", (Trend == UPTREND ? Green : Red));
         ObjectSetInteger(0, str, OBJPROP_YDISTANCE, 5 + (Trend == UPTREND ? 1 : -1));
      }
   }
}

เราจะวนลูปผ่านอาร์เรย์ TrendPeriods[] (เพื่อให้ได้ทุกช่วงเวลา) และตั้งค่าสัญลักษณ์แนวโน้มตามทิศทางแนวโน้มของช่วงเวลานั้น ถ้าแนวโน้มแฟลต เราจะค้นหาทิศทางแรกที่ไม่แฟลตเพื่อทราบว่าแนวโน้มมาจากไหน เพื่อแสดงลูกศรด้านข้างในสีของทิศทางนั้น

ฟังก์ชั่น Create_Panel() ในฟังก์ชั่น OnInit() ของเราจะสร้างวัตถุที่ยึดติดอยู่ที่มุมล่างซ้ายของหน้าจอและใช้ TrendPosition[] เพื่อวางลูกศรในตำแหน่งที่ถูกต้อง

//+------------------------------------------------------------------+
//| สร้างพาแนลแนวโน้มที่มุมล่างซ้ายของหน้าจอ
//+------------------------------------------------------------------+
bool  Create_Panel(void)
{

   int      i;
   string   str;
   
   // สร้างหน้าต่างอินดิเคเตอร์แนวโน้ม
   if(ObjectCreate(TrendPanel, OBJ_RECTANGLE_LABEL, 0, 0, 0))
   {
      ObjectSetInteger(0, TrendPanel, OBJPROP_XDISTANCE, 1);
      ObjectSetInteger(0, TrendPanel, OBJPROP_YDISTANCE, 29);
      ObjectSetInteger(0, TrendPanel, OBJPROP_XSIZE, 240);
      ObjectSetInteger(0, TrendPanel, OBJPROP_YSIZE, 26);
      ObjectSetInteger(0, TrendPanel, OBJPROP_BGCOLOR, White);
      ObjectSetInteger(0, TrendPanel, OBJPROP_BORDER_TYPE, 0);
      ObjectSetInteger(0, TrendPanel, OBJPROP_CORNER, CORNER_LEFT_LOWER);
      ObjectSetInteger(0, TrendPanel, OBJPROP_COLOR, Red);
      ObjectSetInteger(0, TrendPanel, OBJPROP_STYLE, STYLE_SOLID);
      ObjectSetInteger(0, TrendPanel, OBJPROP_WIDTH, 2);
      ObjectSetInteger(0, TrendPanel, OBJPROP_BACK, false);
      ObjectSetInteger(0, TrendPanel, OBJPROP_SELECTABLE, false);
      ObjectSetInteger(0, TrendPanel, OBJPROP_SELECTED, false);
      ObjectSetInteger(0, TrendPanel, OBJPROP_HIDDEN, true);
      ObjectSetString(0, TrendPanel, OBJPROP_TOOLTIP, "\n");
   }
   else
   { PrintFormat(StatObjectError, __FUNCTION__, __LINE__, TrendPanel, GetLastError()); return(false); }

   if(ObjectCreate(InfoLine1, OBJ_LABEL, 0, 0, 0))
   {
      ObjectSet(InfoLine1, OBJPROP_CORNER, CORNER_LEFT_LOWER);
      ObjectSet(InfoLine1, OBJPROP_XDISTANCE, 6);
      ObjectSet(InfoLine1, OBJPROP_YDISTANCE, 15);
      ObjectSetInteger(0, InfoLine1, OBJPROP_SELECTABLE, false);
      ObjectSetInteger(0, InfoLine1, OBJPROP_HIDDEN, true);
      ObjectSetString(0, InfoLine1, OBJPROP_TOOLTIP, "\n");
      ObjectSetText(InfoLine1, TrendLabel, 8, "Arial", Black);
   }
   else
   { PrintFormat(StatObjectError, __FUNCTION__, __LINE__, InfoLine1, GetLastError()); return(false); }
   
   if(ObjectCreate(InfoLine2, OBJ_LABEL, 0, 0, 0))
   {
      ObjectSet(InfoLine2, OBJPROP_CORNER, CORNER_LEFT_LOWER);
      ObjectSet(InfoLine2, OBJPROP_XDISTANCE, 6);
      ObjectSet(InfoLine2, OBJPROP_YDISTANCE, 5);
      ObjectSetInteger(0, InfoLine2, OBJPROP_SELECTABLE, false);
      ObjectSetInteger(0, InfoLine2, OBJPROP_HIDDEN, true);
      ObjectSetString(0, InfoLine2, OBJPROP_TOOLTIP, "\n");
      ObjectSetText(InfoLine2, " " + DoubleToStr(BarCount, 0) + " / " + DoubleToStr(Method, 0), 8, "Arial", Black);
   }
   else
   { PrintFormat(StatObjectError, __FUNCTION__, __LINE__, InfoLine2, GetLastError()); return(false); }

   // สร้างวัตถุแนวโน้มและแสดงแนวโน้มปัจจุบัน    
   for(i=1; i<10; i++)
   {
      str = "Trend" + DoubleToStr(i, 0);
      if(ObjectCreate(str, OBJ_LABEL, 0, 0, 0))
      {
         ObjectSet(str, OBJPROP_CORNER, CORNER_LEFT_LOWER);
         ObjectSet(str, OBJPROP_XDISTANCE, TrendPosition[i-1]);
         ObjectSet(str, OBJPROP_YDISTANCE, 5);
         ObjectSetInteger(0, str, OBJPROP_SELECTABLE, false);
         ObjectSetInteger(0, str, OBJPROP_HIDDEN, true);
         ObjectSetString(0, str, OBJPROP_TOOLTIP, "\n");
      }
      else
      { PrintFormat(StatObjectError, __FUNCTION__, __LINE__, str, GetLastError()); return(false); }
   }

   // แสดงแนวโน้มปัจจุบัน
   DisplayTrend();
      
   // ทุกอย่างเรียบร้อย
   return(true);
}

ฟังก์ชั่นนี้จะส่งคืน TRUE หากการสร้างวัตถุทั้งหมดสำเร็จ หรือส่งคืน FALSE หากเกิดข้อผิดพลาดในการสร้างวัตถุ สิ่งที่ดีคืออินดิเคเตอร์จะแสดงในแท็บ EXPERT ของคอนโซลของคุณรหัสข้อผิดพลาดและหมายเลขบรรทัดของโค้ดที่เกิดข้อผิดพลาด

นอกจากนี้เรายังต้องอัปเดตอินดิเคเตอร์แนวโน้มสำหรับแต่ละ TICK ใหม่ที่เรารับมา ซึ่งทำได้โดยการเรียก DisplayTrend() ในฟังก์ชั่น start()

//+------------------------------------------------------------------+
//| ฟังก์ชั่นวนรอบของอินดิเคเตอร์                              |
//+------------------------------------------------------------------+
int   start()
{
   // แสดงแนวโน้มปัจจุบันสำหรับทุกช่วงเวลา
   DisplayTrend();   

   return(0);
}

สุดท้ายเราจะทำลายวัตถุทั้งหมดที่สร้างโดยอินดิเคเตอร์เมื่อเราปิดอินดิเคเตอร์

//+------------------------------------------------------------------+
//| ฟังก์ชั่นการยกเลิกการเริ่มทำงาน                                        |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   // ลบวัตถุของอินดิเคเตอร์
   if(ObjectFind(TrendPanel) >= 0) ObjectDelete(TrendPanel);
   if(ObjectFind(InfoLine1) >= 0) ObjectDelete(InfoLine1);
   if(ObjectFind(InfoLine2) >= 0) ObjectDelete(InfoLine2);
   for(int i=1; i<10; i++)
      if(ObjectFind("Trend"+DoubleToStr(i, 0)) >= 0) ObjectDelete("Trend"+DoubleToStr(i, 0));
}

แค่นี้ก็เรียบร้อยแล้วครับ คุณมีพาแนลอินดิเคเตอร์ที่แสดงแนวโน้มปัจจุบันสำหรับทุกช่วงเวลาอยู่ที่มุมล่างซ้ายของหน้าจอ

ขอให้สนุกกับการเทรด!

โพสต์ที่เกี่ยวข้อง

ความคิดเห็น (0)