Market Informer Script - Скритите тайни на Брокерите

Мястото за ежедневни дискусии. Текущи сделки и прогнози. Вижте как се прилагат техниките за анализ на forex пазара в реално време.
Потребителски аватар
SvetoslavB
Мнения: 2
Регистриран: 21 юни 2018, 18:11
1 получени
2 дадени

Market Informer Script - Скритите тайни на Брокерите

Мнение от SvetoslavB » 21 юни 2018, 18:30

Здравейте,
Радвам се, че се появиха Български форуми за Трейдъри.
За всички Начинаещи и "Профита" публикувам мой авторски скрипт за преглед на пълната информация за търговия в Терминала на МТ4.
Във връзка с новите условия, наложени от EU, след понеделник всички ще имаме нужда от него.
Скрипта дава информация за инструмента, на който го пуснете. :grin:

Screenshot.png
Screenshot.png (85.81 KБ) Видяна 862 пъти

Не ми задавайте глупави въпроси...
Умната и Успех на Всички!!!
Прикачени файлове
Market Informer.ex4
(14.33 KБ) Свален 17 пъти

Потребителски аватар
saxsten
Мнения: 1374
Регистриран: 04 апр 2010, 23:16
11 получени
3 дадени

Re: Market Informer Script - Скритите тайни на Брокерите

Мнение от saxsten » 22 юни 2018, 14:58

SvetoslavB написа:
21 юни 2018, 18:30
Здравейте,
Радвам се, че се появиха Български форуми за Трейдъри.
За всички Начинаещи и "Профита" публикувам мой авторски скрипт за преглед на пълната информация за търговия в Терминала на МТ4.
Във връзка с новите условия, наложени от EU, след понеделник всички ще имаме нужда от него.
Скрипта дава информация за инструмента, на който го пуснете. :grin:


Screenshot.png


Не ми задавайте глупави въпроси...
Умната и Успех на Всички!!!
Ми как така са се появили бре :(
Тоя форум е тука от незапомнени времева
То ако има нещо което се е появило по скоро това сте Вие Уважаеми :grin:
Иначе ако ще пускаш нещо пускай го с открит код защото иначе как да оцениме нещо което прилича на котка в чувал.
Например пускай ето такова нещо :

Код: Избери всички

void MarketInformation()
 
  {spread=(int)MathMax((SymbolInfoDouble(_Symbol,SYMBOL_ASK)-SymbolInfoDouble(_Symbol,SYMBOL_BID)/_Point),
           MathMax(MarketInfo(_Symbol,MODE_SPREAD),SymbolInfoInteger(_Symbol,SYMBOL_SPREAD)));
   
   StopLevel=(int)MathMax(spread*3+(int)(SymbolInfoDouble(_Symbol,SYMBOL_TRADE_TICK_SIZE)/_Point),
        MathMax(SymbolInfoInteger(_Symbol,SYMBOL_TRADE_STOPS_LEVEL),MarketInfo(_Symbol,MODE_STOPLEVEL)))
        +(int)(SymbolInfoDouble(_Symbol,SYMBOL_TRADE_TICK_SIZE)/_Point);
   
   freezelevel=(int)MathMax(spread*3+(int)(SymbolInfoDouble(_Symbol,SYMBOL_TRADE_TICK_SIZE)/_Point),
                MathMax(SymbolInfoInteger(_Symbol,SYMBOL_TRADE_FREEZE_LEVEL),(int)MarketInfo(_Symbol,MODE_FREEZELEVEL)))+
                (int)(SymbolInfoDouble(_Symbol,SYMBOL_TRADE_TICK_SIZE)/_Point);

   if(tickvalue==0)
   
     { for( i=0; i<OrdersTotal(); i++)
        {if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
           {if(OrderSymbol()==_Symbol && (OrderMagicNumber()==Magic || Magic==-1))
           
       { if(OrderType()==OP_BUY)   {if(OrderProfit()!=0)
    
     tickvalue=MathAbs(OrderProfit()/((OrderClosePrice()-OrderOpenPrice())/Point)/OrderLots());}
      
       if(OrderType()==OP_SELL)     {if(OrderProfit()!=0)
     
      tickvalue=MathAbs(OrderProfit()/((OrderClosePrice()-OrderOpenPrice())/Point)/OrderLots());
        
    //======================================================================    
          if(StopLoss!=0 && StopLoss<StopLevel) StopLoss= StopLevel;         
           if(TakeProfit!=0 && TakeProfit< StopLevel )TakeProfit= StopLevel;          
                 }}}}} return; }
                 
 
 //================================================  
   
Ох дано само оня откачения да не започне да коментира ,че отиде та се ни видя
Форекса е оръжие за масово поразяване

Потребителски аватар
saxsten
Мнения: 1374
Регистриран: 04 апр 2010, 23:16
11 получени
3 дадени

Re: Market Informer Script - Скритите тайни на Брокерите

Мнение от saxsten » 22 юни 2018, 15:04

По принцип всички променливи са дефинирани извън тялото на функцията
Е ,може да се дефинират и още при обявяването на самата функция, но това вече е въпрос на вкус и стил на програмиране
Форекса е оръжие за масово поразяване

Mateev
Мнения: 344
Регистриран: 02 окт 2017, 10:04
56 получени
44 дадени

Re: Market Informer Script - Скритите тайни на Брокерите

Мнение от Mateev » 22 юни 2018, 16:38

saxsten написа:
22 юни 2018, 15:04
По принцип всички променливи са дефинирани извън тялото на функцията
Е ,може да се дефинират и още при обявяването на самата функция, но това вече е въпрос на вкус и стил на програмиране
Само глупаците дефинират локални променливи в глобалното пространство. А ти вместо да се срамуваш, се хвалиш с това. Било стил на прорамиране ...... ха, ха, ха ...... Ще се пръсна от смях. Няма такъв стил на програмиране или ако го има, защото ти го прилагаш, трябва да се нарича МУРДАРСКИ СТИЛ.

Най-тъпото нещо, което може да измисли един начинаещ пишман "програмист", е да сложи променливите далеко от кода, който оперира с тях. По-лош стил на програмиране никой не може да измисли, освен ако не се казва saxteen.

Слагането на локални променливи в глобалното пространство е възможно най-голямата тъпотия, която може да хрумне само на един болен мозък. Разбирам, че твоя явно е такъв, но това не те оправдава. Да не говорим за подредбата на твоя кода, която имам чувството, че нарочно е направена така, щото никой да не може да го прочете и проследи, дори и ти самия.

Единственото обяснение на твоя мурдарски стил на програмиране е това, че ти никога не си писал програма, по-сложна от 100 реда. То и няма как да я напишеш с твоя мурдарски стил на програмиране, защото ще се наплетеш като пиле в кълчища в огромно количество глобални променливи и в безсмислените функции, които и ти не знаеш защо си ги написал и каква функционалност всъщност притежават.

Сега вече осъзнавам и защо обектно-ориентираното програмиране е толкова далече от пилешкия ти мозък. Ами че ти все още не си се научил как се прави функция и за какво се използва, пък да не говорим за класове и обекти, които с твоите темпове на развитие ще започнеш да използваш не в следващия, а чак в по-следващия си живот.

Моля ти се спри да публикуваш смешните си и грешни кодове, защото наистина много се излагаш.

Mateev
Мнения: 344
Регистриран: 02 окт 2017, 10:04
56 получени
44 дадени

Re: Market Informer Script - Скритите тайни на Брокерите

Мнение от Mateev » 22 юни 2018, 17:19

Иначе ето и моята версия на код, с който може да се види информация за брокера и символа, върху който работи кода. При мене обаче кода е оформен като експерт, и той има следната функционалност:
1. Показва информация за брокера и за неговия сървър
2. Показва информация за акаунта и за неговите параметри
3. Показва информация за символа, върху който е пуснат експерта, и за неговите параметри
4. Показва статистика на баровете от всички таймфреймове - брой, както и минимална, средна и максимална височина
5. Натрупва статистика и за тиковете и спреда - Last, Min, Avg и Max стойности
6. Във фонов режим принуждава МетаТрадер-a да Download-ва баровете на всички финансови инструменти на брокера, дори и ако за тях няма отворена графика. По-този начин се решава проблема с дупките, които се получават в баровете на по-рядко използваните финансови инструменти.

Тази последната функционалност ми е най-важната, и най-вече заради нея при мене един такъв експерт винаги работи във всеки един мой MetaTrader, включен към всеки един брокер и акаунт, с които работя. В резултат на това досега през годините съм се сдобил със стотици хиляди минутни барове без дупки в тях, и това е направо безценно, когато се тестват MT4 експерти в исторически план. Трябва обаче да се разреши на MetaTrader-a да съхранява на диска повече от 65000 бара. Това се прави в Tools / Options / Charts / Max bars in history. Също така се постарайте да имате достатъчно място на диска, защото се натрупват по 4-5 GB барове на всеки един MetaTrader, на който пускате този експерт.

Изображение

Тъй като експерта използва Windows-ки DLL за четене на времето с милисекунди, за да заработи правилно, трябва да се включи Allow DLL imports в менюто Tools / Options / Expert Advisors на MetaTrader-а.

А ето и компилирана версия на самия експерт:
Прикачени файлове
Analyses v1.16.ex4
(41.28 KБ) Свален 14 пъти
Последна промяна от Mateev на 22 юни 2018, 17:59, променено общо 11 пъти.

Mateev
Мнения: 344
Регистриран: 02 окт 2017, 10:04
56 получени
44 дадени

Re: Market Informer Script - Скритите тайни на Брокерите

Мнение от Mateev » 22 юни 2018, 17:24

Ето и сорс кода на експерта:

Код: Избери всички

//+------------------------------------------------------------------+
//|                                   Copyright 2017, STS Soft Corp. |
//|                                               http://stssoft.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2017, STS Soft Corp."
#property link      "http://stssoft.com"
//#property version   "1.16"
#property strict
#property description "This Expert shows information for:"
#property description " - Broker Company"
#property description " - Broker Server"
#property description " - Client Account"
#property description " - Current Symbol"
#property description " - Bars Statistics"
#property description " - Spread Statistics"
#property description " - Last Tick Info"

#include <RSM\Structures\Time\StructSystemTime.mqh>
#include <RSM\Structures\Statistics\StructStatistic.mqh>

const string ChartObjectHeader = "Symbol Info: Row "; // Начало на името на всички обекти, създавани по графиката

SSystemTime LastTickTime; // Време на последния тик
SSystemTime LocalTime;    // Локално време с дискрета 1 милисекунда
SStatistic  Spread;       // Структура със статистики за спреда

// Статистика за броя и размерите на баровете от всички мащаби на времето
SStatistic BarsM1;  
SStatistic BarsM5;
SStatistic BarsM15;
SStatistic BarsM30;
SStatistic BarsH1;
SStatistic BarsH4;
SStatistic BarsD1;
SStatistic BarsW1;
SStatistic BarsMN1;

//====================================================================
int OnInit() // Инициализация на експерта
  {
    CalcALLBars(0); // Изчислява статистиките на всичките барове
    PrintInfo(0); // Визуализира информацията на екрана на посочената графика
    
    EventSetTimer(1); //Таймера стартира събитието OnTime всяка секунда
    return(INIT_SUCCEEDED);
  }
//====================================================================
void OnDeinit(const int reason) // Деинициализация на експерта
  {
   EventKillTimer(); //--- destroy timer
   
   switch(reason) 
     {
       case REASON_CHARTCHANGE: return; // Symbol or chart period has been changed
       case REASON_PARAMETERS : return; // Input parameters have been changed by a user
       case REASON_TEMPLATE   : return; // A new template has been applied
     }
   
   // Обектите на графиката се трият само ако наистина експерта е премахнат
   for (int i=0; i<100; i++) // Изтриване на обектите от графиката
     {
       string ObjName = ChartObjectHeader + IntegerToString(i,2,'0');
       if (ObjectFind(ObjName)>=0) {ObjectDelete(ObjName);}
     }
  }
//====================================================================
void OnTimer() // Стартира се веднъж в секундата
  {
    RefreshBars(); // Бавно четене от сървъра на последните барове на всички символи на терминала
    CalcALLBars(0); // Изчислява статистиките на всичките барове
    PrintInfo  (0); //Дори и да няма котировки, програмата се стартира всяка секунда
  }
//====================================================================
void OnTick() // Стартира се на всеки тик
  {
    LastTickTime.ReadLocalTime(); // Чете времето на последния тик
    Spread.Add(MarketInfo(_Symbol,MODE_SPREAD)); // Добавя спред в статистиката
    PrintInfo(0); // Визуализира информацията на екрана
  }  
//=============================================================================
// Визуализиране на информацията върху графиката

void PrintInfo(long chartID)
  {
    // Ако не са изтекли 100ms от предишното визуализирасне на екрана, няма смисъл да го правим отново.
    static ulong oldHomeTime=0; // Еднократна инициализация при стартирането на програмата
    ulong newHomeTime = GetMicrosecondCount();
    if(newHomeTime-oldHomeTime < 100000) return;
    
   string symbol = ChartSymbol();
   int    digits = (int)SymbolInfoInteger(symbol,SYMBOL_DIGITS);
   double point  = SymbolInfoDouble (symbol,SYMBOL_POINT);
  
   static string CR = "\n"; // New row 
   LocalTime.ReadLocalTime();
   
   Row = 0; // Нулира брояча на редовете за визуализация

   Draw(chartID,"Company: " + AccountCompany());
   Draw(chartID,"Server : " + AccountServer());
   Draw(chartID,"Server Time: " + TimeToStr(TimeCurrent(),TIME_DATE | TIME_MINUTES | TIME_SECONDS)); // Време на сървъра
   Draw(chartID,"Local  Time: " + LocalTime.ToString(1,1)); // Време на локалния компютър
   Draw(chartID,"Time Offset: " + IntegerToString(LocalTime.ToDateTime() - TimeCurrent()) + " Seconds"); // Отместване на времето спрямо локалния компютър
   
   Draw(chartID,"");
   Draw(chartID,"Account Leverage: " + IntegerToString(AccountLeverage()));
   
//------------------------------------------------------------------------------------
// Информация за инструмента (символа)
   Draw(chartID,""); 
   Draw(chartID,"Symbol: "   + symbol + " - " + SymbolInfoString(symbol,SYMBOL_DESCRIPTION));
 
   Draw(chartID,"Trade Allowed: " + DoubleToStr(MarketInfo(symbol,MODE_TRADEALLOWED),0) + 
       " CloseBy Allowed: " + DoubleToStr(MarketInfo(symbol,MODE_CLOSEBY_ALLOWED),0));      
       
   Draw(chartID,"Currency: Account:" + AccountCurrency() + 
                    " Base:" + SymbolInfoString(symbol,SYMBOL_CURRENCY_BASE) + 
                  " Profit:" + SymbolInfoString(symbol,SYMBOL_CURRENCY_PROFIT) +
                  " Margin:" + SymbolInfoString(symbol,SYMBOL_CURRENCY_MARGIN));   
                  
   // Информация за лотовете
   Draw(chartID,"Lot Size: " + DoubleToStr(MarketInfo(symbol,MODE_LOTSIZE),0) + " "
                     + SymbolInfoString      (symbol,SYMBOL_CURRENCY_BASE) +
            " Min:"  + DoubleToStr(MarketInfo(symbol,MODE_MINLOT),2) +
            " Step:" + DoubleToStr(MarketInfo(symbol,MODE_LOTSTEP),2) +          
             " Max:" + DoubleToStr(MarketInfo(symbol,MODE_MAXLOT),0));  

   Draw(chartID,"Size: Point:" + DoubleToStr(point,digits) + 
              " Tick:" + DoubleToStr(MarketInfo(symbol,MODE_TICKSIZE) ,digits) +
        " Tick Value:" + DoubleToStr(MarketInfo(symbol,MODE_TICKVALUE),3) + " " + AccountCurrency());
   Draw(chartID,"Digits: " + IntegerToString(digits));
   
   Draw(chartID,""); 
   Draw(chartID,"Stop Level:" + DoubleToStr(MarketInfo(symbol,MODE_STOPLEVEL),0) + 
     " Freeze Level:" + DoubleToStr(MarketInfo(symbol,MODE_FREEZELEVEL),0) + " points"); // Order freeze level in points. If the execution price lies within the range defined by the freeze level, the order cannot be modified, cancelled or closed
   
//---------------------------------------------------------------------------------
// Информация за суапа

   int SwapType = int(MarketInfo(symbol,MODE_SWAPTYPE)); // Swap calculation method. 0 - in points; 1 - in the symbol base currency; 2 - by interest; 3 - in the margin currency
   string SwapTypeStr;
   
   if (SwapType == 0) {SwapTypeStr = "points";}
   if (SwapType == 1) {SwapTypeStr = SymbolInfoString(symbol,SYMBOL_CURRENCY_BASE); }
   if (SwapType == 2) {SwapTypeStr = "%"; } 
   if (SwapType == 3) {SwapTypeStr = SymbolInfoString(symbol,SYMBOL_CURRENCY_MARGIN); } 
            
   Draw(chartID,"Swap: Long:"  + DoubleToStr(MarketInfo(symbol,MODE_SWAPLONG),2) + 
             " Short:" + DoubleToStr(MarketInfo(symbol,MODE_SWAPSHORT),2) + " " + SwapTypeStr); 

//---------------------------------------------------------------------------------               
   
   Draw(chartID,"");
   Draw(chartID,"Margin Calc Mode: "  + DoubleToStr(MarketInfo(symbol,MODE_MARGINCALCMODE),0)); // Margin calculation mode. 0 - Forex; 1 - CFD; 2 - Futures; 3 - CFD for indices 
   Draw(chartID,"Margin Init: "       + DoubleToStr(MarketInfo(symbol,MODE_MARGININIT),2)); // Initial margin requirements for 1 lot
   Draw(chartID,"Margin Maintenace: " + DoubleToStr(MarketInfo(symbol,MODE_MARGINMAINTENANCE),2)); // Margin to maintain open orders calculated for 1 lot
   Draw(chartID,"Margin Hedged: "     + DoubleToStr(MarketInfo(symbol,MODE_MARGINHEDGED),2) + " " + SymbolInfoString(symbol,SYMBOL_CURRENCY_MARGIN)); // Hedged margin calculated for 1 lot
   Draw(chartID,"Margin Required: "   + DoubleToStr(MarketInfo(symbol,MODE_MARGINREQUIRED),2) + " " + AccountCurrency()); // Free margin required to open 1 lot for buying
   
//---------------------------------------------------------------------------------
// Информация за баровете
   
   Draw(chartID,"");
   DrawStat(chartID,BarsMN1,"MN1");
   DrawStat(chartID,BarsW1, "W1 ");
   DrawStat(chartID,BarsD1, "D1 ");
   DrawStat(chartID,BarsH4, "H4 ");
   DrawStat(chartID,BarsH1, "H1 ");
   DrawStat(chartID,BarsM30,"M30");
   DrawStat(chartID,BarsM15,"M15");
   DrawStat(chartID,BarsM5, "M5 ");
   DrawStat(chartID,BarsM1, "M1 ");  

   // Информация за тиковете
   Draw(chartID,"");   
   Draw(chartID,"Ticks Count: "   + DoubleToStr(Spread.Cnt,0));
   Draw(chartID,"Last Tick: Bid:" + DoubleToString(Bid,digits) + 
                  " Ask:" + DoubleToString(Ask,digits) + 
                  " Time:" + LastTickTime.ToString(01,1));
   //Draw("Last Tick Seconds: "  + IntegerToString(TimeLocal()-LastTickTime.ToDateTime()) + " Seconds");
   
   // Информация на спреда
   int spread = int(MarketInfo(symbol,MODE_SPREAD));
   Draw(chartID,"Spread: Last:" + DoubleToStr(spread,0) +
               " Min:"  + DoubleToStr(Spread.Min,0) +
               " Avg:"  + DoubleToStr(Spread.Avg,1) +
               " Max:"  + DoubleToStr(Spread.Max,0) + " points"); 
               
   Draw(chartID,"");               
   Draw(chartID,"Downloading last bars on symbol " + PSymbol + OK);            
   ChartRedraw(chartID);                     
  }

//====================================================================
// Визуализира един стринг на екрана на графиката и премества указателя към нов ред

int Corner  = CORNER_LEFT_UPPER; // В коя част на екрана да се визуализира текста
int CornerX = 10;  // Отместване по X
int CornerY = 15;  // Отместване по Y

int Row     = 0;  // Текущ номер на ред, който се инкрементира след всяко извикване на функцията
int RowSize = 14; // Височина на 1 ред в пиксели

void Draw(long chartID, string Str)
  { 
    string ObjName = ChartObjectHeader + IntegerToString(Row,2,'0');
    
    if (ObjectFind(chartID,ObjName)<0) 
      {
        ObjectCreate    (chartID,ObjName,OBJ_LABEL,0,0,0);
        ObjectSetInteger(chartID,ObjName,OBJPROP_CORNER,Corner);
        ObjectSetInteger(chartID,ObjName,OBJPROP_YDISTANCE,CornerY + Row*RowSize);
        ObjectSetInteger(chartID,ObjName,OBJPROP_XDISTANCE,CornerX);
        ObjectSetInteger(chartID,ObjName,OBJPROP_COLOR,clrYellow);
        ObjectSetString (chartID,ObjName,OBJPROP_FONT,"Courier New Bold");
        ObjectSetInteger(chartID,ObjName,OBJPROP_FONTSIZE,10);
        ObjectSetInteger(chartID,ObjName,OBJPROP_BACK,false);
      }
      
    //ObjectSetString(chartID,ObjName,OBJPROP_TEXT,Str,10,"Courier New Bold",clrYellow);
    ObjectSetString (chartID,ObjName,OBJPROP_TEXT,Str);
    Row ++; // Увеличава текущия ред с 1
  }
  
//====================================================================
// Изчислява статистиката на баровете за едно Timeframe

void CalcStat(long chartID, SStatistic &statistic, int period,)  
  {
    string symbol = ChartSymbol(chartID);
    int    digits = (int)SymbolInfoInteger(symbol,SYMBOL_DIGITS);
    double point  = SymbolInfoDouble (symbol,SYMBOL_POINT);
    
    RefreshRates(); // Това е задължително, за да се ъпдейтнат последните барове
    int bars = iBars(symbol,period);
    if (bars==(statistic.Cnt-1)) return; // Няма нови барове
    
    double BarHeight;
    if (bars==statistic.Cnt) // Добавен е нов бар в дясно. 
      {
        // Бар 0 вече е станал Бар 1. Добавя се в статистиката.
        BarHeight = (iHigh(symbol,period,1)-iLow(symbol,period,1)) / point + 1;
        statistic.Add(BarHeight);
        return;
      }
      
    // Има много нови барове, вероятно добавени отпред. Прави се 100%-ово преизчисляване.
    statistic.Clear();
    for (int i=1; i<bars; i++) // Нулевия бар не се включва в статистиката, защото не му е известна крайната дължина
      { 
        if(IsStopped()) return;
        BarHeight = (iHigh(symbol,period,i)-iLow(symbol,period,i)) / point + 1;
        statistic.Add(BarHeight);
      }  
  }
  
//====================================================================
// Изчислява статистиката на баровете за всички TimeFrames

void CalcALLBars(long chartID)
  {
    if(!IsStopped()) CalcStat(chartID,BarsM1, PERIOD_M1);
    if(!IsStopped()) CalcStat(chartID,BarsM5, PERIOD_M5);
    if(!IsStopped()) CalcStat(chartID,BarsM15,PERIOD_M15);
    if(!IsStopped()) CalcStat(chartID,BarsM30,PERIOD_M30);
    if(!IsStopped()) CalcStat(chartID,BarsH1, PERIOD_H1);
    if(!IsStopped()) CalcStat(chartID,BarsH4, PERIOD_H4);
    if(!IsStopped()) CalcStat(chartID,BarsD1, PERIOD_D1);
    if(!IsStopped()) CalcStat(chartID,BarsW1, PERIOD_W1);
    if(!IsStopped()) CalcStat(chartID,BarsMN1,PERIOD_MN1);
  }

//====================================================================
// Визуализира статистиката на баровете на 1 TimeFrame  

void DrawStat(long chartID, SStatistic &statistic, string period)   
  {  
    Draw(chartID, period + " Bars:" + IntegerToString(statistic.Cnt,6,' ') +
                     " Size: Min:"  + FixLen(DoubleToString(statistic.Min,0),4,' ') +
                           " Avg:"  + FixLen(DoubleToString(statistic.Avg,0),5,' ') +
                           " Max:"  + FixLen(DoubleToString(statistic.Max,0),5,' ') + " points");
  }
//====================================================================
string FixLen(string S, int L, char C=' ') // Добавя символи от ляво на стринга
  {
    while(StringLen(S)<L) S=" "+S;
    return(S);
  }  
//====================================================================
// Принуждава терминала да прочете последните барове на всички символи
// На всяка секунда прави заявка за нов символ, но само ако вече са прочетени баровете на стария.

int      PS=-1;    // Позиция на показалеца в генералния списък със символи на терминала
string   PSymbol; // Символ, който се намира на тази позиция
string   OK;      // Съдържа или "..." или "...ОК", ако символа вече е рефрешнат.
 
void RefreshBars()
  {
    // Еднократно в началото на програмата тегли случаен символ за началото на сканирането
    if(PS<0) PS = MathRand() % SymbolsTotal(false); 
    
    if(PS>=SymbolsTotal(false)) PS=0; // Ако листа се е изчерпил, започваме да го въртим от самото начало.
    PSymbol = SymbolName(PS,false); //Четене на името на символа от генералния лист
    
    ResetLastError(); // За всеки случай се нулира последната грешка
    
    int B;
    RefreshRates();
    OK=  " ."; B = iBars(PSymbol,PERIOD_MN1); if(GetLastError()==ERR_HISTORY_WILL_UPDATED) return;
    OK=OK+"."; B = iBars(PSymbol,PERIOD_W1 ); if(GetLastError()==ERR_HISTORY_WILL_UPDATED) return;
    OK=OK+"."; B = iBars(PSymbol,PERIOD_D1 ); if(GetLastError()==ERR_HISTORY_WILL_UPDATED) return;
    OK=OK+"."; B = iBars(PSymbol,PERIOD_H4 ); if(GetLastError()==ERR_HISTORY_WILL_UPDATED) return;
    OK=OK+"."; B = iBars(PSymbol,PERIOD_H1 ); if(GetLastError()==ERR_HISTORY_WILL_UPDATED) return;
    OK=OK+"."; B = iBars(PSymbol,PERIOD_M30); if(GetLastError()==ERR_HISTORY_WILL_UPDATED) return;
    OK=OK+"."; B = iBars(PSymbol,PERIOD_M15); if(GetLastError()==ERR_HISTORY_WILL_UPDATED) return;
    OK=OK+"."; B = iBars(PSymbol,PERIOD_M5 ); if(GetLastError()==ERR_HISTORY_WILL_UPDATED) return;
    OK=OK+"."; B = iBars(PSymbol,PERIOD_M1 ); if(GetLastError()==ERR_HISTORY_WILL_UPDATED) return;

    OK=OK+" OK";
    PS++; // Ако програмата е стигнала до тука, значи текущия символ е ъпдейтнат
  }
//====================================================================
// Прихващане на натискането на бутон "Home"
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
  {
    if(id!=CHARTEVENT_KEYDOWN) return; // Не е натискане на клавиатура
    if(lparam!=36) return; // Не е натиснат бутон "Home"
    
    // Ако не са изтекли 100ms от предишното натискане на бутона Home,
    // няма смисъл да смятаме баровете и да рефрешваме информацията на екрана
    static ulong oldHomeTime=0; // Еднократна инициализация при стартирането на програмата
    ulong newHomeTime = GetMicrosecondCount();
    if(newHomeTime-oldHomeTime < 100000) return;

    // Ако програмата е стигнала до тука, значи са изтекли 100ms от последното натискане на бутона "Home"
    oldHomeTime = newHomeTime;
    switch(Period())
      { 
        case PERIOD_MN1: CalcStat(0,BarsMN1,PERIOD_MN1); break;
        case PERIOD_W1 : CalcStat(0,BarsW1, PERIOD_W1 ); break;
        case PERIOD_D1 : CalcStat(0,BarsD1, PERIOD_D1 ); break;
        case PERIOD_H4 : CalcStat(0,BarsH4, PERIOD_H4 ); break;
        case PERIOD_H1 : CalcStat(0,BarsH1, PERIOD_H1 ); break;
        case PERIOD_M30: CalcStat(0,BarsM30,PERIOD_M30); break;
        case PERIOD_M15: CalcStat(0,BarsM15,PERIOD_M15); break;
        case PERIOD_M5 : CalcStat(0,BarsM5, PERIOD_M5 ); break;
        case PERIOD_M1 : CalcStat(0,BarsM1, PERIOD_M1 ); break;
      }

    PrintInfo(0); //Дори и да няма котировки, програмата се стартира всяка секунда   
  }
 
За да можете да си го компилирате, ще ви трябва и кода от следните два Include файла:

StructSystemTime.mqh

Код: Избери всички

//+------------------------------------------------------------------+
//|                                             StructSystemTime.mqh |
//|                                        Copyright 2017, Mateev SC |
//|                                            http://www.mateev.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2017, Mateev SC"
#property link      "http://www.mateev.com"
#property version   "1.00"
#property strict

//====================================================================
// 16-байтова структура за времето с дискрета 1 милисекунда.
// Структурата може да съхранява години от 1 до 65535.
//====================================================================
// Грегорианския каледнар е въведен на 4 октомври 1582 г., така че по-старите дати в тази структура може и да не са верни.
// Съгласно Грегорианския каледнар правилата за определяне на високосните години са следните:
// 1. Всяка година, кратна на 4, е високосна
// 2. Всяка година, кратна на 100, но не и на 400, не е високосна
// 3. Всяка година, кратна на 400, е високосна (1600, 2000 и т. н.)
//
// Средната продължителност на 1 година според Грегорианския календар е 365.2425 дни
// или 365.2425 = 365 + 0.25 - 0.01 + 0.0025 = 365 + 1/4 - 1/100 + 1/400
//
// Реалната средна продължителност, измерена със съвременни методи, е 365.242374 дни.
// Това означава, че в Грегорианския календар се натрупва отрицателна грешка от
// -0.000126 дена на на година, или това прави по -10.8864 секунди на година.
// Това означава, че някъде около 3000-ната година трябва да се отнеме 1 ден от календара. :)
//
// Преди Грегориянаския календар е действал Юлианския календар, при който
// се е спазвало само правило номер 1 (всяка година, кратна на 4, е високосна).
// Тази функционалност засега няма да се реализира в тази структура.
//
// Според Windows-a, който поддържа същата структура, валидните години са от 1601 до 30837г.
// Функцията за изчисляване на броя на секундите обаче връща валидни стойности
// само в диапазона от 01.01.1970 до 31.12.2105.
//
// Според MQL4, валидните стойности на неговия datetime формат са от 1970 до 3000 г.
//====================================================================
// Съгласно всичко написано по-горе, във функционалноста на структурата са наложени следните ограничения:
// 1. Структурата съхранява данни от 1 до 65535 г.
// 2. Функцията ToString работи в пълния диапазон от години (1..65535).
// 3. Комуникацията с datetime формат е ограничена в диапазона от 1970 до 3000 г.
// 4. Изчисляването на броя на секундите между две времена е ограничено в диапазона от 01.01.1970 до 31.12.2105 г.
//====================================================================
// Деклариране на импортнатите функции от Kernel32.DLL

#import "kernel32.dll"
void GetLocalTime (ushort &time[]); // Връща локалното време (GMT+2) с точност 1 милисекунда
void GetSystemTime(ushort &time[]); // Връща текущото UTC време (Coordinated Universal Time)
//void RtlTimeToSecondsSince1970(ulong &time[], ulong &seconds); // Връща броя на секундите от 01.01.1970 до 31.12.2105
#import

//====================================================================
// 16-байтова структура за времето с дискрета 1 милисекунда
// Структурата е точно копие на тази, която се намира в Kernel32.DLL

struct SSystemTime // 16-байтова структура за времето с дискрета 1 милисекунда
  {
  ushort year; // Година (виж ограниченията в коментара най-отгоре)
  ushort mon;  // Месец (1..12)
  ushort dow;  // Ден от седмицата от 0-Неделя до 6-Събота 
  ushort day;  // Ден от месеца (1..31)
  ushort hour; // Час (0..23)
  ushort min;  // Минута (0..59)
  ushort sec;  // Секунда (0..59)
  ushort msc;  // Милисекунда (0.999)
  
  SSystemTime(){Clear();} // Default конструктор
 
  // Методи за инициализация на цялата структура SRsmTime
  void Clear();          // Нулира структурата 
  void ReadLocalTime (); // Чете от Kernel32.DLL текущото GMT+2 локално време с точност 1 милисекунда
  void ReadSystemTime(); // Чете от Kernel32.DLL текущото UTC локално време (Coordinated Universal Time)
  
  // Методи за инициализация на части от структурата, след проверка за валидност
  bool SetYear (ushort value); // Проверява валидноста и инициализира годината 
  bool SetMonth(ushort value); // Проверява валидноста и инициализира месеца
  bool SetDay  (ushort value); // Проверява валидноста и инициализира деня 
  void CheckDays(); // Проверява валидноста на датата и ако трябва, прави корекции. Изчислява и деня от седмицата.
    
  bool SetHour    (ushort value); // Проверява валидноста и инициализира часовете 
  bool SetMinute  (ushort value); // Проверява валидноста и инициализира минутите
  bool SetSecond  (ushort value); // Проверява валидноста и инициализира секундите         
  bool SetMSeconds(ushort value); // Проверява валидноста и инициализира милисекундите
    
  // Преобразува цялата структура в различни други Time формати
  datetime    ToDateTime(); // Връща времето в datetime формат (8 байта), при което се губят милисекундите
  MqlDateTime ToMqlTime (); // Връща времето в MqlDateTime формат, при което се губят милисекундите
  
  // Методи за връщане на различни части от структурата или на някаква изчисляема информация
  ushort DaysInMonth() {return(DaysInMonth(mon));} // Връща броя на дните в месеца от структурата
  ushort DayOfYear();  // Връща деня от годината (1..366)
  
  string NameMonth9() {return(NameMonth9(mon));} // Връща дългото име на месеца в структурата
  string NameMonth2() {return(NameMonth2(mon));} // Връща късото име на месеца в структурата
  string NameDay9  () {return(NameDay9  (dow));} // Връща дългото име на деня от седмицата
  string NameDay3  () {return(NameDay3  (dow));} // Връща дългото име на деня от седмицата
  
  // DateTime методи (функции), които не зависят от данните в тази структура
  ushort DaysInMonth(ushort num); // Връща броя на дните в месеца month
  string NameMonth9 (ushort num); // Връща дългото име на месеца
  string NameMonth2 (ushort num); // Връща късото име на месеца  
  string NameDay9   (ushort num); // Връща дългото име на деня от седмицата
  string NameDay3   (ushort num); // Връща късото име на деня от седмицата
  
  // Връща времето като стринг в един от следните формати:
  // За датата (първата десетична цифра):
  //   0 - няма дата
  //   1 - YYYY.MM.DD  
  //   2 - DD.MM.YYYY
  // За времето (втората десетична цифра):
  //   0 - няма време
  //   1 - HH:MM:SS.mmm
  //   2 - HH:MM:SS
  //   3 - HH:MM
  //   4 - HH
  //   5 - MM:SS.mmm
  //   6 - MM:SS
  //   7 - MM
  //   8 - SS.mmm
  //   9 - SS
  //  10 - mmm
  // За в бъдеще ако дотрябва някой друг формат, то той се добавя на празните позиции
  string ToString(int dateFormat=1, int timeFormat=1); // Връща стринг с формат, указан в променливите dateFormat и timeFormat

  // Методи за запис и четене от файл
  bool Save(const int handle); // Записва структурата във файл
  bool Load(const int handle); // Чете структурата от файл     
  };

//====================================================================
// Нулира SKernelTime

SSystemTime::Clear() 
  {
    ZeroMemory(this);
    mon  = 1; // Месец (1..12)
    day  = 1; // Ден от месеца (1..31)
  }  

//====================================================================
// Чете от Kernel32.DLL текущото GMT+2 локално време с точност 1 милисекунда  
  
void SSystemTime::ReadLocalTime()
  {
    ushort time[8]; GetLocalTime(time); // Чете времето от Kernel32.DLL
    
    year = time[0]; // Година (виж ограниченията в коментара най-отгоре)
    mon  = time[1]; // Месец (1..12)
    dow  = time[2]; // Ден от седмицата от 0-Неделя до 6-Събота 
    day  = time[3]; // Ден от месеца (1..31)
    hour = time[4]; // Час (0..23)
    min  = time[5]; // Минута (0..59)
    sec  = time[6]; // Секунда (0..59)
    msc  = time[7]; // Милисекунда (0.999) 
  }
  
//====================================================================
// Чете от Kernel32.DLL текущото UTC локално време с точност 1 милисекунда  
  
void SSystemTime::ReadSystemTime()
  {
    ushort time[8]; GetSystemTime(time); // Чете времето от Kernel32.DLL
    
    year = time[0]; // Година (виж ограниченията в коментара най-отгоре)
    mon  = time[1]; // Месец (1..12)
    dow  = time[2]; // Ден от седмицата от 0-Неделя до 6-Събота 
    day  = time[3]; // Ден от месеца (1..31)
    hour = time[4]; // Час (0..23)
    min  = time[5]; // Минута (0..59)
    sec  = time[6]; // Секунда (0..59)
    msc  = time[7]; // Милисекунда (0.999)
  }

//====================================================================
// Проверява валидноста на датата и ако трябва, прави корекции. Изчислява деня от седмицата. 
 
void SSystemTime::CheckDays()
  { 
    ushort dm = DaysInMonth();
    if(day>dm) day=dm;
    dow = (ushort)TimeDayOfWeek(this.ToDateTime()); //Изчислява деня от седмицата
  }  

//====================================================================
// Проверява валидноста и инициализира годината
  
bool SSystemTime::SetYear(ushort value)
  {
    if (value < 1970) return(false);
    year = value;
    CheckDays();
    return(true);
  }

//====================================================================
// Проверява валидноста и инициализира месеца
  
bool SSystemTime::SetMonth(ushort value)
  {
    if (value <  1) return(false);
    if (value > 12) return(false);
    mon = value;
    CheckDays();
    return(true);
  }    

//====================================================================
// Проверява валидноста и инициализира деня
  
bool SSystemTime::SetDay(ushort value)
  {
    if (value <  1) return(false);
    if (value > 31) return(false);
    day = value;
    CheckDays();
    return(true);
  }

//====================================================================
// Проверява валидноста и инициализира часа
  
bool SSystemTime::SetHour(ushort value)
  {
    if (value > 23) return(false);
    hour = value;
    return(true);
  }  

//====================================================================
// Проверява валидноста и инициализира минутата
  
bool SSystemTime::SetMinute(ushort value)
  {
    if (value > 59) return(false);
    min = value;
    return(true);
  }  
    
//====================================================================
// Проверява валидноста и инициализира секундата
  
bool SSystemTime::SetSecond(ushort value)
  {
    if (value > 59) return(false);
    sec = value;
    return(true);
  }  
    
//====================================================================
// Проверява валидноста и инициализира милисекундата
  
bool SSystemTime::SetMSeconds(ushort value)
  {
    if (value > 999) return(false);
    msc = value;
    return(true);
  }      
//====================================================================
// Връща броя на дните в месеца month

ushort SSystemTime::DaysInMonth(ushort num)
  {
    switch(num)
      {
        case  1: return(31); // Януари
        case  2: {           // Февруари
                   ushort leapYear = year;
                   if (year%100==0) leapYear/=100;
                   return((leapYear%4==0)? 29 : 28);        
                 }
        case  3: return(31); // Март
        case  4: return(30); // Април       
        case  5: return(31); // Май
        case  6: return(30); // Юни       
        case  7: return(31); // Юли
        case  8: return(31); // Август
        case  9: return(30); // Септември
        case 10: return(31); // Октомври
        case 11: return(30); // Ноември       
        case 12: return(31); // Декември
      }
   return(0);  
  }
  
//====================================================================   
// Връща деня от годината (1..366)

ushort SSystemTime::DayOfYear()
  {
    ushort days = 0;
    for (ushort i=1; i<mon; i++) days = days + DaysInMonth(i);
    return(days + day); 
  }  
  
//====================================================================
// Връща времето в MqlDateTime формат, при което се губят милисекундите

MqlDateTime SSystemTime::ToMqlTime()
  {
    MqlDateTime ret;
    ret.year        = year;
    ret.mon         = mon;
    ret.day         = day;
    ret.hour        = hour;
    ret.min         = min;
    ret.sec         = sec;
    ret.day_of_week = dow;
    ret.day_of_year = this.DayOfYear();
    return (ret);
  } 
  
//====================================================================
// Връща времето в datetime формат, при което се губят милисекундите

datetime SSystemTime::ToDateTime()
  {
    if (year < 1970) return(   0); // Минимална година в datetime формата
    if (year > 3000) return(3000); // Максимална година в datetime формата
    
    MqlDateTime MqlTime = this.ToMqlTime();
    return(StructToTime(MqlTime));
  }

//====================================================================
// Връща дългото име на месеца month
  
string SSystemTime::NameMonth9 (ushort num)
  {
   switch(num)
     {
      case  1: return("January");
      case  2: return("February");
      case  3: return("March");
      case  4: return("April");
      case  5: return("May");
      case  6: return("June");
      case  7: return("July");
      case  8: return("August");
      case  9: return("September");
      case 10: return("October");
      case 11: return("November");
      case 12: return("December");
     }
   return("Bad month");  
  }  

//====================================================================
// Връща късото име на месеца month 
  
string SSystemTime::NameMonth2 (ushort num)
  {
   switch(num)
     {
      case  1: return("Jan");
      case  2: return("Feb");
      case  3: return("Mar");
      case  4: return("Apr");
      case  5: return("May");
      case  6: return("Jun");
      case  7: return("Jul");
      case  8: return("Aug");
      case  9: return("Sep");
      case 10: return("Oct");
      case 11: return("Nov");
      case 12: return("Dec");
     }
   return("Bad month");  
  } 

//==================================================================== 
// Връща дългото име на деня от седмицата
  
string SSystemTime::NameDay9(ushort num)
  {
   switch(num)
     {
      case 0: return("Sunday");
      case 1: return("Monday");
      case 2: return("Tuesday");
      case 3: return("Wednesday");
      case 4: return("Thursday");
      case 5: return("Friday");
      case 6: return("Saturday");
     }
   return("Bad day of week");  
  }      

//==================================================================== 
// Връща късото име на деня от седмицата
  
string SSystemTime::NameDay3(ushort num)
  {
   switch(num)
     {
      case 0: return("Su");
      case 1: return("Mo");
      case 2: return("Tu");
      case 3: return("We");
      case 4: return("Th");
      case 5: return("Fr");
      case 6: return("Sa");
     }
   return("Bad day of week");  
  } 
  
//====================================================================  
// Връща времето като стринг в един от следните формати:
// За датата (първата десетична цифра):
//   0 - няма дата
//   1 - YYYY.MM.DD  
//   2 - DD.MM.YYYY
// За времето (втората десетична цифра):
//   0 - няма време
//   1 - HH:MM:SS.mmm
//   2 - HH:MM:SS
//   3 - HH:MM
//   4 - HH
//   5 - MM:SS.mmm
//   6 - MM:SS
//   7 - MM
//   8 - SS.mmm
//   9 - SS
//  10 - mmm
// За в бъдеще ако дотрябва някой друг формат, то той се добавя на празните позиции

string SSystemTime::ToString(int dateFormat=1, int timeFormat=1)
  { 
    // Делимитери
    string T = "."; // Точка
    string D = ":"; // Двуеточие
    
    // Преобразуване на датата в стринг
    string date = "";
    if (dateFormat>0)
      {
        string YYYY = IntegerToString(year,4,'0');
        string MM   = IntegerToString(mon ,2,'0');
        string DD   = IntegerToString(day ,2,'0');
        
        switch (dateFormat)
          {
            case  1: date = YYYY + T + MM + T + DD; break;
            case  2: date = DD + T + MM + T + YYYY; break;
          }
      }
    
    // Преобразуване на времето в стринг
    string time = "";
    if (timeFormat>0)
      {
        string HH  = IntegerToString(hour,2,'0');
        string MM  = IntegerToString(min ,2,'0'); 
        string SS  = IntegerToString(sec ,2,'0');
        string mmm = IntegerToString(msc ,3,'0');
        
        switch (timeFormat)
          {
            case  1: time = HH + D + MM + D + SS + T + mmm; break;
            case  2: time = HH + D + MM + D + SS;           break;
            case  3: time = HH + D + MM;                    break;
            case  4: time = HH;                             break;
            case  5: time = MM + D + SS + T + mmm; break;
            case  6: time = MM + D + SS;           break;
            case  7: time = MM;                    break;
            case  8: time = SS + T + mmm; break;
            case  9: time = SS;           break;
            case 10: time = mmm; break;
          }
      }
      
    if (dateFormat==0) return(time); // Няма дата. Връща само времето.
    if (timeFormat==0) return(date); // Няма време. Връща само датата    
    return(date + " " + time);       // Има ги и двете. Връща ги с добавен интервал между тях като разделител.
  } 
 
//====================================================================
// Записва структурата във файл
 
bool SSystemTime::Save(const int handle)
  {
    if(handle==INVALID_HANDLE) return(false);
    else return(FileWriteStruct(handle,this,sizeof(SSystemTime))==sizeof(SSystemTime));
  } 

//====================================================================
// Чете структурата от файл

bool SSystemTime::Load(const int handle)
  {
    if(handle==INVALID_HANDLE) return(false);
    else return(FileReadStruct(handle,this,sizeof(SSystemTime))==sizeof(SSystemTime));
  }  

StructStatistic.mqh

Код: Избери всички

//+------------------------------------------------------------------+
//|                                             StructStatistic.mqh |
//|                                        Copyright 2017, Mateev SC |
//|                                            http://www.mateev.com |
//+------------------------------------------------------------------+

#property copyright "Copyright 2017, Mateev SC"
#property link      "http://www.mateev.com"
#property version   "1.02"
#property strict

//====================================================================
// Структура със статистиките (агрегатните функции) на определен брой double числа
//====================================================================

struct SStatistic // 68 байта структура - статистика (агрегатни функции) на последователност от числа
  {
    double Min; // 8 байта - Минимална  стойност
    double Max; // 8 байта - Максимална стойност
        
    double Avg; // 8 байта - Arithmetic mean - Среднo-аритметична стойност
    double RMS; // 8 байта - Qudraic    mean - Среднo-квадратична стойност    
    double MnH; // 8 байта - Harmonic   mean - Средно хармоничнa стойност (броя на числата, разделен на сумата от 1/числото)
    
    double Sum; // 8 байта - Сума на стойностите, образували статистиката
    double Sm2; // 8 байта - Сума от квадратите на стойностите, образували статисттиката 
    double Sm1; // 8 байта - Сума от 1/стойностите, образували статисттиката 
    int    Cnt; // 4 байта - Брой на стойностите, образували статистиката (0..2 147 483 647)     

    // Методи за манипулация на данните в статистиката
    void Clear(void){ZeroMemory(this);} // Нулира структурата  
    void Add  (double value); // Добавяне на число в статистиката   

    // Методи за запис и четене от бинарен файл
    bool Save(const int handle); // Записва структурата във файл
    bool Load(const int handle); // Чете структурата от файл
  };
  
//====================================================================
// Добавяне на число в статистиката  

void SStatistic::Add(double value)
  {
    Cnt++;  
    if (Cnt==1) // Това е първата добавена стойност
      {
        Min = value;
        Max = value;
      }
    else // Вече има добавени стойности
      {
        if (Min > value) Min = value;
        if (Max < value) Max = value;
      }
      
    Sum = Sum + value;
    if(value>0) Sm1 = Sm1 + 1.0/value;
    Sm2 = Sm2 + value*value;       
    Avg = Sum / Cnt;
    RMS = MathSqrt(Sm2/Cnt);
    if(Sm1==0) MnH=0; else MnH = double(Cnt) / Sm1;
  }

//====================================================================
// Записва структурата във файл
 
bool SStatistic::Save(const int handle)
  {
    if (handle==INVALID_HANDLE) return(false);
    else return(FileWriteStruct(handle,this,sizeof(SStatistic))==sizeof(SStatistic));
  } 

//====================================================================
// Чете структурата от файл

bool SStatistic::Load(const int handle)
  {
    if (handle==INVALID_HANDLE) return(false);
    else return(FileReadStruct(handle,this,sizeof(SStatistic))==sizeof(SStatistic));
  }
     
Извинявам се на saxteen, че публикувам 800-900 реда код, който пилешкия му мозък няма да го разбере как работи, но се надявам този код да е полезен за другите читатели на форума.

ПП: За да се компилира правилно експерта, трябва да поправите пътя към файловете StructSystemTime.mqh и StructStatistic.mqh в директивите include от ред 18 и 19.

Потребителски аватар
alphaomega
Мнения: 155
Регистриран: 12 апр 2011, 22:09
7 получени
5 дадени

Re: Market Informer Script - Скритите тайни на Брокерите

Мнение от alphaomega » 22 юни 2018, 18:12

Матеев, това нещо не се чете! Тоя жълт текст го подреди малко и го сложи на някакъв фон който да скрие графиката.
Ползвай OBJ_RECTANGLE_LABEL

Кода няма да го коментирам... Всеки си има различни виждания за това как трябва да се програмира.
По важното е крайния резултат.
Ако една програма работи гладко, по предназначение както е замислена, без грешки и без да консумира много ресурси значи е добре написана!
А дали подредбата на кода е красива и четлива това вече е отделен въпрос. :grin:

Mateev
Мнения: 344
Регистриран: 02 окт 2017, 10:04
56 получени
44 дадени

Re: Market Informer Script - Скритите тайни на Брокерите

Мнение от Mateev » 22 юни 2018, 18:33

Цвета и шрифта се контролират в редове 214, 215 и 216. Ако искаш - промени си ги. Направил съм си ги такива, защото на мене така ми харесват. Жълтото стои много добре на черен фон или поне на мене ми се струва така. Този експерт съм си го писал за собствена употреба и не съм полагал усилия да го направя удобен за употреба от външни хора. Иначе да - настройката на цветове и шрифтове може да се изведе като параметри и всеки да си ги настройва сам при пускане на експерта.

Mateev
Мнения: 344
Регистриран: 02 окт 2017, 10:04
56 получени
44 дадени

Re: Market Informer Script - Скритите тайни на Брокерите

Мнение от Mateev » 22 юни 2018, 19:01

Искам да кажа, че експерта има още една функционалност - прихваща натискането на бутона Home и това предизвиква преизчисляване на статистиката на баровете. Защо е необходимо това?

По принцип логиката на натрупване на барове в МетаТрадер 4 e следната:
1. При първо отваряне на графиката на даден финансов инструмент MetaTrader 4 чете само една малка част от историческите барове. Не знам точно, но са някъде от порядъка на 300-500 бара или толкова, колкото да се напълни екрана и още малко.
2. От този момент нататък MetaTrader 4 влиза в режим АВТОНОМНО СЪЗДАВАНЕ НА БАРОВЕ от новопристигащите тикове. Тези барове може и да се различават от баровете на сървъра, ако часовника на компютъра върви неточно.
3. Ако MetaTrader се спре и след време се пусне отново, първата му задача е да поиска от сървъра липсващите барове за времето, през което е бил спрян. Да, но ако това време е било много дълго, сървъра вече ги е забравил тези барове, и в локалната графика се появява дупка (липсващи барове). И това важи само за инструментите, на които има отворена графика. По другите инструменти нищо не се Download-ва и в техните графики се появяват огромни дупки.
4. За който не знае, МТ4 по подразбиране помни само последните 65000 бара от всеки един таймфрейм, но някой брокери настройват това количество до още по-малки стойности. Виждал съм дори и брокери, които помнят само последните 2000 бара.
5. И тъй като на някои инструменти на брокера им се отваря графиката по-рядко от на други, или въобще не се отваря, в баровете от малките таймфреймове на тези инструменти се появяват огромни дупки.

Всичките тези проблеми се разрешават от моя експерт. Няма значение на кой символ ще бъде пуснат или на кой таймфрейм. Независимо къде е стартиран, той започва да се грижи за DownLoad-ването на абсолютно всички барове по абсолютно всички финансови инструменти на дадения брокер.

Тука обаче има един проблем. MT4 държи Download-натите барове в RAM паметта и ги записва на диск само при затварянето си. Да, ама паметта на 32-битовата версия е лимитирана до 2 GB, и като се препълни, МТ4 гърми. Това поне беше така преди няколко години, когато е писан този код, а сега не знам - може и да са го поправили. При всички случаи е добре МетаТрадер-a да се спира и пуска по веднъж на всеки половин-един час дотогава, докато направи една пълна обиколка из всички символи, и с нея свали огромно количество първоначални барове. След това при бъдеща употреба се свалят само разликите и паметта не се задръства толкова бързо.

А сега и за бутона Home. Той се използва за ръчно DownLoad-ване на барове, които са с по-ставра дата от първия бар в локалния MetaTrader. На всяко едно натискане Download-ва по 200-300 бара, така че за да се източи цялата история на сървъра е необходимо бутона да се натисне и да не се пуска дотогава, докато се изтегли всичко. В моя експерт аз прихващам този бутон и на всяка една новопристигнала порция с барове преизчислявам статистиката на баровете. По този начин се получава визуална обратна връзка за времето, през което трябва да се държи натиснат бутона Home. Тоест държите го натиснат дотогава, докато бройката на баровете в статистиката спре да нараства.

Тази хватка с натискането на бутона Home се прави за всеки един таймфрейм по всеки един финансов инструмент, и това е единствения възможен начин да източите от сървъра всеки един бар, който той все още не го е забравил. За съжаление не успях да го автоматизирам този процес, защото не открих лесен начин да имитирам натискането на бутон Home, така че операцията трябва да се извършва на ръка.

Mateev
Мнения: 344
Регистриран: 02 окт 2017, 10:04
56 получени
44 дадени

Re: Market Informer Script - Скритите тайни на Брокерите

Мнение от Mateev » 22 юни 2018, 19:21

Всъщност този експерт съм го писал преди всичко с цел да си изтегля от сървъра истинските барове на брокера, а не фалшивите такива от MetaQuotes. Процедурата е следната:
1. Инсталирам нов MetaTrader 4 към нов брокер.
2. Пускам експерта на който и да е финансов инструмент
3. С бутона Home изтеглям старата история по всеки един таймфрейм на всеки един инструмент, който ме интересува.
4. На всеки половин-един час рестартирам МетаТрадер-a
5. Когато видя на диска, че всички файлове с барове са вече изтеглени и записани, спирам да рестартирам MetaTrader-а и го оставям да си работи денонощно.
6. Все пак от дъжд на вятър пак го рестартирам най-вече защото ако мигне тока, цялата информация от паметта се губи, и баровете остават незаписани.

Та това е всичко около доставката на истински барове с MT4. Въпреки известната автоматизация, процесът пак е трудоемък и ненадежден. Това е и една от причините, поради които за развойна дейност вече предпочитам да работя на МТ5, където проблемът с доставката на исторически барове вече е разрешен - сървъра ги пази всички без изключение и можеш да си ги поискаш автоматично с код вътре в експерта.

Потребителски аватар
alphaomega
Мнения: 155
Регистриран: 12 апр 2011, 22:09
7 получени
5 дадени

Re: Market Informer Script - Скритите тайни на Брокерите

Мнение от alphaomega » 22 юни 2018, 20:13

Моя стил на програмиране е съвсем различен и по принцип не обичам да се занимавам със чужд код.
Но все пак направих няколко промени по твоя, така че поне да може да се чете нормално.
Прикачени файлове
mqh.rar
(6.01 KБ) Свален 13 пъти
Mateev Analyses.mq4
(36.53 KБ) Свален 12 пъти
Mateev Analyses.ex4
(31.81 KБ) Свален 10 пъти


Потребителски аватар
saxsten
Мнения: 1374
Регистриран: 04 апр 2010, 23:16
11 получени
3 дадени

Re: Market Informer Script - Скритите тайни на Брокерите

Мнение от saxsten » 22 юни 2018, 20:44

Моя стил на програмиране е съвсем различен и по принцип не обичам да се занимавам със чужд код.
Но все пак направих няколко промени по твоя, така че поне да може да се чете нормално.
[/quote]


М , дааа !
Дойде човека, и се започна една.... :grin:
Алфа Омега ,който се е качил на налудничавата каручка на Матеев добро не е видял
Архива с инклудниците не се отваря
Прикачени файлове
Screenshot_1.jpg
Screenshot_1.jpg (338.97 KБ) Видяна 705 пъти
Последна промяна от saxsten на 22 юни 2018, 21:08, променено общо 1 път.
Форекса е оръжие за масово поразяване

Потребителски аватар
alphaomega
Мнения: 155
Регистриран: 12 апр 2011, 22:09
7 получени
5 дадени

Re: Market Informer Script - Скритите тайни на Брокерите

Мнение от alphaomega » 22 юни 2018, 21:02

Няма никакви грешки. Трябва да сложиш допълнителните файлове във папката на експерта.
MateevStructStatistic и MateevStructSystemTime

Аз само им промених директорията и имената.

Mateev
Мнения: 344
Регистриран: 02 окт 2017, 10:04
56 получени
44 дадени

Re: Market Informer Script - Скритите тайни на Брокерите

Мнение от Mateev » 22 юни 2018, 21:09

alphaomega,
Не разбра ли, че saxteen е много бос в програмирането, но се изживява като голямата работа. Не знае елементарни конструкции на езика, допуска елементарни грешки, а в същото време се пищови и обижда наляво и надясно други хора за собствената си простотия и некадърност.

Проблемът не е в това, че е начинаещ. Проблемът е, че се представя за много велик и че обижда хората, които му казват истината и искат да му помогнат. Просто е непоправим чешит и комплексар. Забележи как във всеки свой постинг ми нанася незаслужени обиди за неща, за които аз съм прав, а той греши.

В момента направи същото. Поради собствената си некадърност не можа да компилира експерта, и веднага започна да ме обижда. Аз какво съм му виновен, че той не знае елементарни неща, и затова аз трябва да му търпя обидите и простотиите. При това забележи - в постинга с кода изрично намекнах, че трябва пътя в Include-тата да се смени. Написах го точно заради олигофрени като saxteen, но той пак се изхитри да не го прочете и да го сбърка. И след това веднага започна с обидите ....... Просто нямам думи ......

Историята с него не е от сега. Той започна да ме напада и да пише простотии още в момента, в който започнах да си развивам концепцията в другия форум. И от всеки един негов постинг лъхаше на простотия и комплексарщина. Разбирам го, че Господ му е дал много малко, но нека тихо да си крие простотията, а той прави точно обратното - размахва я наляво и надясно и сам не се усеща колко е смешен.

Потребителски аватар
saxsten
Мнения: 1374
Регистриран: 04 апр 2010, 23:16
11 получени
3 дадени

Re: Market Informer Script - Скритите тайни на Брокерите

Мнение от saxsten » 22 юни 2018, 21:33

Mateev написа:
22 юни 2018, 21:09
alphaomega,
Не разбра ли, че saxteen е много бос в програмирането, но се изживява като голямата работа. Не знае елементарни конструкции на езика, допуска елементарни грешки, а в същото време се пищови и обижда наляво и надясно други хора за собствената си простотия и некадърност.

Проблемът не е в това, че е начинаещ. Проблемът е, че се представя за много велик и че обижда хората, които му казват истината и искат да му помогнат. Просто е непоправим чешит и комплексар. Забележи как във всеки свой постинг ми нанася незаслужени обиди за неща, за които аз съм прав, а той греши.

В момента направи същото. Поради собствената си некадърност не можа да компилира експерта, и веднага започна да ме обижда. Аз какво съм му виновен, че той не знае елементарни неща, и затова аз трябва да му търпя обидите и простотиите. При това забележи - в постинга с кода изрично намекнах, че трябва пътя в Include-тата да се смени. Написах го точно заради олигофрени като saxteen, но той пак се изхитри да не го прочете и да го сбърка. И след това веднага започна с обидите ....... Просто нямам думи ......

Историята с него не е от сега. Той започна да ме напада и да пише простотии още в момента, в който започнах да си развивам концепцията в другия форум. И от всеки един негов постинг лъхаше на простотия и комплексарщина. Разбирам го, че Господ му е дал много малко, но нека тихо да си крие простотията, а той прави точно обратното - размахва я наляво и надясно и сам не се усеща колко е смешен.
Абе форекс -идиот такъв Това което си пуснал пак не работи и как може след като не работи да даваш оценки Че ти си идиот бе какви оценки даваш за нещо което не разбираш
Форекса е оръжие за масово поразяване

Потребителски аватар
saxsten
Мнения: 1374
Регистриран: 04 апр 2010, 23:16
11 получени
3 дадени

Re: Market Informer Script - Скритите тайни на Брокерите

Мнение от saxsten » 22 юни 2018, 21:37

alphaomega написа:
22 юни 2018, 21:02
Няма никакви грешки. Трябва да сложиш допълнителните файлове във папката на експерта.
MateevStructStatistic и MateevStructSystemTime

Аз само им промених директорията и имената.
Абе сложих ги
Дори и инклудниците на идиота дават грешки в кода ,не само така наречения му "експерт"
Ами то си е съвсем нормално да е така като се има предвид ,че човека е невменяем
Луд човек работещ код код не прави
Прикачени файлове
Idiot.zip
(6.4 KБ) Свален 10 пъти
Последна промяна от saxsten на 22 юни 2018, 21:48, променено общо 1 път.
Форекса е оръжие за масово поразяване

Потребителски аватар
alphaomega
Мнения: 155
Регистриран: 12 апр 2011, 22:09
7 получени
5 дадени

Re: Market Informer Script - Скритите тайни на Брокерите

Мнение от alphaomega » 22 юни 2018, 21:46

saxsten написа:
22 юни 2018, 21:37
alphaomega написа:
22 юни 2018, 21:02
Няма никакви грешки. Трябва да сложиш допълнителните файлове във папката на експерта.
MateevStructStatistic и MateevStructSystemTime

Аз само им промених директорията и имената.
Абе сложих ги Дори и инклудниците на идиота дават грешки в кода не само така наречения му "експерт"
Ама ти целия архив ли сложи без да го разархивираш :lol:

Потребителски аватар
saxsten
Мнения: 1374
Регистриран: 04 апр 2010, 23:16
11 получени
3 дадени

Re: Market Informer Script - Скритите тайни на Брокерите

Мнение от saxsten » 22 юни 2018, 22:02

Screenshot_1.jpg
Screenshot_1.jpg (83.97 KБ) Видяна 662 пъти
Screenshot_1.jpg
Screenshot_1.jpg (83.97 KБ) Видяна 662 пъти
alphaomega написа:
22 юни 2018, 21:46
saxsten написа:
22 юни 2018, 21:37
alphaomega написа:
22 юни 2018, 21:02
Няма никакви грешки. Трябва да сложиш допълнителните файлове във папката на експерта.
MateevStructStatistic и MateevStructSystemTime

Аз само им промених директорията и имената.
Абе сложих ги Дори и инклудниците на идиота дават грешки в кода не само така наречения му "експерт"
Ама ти целия архив ли сложи без да го разархивираш :lol:
Е ама не съм аз лудия тука бре
Айде инклудниците не грешат ама експерта
Дори твоят вариант на Mateev Analyses.ex4 не ще да се закача на графиката ти пробва ли го преди да го пуснеш тук
Прикачени файлове
Screenshot_3.jpg
Screenshot_3.jpg (377.94 KБ) Видяна 662 пъти
Screenshot_2.jpg
Screenshot_2.jpg (149.42 KБ) Видяна 662 пъти
Форекса е оръжие за масово поразяване

Потребителски аватар
alphaomega
Мнения: 155
Регистриран: 12 апр 2011, 22:09
7 получени
5 дадени

Re: Market Informer Script - Скритите тайни на Брокерите

Мнение от alphaomega » 22 юни 2018, 22:26

Човек ти не четеш какво съм написал!
Нали вече казах че съм променил директорията и тези файлове трябва да ги сложиш във папката на експертите (Experts). Като искаш си сложи друга директория. На мен всички файлове са ми на едно място във една папка. (Не ме питай защо :grin: )

Отговори

Върни се в “FOREX - ТЪРГОВИЯ С ВАЛУТА”

Кой е на линия

Потребители, разглеждащи този форум: Няма регистрирани потребители и 15 госта