होम सिस्टम ट्रेडिंग पोस्ट

ForexFactory.com से उच्च प्रभाव वाले इवेंट्स को प्राप्त करें और अपने EA में प्रदर्शित करें

संलग्नक
15505.zip (2.86 KB, डाउनलोड 0 बार)

नमस्ते दोस्तों! आज हम बात करेंगे कि कैसे हम ForexFactory.com से उच्च प्रभाव वाले इवेंट्स की जानकारी प्राप्त कर सकते हैं और उसे अपने Expert Advisor (EA) में प्रदर्शित कर सकते हैं। मैं वर्तमान में क्रूड ऑयल और ब्रेंट के लिए एक EA विकसित कर रहा हूँ और मुझे 'क्रूड ऑयल इन्वेंट्री' रिपोर्ट की सही तारीख और समय चाहिए। यह रिपोर्ट आमतौर पर बुधवार को सुबह 10:30 बजे ईस्टर्न टाइम पर जारी होती है, लेकिन छुट्टियों के दौरान इसकी तारीख बदल सकती है। इसलिए, इसकी सही तारीख जानने के लिए हमें ऑनलाइन सेवा का उपयोग करना पड़ा।

पहला कदम है OPTIONS | EXPERT ADVISOR टैब में उस वेबसाइट का URL जोड़ना जिसका उपयोग हम WebRequest बनाने के लिए करेंगे, जो है 'http://www.forexfactory.com/'। (चित्र 1 देखें)

इसके बाद, हमें अपने कोड में एक संरचना को परिभाषित करना होगा ताकि हम इवेंट्स को स्टोर कर सकें। इसे अपने कोड के शीर्ष पर कहीं रखना है, जो 'DailyEvents' को एक वैश्विक वेरिएबल के रूप में घोषित करेगा, जिसकी अधिकतम संख्या 'MaxDailyEvents' वेरिएबल द्वारा परिभाषित की जाएगी।

// इवेंट संरचना को परिभाषित करें
struct EVENTS
{
   string   time;
   string   title;
   string   currency;
   bool     displayed;
};

#define     MaxDailyEvents       20    // अगर आपको लगता है कि आपके पास 20 से अधिक उच्च प्रभाव वाले इवेंट्स होंगे, तो इस संख्या को बढ़ाएँ।
EVENTS      DailyEvents[MaxDailyEvents];

अब हमें ForexFactory.com से HTML कोड को प्राप्त करना और उसे पार्स करना है। अगर आपको HTML कोड समझ में नहीं आता, तो कोई बात नहीं, मैं आपको इसे समझा दूंगा :)

पहले हमें WebRequest के लिए URL बनाना है। चूंकि मैं केवल उस दिन का कैलेंडर चाहता था और डिफ़ॉल्ट (सप्ताह भर) नहीं, इसलिए हम 'day' पैरामीटर को आज की तारीख पर सेट कर सकते हैं और अनुरोध भेज सकते हैं।

string   url="http://www.forexfactory.com/calendar.php?day="; url += MthName(Month()) + DoubleToStr(Day(), 0) + "." + DoubleToStr(Year(), 0);

अब हम अनुरोध भेजते हैं, त्रुटि कोड की जांच करते हैं (यदि कोई हो) और लौटाए गए कैरेक्टर ऐरे को एक स्ट्रिंग में परिवर्तित करते हैं। इससे HTML कोड को पार्स करना आसान हो जाता है।

// वेब अनुरोध भेजें
   ResetLastError();
   res = WebRequest("GET", url, cookie, NULL, timeout, post, 0, result, headers);

   // त्रुटियों की जांच करें
   if(res == -1)
   {
      Print("WebRequest में त्रुटि। त्रुटि कोड = ", GetLastError());
      MessageBox("'http://forexfactory.com/' का पता 'Expert Advisors' टैब पर अनुमत URL की सूची में जोड़ें", "त्रुटि", MB_ICONINFORMATION);
      return(false);
   }

अगर कोई त्रुटि नहीं है, तो हम कैरेक्टर ऐरे 'result' को एक स्ट्रिंग में परिवर्तित करते हैं ताकि इसे बेहतर तरीके से पार्स किया जा सके।

// कैरेक्टर ऐरे को स्ट्रिंग में परिवर्तित करें
HTML = CharArrayToString(result);

अब जब हमारे पास एक स्ट्रिंग है, हम 'StringFind' फ़ंक्शन का उपयोग करके HTML तत्वों को खोज सकते हैं। सबसे पहले, हमें यह सुनिश्चित करना है कि लौटाया गया HTML वास्तव में आज की तारीख के लिए है और इस HTML टैग से पहले कुछ भी नहीं होना चाहिए। 'GetHTMLElement' फ़ंक्शन का उपयोग करके हम HTML को पार्स कर सकते हैं और निर्दिष्ट HTML टैग के बीच का मान प्राप्त कर सकते हैं। इसके नीचे इसकी परिभाषा देखें।

