Live News Code

 

Hello everyone,


Does anyone know how we can go and capture news data from public websites (such as forexfactory.com, tradingiew.com, investing.com, etc) in LIVE within a MQL code ?

I mean without having to download the CSV files manually and import it.

I wanna write a EA placing an order automatically if the outcome of a given news were greater than certain amount.

Thanks in advance, if you could show a piece of code

Regards,

 
You can use Python.
 
Marco vd Heijden:
You can use Python.

Thank you,

how is that, do you have any piece of Python code for that ?



 
You have to invent it there are many modules you can use for that and if you do not know Python you can have it made over here: https://www.mql5.com/en/job
Trading applications for MetaTrader 5 to order
Trading applications for MetaTrader 5 to order
  • www.mql5.com
حدد مواصفات متطلباتك هنا نقطة تلو الأخرى. حاول وصف متطلباتك باختصار وبوضوح ، حتى يتمكن مطور البرامج المحتمل من تقييم مدى تعقيده وتكلفته بشكل صحيح ، بالإضافة إلى وقت التنفيذ المطلوب. سيؤدي الوصف السيئ أو العام جدًا إلى تجاهل طلبك ، وإلا ستقضي الكثير من الوقت في التفاوض على التفاصيل مع كل مقدم طلب. تذكر: من الأفضل قضاء ثلاثين دقيقة لإعداد نص جيد...
 
pmemari:

Thank you,

how is that, do you have any piece of Python code for that ?



You can use this script which leverages the myfxbook news calendar

  1. Login to myfxbook with chrome.
  2. Make sure the time-zone matches your broker in the myfxbook account settings
  3. Go to the myfxb economic calendar and change the settings for your desired data e.g. Impact, currency, etc.
  4. With the chrome window selected hit F12 (inspect) 
  5. Click on the network tab in the inspection window
  6. reload the calendar page
  7. click on the first item in the "Name" window
  8. Click the headers tab and copy the headers under request headers and save to "headers.txt" in the same path as the script
  9. run script -- python script.py
  10. The first run you will be prompted for the path to the MQL common files directory... paste directory and press enter. 
  11. The events will be parsed and saved to a TSV (tab [\t] sep file) named "news_events.tsv" which is found in the common dir

import csv
import datetime
import json
import re
import sys
import time
from pathlib import Path

import requests

# remove spaces in url
URL = 'https: / / www.myfxbook.com / calendar_statement.csv'


def myfx_to_mql_time(time):
    dt = datetime.datetime.strptime(time, '%Y, %B %d, %H:%M')
    return dt.strftime('%Y.%m.%d %H:%M')


def str_to_float(num):
    is_percent = False
    if '%' in num:
        is_percent = True
    p = re.compile(r'(-?).*?([0-9.]+)')
    m = p.search(num)
    if m:
        res = float(''.join(m.groups()))
        if is_percent:
            res = round(res / 100.0, 4)
        return res
    return None


def get_config():
    conf = Path() / 'news_conf.json'
    if conf.exists():
        conf_d = json.loads(conf.read_text())
    else:
        common = Path(input("MQL common path >>> "))
        if not common.exists():
            raise Exception(f'{common} does not exits')
        update_interval = int(input('update interval in seconds >>> '))
        conf_d = {
            'common'  : str(common.absolute()),
            'interval': update_interval,
        }
        conf.write_text(json.dumps(conf_d))
    return conf_d


def get_headers():
    cookies = Path('headers.txt')
    if not cookies.exists():
        raise FileNotFoundError('NO HEADERS FILE')
    headers = {}
    with open(cookies) as f:
        p = re.compile(r'(.*?):\s?(.*)')
        for line in f:
            m = p.match(line)
            if m:
                key, val = m.group(1), m.group(2)
                headers[key] = val
            else:
                raise Exception(f'Error in {cookies}')
    return headers


def get_csv():
    r = requests.get(URL, headers=get_headers())
    reader = csv.reader(r.text.split('\n'))
    headers = next(reader)
    results = [dict(zip(headers, row)) for row in reader]
    if not headers or not reader:
        raise Exception()
    for res in results:
        for k, v in res.items():
            if k == 'Date':
                res['Date'] = myfx_to_mql_time(res['Date'])
            elif k in ['Previous', 'Consensus', 'Actual', 'Currency']:
                new_val = str_to_float(v)
                if new_val is not None:
                    res[k] = new_val
    return results


