Я знал, что сразу не получится :)
Вот уже и следующий вопрос. Почему не работает закомментированный код. МТ вешается.
ЭТО СКРИПТ.
так работает
Вот уже и следующий вопрос. Почему не работает закомментированный код. МТ вешается.
ЭТО СКРИПТ.
так работает
int start() { int err; double price[][6]; double price500[500][6]; int count = ArrayCopyRates( price, "EURUSD", PERIOD_H1); err = GetLastError(); if ( err == 4066) // ERR_HISTORY_WILL_UPDATED { // Пропускаем этот тик return (0); } Print( count); // count == 2680 bbl_write_rates( price, count); // count = ArrayCopy( price500, price, 0, count-499, 500); // bbl_write_rates( price500, count); return(0); }
так не работает
int start() { int err; double price[][6]; double price500[500][6]; int count = ArrayCopyRates( price, "EURUSD", PERIOD_H1); err = GetLastError(); if ( err == 4066) // ERR_HISTORY_WILL_UPDATED { // Пропускаем этот тик return (0); } Print( count); // count == 2680 // bbl_write_rates( price, count); count = ArrayCopy( price500, price, 0, count-499, 500); bbl_write_rates( price500, count); return(0); }
Чем же так отличаются массивы price & price500
код длл примерно такой
MT4_EXPFUNC void __stdcall bbl_write_rates(const RateInfo* rates, const int bar_count) { file_open_write( "C:\\Work\\Test\\rates.txt"); char buf[200]; for( int i=bar_count-1; i>=0; i--) { sprintf_s( buf, 199, "%6d %f\r\n", i, rates[i].close); file_write( buf); } file_close(); }
Чем же так отличаются массивы price & price500
код длл примерно такой
код длл примерно такой
Дело в том, что функция ArrayCopyRates() не производит фактического копирования в массив price[], происходит простое перенаправление, поэтому обращение к price[] становится равносильным обращению к EURUSD H1 (в данном случае) .
Соотвественно , ресайзить массив price после
ArrayCopyRates( price, "EURUSD", PERIOD_H1);
тоже не получится (на всякий случай добавляю).
Вот здесь предположим, что массив price[] содержит 500 элементов. Тогда вот это
count = ArrayCopy( price500, price, 0, count-499, 500); bbl_write_rates( price500, count);
можем переписать как
count = ArrayCopy( price500, price, 0, 1, 500); bbl_write_rates( price500, count);
так как count-499==500-499==1
я не понял ответ
ArrayCopyRates() у меня работает. и скрипт выводит опены в файл.
во втором варианте я не делаю ресайза, а копирую один массив в другой. В хелпе так написано.
А копирование это я делаю, для предотвращения несанкционированного мной доступа какой-нибудь обновлялки котировок к массиву в мойе длл (так уж я понял хелп и старые посты на этом форуме)
ArrayCopyRates() у меня работает. и скрипт выводит опены в файл.
во втором варианте я не делаю ресайза, а копирую один массив в другой. В хелпе так написано.
А копирование это я делаю, для предотвращения несанкционированного мной доступа какой-нибудь обновлялки котировок к массиву в мойе длл (так уж я понял хелп и старые посты на этом форуме)
я не понял ответ
ArrayCopyRates() у меня работает. и скрипт выводит опены в файл.
во втором варианте я не делаю ресайза, а копирую один массив в другой. В хелпе так написано.
А копирование это я делаю, для предотвращения несанкционированного мной доступа какой-нибудь обновлялки котировок к массиву в мойе длл (так уж я понял хелп и старые посты на этом форуме)
ArrayCopyRates() у меня работает. и скрипт выводит опены в файл.
во втором варианте я не делаю ресайза, а копирую один массив в другой. В хелпе так написано.
А копирование это я делаю, для предотвращения несанкционированного мной доступа какой-нибудь обновлялки котировок к массиву в мойе длл (так уж я понял хелп и старые посты на этом форуме)
Попробуй написать
count = ArrayCopy( price500, price, 0, count-500, 500); bbl_write_rates( price500, count);
попробовал 500 и 510 написать - виснет :(
я предполагаю, что в price больше 2500 свечей
я предполагаю, что в price больше 2500 свечей
Print( count); // count == 2680 // bbl_write_rates( price, count); count = ArrayCopy( price500, price, 0, count-510, 500); Print( count); // count == 500
похоже, разница в выравнивании
//#pragma pack(push,1) struct RateInfo { unsigned int ctm; double open; double low; double high; double close; double vol; }; //#pragma pack(pop)
так второй вариант не виснет
ПРОСЬБА К ПРОГРАММИСТАМ.
Ответьте на уже заданные мною вопросы. И еще один вопрос
Если разное выравнивание - это ваша ошибка, то будет ли эта разница устранена.
Вот полный код длл VisualStudio 2005
#include "stdafx.h" #define MT4_EXPFUNC __declspec(dllexport) #ifdef _MANAGED #pragma managed(push, off) #endif BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { return TRUE; } #ifdef _MANAGED #pragma managed(pop) #endif //#pragma pack(push,1) struct RateInfo { unsigned int ctm; double open; double low; double high; double close; double vol; }; //#pragma pack(pop) ////////////////////////// // for Test only ! #include <stdio.h> #include <fstream> #include <time.h> using namespace std; void mb( char* str) { WCHAR wszMessage[5000]; char* source = str; int k=0; while ( *source != 0) wszMessage[k++] = *(source++); wszMessage[k] = 0; ::MessageBoxW( NULL, wszMessage, L"Hello! :)", MB_OK); } ofstream* m_pOutFileStream; char FileName[500]; void file_open_write( char* file_name) { strcpy_s( FileName, 499, file_name); m_pOutFileStream = new ofstream( FileName, ios::out | ios::binary); //"C:\\Work\\Umnick\\test.txt" } void file_close() { m_pOutFileStream->close(); } void file_write( char* str) { m_pOutFileStream->write( str, std::streamsize( strlen(str))); } ////////////////////////////////////////// MT4_EXPFUNC void __stdcall bbl_write_rates(const RateInfo* rates, const int bar_count) { // char timebuf[26]; // _tzset(); file_open_write( "C:\\Work\\Test\\rates.txt"); char buf[200]; for( int i=bar_count-1; i>=0; i--) { // time_t ltime = rates[i].ctm; // tm today; // _localtime64_s( &today, <ime ); //ctime_s(timebuf, 26, <ime); // sprintf_s( buf, 199, "%d.%d.%d %d:%d:%d\r\n", today.tm_mday, today.tm_mon, today.tm_year, today.tm_hour, today.tm_min, today.tm_sec); // sprintf_s( buf, 199, "%f\r\n", rates[i].close); sprintf_s( buf, 199, "%6d %f\r\n", i, rates[i].close); // rates[i].close; file_write( buf); } file_close(); }
сори, за лишние комменты в коде :)
с массивом price работает вариант
#pragma pack(push,1) struct RateInfo { unsigned int ctm; double open; double low; double high; double close; double vol; }; #pragma pack(pop)
Нет, думаю тут проблема в другом. Вот выкладываю отлаженный вариант скрипта, который корректно копирует из Rate серии в обычный массив
//+------------------------------------------------------------------+ //| CheckArrayCopybabybear.mq4 | //| Copyright © 2007, MetaQuotes Software Corp. | //| http://www.metaquotes.ru/forum/8121/ | //+------------------------------------------------------------------+ #property copyright "Copyright © 2007, MetaQuotes Software Corp." #property link "http://www.metaquotes.ru/forum/8121/" #define copyBars 100 int start() { int err; double price[][6]; double price500[copyBars][6]; int count1 = ArrayCopyRates( price, "EURUSD", PERIOD_H1); err = GetLastError(); if ( err == 4066) // ERR_HISTORY_WILL_UPDATED { // Пропускаем этот тик Alert("Идет подкачка отсутствующих данных, перезапустите скрипт через несколько секунд"); return (0); } Print("copyBars=",copyBars); Print( "count1=",count1); // count == 2680 //bbl_write_rates( price, count); int count2 = ArrayCopy( price500, price, 0, 0, copyBars*6); Print( "count2=",count2); for (int i=0;i<copyBars;i++) { Print("i=",i," price500[i]=",TimeToStr(price500[copyBars-i-1][0]) /*," price500[i]=",price500[copyBars-i-1][1]," price500[i]=", price500[copyBars-i-1][2]," price500[i]=",price500[copyBars-i-1][3]," price500[i]=",price500[copyBars-i-1][4], " price500[i]=",price500[copyBars-i-1][5] */ ," price[count1-i]=",TimeToStr(price[count1-i-1][0])); } return(0); }
В кратком виде можно посмотреть здесь - "MQL4: ArrayCopy with arrays of rank 2."
Кончательный вариант такой
struct RateInfo { double dtime; double open; double low; double high; double close; double vol; }; MT4_EXPFUNC void __stdcall bbl_write_rates(const RateInfo* rates, const int bar_count) { file_open_write( "C:\\Work\\Test\\rates.txt"); char buf[200]; for( int i=bar_count-1; i>=0; i--) { time_t ltime = time_t( rates[i].dtime); tm today; _gmtime64_s( &today, <ime ); sprintf_s( buf, 199, "%6d %02d.%02d.%4d %02d:%02d:%02d ", i, today.tm_mday, today.tm_mon, today.tm_year+1900, today.tm_hour, today.tm_min, today.tm_sec); file_write( buf); sprintf_s( buf, 199, "%.4f\r\n", rates[i].close); file_write( buf); } file_close(); }
int start() { int err; double price[][6]; double price500[500][6]; int count = ArrayCopyRates( price, "EURUSD", PERIOD_H1); err = GetLastError(); if ( err == 4066) // ERR_HISTORY_WILL_UPDATED { // Пропускаем этот тик return (0); } count = ArrayCopy( price500, price, 0, 6*(count-500), 6*500); bbl_write_rates( price500, count/6); return(0); }
В нашем ExpertSample.dll и в соответствующем ему ExportFunctions.mq4 есть уже готовый пример вызова функции GetRatesItemValue. В длл передаётся массив котировок, возвращает прочитанное в этом массиве значение.
Вы упускаете торговые возможности:
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Регистрация
Вход
Вы принимаете политику сайта и условия использования
Если у вас нет учетной записи, зарегистрируйтесь
1. Мне нужно передать в длл ровно 500 свечей для работы советника в реалтайме. Как это сделать со стороны MQL? Меня интересует следующий вопрос, не может ли МТ в процессе обновления данных залезть в этот массив и его "подправить", в то время, когда моя длл будет с ним работать? Если не сложно, приведите правильный код обработки ERR_HISTORY_WILL_UPDATED.
2. Напишите, пожалуйста на программистском языке, что делают
а) ArrayCopyRates - (например, "ArrayCopyRates устанавливает ссылку на начало массива с котировками"), если она выделяет память, напишите тожа.
б) ArrayCopy()
3. oftop :) как вернуть из функции более одного значения? Интересует возможность передачи параметров в длл по ссылке. Можно это сделать? Опять же со стороны MQL. внутри длл я разберусь сам, если там особых хитростей нет.