MetaTrader 5 herunterladen

Integration von MetaTrader 4 Client Terminal mit MS SQL Server

25 März 2016, 13:58
Yuriy Zaytsev
0
365

Einführung

Die Verwendung von Integrationen mit anderen Produkten bietet eine zusätzliche Herausforderung in Trading.

Es kann so viele Verwendungen davon geben, also werde ich einige von ihnen unten angeben

Sie können Ticks sammeln und diese an MS SQL SERVER zur weiteren Analyse übergeben. Mit einer großen Tick Historie, können Sie jede Periode sammeln, beginnend von dem minimalen Zeitschnitt und bis zu atypischen Perioden. Mit realen Tick Kursen können Sie Tick-Daten abhängige Strategien debuggen, bekannt als 'Scalper'.

Sie können einen Speicher für eine schnelle Analyse der von Anwendungen entnommenen Daten verwenden, zum Beispiel von MS Excel oder anderer Drittanbieter Software oder von Ihren eigenen Produkten.

Zum Beispiel, Sie können die gesamte Historie aus der Historiendatenbank des Terminals in MS SQL herunterladen. Dann müssen Sie nicht die Historie in MQL4 speichern. Dies wird helfen den Terminal-Speicher zu entlasten.

Sie können neuronale Netze mit in MS SQL SERVER gespeicherten Kursen berechnen: zum Beispiel, STATISTICA - 7.8 um Ihnen zu ermöglichen Kurse von SQL herunterzuladen, kann im Echtzeit-Modus gelöst werden, durch übergeben der Netz-Signale in MT4.

Sie können Ihr eigenes Programm in einer anderen Sprache oder für ein anderes Symbol entwickeln, und Signale mit MS SQL SERVVER übergeben, nur ausführende Funktionen für das Client Terminal belassen und es von ernsthaften Berechnungen entlasten.


Die folgende Software-Produkte wurden für dieses Projekt verwendet

  • MS SQL SERVER 2000 Developer - BASE
  • VISUAL C++ 6.0 SP5 - zum Erzeugen von DLL "YZMSSQLExpertSample.dll"
  • MDAC 7

Der minimale zu installierende Satz:

1 MS SQL SERVER 2000 Developer
2 MDAC 7

Ich habe das Programm mit MDAC 7 debugged. Allerdings ist es möglich, dass alles mit einigen älteren Versionen ok funktioniert. Wenn Sie die DLL nicht kompilieren möchten, müssen Sie Visual C++ 6.0 nicht installieren oder installiert haben. Sie können eine fertige DLL verwenden. Allerdings habe ich den Benutzernamen in ihm, den Namen von DSN und Verbindungen festverdrahtet. Also müssen Sie alles oben aufgelistete in Ihrer Version des Programms wiederholen. Ich werde hier nicht beschrieben wie MS SQL SERVER oder Visual C++ 6.0 installiert werden, das liegt außerhalb des Bereichs dieses spezifischen Artikels.

Nachdem die notwendigen Software-Produkte installiert wurden, müssen mir ein DSN erstellen:

dsn=MT4_SQL_BASE;", "yuraz", "qwerty"

Beispiel von Tick-Empfang in MS SQL

Alle Experimente wurden mit MS SQL SERVER 2000 Developer durchgeführt. In Visual C++ 6.0, wurde YZMSSQLExpertSample.DLL erzeugt mit der Methode des Zugangs zu MS SQL via ADO. MDAC 7 oder MDAC 8 muss installiert sein. Ich werde nur die Beispiele beschreiben, wie man Verfahren und Tabellen erstellt. Der minimale Satz, den wir in MS SQL erstellen müssen ist die Datenbank, Tabellen und Verfahren. Betrachten wir die Tabelle und Prozeduren die mit Tick Kursen arbeiten. Sie können einige Funktionen hinzufügen, wenn Sie möchten.

Es ist notwendig eine Datenbank und Tabellen in MS SQL zu erstellen. Ich habe eine neue Datenbank mit dem Namen MT4TRADE erstellt. Dann müssen wir die Tabellen in ihr erstellen:

MT4TICK - Tabelle der Ticks