def save_csv(event_csv, save_path):
    fields = 'Date Event Impact Previous Consensus Actual Currency'.split()
    with open(save_path, 'w', newline='\n') as f:
        writer = csv.DictWriter(f, fieldnames=fields, delimiter='\t')
        writer.writeheader()
        writer.writerows(event_csv)


def main():
    config = get_config()
    save_path = Path(config['common']) / 'news_events.tsv'
    interval = config['interval']
    while True:
        try:
            event_csv = get_csv()
            save_csv(event_csv, save_path)
            print('updated:', datetime.datetime.now())
        except PermissionError:
            print('CANNOT OPEN FILE. OPEN with flags=FILE_SHARE...')
        except KeyboardInterrupt:
            sys.exit('exiting now...')
        except Exception:
            raise
        time.sleep(interval)


if __name__ == '__main__':
    main()
Files:
 

Update: headers now cached for performance. 


import csv
import datetime
import json
import re
import sys
import time
from functools import lru_cache
from pathlib import Path

import requests

URL = 'https:/ /www.myfxbook.com/ calendar_statement.csv'


def myfx_to_mql_time(time):
    dt = datetime.datetime.strptime(time, '%Y, %B %d, %H:%M')
    return dt.strftime('%Y.%m.%d %H:%M')


def str_to_float(num):
    is_percent = False
    if '%' in num:
        is_percent = True
    p = re.compile(r'(-?).*?([0-9.]+)')
    m = p.search(num)
    if m:
        res = float(''.join(m.groups()))
        if is_percent:
            res = round(res / 100.0, 4)
        return res
    return None


def get_config():
    conf = Path() / 'news_conf.json'
    if conf.exists():
        conf_d = json.loads(conf.read_text())
    else:
        common = Path(input("MQL common path >>> "))
        if not common.exists():
            raise Exception(f'{common} does not exits')
        update_interval = int(input('update interval in seconds >>> '))
        conf_d = {
            'common'  : str(common.absolute()),
            'interval': update_interval,
        }
        conf.write_text(json.dumps(conf_d))
    return conf_d


@lru_cache(None)
def get_headers():
    cookies = Path('headers.txt')
    if not cookies.exists():
        raise FileNotFoundError('NO HEADERS FILE')
    headers = {}
    with open(cookies) as f:
        p = re.compile(r'(.*?):\s?(.*)')
        for line in f:
            m = p.match(line)
            if m:
                key, val = m.group(1), m.group(2)
                headers[key] = val
            else:
                raise Exception(f'Error in {cookies}')
    return headers


def get_csv():
    r = requests.get(URL, headers=get_headers())
    reader = csv.reader(r.text.split('\n'))
    headers = next(reader)
    results = [dict(zip(headers, row)) for row in reader]
    if not headers or not reader:
        raise Exception()
    for res in results:
        for k, v in res.items():
            if k == 'Date':
                res['Date'] = myfx_to_mql_time(res['Date'])
            elif k in ['Previous', 'Consensus', 'Actual', 'Currency']:
                new_val = str_to_float(v)
                if new_val is not None:
                    res[k] = new_val
    return results


def save_csv(event_csv, save_path):
    fields = 'Date Event Impact Previous Consensus Actual Currency'.split()
    with open(save_path, 'w', newline='\n') as f:
        writer = csv.DictWriter(f, fieldnames=fields, delimiter='\t')
        writer.writeheader()
        writer.writerows(event_csv)


def main():
    config = get_config()
    save_path = Path(config['common']) / 'news_events.tsv'
    interval = config['interval']
    while True:
        try:
            event_csv = get_csv()
            save_csv(event_csv, save_path)
            print('updated:', datetime.datetime.now())
        except PermissionError:
            print('CANNOT OPEN FILE. OPEN with flags=FILE_SHARE...')
        except KeyboardInterrupt:
            sys.exit('exiting now...')
        except Exception:
            raise
        time.sleep(interval)


if __name__ == '__main__':
    main()
 
nicholi shen:

Update: headers now cached for performance. 


Great answer! Your are the top Nicholi!

 
pmemari:

