
Интеграция MetaTrader 4 с MS SQL-сервером
Введение
Использование интеграции с другими продуктами открывает дополнительные возможности в трейдинге.
Способов применения может быть множество, приведу некоторые из них.
Вы можете собирать тики и передавать их в MS SQL SERVER для дальнейшего анализа. Имея большую историю тиков, можно собрать любой период начиная от самого минимального кванта времени до самого нестандартного периода. Имея реальные тиковые котировки, желающие могут отлаживать стратегии зависимые от тиковых данных - известные как пипсовщики.
Можно использовать хранилище для быстрого анализа данных из других приложений, например, EXCEL, и других сторонних программных продуктов или собственных.
К примеру, можно выгрузить всю историю из History Center терминала в MS SQL, и не хранить историю в MT4, тем самым разгрузив терминал от хранения большой истории.
Вы можете выполнять расчеты нейросети, используя хранимые котировки в MS SQL SERVER: к примеру STATISTICA - 7,8 позволяют загружать котировки из SQL, можно решить в реальном времени, передавая сигналы сети в MT4.
Вы можете разработать собственную программу на другом языке и инструменте и передавать сигналы и котировки, используя SQL SERVER, оставив терминалу лишь исполнительские функции и разгрузив его от серьезных расчетов.
При реализации проекта использовалось программное обеспечение
- MS SQL SERVER 2000 Developer - БАЗА
- VISUAL C++ 6.0 SP5 - для создания DLL "YZMSSQLExpertSample.dll"
- MDAC 7
Минимум который необходимо инсталировать:
1 MS SQL SERVER 2000 Developer
2 MDAC 7
Я отлаживал на MDAC 7, возможно на более низких версиях тоже все будет работать. Если вы не собираетесь компилировать DLL, то инсталяция или наличие Visual C++ 6.0 не обязательно, можете использовать готовую DLL. Но я жестко прописал в ней имя пользователя, название DSN, соединения - их в этом случае прийдется повторить. Я не буду подробно описывать как инсталировать MS SQL SERVER или Visual C++ 6.0, это выходит за рамки темы.
После инсталяции ПО необходимо создать DSN,
dsn=MT4_SQL_BASE;", "yuraz", "qwerty"
Рассмотрим пример реализации приема тиков в MS SQL
Все опыты проводились с MS SQL SERVER 2000 Developer. На Visual C++ 6.0 была создана YZMSSQLExpertSample.DLL, используется метод доступа к MS SQL через ADO. Необходимо инсталлировать MDAC 7 или MDAC 8. Опишу лишь примеры создания процедур и таблиц. Минимально что нам потребуется - это создать на MS SQL базу, таблицы, процедуры; рассмотрим таблицу и процедуры для работы с тиковыми котировками. Далее функционал можно нарастить.
В MS SQL необходимо создать базу и таблицы, я сделал новую базу MT4TRADE. Далее в ней необходимо создать таблицы:
MT4TICK - таблица тиков
//----------------------------------------------------------------------------------- // // Структура базы MT4TICK // // idc - Формируется автоматически, уникальный номер записи // ServerDateTime - Заполняется автоматически, при добавлении записи // Серверное локальное время - время помещения котировки в таблицу // ( не имеет ничего общего с датой в временем - которые передает МТ) // это время которое отсчитывает сам сервер - оно будет совпадать с временем // машины на котором запущен сервер. //--- // iDateTime - дата и время в формате MT4, передается из MT4 // sSymbol - инструмент // cAsk - котировка Ask // cBid - Котировка 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 --- Пропишем автоматическое заполнение поля ServerDateTime датой и временем сервера MS SQL ALTER TABLE [dbo].[MT4TICK] ADD CONSTRAINT [DF_MT4TICK_ServerDateTime] DEFAULT (getdate()) FOR [ServerDateTime] GO
Процедура приема тика и записи в таблицу выглядит так:
// // @RetCode int out --- используется для возврата // ,@psSymbol char(6) --- инструмент // ,@piDateTime bigint --- дата и время прихода тика // ,@pdAsk float --- Ask // ,@pdBid float --- Bid // // Процедура просто возвращает 0 // если проанализировать код возврата в MQL4 то можно понять что котировка дошла до процедуры и записана в таблицу // // 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
по описанию видно какие параметры для чего используются.
@RetCode - при передаче из DLL он не несет функционала, он служит лишь для получения кода завершения.
Настройка MS SQL SERVER окончена. Скрипт по созданию типовой конфигурации прилагается.
Немного пофантазируем, возможные решения и плюсы.
Мы можем создать хранилище данных, помещать в него и извлекать информацию. Тем самым мы можем разгрузить терминал от функции хранения истории котировок в самом MT4. Теперь история котировок находится в SQL сервере в хранилище и мы можем оперировать этой информацией с большой скоростью извлекать ее в другие приложения. Мы можем использовать данные для аналитики в НЕЙРОННЫХ пакетах, большинство из которых умеет работать с хранилищами SQL.
В реальном времени можно оставить за терминалом функционал формирования сигналов от индикаторов с передачей их в хранилище, для фиксации, далее внешнее приложение в реальном времени может извлекать сигнал и историю, анализировать ее и формировать сигналы, фиксируя исполнение и хранение лога в SQL сервере, отправлять терминалу для исполнения.
Мы получаем интеграцию и распределение функционала между приложениями, задействованными в автоматизированном торговом комплексе.
Если в MT4 теперь нет надобности в хранении котировок, можно настроить его следующим образом. В интерфейсе MT4 сервис->настройки->графики выставить минимальное количество баров, например, 5000 баров. Терминал значительно быстрее работает так как не выделяет память под хранение большой истории.
Исходные тексты
Код DLL
//+------------------------------------------------------------------+ //| Sample DLL for MQL4 | //| Copyright c 2004-2006, MetaQuotes Software Corp. | //| https://www.metaquotes.net | //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ // // YURAZ 2008 YZMSSQLExpertSample // // Пример DLL интеграция MT4 с MS SQL 2000 // // ADO MS SQL SERVER // // используемое программное обеспечение // // 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); } // укладываем тики в MS SQL // вызываем процедуру как SQL строку передавая параметры "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); } */ // вызываем как процедуру передавая параметры 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); } // уложить в историю MS SQL конкретную свечу 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); } // вызываем процедуру sProcedure // // возврат -1 ошибка // 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); }; // метод вызова процедуры 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; // имя процедуры 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")); // получим из процедуры codRet = Par1->GetValue(); } } catch(_com_error ) { // // при необходимости обработаем ошибку исполнения // codRet = -1; } if (pConnection) if (pConnection->State == adStateOpen) pConnection->Close(); ::CoUninitialize(); return((int)codRet); } // поместить в историю 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; // имя процедуры 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")); // получим из процедуры codRet = ParReturn->GetValue(); } } catch(_com_error ) { // // при необходимости обработаем ошибку исполнения // codRet = -1; } if (pConnection) if (pConnection->State == adStateOpen) pConnection->Close(); ::CoUninitialize(); return((int)codRet); } // // вернем значение возвращаемое процедурой // 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; // имя процедуру 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")); // получим из процедуры codRet = pParm1->GetValue(); } } catch(_com_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; // имя процедуру 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")); // получим из процедуры codRet = pParm2->GetValue(); // printf("\n [%d] \n",codRet ); // ПОЛУЧАЕМ из процедуры } catch(_com_error ) { // // при необходимости обработаем ошибку исполнения // } if (pConnection) if (pConnection->State == adStateOpen) pConnection->Close(); ::CoUninitialize(); return((int)codRet); }
Пример вызова из MQL4 -
// Помещаю с сокращениями комментариев для простоты восприятия, в прикрепленных файлах комментарии полные //+------------------------------------------------------------------+ //| | //| Copyright c 1999-2006, MetaQuotes Software Corp. | //| http://www.metaquotes.ru | //| YZMSSQLSample.mq4 | //| Yuriy Zaitsev | //+------------------------------------------------------------------+ // Пример интеграции с MS SQL | //+------------------------------------------------------------------+ #property copyright "YURAZ Copyright(C) 2008" #property link "yzн @ mail.ru" //+------------------------------------------------------------------+ // Библиотека функций DLL //+------------------------------------------------------------------+ #import "YZMSSQLExpertSample.dll" // Выполнение каких либо действий на MS SQL сервере, вызывается процедура SQLProcedureGetInt // Сбор тиков int SQLProcedureTickPut( string, int , double , double ,string ); int Prc = 0; int init() { // // SQLProcedureGetInt Функция вызвав определенную процедуру , // вернет в MT4 int значение к примеру параметры // сохраненные на MS SQL сервере , сформронанные иным программным обеспечением // Prc = SQLProcedureGetInt ("YZ_MT4_T1"); return(0); } int start() { int a; int RetCode = SQLProcedureTickPut( Symbol(), TimeCurrent() , Ask, Bid ,"YZ_MT4_TICK"); // вызываем процедуру сбора тиков Print(" SQLProcedureTickPut (YZ_MT4_NEWDAY)"+ RetCode ); // Как пример: // на сервере MS SQL возможно формировать сигналы сформированные с помощью стороннего программного обеспечения // нейронных сетей // других программных продуктов // /* int Signal = SQLProcedureGetSignal (Symbol() , "YZ_MT4_SIGNAL" ); // процедура MS SQL , вернет сигнал Print(" SQLProcedureGetSignal (Symbol() , YZ_MT4_SIGNAL )"+ Signal ); if ( Signal == OP_BUY ) { // процедура вернула сигнал, рекомендует покупку } if ( Signal == OP_SELL ) { // процедура вернула сигнал, рекомендует продажу } */ return(0); }
Скрипт по загрузки истории в MS SQL сервер:
// // YURAZ 2008 yzh @ mail.ru // // скрипт загрузки истории в MS SQL // перегрузить всю историю по всем парам по всем ТАЙМФРЕМАМ // в 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(" ЗАГРУЗКА ПРОИЗВЕДЕНА " ); } void PutHistor(string sSymbol) { for ( int iPeriod = 0; iPeriod <= 8 ; iPeriod++ ) { int pPERIOD_XX = mPeriod[iPeriod]; int Bar = iBars(sSymbol,pPERIOD_XX ); // получим глубину истории по данному тф // не организован прогресс бар for ( int iBar = Bar; iBar >= 0 ; iBar--) { Comment( "ЖДИТЕ Период "+pPERIOD_XX+" СИМВОЛ "+sSymbol+" БАРОВ "+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); } } }
Внимание: к сожалению загрузка всей истории через скрипт происходит не быстро, но она четко и качественно фиксирует номер бара.
Лучшее решение - это выгрузка котировок в текстовый файл и загрузка в MS SQL через IMPRT EXPORT DTS. По времени загрузка минутки 1999-2008 занимает несколько минут по инструменту.
При выгрузке в текстовый файл не выгружается индекс бара. Если принять решение, что индексом бара будет просто порядковый номер строки, то нас ожидает проблема пропущенных баров, и при изменении - перезагрузки номера выгруженных баров в MS SQL и MT4 могут не совпасть. Пока я не решил эту проблему, но думаю, что ее решение вполне возможно перезагрузкой истории после качественного обновления истории в самом MT4.
Описание списка прикрепленных файлов

- Скрипт в формате SQL как пример создания баз, таблиц, процедур на MS SQL сервере

- Скрипт для загрузки истории в MS SQL

- проект DLL

Вешается как советник на график инструмента, тики которого необходимо собирать, вешать можно на любой таймфрейм.
Заключение
Интеграция с другими продуктами расширяет функциональность MetaTrader 4, позволяет более качественно распределить задачи и функции автоматизированной торговой системы.





- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
Привет всем!
Убил 2 дня все настроил - подключил, МТ4 данныепередает, база якобы принимает, в логах пишет что соединение успешное.
А база пустая.
Кто сможет помочь?
Александр
Тема актуальна..но я не понял-в каком формате предлагаетя хранить свечи на диске?
Это будут столбцы с миллионом строк?
И какой процент объёма занимает вспомогатедьная информация о дате и времени-м кстати в каком фрпмате она будет хранится ( сколько байт требуется для 1 значения Bid ) ?
Тема актуальна..но я не понял-в каком формате предлагаетя хранить свечи на диске?
Это будут столбцы с миллионом строк?
И какой процент объёма занимает вспомогатедьная информация о дате и времени-м кстати в каком фрпмате она будет хранится ( сколько байт требуется для 1 значения Bid ) ?
Реально например только по одной паре - загружено более 229 миллионов строк - и это только одна пара!
загружены тики
свечи не вижу смысла грузить их всегда можно собрать из тиков
-
недавно перезагружал - 229 миллионов тиков по eurusd загружается один раз за 12 минут это за 23 года
потом только докачка ( можно в реальном времени а можно по завершению дня )
можно грузить и быстрее машина не сильно бодрая для sql 24 ядра ксеноны и всего 64гига память
Если эта DLL работает с MDAC, то, похоже, мы можем данные выгружать не только в SQL Server, но и в Access. Если конечно DLL не содержит экстравагантных запросов, не поддерживаемых JET.
Если я, конечно, правильно понял.
Насколько я помню, в MDAC имеется коннектор с Excel. С этим не работал, не знаю. Но наверное можно с доработками.