//-----------------------------------------------------------------------------------
//
//  Structure of MT4TICK Base
//
//    idc             - formed automatically, unique number of record
//    ServerDateTime  - Filled out automatically, when adding a record
//                        Server local time - time when the quote was placed in the table 
//                        (it doesn't have anything in common with the date and time passed by MT4)
//                        it is the time counted by the server itself - it will be the same as the time
//                        of the machine, on which the server has been launched. 
//--- 
//    iDateTime       - date and time in MT4 format, passed from MT4
//    sSymbol         - symbol
//    cAsk            - quote Ask
//    cBid            - quote Bid
//
CREATE TABLE [dbo].[MT4TICK] (
    [idc] [bigint] IDENTITY (1, 1) NOT NULL ,
    [ServerDateTime] [datetime] NULL ,
    [iDateTime] [bigint] NULL ,
    [sSymbol] [char] (6) COLLATE SQL_Latin1_General_CP1251_CI_AS NULL ,
    [cAsk] [numeric](18, 4) NULL ,
    [cBid] [numeric](18, 4) NULL 
) ON [PRIMARY]
GO
 
--- Include automated filling out the ServerDateTime field with the date and time of server MS SQL
ALTER TABLE [dbo].[MT4TICK] ADD 
    CONSTRAINT [DF_MT4TICK_ServerDateTime] DEFAULT (getdate()) FOR [ServerDateTime]
GO

Unten ist wie Tick-Empfang und Tabellierungsverfahren ersccheinen:


// 
//    @RetCode int out          --- used for returning
//   ,@psSymbol char(6)         --- symbol
//   ,@piDateTime  bigint       --- date and time of tick arrival
//   ,@pdAsk  float             --- Ask 
//   ,@pdBid  float             --- Bid
//  
//   The procedure just returns 0 
//     if we analyze the code of returning to MQL4, we can see that the quote has reached the procedure and has been tabulated
//     
//
CREATE PROCEDURE dbo.YZ_MT4_TICK
    @RetCode int out          
   ,@psSymbol char(6)
   ,@piDateTime  bigint
   ,@pdAsk  float
   ,@pdBid  float
AS
insert into  MT4TICK   ( sSymbol, iDateTime, cAsk, cBid   )  values  ( @psSymbol , @piDateTime,  @pdAsk ,  @pdBid  )
select @RetCode=0
return @RetCode


Wir können aus der obigen Beschreibung erkennen welche Verfahren zu welchem Zweck verwendet werden.

@RetCode - es bringt keine Funktionalität, wenn von der DLL übergeben wird, es dient nur dem Empfang des Terminierungscode.

Die MS SQL SERVER Einrichtung ist abgeschlossen. Ein Skript zum Erstellen der Standard-Konfiguration ist an den Artikel angehangen.


Lassen Sie uns Fantasieren: Mögliche Lösungen und Pluspunkte

Wir können einen Datenspeicher erstellen und Informationen in/aus ihm platzieren/extrahieren. Auf diese Art können wir das MT4 Client Terminal von der Notwendigkeit die Kurs-Historie zu speichern entlasten. Jetzt ist die Kurs-Historie auf dem MS SQL SERVER gespeichert und wir können mit diesen Informationen arbeiten, sie schneller entnehmen und sie zu anderen Anwendungen exportieren. Wir können die Daten in NEURONALEN Paketen analysieren, von denen die meisten mit SQL Speichern arbeiten.

In der Echtzeit kann das Terminal fortfahren Signale von Indikatoren zu bilden und diese an den Speicher übergeben und auf diese Art fixieren. Eine externe Anwendung kann die Signale und die Historie in Echtzeit entnehmen, sie analysieren und Signale bilden, festlegen der Ausführung und die Speicherung der Protokolldatei auf dem MS SQL Server, und diese zur Ausführung an das Terminal senden.

Folglich erhalten wir Integration und funktionelle Verteilung unter beteiligten Anwendungen in einem automatisierten Handelskomplex.