Great answer! Your are the top Nicholi!

Did you get it working?

 
pmemari:

Great answer! Your are the top Nicholi!

not yet, but I got the point. I am working on it
 

To use the news filter, you need: In the trading terminal, in the menu, open "Tools" ---> "Settings" ---> "Advisors" ---> add the address "http://calendar.fxstreet.com" in the "Allow WebRequest for the following URLs ".

//+------------------------------------------------------------------+
//|                                                         NEWS.mq4 |
//|                               Copyright 2019, Vladimir Gribachev |
//|                      https://www.mql5.com/ru/users/moneystrategy |
//+------------------------------------------------------------------+
#property copyright "Copyright 2019, Vladimir Gribachev"
#property link      "https://www.mql5.com/ru/users/moneystrategy"
#property version   "1.00"
#property strict

enum NEWS
  {
   ALL,
   LOW,
   MEDIUM,
   HIGH
  };
//---    

struct sNews
  {
   datetime          dTime;
   string            time; // Время новостей
   string            currency; // Валюта
   string            importance; // Важность
   string            news; // Новости
   string            Actual; // Фактические данные
   string            forecast; // Прогнозные данные
   string            previus; // Предыдущий показатель
  };

input bool               NEWS_FILTER        = true;
input NEWS               NEWS_IMPOTANCE     = ALL;
input int                STOP_BEFORE_NEWS   = 30;
input int                START_AFTER_NEWS   = 30;

string LANG="en-US";
sNews NEWS_TABLE[],HEADS;
datetime date;
int TIME_CORRECTION,NEWS_ON=0;

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   if(!IsTesting() || !IsOptimization())
     {
      if(NEWS_FILTER==true && READ_NEWS(NEWS_TABLE) && ArraySize(NEWS_TABLE)>0)DRAW_NEWS(NEWS_TABLE);
      TIME_CORRECTION=(-TimeGMTOffset());
     }
   EventSetTimer(1);

   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   DEINIT_PANEL();
      EventKillTimer();

  }
  
void OnTimer()
  {
   OnTick();
   if(NEWS_FILTER==false)return;
   static int waiting=0;
   if(waiting<=0)
     {
      if(!IsTesting())
        {
         if(READ_NEWS(NEWS_TABLE))
            waiting=100;
         if(ArraySize(NEWS_TABLE)<=0)
            return;
         DRAW_NEWS(NEWS_TABLE);
        }
     }
   else
      waiting--;
   if(ArraySize(NEWS_TABLE)<=0)
      return;

   datetime time=TimeGMT()+TIME_CORRECTION;
   string SYM_BASE=SymbolInfoString(_Symbol,SYMBOL_CURRENCY_BASE);
   string SYM_PROFIT=SymbolInfoString(_Symbol,SYMBOL_CURRENCY_PROFIT);
//---   
   for(int i=0; i<ArraySize(NEWS_TABLE); i++)
     {
      datetime news_time=NEWS_TABLE[i].dTime+TIME_CORRECTION;
      if((SYM_BASE!=NEWS_TABLE[i].currency && SYM_PROFIT!=NEWS_TABLE[i].currency))
         continue;
      if((news_time<=time && (news_time+(datetime)(START_AFTER_NEWS*60))>=time) ||
         (news_time>=time && (news_time-(datetime)(STOP_BEFORE_NEWS*60))<=time))
        {
         NEWS_ON=1;
         break;
        }
      else
         NEWS_ON=0;
     }
   return;
  }  
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   
  }