// कैलेंडर लोड हुआ, सुनिश्चित करें कि यह आज की तारीख के लिए है
int i = StringFind(HTML, "<span class=\"date\">");
if(i == -1) return(false);
HTML = StringSubstr(HTML, i);
string date = GetHTMLElement(HTML, "<span>", "</span>");
if(date != MthName(Month()) + " " + DoubleToStr(Day(), 0)) return(false);

अब हमें प्रत्येक इवेंट के लिए तालिका की पंक्तियों को पार्स करना है और हमें जिन तत्वों की आवश्यकता है, उन्हें निकालना है। यथा इवेंट समय, इवेंट मुद्रा, इवेंट प्रभाव और इवेंट शीर्षक। हमें HTML कोड में अंतिम तक के लिए यह करना है या जब तक MaxDailyEvents नहीं पहुँच जाते।

एक बार जब हर पंक्ति के लिए डेटा निकाला जाता है, तो हम इसे DailyEvents संरचना में जोड़ देते हैं।

// अब प्रत्येक इवेंट के लिए तालिका की पंक्तियाँ प्राप्त करें
lasttime = NULL;
cnrt = 0;
date = DoubleToStr(Year(), 0) + "." + DoubleToStr(Month(), 0) + "." + DoubleToStr(Day(), 0) + " ";
do
{
   // इवेंट जानकारी प्राप्त करें
   time = GetHTMLElement(HTML, "<td class=\"calendar__cell calendar__time time\">", "</td>");
   if(StringFind(time, "<a name=\"upnext\"") == 0) time = GetHTMLElement(time, "class=\"upnext\">", "</span>");
   if(StringLen(time) != 0) lasttime = time;
   if(StringLen(time) == 0) time = lasttime; 
   time = date + time;
   currency = GetHTMLElement(HTML, "<td class=\"calendar__cell calendar__currency currency\">", "</td>");
   impact = GetHTMLElement(HTML, "<span title=\"", "\" class=\"");
   i = StringFind(impact, " Impact");
   if(i != -1) impact = StringSubstr(impact, 0, i);
   title = GetHTMLElement(HTML, "\"calendar__event-title\">", "</span>");
         
   // क्या यह एक उच्च प्रभाव वाला इवेंट है?
   if(StringFind(Symbol(), currency) != -1 && impact == "High")
   {
      // दैनिक इवेंट संरचना में जोड़ें
      DailyEvents[cntr].displayed = false;
      DailyEvents[cntr].time = time;
      DailyEvents[cntr].title = title;
      DailyEvents[cntr++].currency = currency;
   }
                  
   // HTML स्ट्रिंग को अगले तालिका की पंक्ति तक काटें
   i = StringFind(HTML, "</tbody> </table> </td> </tr> ");
   if(i != -1) HTML = StringSubstr(HTML, i+30);
   if(StringFind(HTML, "</table> <div class=\"foot\">") == 0) i = -1;
} while(i != -1 || cntr == MaxDailyEvents);

एक बार जब हम सभी तालिका की पंक्तियाँ पार्स कर लेते हैं और कैलेंडर के अंत तक पहुँच जाते हैं, तो हमें चार्ट पर इवेंट्स को प्रदर्शित करने की आवश्यकता होती है। यदि इवेंट भविष्य में है, तो मैं एक वर्टिकल लाइन प्रदर्शित करना चाहता हूँ और यदि अतीत में है, तो कोई लाइन नहीं।