Nun, wenn es keine Notwendigkeit zum Speichern der historischen Kurse mehr gibt, können wir es auf die folgende Weise einrichten. Setzen Sie die Mindest-Balken in Extras>Options>Charts, zum Beispiel, auf 5000. Das Terminal startet schneller, da es keinen Speicher für die große Historie zuweisen muss.





Quelltexte

DLL Code:

//+------------------------------------------------------------------+
//|                                              Sample DLL for MQL4 |
//|                 Copyright c 2004-2008, MetaQuotes Software Corp. |
//|                                        https://www.metaquotes.net |
//+------------------------------------------------------------------+
 
//+------------------------------------------------------------------+
//
//  YURAZ 2008  YZMSSQLExpertSample
//
//  Example DLL Integrating  MT4 with MS SQL 2000
//
//  ADO  MS SQL SERVER
//
//  software used
//
//  VISUAL C++ 6 , SP5 ,  MDAC 7 ,  MS SQL2000 + SP4
//
//+------------------------------------------------------------------+
  
#define WIN32_LEAN_AND_MEAN  // Exclude rarely-used stuff from Windows headers
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
//----
#define MT4_EXPFUNC __declspec(dllexport)
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
#pragma pack(push,1)
 
struct RateInfo
  {
   unsigned int      ctm;
   double            open;
   double            low;
   double            high;
   double            close;
   double            vol;
   double            vol1;
   double            vol2;
   double            vol3;
   double            vol4;
   double            vol5;
 
  };
 
#pragma pack(pop)
   
struct MqlStr
  {
   int               len;
   char             *string;
  };
  
static int CompareMqlStr(const void *left,const void *right);
   
static int SQLexecProcedure( char *nprc );
static int SQLexecProcedureSignal( char *sSymbol, char* sProcedure );
// static int _YZSQLsqlstrinsql( char *Symbol , unsigned int DateTime , double Ask, double Bid, char *NamePrc );
static int _YZSQLprocedure  ( char *sSymbol, unsigned int pDateTime, double Ask, double Bid, char *NamePrc );
static int _YZSQLprocedureHISTORYPut(char *Symbol,unsigned int Period, unsigned int DateTime,double Open,
                        double High,double  Low, double Close ,double Volume, unsigned int Bar ,char *Procedure);
 
                                                                                                             
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
BOOL APIENTRY DllMain(HANDLE hModule,DWORD ul_reason_for_call,LPVOID lpReserved)
  {
//----
   switch(ul_reason_for_call)
     {
      case DLL_PROCESS_ATTACH:
      case DLL_THREAD_ATTACH:
      case DLL_THREAD_DETACH:
      case DLL_PROCESS_DETACH:
         break;
     }
//----
   return(TRUE);
  }
 
 // place ticks in MS SQL
 // call the procedure as an SQL line passing parameters   "exec YZ_MT4_TICK ?,?,?,?"
/*
  MT4_EXPFUNC int  __stdcall SQLsqlstringTickPut(char *Symbol,unsigned int DateTime,double Ask,double Bid,char *sSQLstring)
 {
    int ccc =  _YZSQLsqlstrinsql( Symbol  , DateTime ,  Ask , Bid  , sSQLstring  );
    return(ccc);
 }
*/
 
 // call as a procedure passing parameters
  MT4_EXPFUNC int  __stdcall SQLProcedureTickPut(char *Symbol,unsigned int DateTime,double Ask,double Bid,char *Procedure)
 {
    int ccc =  _YZSQLprocedure( Symbol  , DateTime ,  Ask , Bid  ,Procedure );
    return(ccc);
 }
 
 // place a specific candlestick in MS SQL history
 MT4_EXPFUNC int  __stdcall SQLProcedureHistoryPut(char *Symbol,unsigned int Period , unsigned int DateTime,
                double Open,double High,double  Low, double Close ,double Volume,unsigned int Bar ,char *Procedure)
 {
    int ccc  =  _YZSQLprocedureHISTORYPut(Symbol,Period,DateTime,Open,High,Low,Close,Volume,Bar,Procedure);
    return(ccc);
 }
 
 
 // call procedure sProcedure
 // 
 // return -1 error
 //
 MT4_EXPFUNC int  __stdcall SQLProcedureGetInt(char *sProcedure)
 {
        int Ret =    SQLexecProcedure( sProcedure );
     return((int)Ret);
 }
 
 
 MT4_EXPFUNC int  __stdcall SQLProcedureGetSignal  (char *sSymbol, char *sProcedure)
 {
     
     int Ret =    SQLexecProcedureSignal( sSymbol, sProcedure );
     return((int)Ret);
 }
  