//+------------------------------------------------------------------+
void DEL_ROW(sNews &l_a_news[],int row)
  {
//Print(__FUNCTION__," ",__LINE__);
   int size=ArraySize(l_a_news)-1;
   for(int i=row; i<size; i++)
     {
      l_a_news[i].Actual=l_a_news[i+1].Actual;
      l_a_news[i].currency=l_a_news[i+1].currency;
      l_a_news[i].dTime=l_a_news[i+1].dTime;
      l_a_news[i].forecast=l_a_news[i+1].forecast;
      l_a_news[i].importance=l_a_news[i+1].importance;
      l_a_news[i].news=l_a_news[i+1].news;
      l_a_news[i].previus=l_a_news[i+1].previus;
      l_a_news[i].time=l_a_news[i+1].time;
     }
   ArrayResize(l_a_news,size);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool READ_NEWS(sNews &l_NewsTable[])
  {
//Print(__FUNCTION__," ",__LINE__);
   string cookie=NULL,referer=NULL,headers;
   char post[],result[];
   string tmpStr="";
   string st_date=TimeToString(TimeCurrent(),TIME_DATE),end_date=TimeToString((TimeCurrent()+(datetime)(7*24*60*60)),TIME_DATE);
   StringReplace(st_date,".","");
   StringReplace(end_date,".","");
   string url=StringConcatenate("http://calendar.fxstreet.com/EventDateWidget/GetMini?culture=",LANG,"&view=range&start=",st_date,"&end=",end_date,"&timezone=UTC&columns=date%2Ctime%2Ccountry%2Ccountrycurrency%2Cevent%2Cconsensus%2Cprevious%2Cvolatility%2Cactual&showcountryname=false&showcurrencyname=true&isfree=true&_=1455009216444");
//StringToCharArray(body,post);
   ResetLastError();
   WebRequest("GET",url,cookie,referer,10000,post,sizeof(post),result,headers);
   if(ArraySize(result)<=0)
     {
      int er=GetLastError();
      ResetLastError();
      Print("ERROR_TXT IN WebRequest");
      //--- возможно, URL отсутствует в списке, выводим сообщение о необходимости его добавления 
      if(er==4060)
         MessageBox("YOU MUST ADD THE ADDRESS '"+"http://calendar.fxstreet.com/"+"' IN THE LIST OF ALLOWED URL IN THE TAB 'ADVISERS'","ERROR_TXT",MB_ICONINFORMATION);
      return false;
     }

   tmpStr=CharArrayToString(result,0,WHOLE_ARRAY,CP_UTF8);
   int handl=FileOpen("News.txt",FILE_WRITE|FILE_TXT);
   FileWrite(handl,tmpStr);
   FileFlush(handl);
   FileClose(handl);
   StringReplace(tmpStr,"&#39;","'");
   StringReplace(tmpStr,"&#163;","");
   StringReplace(tmpStr,"&#165;","");
   StringReplace(tmpStr,"&amp;","&");

   int st=StringFind(tmpStr,"fxst-thevent",0);
   st=StringFind(tmpStr,">",st)+1;
   int end=StringFind(tmpStr,"</th>",st);
   HEADS.news=(st<end ? StringSubstr(tmpStr,st,end-st) :"");
   st=StringFind(tmpStr,"fxst-thvolatility",0);
   st=StringFind(tmpStr,">",st)+1;
   end=StringFind(tmpStr,"</th>",st);
   HEADS.importance=(st<end ? StringSubstr(tmpStr,st,fmin(end-st,8)) :"");
   st=StringFind(tmpStr,"fxst-thactual",0);
   st=StringFind(tmpStr,">",st)+1;
   end=StringFind(tmpStr,"</th>",st);
   HEADS.Actual=(st<end ? StringSubstr(tmpStr,st,fmin(end-st,8)) :"");
   st=StringFind(tmpStr,"fxst-thconsensus",0);
   st=StringFind(tmpStr,">",st)+1;
   end=StringFind(tmpStr,"</th>",st);
   HEADS.forecast=(st<end ? StringSubstr(tmpStr,st,fmin(end-st,8)) :"");
   st=StringFind(tmpStr,"fxst-thprevious",0);
   st=StringFind(tmpStr,">",st)+1;
   end=StringFind(tmpStr,"</th>",st);
   HEADS.previus=(st<end ? StringSubstr(tmpStr,st,end-st) :"");
   HEADS.currency="";
   HEADS.dTime=0;
   HEADS.time="";
   int startLoad=StringFind(tmpStr,"<tbody>",0)+7;
   int endLoad=StringFind(tmpStr,"</tbody>",startLoad);
   if(startLoad>=0 && endLoad>startLoad)
     {
      tmpStr=StringSubstr(tmpStr,startLoad,endLoad-startLoad);
      while(StringReplace(tmpStr,"  "," "));
     }
   else
      return false;
   int begin=-1;
   do
     {
      begin=StringFind(tmpStr,"<span",0);
      if(begin>=0)
        {
         end=StringFind(tmpStr,"</span>",begin)+7;
         tmpStr=StringConcatenate(StringSubstr(tmpStr,0,begin),StringSubstr(tmpStr,end));
        }
     }
   while(begin>=0);
   StringReplace(tmpStr,"<strong>",NULL);
   StringReplace(tmpStr,"</strong>",NULL);
   int BackShift=0;
   string arNews[];
   for(uchar tr=1;tr<255;tr++)
     {
      if(StringFind(tmpStr,CharToString(tr),0)>0)
         continue;
      int K=StringReplace(tmpStr,"</tr>",CharToString(tr));
      //ArrayResize(arNews,StringReplace(tmpStr,"</tr>",CharToString(tr)));
      K=StringSplit(tmpStr,tr,arNews);
      ArrayResize(l_NewsTable,K);
      for(int td=0;td<ArraySize(arNews);td++)
        {
         st=StringFind(arNews[td],"fxst-td-date",0);
         if(st>0)
           {
            st=StringFind(arNews[td],">",st)+1;
            end=StringFind(arNews[td],"</td>",st)-1;
            int d=(int)StringToInteger(StringSubstr(arNews[td],end-4,end-st));
            MqlDateTime time;
            TimeCurrent(time);
            if(d<(time.day-5))
              {
               if(time.mon==12)
                 {
                  time.mon=1;
                  time.year++;
                 }
               else
                 {
                  time.mon++;
                 }
              }
            time.day=d;
            time.min=0;
            time.hour=0;
            time.sec=0;
            date=StructToTime(time);
            BackShift++;
            continue;
           }
         st=StringFind(arNews[td],"fxst-evenRow",0);
         if(st<0)
           {
            BackShift++;
            continue;
           }
         int st1=StringFind(arNews[td],"fxst-td-time",st);
         st1=StringFind(arNews[td],">",st1)+1;
         end=StringFind(arNews[td],"</td>",st1);
         l_NewsTable[td-BackShift].time=StringSubstr(arNews[td],st1,end-st1);
         if(StringFind(l_NewsTable[td-BackShift].time,":")>0)
           {
            l_NewsTable[td-BackShift].dTime=StringToTime(TimeToString(date,TIME_DATE)+" "+StringSubstr(arNews[td],st1,end-st1));
           }
         else
           {
            l_NewsTable[td-BackShift].dTime=date;
           }
         st1=StringFind(arNews[td],"fxst-td-currency",st);
         st1=StringFind(arNews[td],">",st1)+1;
         end=StringFind(arNews[td],"</td>",st1);
         l_NewsTable[td-BackShift].currency=(st1<end ? StringSubstr(arNews[td],st1,end-st1) :"");
         st1=StringFind(arNews[td],"fxst-i-vol",st);
         st1=StringFind(arNews[td],">",st1)+1;
         end=StringFind(arNews[td],"</td>",st1);
         StringInit(l_NewsTable[td-BackShift].importance,(int)StringToInteger(StringSubstr(arNews[td],st1,end-st1)),'*');
         st1=StringFind(arNews[td],"fxst-td-event",st);
         int st2=StringFind(arNews[td],"fxst-eventurl",st1);
         st1=StringFind(arNews[td],">",fmax(st1,st2))+1;
         end=StringFind(arNews[td],"</td>",st1);
         int end1=StringFind(arNews[td],"</a>",st1);
         l_NewsTable[td-BackShift].news=StringSubstr(arNews[td],st1,(end1>0 ? fmin(end,end1):end)-st1);
         st1=StringFind(arNews[td],"fxst-td-act",st);
         st1=StringFind(arNews[td],">",st1)+1;
         end=StringFind(arNews[td],"</td>",st1);
         l_NewsTable[td-BackShift].Actual=(end>st1 ? StringSubstr(arNews[td],st1,end-st1) : "");
         st1=StringFind(arNews[td],"fxst-td-cons",st);
         st1=StringFind(arNews[td],">",st1)+1;
         end=StringFind(arNews[td],"</td>",st1);
         l_NewsTable[td-BackShift].forecast=(end>st1 ? StringSubstr(arNews[td],st1,end-st1) : "");
         st1=StringFind(arNews[td],"fxst-td-prev",st);
         st1=StringFind(arNews[td],">",st1)+1;
         end=StringFind(arNews[td],"</td>",st1);
         l_NewsTable[td-BackShift].previus=(end>st1 ? StringSubstr(arNews[td],st1,end-st1) : "");
        }
      break;
     }
   ArrayResize(l_NewsTable,(ArraySize(l_NewsTable)-BackShift));
   return(true);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void DRAW_NEWS(sNews &l_a_news[])
  {

   if(NEWS_FILTER==false)return;
   string SYM_BASE=SymbolInfoString(_Symbol,SYMBOL_CURRENCY_BASE);
   string SYM_PROFIT=SymbolInfoString(_Symbol,SYMBOL_CURRENCY_PROFIT);
   for(int i=ArraySize(l_a_news)-1; i>=0; i--)
     {
      StringReplace(l_a_news[i].currency," ","");
      bool l1=(l_a_news[i].currency!=SYM_BASE);
      bool l2=(l_a_news[i].currency!=SYM_PROFIT);
      datetime time=TimeGMT()+TIME_CORRECTION;
      datetime news_time=NEWS_TABLE[i].dTime+TIME_CORRECTION;
      //Print(l_a_news[i].dTime);
      datetime t1=(l_a_news[i].dTime+(datetime)(START_AFTER_NEWS*60));
      datetime t2=((TimeCurrent()-(datetime)TIME_CORRECTION));
      if((l_a_news[i].currency!=SYM_BASE && l_a_news[i].currency!=SYM_PROFIT) || t1<t2)
        {
         DEL_ROW(l_a_news,i);
         continue;
        }

      //проверка на важность новости     
      if((NEWS_IMPOTANCE==LOW && l_a_news[i].importance!="*") ||
         (NEWS_IMPOTANCE==MEDIUM && l_a_news[i].importance!="**") ||
         (NEWS_IMPOTANCE==HIGH && l_a_news[i].importance!="***"))
        {
         DEL_ROW(l_a_news,i);
         continue;
        }
      string NAME="PANEL_NEWS_"+(string)(l_a_news[i].dTime+TIME_CORRECTION);
      if(ObjectFind(0,NAME)<0)
         ObjectCreate(0,NAME,OBJ_EVENT,0,l_a_news[i].dTime+TIME_CORRECTION,0);
      ObjectSetString(0,NAME,OBJPROP_TEXT,l_a_news[i].news);
      ObjectSetInteger(0,NAME,OBJPROP_SELECTABLE,false);
      ObjectSetInteger(0,NAME,OBJPROP_SELECTED,false);
      ObjectSetInteger(0,NAME,OBJPROP_HIDDEN,true);
      ObjectSetInteger(0,NAME,OBJPROP_BACK,false);
      //ChartSetInteger(0,NAME,CHART_FOREGROUND,true);
     }
   string NAME;
   int K=0,Z=0;
   for(int l=1;l<=9 && Z<ArraySize(l_a_news);l++)
     {
      for(K=Z; K<ArraySize(l_a_news);K++)
         if(l_a_news[K].currency!="")
            break;
      Z=K+1;

      int X = -225;
      int Y = 371;
      NAME="PANEL_NEWS_T"+(string)l;
      if(ObjectFind(0,NAME)<0)OBJECT_LABEL(0,NAME,0,X+570,Y-(int)(22*(l+5)),CORNER_LEFT_LOWER,TimeToString(l_a_news[K].dTime+TIME_CORRECTION,TIME_DATE|TIME_MINUTES),"Arial",10,color("0, 255, 255"),0,ANCHOR_LEFT_UPPER,FALSE,FALSE,TRUE,0);

      //NAME="PANEL_NEWS_I"+(string)l;
      //if(ObjectFind(0,NAME)<0)OBJECT_LABEL(0,NAME,0,X+680,Y-(int)(22*(l+5)),CORNER_LEFT_LOWER,l_a_news[K].importance,"Arial",10,color("0, 255, 255"),0,ANCHOR_LEFT_UPPER,FALSE,FALSE,TRUE,0);

      NAME="PANEL_NEWS_N"+(string)l;
      if(ObjectFind(0,NAME)<0)OBJECT_LABEL(0,NAME,0,X+680,Y-(int)(22*(l+5)),CORNER_LEFT_LOWER,TO_UPPER(l_a_news[K].news),"Arial",10,color("0, 255, 255"),0,ANCHOR_LEFT_UPPER,FALSE,FALSE,TRUE,0);

     }
   return;
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
string TO_UPPER(string IN)
  {
   string OUT;
   int CHAR,i;
   for(i=0;i<StringLen(IN);i++)
     {
      CHAR=StringGetChar(IN,i);
      if(CHAR>=97 && CHAR<=122)CHAR-=32;
      OUT=OUT+CharToStr(CHAR);
     }
   return(OUT);
  }
//+------------------------------------------------------------------+
void DEINIT_PANEL()
  {
   for(int i=ObjectsTotal()-1; i>=0; i--)
     {
      if(StringFind(ObjectName(i),"PANEL")>=0)
         ObjectDelete(ObjectName(i));
     }
  }
  
bool OBJECT_LABEL(const long              CHART_ID=0,
                  const string            NAME        = "",
                  const int               SUB_WINDOW  = 0,
                  const int               X           = 0,
                  const int               Y           = 0,
                  const ENUM_BASE_CORNER  CORNER      = CORNER_LEFT_UPPER,
                  const string            TEXT        = "",
                  const string            FONT        = "",
                  const int               FONT_SIZE   = 10,
                  const color             CLR         = color("255,0,0"),
                  const double            ANGLE       = 0.0,
                  const ENUM_ANCHOR_POINT ANCHOR      = ANCHOR_LEFT_UPPER,
                  const bool              BACK        = FALSE,
                  const bool              SELECTION   = FALSE,
                  const bool              HIDDEN      = TRUE,
                  const long              ZORDER      = 0,
                  string                  TOOLTIP     = "\n")
  {
   ResetLastError();
   if(ObjectFind(NAME)<0)
     {
      ObjectCreate(CHART_ID,NAME,OBJ_LABEL,SUB_WINDOW,0,0);
      ObjectSetInteger(CHART_ID,NAME,OBJPROP_XDISTANCE,X);
      ObjectSetInteger(CHART_ID,NAME,OBJPROP_YDISTANCE,Y);
      ObjectSetInteger(CHART_ID,NAME,OBJPROP_CORNER,CORNER);
      ObjectSetString(CHART_ID,NAME,OBJPROP_TEXT,TEXT);
      ObjectSetString(CHART_ID,NAME,OBJPROP_FONT,FONT);
      ObjectSetInteger(CHART_ID,NAME,OBJPROP_FONTSIZE,FONT_SIZE);
      ObjectSetDouble(CHART_ID,NAME,OBJPROP_ANGLE,ANGLE);
      ObjectSetInteger(CHART_ID,NAME,OBJPROP_ANCHOR,ANCHOR);
      ObjectSetInteger(CHART_ID,NAME,OBJPROP_COLOR,CLR);
      ObjectSetInteger(CHART_ID,NAME,OBJPROP_BACK,BACK);
      ObjectSetInteger(CHART_ID,NAME,OBJPROP_SELECTABLE,SELECTION);
      ObjectSetInteger(CHART_ID,NAME,OBJPROP_SELECTED,SELECTION);
      ObjectSetInteger(CHART_ID,NAME,OBJPROP_HIDDEN,HIDDEN);
      ObjectSetInteger(CHART_ID,NAME,OBJPROP_ZORDER,ZORDER);
      ObjectSetString(CHART_ID,NAME,OBJPROP_TOOLTIP,TOOLTIP);
     }
   else
     {
      ObjectSetInteger(CHART_ID,NAME,OBJPROP_COLOR,CLR);
      ObjectSetString(CHART_ID,NAME,OBJPROP_TEXT,TEXT);
      ObjectSetInteger(CHART_ID,NAME,OBJPROP_XDISTANCE,X);
      ObjectSetInteger(CHART_ID,NAME,OBJPROP_YDISTANCE,Y);
     }
   return(true);
   ChartRedraw();
  }  
Files:
NEWS.mq4  35 kb
NEWS.ex4  30 kb
 
nicholi shen:

Did you get it working?

the
URL = 'https:/ /www.myfxbook.com/ calendar_statement.csv'

is empty! 

My headers.txt file is attached. Do you have any idea of what is the problem ? 

Files:
headers.txt  2 kb
Reason: