Скачать MetaTrader 5
Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий
Пиши роботов на заказ. Зарабатывай с сервисом Фриланс!
220Volt
1175
220Volt 2013.07.06 04:46  

Думаю Ваш случай хорошо понимаю, сам с таким вопросом сталкивался. Для себя сделал следующим образом: из мкл вызывается функция, которая открывает окно блокнота (стандартный виндоус блокнот) и в нем отображается это сообщение. Одно сообщение, одно окно блокнота. Очень удобно, прочитал - закрыл. Если интересно, могу выложить код. Но написано на C++, т.е. нужно создать dll и подключать ее к эксперту. Вам интересно?

Artyom Trishkin
Модератор
71650
Artyom Trishkin 2013.07.06 05:04  
expertboss:

Опять же вопрос не теоретический а практический КАК сделать?

  =============================================================================

Как-то для себя писал функцию, которая выводит в отдельном окне пустого индикатора события, происходящие в эксперте строчку за строчкой, строчки могут иметь каждая свой цвет. Неохота тут всё расписывать. Поглядите проверочный эксперт с этой функцией. Не забудьте сначала повесить на график окно индикатора Win_Inform. Без него функция выводит в журнал. Может подойдёт вам, если разберётесь...

Эксперт пустой, я взял свой шаблончик и вписал только определения необходимых параметров для вызова функции и, соответственно сама функция. (из него потом функцию выдерните и по аналогии будете в своём вызывать)

//-----------------------------------------------------------------------------+
#property copyright "Copyright © 2012, Trishkin Artyom A."
#property link      "artmedia70@gmail.com"
//                   Skype: Artmedia70
//-----------------------------------------------------------------------------+
#include <stdlib.mqh>
#include <stderror.mqh>
#include <WinUser32.mqh>
//==============================================================================
// --------------------------- Переменные советника ---------------------------+
//==============================================================================
extern string  P_Expert= "-- Experts Variables --";
//------- Параметры исполнения торговых приказов ------------------------------+
extern string  P_Performanc= "-- Parameters for Trades --";
//-----------------------------------------------------------------------------+
double         PointX, LotsB, LotsS, Lots_New, MinLot, MaxLot, LotStp,
               Equ_Start, EquPerc, Equ_OLD, Equ_NEW;
string         sy;
int            tf, dg, sp, a,b,c;
double         pt, pa, pb;
//-----------------------------------------------------------------------------+
int            Level_old, 
               Level_new, 
               Magic;
string         New_Comm, Exp_Name, Prefix,
               message1, message2, message3, message4, 
               Mass_Name_Message[10];