//////////////////////////////////
#include "stdafx.h"
#include <stdio.h>
#import "C:\Program Files\Common Files\System\ado\msado20.tlb" \
        rename("EOF","ADOEOF") rename("BOF","ADOBOF")
 
using namespace ADODB;
  
inline void TESTHR(HRESULT x) { if FAILED(x) _com_issue_error(x); };
 
// procedure call method
int _YZSQLprocedure( char *sSymbol, unsigned int pDateTime, double Ask, double Bid,   char *NamePrc )
{
  
   HRESULT hr = S_OK;
   _CommandPtr pCmd = NULL;
   _ConnectionPtr pConnection = NULL;
   _bstr_t strMessage, strAuthorID;
 
       ::CoInitialize(NULL);
 
   long codRet = -1;
 
   try {
      
      _ParameterPtr Par1;
      _ParameterPtr Par2;
      _ParameterPtr Par3;
      _ParameterPtr Par4;
      _ParameterPtr Par5;
 
      TESTHR(pConnection.CreateInstance(__uuidof(Connection)));
      hr = pConnection->Open("dsn=MT4_SQL_BASE;", "yuraz", "qwerty", adConnectUnspecified);
      pConnection->CursorLocation = adUseClient;
      TESTHR(pCmd.CreateInstance(__uuidof(Command)));
      pCmd->CommandText = NamePrc;  // procedure name
      pCmd->CommandType = adCmdStoredProc;
     
      Par1 = pCmd->CreateParameter( _bstr_t("@P1"), adInteger,   adParamOutput,0,    codRet );
      pCmd->Parameters->Append( Par1 );
      Par1 = pCmd->CreateParameter("@psSymbol",adChar, adParamInput, strlen(sSymbol) ,sSymbol );
         pCmd->Parameters->Append(Par1);
      Par2 = pCmd->CreateParameter("@piDateTime", adDouble , adParamInput, sizeof(double) ,  (double)pDateTime );
      pCmd->Parameters->Append(Par2);
      Par3 = pCmd->CreateParameter("@pdAsk", adDouble, adParamInput, 4, Ask );
      pCmd->Parameters->Append(Par3);
      Par4 = pCmd->CreateParameter("@pdBid", adDouble, adParamInput, 4, Bid );
      pCmd->Parameters->Append(Par4);
 
      
      pCmd->ActiveConnection = pConnection;
      int hr = pCmd->Execute( 0, 0, adCmdStoredProc );
      if( FAILED(hr) )
      {
                codRet = -1;
      }
      else
      {
         Par1 = pCmd->Parameters->GetItem(_bstr_t("@P1"));     // obtain from the procedure
         codRet = Par1->GetValue();
      }
   }
   catch(_com_error  ) {
       //
       // if necessary, process the execution error
          //
       codRet = -1;
 
   }
   if (pConnection)
      if (pConnection->State == adStateOpen)
         pConnection->Close();
 
   ::CoUninitialize();
    return((int)codRet);
}
 
 
 