// उच्च प्रभाव वाले इवेंट्स को प्रदर्शित करें, यदि कोई हो
lasttime = NULL;
for(cntr = 0; cntr < MaxDailyEvents; cntr++)
{
   if(StringLen(DailyEvents[cntr].time) == 0) break;
      
   // यदि अंतिम मार्केट वही समय नहीं था तो चार्ट पर इवेंट मार्कर बनाएं
   if(lasttime != DailyEvents[cntr].time)
   {
      res = cntr;
      // यदि हमें स्ट्रिंग में 'pm' है, तो समय में 12 घंटे जोड़ें
      if(StringFind(DailyEvents[cntr].time, "pm") != -1) DailyEvents[cntr].time = TimeToStr(StrToTime(DailyEvents[cntr].time) + 43200);
      if(ObjectCreate(0, Event + cntr, OBJ_EVENT, 0, StrToTime(DailyEvents[cntr].time), 0))
    {
      ObjectSetString(0, Event + cntr, OBJPROP_TEXT, DailyEvents[cntr].title + " (" + DailyEvents[cntr].currency + ")");
      ObjectSetInteger(0, Event + cntr, OBJPROP_COLOR, Red);
      ObjectSetInteger(0, Event + cntr, OBJPROP_WIDTH, 2);
      ObjectSetInteger(0, Event + cntr, OBJPROP_BACK, true);
      ObjectSetInteger(0, Event + cntr, OBJPROP_SELECTABLE, false);
      ObjectSetInteger(0, Event + cntr, OBJPROP_SELECTED, false);
      ObjectSetInteger(0, Event + cntr, OBJPROP_HIDDEN, true);
      ObjectSetString(0, Event + cntr, OBJPROP_TOOLTIP, DailyEvents[cntr].title + " (" + DailyEvents[cntr].currency + ")");
      }
      
      // यदि इवेंट भविष्य में है तो वर्टिकल लाइन बनाएं
      if(TimeCurrent() < TimeOffset(DailyEvents[cntr].time, 0))
      {
         if(ObjectCreate(0, VLine + cntr, OBJ_VLINE, 0, TimeOffset(DailyEvents[cntr].time, 0), 0))
         {
            ObjectSetInteger(0, VLine + cntr, OBJPROP_COLOR, Red);
            ObjectSetInteger(0, VLine + cntr, OBJPROP_WIDTH, 1);
            ObjectSetInteger(0, VLine + cntr, OBJPROP_BACK, true);
            ObjectSetInteger(0, VLine + cntr, OBJPROP_SELECTABLE, false);
            ObjectSetInteger(0, VLine + cntr, OBJPROP_SELECTED, false);
            ObjectSetInteger(0, VLine + cntr, OBJPROP_HIDDEN, true);
            ObjectSetString(0, VLine + cntr, OBJPROP_TOOLTIP, DailyEvents[cntr].title + " (" + DailyEvents[cntr].currency + ")");
        }
      }
      else
         DailyEvents[cntr].displayed = true;
   }
   else
   {
      title = ObjectGetString(0, Event + res, OBJPROP_TOOLTIP);            
      title += "\n" + DailyEvents[cntr].title + " (" + DailyEvents[cntr].currency + ")";
      ObjectSetString(0, Event + res, OBJPROP_TOOLTIP, title);
      if(TimeCurrent() < TimeOffset(DailyEvents[cntr].time, 0)) ObjectSetString(0, VLine + res, OBJPROP_TOOLTIP, title);
   }
   lasttime = DailyEvents[cntr].time;
}

यदि इवेंट भविष्य में हैं, तो मैं उपयोगकर्ता को एक आगामी इवेंट की सूचना देना चाहता हूँ यदि यह वर्तमान समय से 5 मिनट के भीतर है और वर्टिकल लाइन को हटा देना चाहता हूँ। यह आपके EA या इंडिकेटर के 'start()' फ़ंक्शन में कुछ कोड जोड़कर किया जा सकता है।

//+------------------------------------------------------------------+
//| एक्सपर्ट स्टार्ट फ़ंक्शन                                             |
//+------------------------------------------------------------------+
void start()
{
   string   event = NULL;
   
   // क्या अगले 5 मिनट में कोई उच्च प्रभाव वाला इवेंट है?
   for(int i = 0; i < MaxDailyEvents; i++)
   {
      if(StringLen(DailyEvents[i].time) == 0) break;
      if(TimeCurrent() >= StrToTime(DailyEvents[i].time) - 300 && TimeCurrent() < StrToTime(DailyEvents[i].time) && !DailyEvents[i].displayed)
      {
         // इवेंट 5 मिनट में...
         event += DailyEvents[i].title + " (" + DailyEvents[i].currency + "), ";
         DailyEvents[i].displayed = true;
         
         // इवेंट से संबंधित वर्टिकल लाइन को हटा दें
         if(ObjectFind("VLine" + DoubleToStr(i, 0)) >= 0) ObjectDelete("VLine" + DoubleToStr(i, 0));
      }
   }
   
   // क्या कुछ प्रदर्शित करने के लिए है?
   if(StringLen(event) != 0)
   {
      event += "5 मिनट में।";
      Alert(event);
   }
}

और अंत में, हमें दैनिक इवेंट्स प्राप्त करने की आवश्यकता है। यह आपके OnInit() फ़ंक्शन में एक लाइन जोड़कर किया जा सकता है।

//+------------------------------------------------------------------+
//| एक्सपर्ट इनिशियलाइजेशन फ़ंक्शन                                   |
//+------------------------------------------------------------------+
int OnInit()
{
   // आज के इवेंट्स प्राप्त करें
   GetHighImpactEvents();
   
   return(INIT_SUCCEEDED);
}

बहुत सरल। आप कोड को निश्चित रूप से संशोधित कर सकते हैं ताकि आप सभी इवेंट्स को मुद्रा जोड़ी के लिए प्रदर्शित कर सकें या अपने इंडिकेटर या EA में इनपुट पैरामीटर्स जोड़ सकें ताकि यह निर्दिष्ट कर सकें कि कौन सा प्रभाव प्रदर्शित करना है (उच्च, मध्यम या निम्न) और निश्चित रूप से मध्यरात्रि टर्नअराउंड के लिए एक चेक जोड़ें ताकि दैनिक इवेंट्स की एक नई सूची प्राप्त की जा सके, लेकिन मैं आपको इसके साथ खेलने दूंगा :)


धन्यवाद!

-क्लॉड।

संबंधित पोस्ट

टिप्पणी (0)