//==============================================================================
//---------------------- Переменные для функций--------------------------------+
//==============================================================================
//+----------------------------------------------------------------------------+
int init() {
   if(Digits==5 || Digits==3) PointX = Point * 10; // Корректировка Point под трёх- пятизнак
   if(Digits==4 || Digits==2) PointX = Point;
   Exp_Name=WindowExpertName(); 
   Prefix=Exp_Name;  
   Magic=GetMagic(Exp_Name+Symbol(),Period()); 
   return;                                         // Выход из init() 
}
//+----------------------------------------------------------------------------+
int deinit() {
   if (!IsTesting()) {
      Comment("");
   // -------- Блок удаления всех объектов, построенных на графике --------
      string Name_Del[1]; 
      int Quant_Del=0;                    
      int Quant_Objects=ObjectsTotal();   
      int LenPref=StringLen(Prefix);
      ArrayResize(Name_Del,Quant_Objects);
      for(int k=0; k<Quant_Objects; k++) {
         string Obj_Name=ObjectName(k);   
         string Head=StringSubstr(Obj_Name,0,LenPref);
         if (Head==Prefix) {                              
            Quant_Del+=1;        
            Name_Del[Quant_Del-1]=Obj_Name;
            }
        }
      for(int i=0; i<Quant_Del; i++)    
         ObjectDelete(Name_Del[i]); 
// ----- Конец блока удаления всех объектов, построенных на графике -----
      }
   return;                                // Выход из deinit()
}
//+----------------------------------------------------------------------------+
int start() {
   sy=Symbol();
   tf=Period();
   dg=MarketInfo(sy,MODE_DIGITS);
   sp=MarketInfo(sy,MODE_SPREAD);
   pt=MarketInfo(sy,MODE_POINT);
   pa=MarketInfo(sy,MODE_ASK);
   pb=MarketInfo(sy,MODE_BID);
//----------- Инициализация флагов ------------   

//----------- Инициализация лотов -------------   

//----------- Имена глоб. переменных ----------   

//----------- Инициализация глоб. переменных ------------   

//-------------------------------------------------------
   message1=StringConcatenate("Тик: ",GetTickCount()," ");
   message2=StringConcatenate("Цена Bid: ", DoubleToStr(Bid,dg));
   iPrint(false, message1, message2, "", "", 9, Aqua, DarkOrange);
   b=4; c=7;
   a=b+c;
   message1=StringConcatenate("a=",a," ");
   message2=StringConcatenate("b=",b," ");
   message3=StringConcatenate("c=",c);
   iPrint(false, message1, message2, message3, "", 9, Aqua, LimeGreen, DarkOrange);
   
   message1=StringConcatenate("Время: ", TimeToStr(TimeCurrent())," ");
   message2=StringConcatenate("Тик: ",GetTickCount()," ");
   message3=StringConcatenate("Время бара: ",TimeToStr(Time[0])," ");
   message4=StringConcatenate("Цена Bid: ", DoubleToStr(Bid,dg));
   iPrint(false, message1, message2, message3, message4, 9, Aqua, Aqua, Aqua, DarkOrange);
   return;                                // Выход из start()
}
//+----------------------------------------------------------------------------+
void iPrint(bool print, string mess1, string mess2="", string mess3="", string mess4="", 
            int sz=9, color cl1=Aqua, color cl2=Aqua, color cl3=Aqua, color cl4=Aqua) {
   string   NameGrafText, message, nm;
   int      i, y, k, LenStr, shift, Win_Num=-1, num=0;
   color    cl;
   if (mess1=="") {
      Print("Func iPrint: Передана пустая строка, выходим");
      return;
      }
   Win_Num=WindowFind("Win_Inform");
   if (print || Win_Num<0) {
      message=mess1+mess2+mess3+mess4;
      Print(message); 
      return;
      }
   k=ArraySize(Mass_Name_Message)-1;
   if (StringLen(mess1)>0) num++;
   if (StringLen(mess2)>0) num++;
   if (StringLen(mess3)>0) num++;
   if (StringLen(mess4)>0) num++;
   for (i=k; i>=0; i--) {                             
      NameGrafText=Mass_Name_Message[i];           
      if (StringLen(NameGrafText)>0)
      if (ObjectFind(NameGrafText)==Win_Num) {
         if (i+num>k) {
            ObjectDelete(NameGrafText);  
            Mass_Name_Message[i]="";
            }
         else if (i+num<=k) {
            Mass_Name_Message[i+num]=Mass_Name_Message[i];
            y=ObjectGet(NameGrafText, OBJPROP_YDISTANCE);               // координата Y
            ObjectSet  (NameGrafText, OBJPROP_YDISTANCE, y+(sz+1)*num); // координата Y
            ObjectSet  (NameGrafText, OBJPROP_COLOR, LightSeaGreen);    // цвет
            }
         }
      }
   shift=num;
   int v=GetTickCount();
   for (i=0; i<num; i++) {
      shift--;
      NameGrafText=Prefix+"_Graf_Text_"+i+"_"+sy+"_"+v;
      int app=0;
      while (ObjectFind(NameGrafText)==Win_Num) {
         app++;
         NameGrafText=Prefix+"_Graf_Text_"+i+"_"+sy+"_"+v+"_"+app;
         }
      Mass_Name_Message[num-1-i]=NameGrafText;
      switch (i) {
         case 0: message=mess1; cl=cl1; break;
         case 1: message=mess2; cl=cl2; break;
         case 2: message=mess3; cl=cl3; break;
         case 3: message=mess4; cl=cl4; break;
         default:message=mess1; cl=cl1; break;
         }
      ObjectCreate (NameGrafText, OBJ_LABEL, Win_Num, 0, 0);
      ObjectSetText(NameGrafText, message, sz, "Courier New", cl);
      ObjectSet    (NameGrafText, OBJPROP_COLOR, cl);                   // цвет
      ObjectSet    (NameGrafText, OBJPROP_CORNER,    2);                // угол
      ObjectSet    (NameGrafText, OBJPROP_XDISTANCE, 150);              // координата Х
      ObjectSet    (NameGrafText, OBJPROP_YDISTANCE, 2+(sz+1)*shift);   // координата Y
      WindowRedraw();
      }
//---------------------------------      
   nm=Prefix+"_Balance_txt";
   message="Баланс :";
   cl=Yellow;
   SetText(message, cl, nm, 2, 4, 20, "Arial", 9, Win_Num);
   nm=Prefix+"_Balance";
   message=DoubleToStr(AccountBalance(),2);
   cl=DarkTurquoise;
   SetText(message, cl, nm, 2, 70, 20, "Arial", 9, Win_Num);
//---------------------------------      
   nm=Prefix+"_Equity_txt";
   message="Средства :";
   cl=Yellow;
   SetText(message, cl, nm, 2, 4, 8, "Arial", 9, Win_Num);
   nm=Prefix+"_Equity";
   message=DoubleToStr(AccountEquity(),2);
   cl=DarkTurquoise;
   SetText(message, cl, nm, 2, 70, 8, "Arial", 9, Win_Num);
//---------------------------------      
}
//+----------------------------------------------------------------------------+
void SetText(string Text, color cl, string nm, int angle, int x, int y, string font, int sz=0, int wnd=0) {
   if (ObjectFind(nm)<0) ObjectCreate(nm, OBJ_LABEL, wnd, 0, 0);
   ObjectSet(nm, OBJPROP_CORNER   , angle);
   ObjectSet(nm, OBJPROP_XDISTANCE, x);
   ObjectSet(nm, OBJPROP_YDISTANCE, y);
   ObjectSet(nm, OBJPROP_WIDTH    , sz);
   ObjectSetText(nm, Text, sz, font, cl);
   }