// place in history Symbol , Period . DateTime, Open , High , Low , Close , Value , Bar
int _YZSQLprocedureHISTORYPut(char *pSymbol,unsigned int pPeriod, unsigned int pDateTime,double pOpen,double pHigh,
                                        double  pLow, double pClose ,double pVolume, unsigned int pBar ,char *pProcedure )
{
 
 
        HRESULT hr = S_OK;
   _CommandPtr pCmd = NULL;
   _ConnectionPtr pConnection = NULL;
   _bstr_t strMessage, strAuthorID;
 
       ::CoInitialize(NULL);
 
   long codRet = -1;
 
   try {
 
      _ParameterPtr ParReturn; // 
      _ParameterPtr Par1; // SYMBOL
      _ParameterPtr Par2; // PERIOD
      _ParameterPtr Par3; // DATETIME
      _ParameterPtr Par4; // OPEN
      _ParameterPtr Par5; // HIGH
      _ParameterPtr Par6; // LOW
      _ParameterPtr Par7; // CLOSE
      _ParameterPtr Par8; // VOLUME
      _ParameterPtr Par9; // BAR
 
 
      TESTHR(pConnection.CreateInstance(__uuidof(Connection)));
      hr = pConnection->Open("dsn=MT4_SQL_BASE;", "yuraz", "qwerty", adConnectUnspecified);
      pConnection->CursorLocation = adUseClient;
      TESTHR(pCmd.CreateInstance(__uuidof(Command)));
      pCmd->CommandText = pProcedure;  // procedure name
      pCmd->CommandType = adCmdStoredProc;
     
      ParReturn = pCmd->CreateParameter( _bstr_t("@P1"), adInteger,   adParamOutput,0,    codRet );
      pCmd->Parameters->Append( ParReturn );
 
      Par1 = pCmd->CreateParameter("@psSymbol",adChar, adParamInput, strlen(pSymbol) ,pSymbol );
         pCmd->Parameters->Append(Par1);
 
      Par2 = pCmd->CreateParameter("@piDateTime", adDouble , adParamInput, sizeof(double) ,  (double)pPeriod );
      pCmd->Parameters->Append(Par2);
 
      Par3 = pCmd->CreateParameter("@piDateTime", adDouble , adParamInput, sizeof(double) ,  (double)pDateTime );
      pCmd->Parameters->Append(Par3);
 
      Par4 = pCmd->CreateParameter("@pdOpen", adDouble, adParamInput, 4, pOpen );
      pCmd->Parameters->Append(Par4);
 
      Par5 = pCmd->CreateParameter("@pdHigh", adDouble, adParamInput, 4, pHigh );
      pCmd->Parameters->Append(Par5);
 
      Par6 = pCmd->CreateParameter("@pdLow", adDouble, adParamInput, 4, pLow );
      pCmd->Parameters->Append(Par6);
 
      Par7 = pCmd->CreateParameter("@pdClose", adDouble, adParamInput, 4, pClose );
      pCmd->Parameters->Append(Par7);
      
      Par8 = pCmd->CreateParameter("@pdVolume", adDouble, adParamInput, 4, pVolume );
      pCmd->Parameters->Append(Par8);
 
      Par9 = pCmd->CreateParameter("@piBar", adDouble , adParamInput, sizeof(double) ,  (double)pBar );
      pCmd->Parameters->Append(Par9);
 
 
      pCmd->ActiveConnection = pConnection;
      int hr = pCmd->Execute( 0, 0, adCmdStoredProc );
      if( FAILED(hr) )
      {
                codRet = -1;
      }
      else
      {
         ParReturn = pCmd->Parameters->GetItem(_bstr_t("@P1"));     // obtain from the procedure
         codRet = ParReturn->GetValue();
      }
   }
   catch(_com_error  ) {
       //
       // if necessary, process the execution error
          //
       codRet = -1;
 
   }
   if (pConnection)
      if (pConnection->State == adStateOpen)
         pConnection->Close();
 
   ::CoUninitialize();
    return((int)codRet);
}
 
 
//
// return the value returned by the procedure
//
int  SQLexecProcedure( char *nprc )
{
   
    HRESULT hr = S_OK;
   _CommandPtr pcmd = NULL;
   _ConnectionPtr pConnection = NULL;
   _bstr_t strMessage, strAuthorID;
 
       ::CoInitialize(NULL);
 
   long codRet = -1;
 
   try {
      TESTHR(pConnection.CreateInstance(__uuidof(Connection)));
      hr = pConnection->Open("dsn=MT4_SQL_BASE;", "yuraz", "qwerty", adConnectUnspecified);
      pConnection->CursorLocation = adUseClient;
      TESTHR(pcmd.CreateInstance(__uuidof(Command)));
      pcmd->CommandText = nprc;  // procedure name
      pcmd->CommandType = adCmdStoredProc;
     
      _ParameterPtr  pParm1 = pcmd->CreateParameter( _bstr_t("@P1"), adInteger,   adParamOutput,0,    codRet );
      pcmd->Parameters->Append( pParm1 );
      pcmd->ActiveConnection = pConnection;
      int hr = pcmd->Execute( 0, 0, adCmdStoredProc );
      if( FAILED(hr) )
      {
                codRet = -1;
      }
      else
      {
         pParm1 = pcmd->Parameters->GetItem(_bstr_t("@P1"));     // obtain from the procedure
         codRet = pParm1->GetValue();
      }
   }
   catch(_com_error  ) {
       //
       // if necessary, process the execution error
          //
       codRet = -1;
 
   }
   if (pConnection)
      if (pConnection->State == adStateOpen)
         pConnection->Close();
 
   ::CoUninitialize();
    return((int)codRet);
}
 
//
//
//
int  SQLexecProcedureSignal( char *sSymbol, char* sProcedure )
{
   
    HRESULT hr = S_OK;
   _CommandPtr pcmd = NULL;
   _ConnectionPtr pConnection = NULL;
   _bstr_t strMessage;
   _bstr_t strAuthorID;
 
       ::CoInitialize(NULL);
 
   long codRet = 0;
 
   try {
      TESTHR(pConnection.CreateInstance(__uuidof(Connection)));
      hr = pConnection->Open("dsn=MT4_SQL_BASE;", "yuraz", "qwerty", adConnectUnspecified);
      pConnection->CursorLocation = adUseClient;
      TESTHR(pcmd.CreateInstance(__uuidof(Command)));
      pcmd->CommandText = sProcedure;  // procedure name
      pcmd->CommandType = adCmdStoredProc;
 
      _ParameterPtr pParm1 = pcmd->CreateParameter("@psSymbol",adChar, adParamInput, strlen(sSymbol) ,sSymbol );
      pcmd->Parameters->Append(pParm1);
      _ParameterPtr pParm2 = pcmd->CreateParameter( _bstr_t("@P1"), adInteger,   adParamOutput,0,    codRet );
      pcmd->Parameters->Append( pParm2 );
      pcmd->ActiveConnection = pConnection;
      int hr = pcmd->Execute( 0, 0, adCmdStoredProc );
            if( FAILED(hr) )
            {
                bool bSuccess = false;
            }
            pParm2 = pcmd->Parameters->GetItem(_bstr_t("@P1"));     // obtain from the procedure
            codRet = pParm2->GetValue();
 
//             printf("\n [%d] \n",codRet );       // OBTAINING from the procedure
   }
   catch(_com_error  ) {
       //
       // if necessary, process the execution error
          //
   }
   if (pConnection)
      if (pConnection->State == adStateOpen)
         pConnection->Close();
 
   ::CoUninitialize();
    return((int)codRet);
}

Beispiel des Aufrufs von MQL4 -

// Comments are reduced to make it appear simpler, the comments in the attached files are complete
 
//+------------------------------------------------------------------+
//|                                                                  |
//|                 Copyright c 1999-2006, MetaQuotes Software Corp. |
//|                                         http://www.metaquotes.ru |
//|                                                YZMSSQLSample.mq4 |
//|                                                   Yuriy Zaitsev  |
//+------------------------------------------------------------------+
// Example of integrating with MS SQL                                |
//+------------------------------------------------------------------+
 
#property copyright "YURAZ Copyright(C) 2008"
#property link      "yzy @ mail.ru"
 
//+------------------------------------------------------------------+
// DLL function library 
//+------------------------------------------------------------------+
#import "YZMSSQLExpertSample.dll"
// Performing any actions on MS SQL Server, procedure is called
SQLProcedureGetInt 
// Collecting ticks
int SQLProcedureTickPut( string,  int , double , double ,string );  
 
int Prc = 0;
int init()
  {
 
//
// SQLProcedureGetInt The function, once having called a certain procedure, 
// will return into MT4 int value, for example, parameters
// stored on MS SQL server, formed by another software
//
   Prc =     SQLProcedureGetInt ("YZ_MT4_T1"); 
   return(0);
  }
 
int start()
  {
   int a;
 
   int RetCode = SQLProcedureTickPut( Symbol(), TimeCurrent() , Ask, Bid ,"YZ_MT4_TICK"); // call to the tick collecting procedure
   Print(" SQLProcedureTickPut (YZ_MT4_NEWDAY)"+ RetCode );
 
// Example:
//    on MS SQL server, you can filter signals formed using third-party software
//    neural networks 
//    other software products 
//
/*
   int Signal = SQLProcedureGetSignal (Symbol() , "YZ_MT4_SIGNAL" ); // procedure MS SQL , will return signal
   Print(" SQLProcedureGetSignal (Symbol() , YZ_MT4_SIGNAL )"+ Signal );
   if ( Signal == OP_BUY )
   {
       // the procedure has returned the signal and is recommending to buy
   }
   if ( Signal == OP_SELL )
   {
       // the procedure has returned the signal and is recommending to sell
   }
*/
 
   return(0);
  }

Skript zum Laden der Historie auf MS SQL Server:

//
// YURAZ  2008 yzh @ mail.ru
//
// script loading history onto MS SQL
// reload all history for all currency pairs and for all TIMEFRAMES
// in MS SQL
//
 
#import "YZMSSQLExpertSample.dll"
int SQLProcedureHistoryPut( string,  int  , int, double , double ,double , double ,double ,int,  string );  
 
static int mPeriod[8]={PERIOD_M1,PERIOD_M5,PERIOD_M15,PERIOD_M30,PERIOD_H1,PERIOD_H4,PERIOD_D1,PERIOD_W1,PERIOD_MN1};
 
void start()
{
    PutHistor("EURUSD"); 
    PutHistor("USDCHF"); 
    Comment(" LOADING COMPLETE " );
}
 
void PutHistor(string sSymbol)
{
  for ( int iPeriod = 0; iPeriod <= 8 ; iPeriod++ )
  {
     int pPERIOD_XX = mPeriod[iPeriod];
      int Bar = iBars(sSymbol,pPERIOD_XX ); // obtain the depth of history for the given timeframe
 // no progress bar organized 
     for ( int iBar = Bar; iBar >= 0 ; iBar--)
     {
     Comment( "WAIT  TIMEFRAME "+pPERIOD_XX+" SYMBOL "+sSymbol+" BARS "+iBar );
       double   o = iOpen  (sSymbol,pPERIOD_XX,iBar);
       double   h = iHigh  (sSymbol,pPERIOD_XX,iBar);
       double   l = iLow   (sSymbol,pPERIOD_XX,iBar);
       double   c = iClose (sSymbol,pPERIOD_XX,iBar);
       double   v = iVolume(sSymbol,pPERIOD_XX,iBar);
       datetime d = iTime  (sSymbol,pPERIOD_XX,iBar);
       int RetCode = SQLProcedureHistoryPut( sSymbol,pPERIOD_XX,d,o,h,l,c,v,iBar, "YZ_MT4_HISTORY");
       // Print ( " YZ_MT4_HITSRY "+RetCode);
      }
  }
}

Achtung: Leider wird die gesamte Historie mit dem Skript eher langsam geladen, aber es fixiert die Balkenanzahl klar und mit hoher Qualität.

Die beste Lösung wäre die Kurse in eine Textdatei zu entladen und diese über IMPRT EXPORT DTS in MS SQL zu laden. Das Laden der M1 Historie von 1999-2008 wird für jedes Symbol ein paar Minuten dauern.
Der Balken-Index wird nicht entladen, wenn Sie in eine Textdatei entladen. Wenn Sie entscheiden, dass der Balken-Index nur eine Zeilen-Nummer ist, werden Sie das Problem verpasster Balken haben und, wenn Sie ändern oder neu laden, kann die Anzahl der Balken in MS SQL und MT4 unterschiedlich sein. Ich habe das Problem noch nicht gelöst, aber ich vermute es kann gelöst werden durch neu-Laden der Historie nach einer hochwertigen Aktualisierung der Historie in MT4 selbst.


Beschreibung angehangener Dateien

CreateSQLallDate.txt (9.0 Kb)

- Skript in SQL Format als ein Beispiel, wie Datenbanken, Tabellen und Verfahren in MS SQL Server erstellt.

SQLGETHISTORY.mq4 (1.4 Kb)

- Skript zum Laden der Historie in MS SQL

YZMSSQLExpertSample.rar (89.9 Kb)

- DLL Projekt

YZMSSQLSample.mq4 (13.1 Kb) -

Um als EA an ein Symbol-Chart angehangen zu werden, dessen Ticks gesammelt werden sollen: Sie können es an jeden Zeitrahmen anhängen.


Fazit

Integration mit anderen Software-Produkten wird die Funktionalität von MetaTrader 4 erweitern und ermöglichen die Verteilung von Aufgaben und Funktionen eines automatisierten Handelssystems effizienter zu verteilen.

Übersetzt aus dem Russischen von MetaQuotes Software Corp.
Originalartikel: https://www.mql5.com/ru/articles/1533

Beigefügte Dateien |
SQLGETHISTORY.mq4 (1.45 KB)
YZMSSQLSample.mq4 (13.07 KB)
Ein Non-Trading EA Indikatoren Test Ein Non-Trading EA Indikatoren Test

Alle Indikatoren können in zwei Gruppen unterteilt werden: statische Indikatoren, deren Anzeige, einmal angezeigt, immer die gleiche in der Historie bleibt und sich nicht mit neu hereinkommenden Kursen ändert, und dynamische Indikatoren, die ihren Zustand nur für den aktuellen Augenblick anzeigen und vollständig neu gezeichnet werden, wenn ein neuer Kurs kommt. Die Effizienz eines statischen Indikators ist direkt auf den Chart sichtbar. Aber wie können wir prüfen, ob ein dynamischer Indikator richtig arbeitet? Dieser Frage ist der Artikel gewidmet.

Expert Advisors Basierend auf Beliebten Handelssystemen und Alchemie der Handelsroboter Optimierung (Forts.) Expert Advisors Basierend auf Beliebten Handelssystemen und Alchemie der Handelsroboter Optimierung (Forts.)

In diesem Artikel schlägt der Autor einen Weg vor, zur Verbesserung der Handelssysteme, die in seinen vorherigen Artikeln vorgestellt wurden. Der Artikel ist interessant für Trader die bereits über einige Erfahrung im Schreiben von Expert Advisors verfügen.

Show Must Go On, oder WIeder Einmal über ZigZagl Show Must Go On, oder WIeder Einmal über ZigZagl

Über ein offensichtliches, aber noch immer unzureichendes Verfahren der ZigZag Zusammensetzung, und was sich daraus ergibt: der Multiframe Fractal ZigZag Indikator, der auf drei größeren gebildete auf einem einzelnen Zeitrahmen (TF - Timeframe) darstellt. Die größeren Zeitrahmen ihrerseits können auch atypisch sein und reichen von M5 bis MN1.

Irrtümer, Teil 2. Statistiken sind eine Pseudo-Wissenschaft, oder eine Chronik des Nase Eintauchen in Brot und Butter Irrtümer, Teil 2. Statistiken sind eine Pseudo-Wissenschaft, oder eine Chronik des Nase Eintauchen in Brot und Butter

Zahlreiche Versuche statistische Methoden an der objektiven Realität anzuwenden, das heißt an Finanzreihen, stürzen ab wenn sie auf die Nichtstationarität von Verfahren treffen, "Fat Tails" begleitender Wahrscheinlichkeitsverteilungen und unzureichendes Volumen von Finanzdaten. In dieser Veröffentlichung werde ich versuchen nicht auf die Finanzreihe als solches zu beziehen, sondern auf ihre subjektive Darstellung - in diesem Fall, auf die Art, wie ein Trader versucht die Reihen zu halftern, d.h. auf das Handelssystem. Die Bildung von statistischen Regelmäßigkeiten des Handelsergebnis-Verfahren ist eine ziemlich fesselnde Aufgabe. In einigen Fällen können durchaus wahre Schlüsse über das Modell dieses Verfahren gezogen werden, und diese können an dem Handelssystem angewandt werden.