//+----------------------------------------------------------------------------+
int GetMagic(string symbolstring, int multiplier){
   int res=0;
   int len=StringLen(symbolstring);
   for(int i=0; i<len; i++)
       res+=StringGetChar(symbolstring,i);      
   return(res*multiplier);
}
//+----------------------------------------------------------------------------+

Индюкатор во вложении.

Файлы:
220Volt
1175
220Volt 2013.07.06 09:51  

Наверное стесняетесь, начну сам :)

dll:

#include <Windows.h>
#include <string>
#include <fstream>      
#include <memory>
using namespace std;


 // Создает файл, пишет в него сообщение, запускает в блокноте. В случаи успеха true.
bool __stdcall notepad_message(const char *file_name,
                               const char *message)
{
        std::ofstream file (file_name);
        file << message;
        file.close();
        if( file.fail() )
                return false;

        string commandLine = "notepad.exe ";
        commandLine += file_name;
        std::unique_ptr<char[]> commandLine_buf( new char[commandLine.length() + 1] );
        commandLine.copy(commandLine_buf.get(),
                         commandLine.length());
        commandLine_buf[commandLine.length()] = '\0';

        STARTUPINFOA si = { sizeof(si) };
        PROCESS_INFORMATION pi;
        if( ! CreateProcessA(NULL, commandLine_buf.get(), NULL,
                             NULL, FALSE, 0, NULL, NULL, &si, &pi) )
                return false;
        CloseHandle(pi.hProcess);
        CloseHandle(pi.hThread);
        return true;
}

 // Открывает файл указанным плеером. В случаи успеха true.
bool __stdcall music_signal(const char *player,
                            const char *file_name)
{
        string commandLine = player;
        commandLine += " ";
        commandLine += file_name;
        std::unique_ptr<char[]> commandLine_buf( new char[commandLine.length() + 1] );
        commandLine.copy(commandLine_buf.get(),
                         commandLine.length());
        commandLine_buf[commandLine.length()] = '\0';

        STARTUPINFOA si = { sizeof(si) };
        PROCESS_INFORMATION pi;
        if( ! CreateProcessA(NULL, commandLine_buf.get(), NULL,
                             NULL, FALSE, 0, NULL, NULL, &si, &pi) )
                return false;
        CloseHandle(pi.hProcess);
        CloseHandle(pi.hThread);
        return true;
}

mql:

#import "DDD.dll"
   bool notepad_message(string file_name,
                        string message);
                                                           
   bool music_signal(string player,
                     string file_name);


int start()
{  
   if( ! notepad_message("C:\\Signal_from_mql\\Signal_1.txt",     // Папка Signal_from_mql должна существовать
                         "Take profit !!!") )
      Alert("Ошибка");
      
   if( ! music_signal("C:\\Program Files (x86)\\Windows Media Player\\wmplayer.exe",
                      "C:\\Back.mp3") )
          Alert("Ошибка");
          
   return(0);
}


В именах файлов пробелами не увлекаться, типа: хорошая песня.mp3, исправить на хорошая_песня.mp3.

Я код немного подкорректировал, поэтому возможно завелись баги.

Александр
123
Александр 2013.07.06 19:36  
Еще раз спасибо за отклики, когда начнешь о чем-то соображать и ваять внешний мир меркнет, время незаметно проскакивает, все просмотрю и проштудирую. Как у меня получиться и что сделаю обязательно напишу. Александр.
220Volt
1175
220Volt 2013.07.10 12:43  

    Вот еще одна полезная штучка, на тему уведомлений. Эта функция шлет SMS (в текстовом режиме, не PDU, латиницей) на указанный номер.

    Что для этого нужно (аппаратура)?: устройство, имеющее com (последовательный порт) подключение с ПК (или его эмулирующее) и понимающее AT команды, делал для USB модема (имеет свою СИМ карту, для отправки SMS подключение с интернетом не требуется).

    Не гарантирую, что у всех будет работать, у меня на модеме HUAWEI E173 работает.

#include <stdexcept>
#include <Windows.h>
#include <string>


class Serial_port
{
        HANDLE port;
        std::string response;
public:
        Serial_port(const char *port_name)
        {
                this->port = CreateFileA(port_name, GENERIC_READ | GENERIC_WRITE, 0, 
                                                      NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
                if(this->port == INVALID_HANDLE_VALUE)
                        throw std::runtime_error("Не удалось открыть порт\n");
                if( ! SetCommMask(port, EV_RXCHAR | EV_ERR) )
                        throw std::runtime_error("SetCommMask\n");

                DCB dcb;
                if( ! GetCommState(this->port, &dcb) )
                        throw std::runtime_error("GetCommState\n");
                dcb.DCBlength = sizeof(DCB);
                dcb.BaudRate = CBR_9600;
                dcb.fBinary = TRUE;
                dcb.fParity = FALSE;
                dcb.fOutxCtsFlow = FALSE;                                       // hardware flow control //
                dcb.fOutxDsrFlow = FALSE;                                       // hardware flow control //
                dcb.fDtrControl = DTR_CONTROL_DISABLE;          // hardware flow control
                dcb.fDsrSensitivity = FALSE;                            // software flow control
                //dcb.fTXContinueOnXoff = ;                                     // software flow control
                dcb.fOutX = FALSE;                                                      // software flow control  //
                dcb.fInX = FALSE;                                                       // software flow control
                //dcb.fErrorChar = ;
                dcb.fNull = TRUE;
                dcb.fRtsControl = RTS_CONTROL_DISABLE;          // hardware flow control
                dcb.fAbortOnError = FALSE;  //
                //dcb.fDummy2 = ;
                dcb.wReserved = 0;
                //dcb.XonLim = ;                                                        // software flow control
                //dcb.XoffLim = ;                                                       // software flow control
                dcb.ByteSize = 8;
                dcb.Parity = NOPARITY;
                dcb.StopBits = ONESTOPBIT;
                //dcb.XonChar = ;                                                       // software flow control
                //dcb.XoffChar = ;                                                      // software flow control
                //dcb.ErrorChar = ;
                //dcb.EofChar = ;
                //dcb.EvtChar = ;
                //dcb.wReserved1 = ;
                if( ! SetCommState(this->port, &dcb) )
                        throw std::runtime_error("SetCommState\n");

                COMMTIMEOUTS timeouts;
                timeouts.ReadIntervalTimeout = MAXDWORD; 
                timeouts.ReadTotalTimeoutMultiplier = 0;
                timeouts.ReadTotalTimeoutConstant = 0;
                timeouts.WriteTotalTimeoutMultiplier = 2;
                timeouts.WriteTotalTimeoutConstant = 5;
                if ( ! SetCommTimeouts(this->port, &timeouts) )
                        throw std::runtime_error("SetCommTimeouts\n");
        }

        Serial_port(const Serial_port &);       // delete
        Serial_port &operator=(const Serial_port &);    // delete

        ~Serial_port(void)
        {
                if( ! CloseHandle(this->port) )
                        throw std::runtime_error("CloseHandle\n");
        }
         
         // Запись в порт.
        void write(const char *str)
        {
                DWORD written;
                if( ! WriteFile(this->port, 
                                                str, 
                                                strlen(str),
                                                &written, 
                                                NULL) )
                        throw std::runtime_error("WriteFile\n");
                return;
        }
         
        // Чтение из порта. Использовать только для отладки.
        const std::string &read(void)
        {
                this->response.clear();
                DWORD event;
                char buf;
                DWORD read_count;
                if( WaitCommEvent(this->port, &event, NULL) )
                {
                        switch(event)
                        {
                        case EV_RXCHAR:         
                                do
                                {
                                        if( ! ReadFile(this->port, &buf, 1, &read_count, NULL) )        
                                                throw std::runtime_error("ReadFile\n");
                                        if(read_count > 0)      
                                                this->response += buf;
                                }
                                while(read_count > 0);
                                break;

                        default:
                                throw std::runtime_error("WaitCommEvent default\n");
                        }
                }
                else
                        throw std::runtime_error("WaitCommEvent\n");
                return this->response;
        }
};


int __stdcall send_sms(const char *message,
                                           const char *phone_number,
                                           const char *port_name)
{
        try
        {
                Serial_port port(port_name);
                std::string at_command;

                port.write("at+cmgf=1\r");

                at_command = "at+cmgs=\"";
                at_command += phone_number;
                at_command += "\"\r";
                port.write( at_command.c_str() );

                at_command = message;
                at_command += '\x1A';
                port.write( at_command.c_str() );
        }
        catch(const std::exception &ex)
        {
                //MessageBoxA(NULL, ex.what(), "", MB_OK); // раскомментировать только при отладке.
                return false;
        }
        catch(...)
        {
                return false;
        }
        return true;
}
mql:
#import "DDD.dll"               
        int send_sms(string message,
                     string phone_number,
                     string port_name);
                                          

int start()
{  
   if( send_sms("Take profit",
                "+71111111111",
                "com6") == 0 )
      Alert("Ошибка");
      
   return(0);
}
220Volt
1175
220Volt 2013.07.10 12:48  

Com порт не должен быть занят. Т.е. недопустима одновременная работа таких вещей как: megafon modem или коннект менеджер одновременно с кодом выше.

P.S: если индекс com порта больше 9, то писать так (в мкл): "\\.\COMx", где x - номер порта. Такой записью можно пользоваться и в случаи, если индекс не больше 9, она универсальная.

Александр
123
Александр 2013.07.10 18:49  

Спасибо. Много информации здорово. Честно : пока не смогу все применить сейчас, но в голове уже складывается картинка - что, куда, и как будет работать.

С Ув. Александр. 

/ /12
Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий