PDA

Просмотр полной версии : Volume Data in Experts



deniss
21.07.2020, 09:48
Отдельная благодарность за создание кода aorekhov@rambler.ru
Ниже привожу исходное письмо отправленное мне от разработчика
--------------------
Volume & Delta Expert template

Подготовил шаблон для робота который использует данные ваших индикаторов. Может работать как на истории так и на реале. Hужно только дописать торговую логику робота.
Есть пара нюансов:
1. Не стал заморачиваться и недоделал автоматическую GMT коррекцию, нужно ставить вручную.
2. Если робот уже использовался и нужно протестировать историю на последних днях нужно стереть данные за последний месяц в папке сохраненных фаилов.
3. Массив данных полностью стирается по 1 числу каждого месаца. И заполняеться данными на текущий месяц и дополнительно 2 недели предыдущего для возможности анализа в логике робота данных за последние 2 недели.
4. Работает на М1, на других не проврялось


#property strict

//################################################## ##################
//+----------------- CLUSTERDELTA VOLUME DATA --------------------------+

#import "premium_mt4_v4x1.dll"
int InitDLL(int &);
string Receive_Information(int &, string);
int Send_Query(int &, string, string, int, string, string, string,
string, string, string, int, string, string, string,int);
#import


#import "online_mt4_v4x1.dll"
int Online_Init(int&, string, int);
string Online_Data(int&,string);
int Online_Subscribe(int &, string, string, int, string, string, string,
string, string, string, int, string, string, string,int);
#import


datetime TIME_Array[]; // Array for TIME
double VOLUME_Array[]; // Array of Volumes, indexes of array are corelated to TIME_ARRAY
double DELTA_Array[]; // Array of Deltas, indexes of array are corelated to TIME_ARRAY
datetime last_loaded = 0;
string indicator_client;
bool VOLUMES_INIT, ReverseChart_SET = false; // not used in expert


int Days_in_History;
datetime Custom_Start_time, Custom_End_time;

int INIT_DLL_result;



int GMT_SET=1;
int GMT =3; string MetaTrader_GMT = "+3"; // Change if GMT is different for both

input string Ticker = "AUTO";


//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit() {

// --- Volume & Delta ---
GlobalVariableDel(indicator_client);

InitDLL(INIT_DLL_result); // in the next version you dont have use this function
if(INIT_DLL_result==-1) { Print("Error during DLL init. ") ; ExpertRemove();}

do // DO NOT CHANGE THIS CODE & DATA --- Volume & Delta
{
indicator_client =
"CDPA" + StringSubstr(DoubleToString(TimeLocal(),0),7,3)+"" +DoubleToStr(MathAbs((MathRand()+3)%10),0);
} while (GlobalVariableCheck(indicator_client));
GlobalVariableTemp(indicator_client);

if(!IsTesting())
{
Custom_Start_time = D'2017.01.01 00:00'; // Indicator parameters to load 14 last days
Custom_End_time = D'2017.01.01 00:00';
Days_in_History = 14;
Online_Init(INIT_DLL_result, AccountCompany(), AccountNumber());
}
Vol_Delta_Cycle_Load();


//--- create timer
if(!IsTesting()) EventSetMillisecondTimer(100);

//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason) {
EventKillTimer();
GlobalVariableDel(indicator_client);

for(int it = 1; it < 10; it ++) Print(Time[it]," / Vol ",VOLUME_by_index(it)," / Del ",DELTA_by_index(it)); // just yo check vol & delta is working
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick() {

static int mmm, mn, vol, del; int vol_t, del_t;

if(IsTesting() && mmm != Month()) {mmm = Month(); Testing_Load_ind_Vol_Del();}
if(!IsTesting())
{
vol_t = VOLUME_by_index(1); del_t = DELTA_by_index(1);
if(mn != Minute()) {mn = Minute(); vol = vol_t; del = del_t; Print("Vol ",vol," // Del ",del);}
if(vol_t != vol || del_t != del) {vol = vol_t; del = del_t; Print("Update: Vol ",vol," // Del ",del);}
}
}
//+------------------------------------------------------------------+
//| Timer function |
//+------------------------------------------------------------------+
void OnTimer() {
uchar static Timer, Timer_V;
bool static Get_new_Vol = false;

if(TimeHour(TimeCurrent()) < 1) return; // Do not download DPOC data before 1:00 (if set)
if(!IsTesting())
{
Timer ++;
if(TimeSeconds(TimeCurrent()) == 59) {VOLUMES_GetOnline();}
else Timer_V ++;
{
Timer_V ++;
if(Timer_V >= 10)
{
Timer_V = 0; VOLUMES_GetOnline();
if(Get_new_Vol) { if(VOLUMES_GetData()) Get_new_Vol = false;}
}
}
if(Timer >= 50) { VOLUMES_SetData(); Timer = 0; Get_new_Vol = true;}
}

}
//+------------------------------------------------------------------+



void Testing_Load_ind_Vol_Del() {

ulong Timer_uSEC;
int it, MM_0, MM_1, YY_0, YY_1, temp, cc;
string mm_0, mm_1;
int temp_1_Vol[], temp_2_Vol[], temp_1_Del[], temp_2_Del[];
datetime temp_1_Time[], temp_2_Time[];

ArrayFree(temp_1_Time); ArrayFree(temp_1_Vol); ArrayFree(temp_1_Del);
ArrayFree(temp_2_Time); ArrayFree(temp_2_Vol); ArrayFree(temp_2_Del);
ArrayFree(TIME_Array); ArrayFree(VOLUME_Array); ArrayFree(DELTA_Array);

string f_name, f_handle, yyy, mmm;
yyy = IntegerToString(Year());
if(Month() < 10) mmm = "0"+ IntegerToString(Month()); else mmm = Month();
f_name = Symbol() +"\\"+ IntegerToString(yyy) +"_"+ mmm +".csv";
if(IsTesting() && FileIsExist(f_name)) {Testing_Load_file_Vol_Delta_by_Month(); return;}
ArrayFree(TIME_Array); ArrayFree(VOLUME_Array); ArrayFree(DELTA_Array); // Reset Array for Vol & Delta: load 1st part
MM_0 = Month() -1; YY_0 = Year(); MM_1 = Month(); YY_1 = YY_0;
if(MM_0 == 0) {MM_0 = 12; YY_0 -= 1;}
if(MM_0 < 10) mm_0 = "0"+ IntegerToString(MM_0); else mm_0 = IntegerToString(MM_0);
if(MM_1 < 10) mm_1 = "0"+ IntegerToString(MM_1); else mm_1 = IntegerToString(MM_1);

Custom_Start_time = StringToTime(IntegerToString(YY_0) +"."+ mm_0 +".12");
Custom_End_time = StringToTime(IntegerToString(YY_1) +"."+ mm_1 +".01");
Days_in_History = 0;
Print("Load indicator data for period: ",TimeToString(Custom_Start_time)," - ",TimeToString(Custom_End_time));
Vol_Delta_Cycle_Load(); if(!VOLUMES_INIT) {Print("Indicator Volume & Delta Data not loaded, exit"); ExpertRemove();}

ArrayResize(temp_1_Time, ArraySize(TIME_Array));
ArrayResize(temp_1_Vol , ArraySize(TIME_Array));
ArrayResize(temp_1_Del, ArraySize(TIME_Array));
for(it = 0; it < ArraySize(TIME_Array); it ++)
{
if(TimeMonth(TIME_Array[it]) == MM_1) continue;
temp_1_Time[it] = TIME_Array[it];
if(it < ArraySize(VOLUME_Array)) temp_1_Vol[it] = VOLUME_Array[it];
if(it < ArraySize(DELTA_Array)) temp_1_Del[it] = DELTA_Array [it];
}

ArrayFree(TIME_Array); ArrayFree(VOLUME_Array); ArrayFree(DELTA_Array); // Reset Array for Vol & Delta: Load 2nd part
MM_0 = Month(); YY_0 = Year(); MM_1 = Month() +1; YY_1 = YY_0;
if(MM_1 == 13) {MM_1 = 1; YY_1 += 1;}
if(MM_0 < 10) mm_0 = "0"+ IntegerToString(MM_0); else mm_0 = IntegerToString(MM_0);
if(MM_1 < 10) mm_1 = "0"+ IntegerToString(MM_1); else mm_1 = IntegerToString(MM_1);
Custom_Start_time = StringToTime(IntegerToString(YY_0) +"."+ mm_0 +".01");
Custom_End_time = StringToTime(IntegerToString(YY_1) +"."+ mm_1 +".01");
Days_in_History = 0;
Print("Load indicator data for period: ",TimeToString(Custom_Start_time)," - ",TimeToString(Custom_End_time));
Vol_Delta_Cycle_Load(); if(!VOLUMES_INIT) {Print("Indicator Volume & Delta Data not loaded, exit"); ExpertRemove();}

ArrayResize(temp_2_Time, ArraySize(TIME_Array));
ArrayResize(temp_2_Vol, ArraySize(TIME_Array));
ArrayResize(temp_2_Del, ArraySize(TIME_Array));
for(it = 0; it < ArraySize(TIME_Array); it ++)
{
if(TimeMonth(TIME_Array[it]) < MM_0) continue;
temp_2_Time[it] = TIME_Array[it];
if(it < ArraySize(VOLUME_Array)) temp_2_Vol[it] = VOLUME_Array[it];
if(it < ArraySize(DELTA_Array)) temp_2_Del[it] = DELTA_Array [it];
}



ArrayFree(TIME_Array); ArrayFree(VOLUME_Array); ArrayFree(DELTA_Array); // Reset Array for Vol & Delta: merge 1st & 2nd parts
for(it = 0; it < ArraySize(temp_1_Time); it ++)
{
ArrayResize(TIME_Array, ArraySize(TIME_Array) +1); TIME_Array [it] = temp_1_Time[it];
ArrayResize(VOLUME_Array, ArraySize(VOLUME_Array) +1); VOLUME_Array[it] = temp_1_Vol [it];
ArrayResize(DELTA_Array, ArraySize(DELTA_Array) +1); DELTA_Array [it] = temp_1_Del [it];
}

temp = ArraySize(temp_1_Time);
for(it = 0; it < ArraySize(temp_2_Time); it ++)
{
ArrayResize(TIME_Array, ArraySize(TIME_Array) +1); TIME_Array [it +temp] = temp_2_Time[it];
ArrayResize(VOLUME_Array, ArraySize(VOLUME_Array) +1); VOLUME_Array[it +temp] = temp_2_Vol [it];
ArrayResize(DELTA_Array, ArraySize(DELTA_Array) +1); DELTA_Array [it +temp] = temp_2_Del [it];
}

Testing_Write_file_Vol_Delta_by_Month(); // save merged data to file

}
void Vol_Delta_Init() {

indicator_client =
"CDPA" + StringSubstr(DoubleToString(TimeLocal(),0),7,3)+"" +DoubleToStr(MathAbs((MathRand()+3)%10),0);
}
void Vol_Delta_Cycle_Load() {

ulong Timer_uSEC;
int it, itt, c;

for(itt = 0; itt < 5; itt ++) // 5 attempt with reinitialization
{
Vol_Delta_Init(); Print("initialization Vol & Delta client # ",itt +1);
for(it = 0; it < 3; it ++) // 3 attempt to load single request
{
Timer_uSEC = GetMicrosecondCount(); // ---------- send server request
for(c = 1; c <= 3; c ++)
{
last_loaded = 0;
if(VOLUMES_SetData() < 0) // Server request data
{
while(!IsStopped() && GetMicrosecondCount() < (Timer_uSEC + 5000000 *c)) { for( int cc = 0; cc < 100; cc ++)}
Print("Volume - send server request #",c);
}
else break;
}

Timer_uSEC = GetMicrosecondCount(); // ---------- check for loaded data
for(c = 1; c <= 5; c ++)
{
ArrayFree(TIME_Array); ArrayFree(VOLUME_Array); ArrayFree(DELTA_Array);
if(VOLUMES_GetData() == 0) // Check is data ready ???
{
while(!IsStopped() && GetMicrosecondCount() < (Timer_uSEC + 5000000 * c)) for( int cc = 0; cc < 100; cc ++); // pause before next try
}
else
{ if(!VOLUMES_INIT)
{ while(!IsStopped() && GetMicrosecondCount() < (Timer_uSEC + 5000000 *c)) for( int cc = 0; cc < 100; cc ++); }}
Print("Volume - check for loaded data #",c);
if(VOLUMES_INIT) { Print("Volume Loaded # ",it); break;}
}
if(VOLUMES_INIT) break;
}
if(VOLUMES_INIT) break;
}

}
int ArrayBsearchCorrect(datetime &array[], double value,
int count = WHOLE_ARRAY, int start = 0,
int direction = MODE_ASCEND) {
if(ArraySize(array)==0) return(-1);
int i = ArrayBsearch(array, (datetime)value, count, start, direction);
if (value != array[i])
{
i = -1;
}
return (i);
}
void SortDictionary(datetime &keys[], double &values[], double &values2[], int sortDirection = MODE_ASCEND) {
datetime keyCopy[];
double valueCopy[];
double valueCopy2[];
ArrayCopy(keyCopy, keys);
ArrayCopy(valueCopy, values);
ArrayCopy(valueCopy2, values2);
ArraySort(keys, WHOLE_ARRAY, 0, sortDirection);
for (int i = 0; i < MathMin(ArraySize(keys), ArraySize(values)); i++)
{
values[ArrayBsearch(keys, keyCopy[i])] = valueCopy[i];
values2[ArrayBsearch(keys, keyCopy[i])] = valueCopy2[i];
}
}
void UpdateArray(datetime& td[],double& ad[], double& bd[], double dtp, double dta, double dtb) {
datetime indexx = (datetime)dtp;

int i=ArraySize(td);
int iBase = ArrayBsearchCorrect(td, indexx );

if (iBase >= 0) { i=iBase; }

if(i>=ArraySize(td))
{
ArrayResize(td, i+1);
ArrayResize(ad, i+1);
ArrayResize(bd, i+1);
} else {
if(ad[i]>dta && i>=ArraySize(td)-2) { dta=ad[i]; dtb=bd[i]; }
}

td[i]= (datetime)dtp;
ad[i]= dta;
bd[i]= dtb;
}
int VOLUMES_SetData() {

datetime Time_Current;
datetime Time_bar_arr;

if(IsTesting())
{
Time_Current = Custom_End_time;
Time_bar_arr = Custom_End_time;
}
else
{
Time_Current = TimeCurrent();
Time_bar_arr = Time[0];
}


int k=0,i;

string Instrument = Ticker;
string ver="4.1";



i = Send_Query(k,indicator_client,
Symbol(), Period(),
TimeToStr(Time_Current), TimeToStr(Time_bar_arr),
Instrument,TimeToStr(last_loaded),MetaTrader_GMT,v er,
Days_in_History,TimeToStr(Custom_Start_time),TimeT oStr(Custom_End_time),
AccountCompany(),AccountNumber());

if (i < 0) { Alert ("Error during query registration"); return -1; }

if(!IsTesting())
{
i = Online_Subscribe(k,indicator_client,
Symbol(), Period(),
TimeToStr(TimeCurrent()), TimeToStr(Time[0]),
Instrument, TimeToStr(last_loaded),MetaTrader_GMT,ver,
Days_in_History,TimeToStr(Custom_Start_time),TimeT oStr(Custom_End_time),
AccountCompany(),AccountNumber()); //
}

VOLUMES_INIT = false;
return 1;
}
int VOLUMES_GetData() {

string response="";
int length=0;
int valid=0;
int len=0,td_index;
int i=0;
double index;
int iBase=0;
double ask_value=0, bid_value=0;
string result[];
string bardata[];
string MessageFromServer;

// get query from dLL
response = Receive_Information(length, indicator_client);
if (length==0) { return 0; }

if(StringLen(response)>1)
{
len=StringSplit(response,StringGetCharacter("\n",0 ),result);
if(!len) { return 0; }
MessageFromServer=result[0];

for(i=1;i<len;i++)
{
if(StringLen(result[i])==0) continue;
StringSplit (result[i],StringGetCharacter(";",0),bardata);
// --- my check
if(ArraySize(bardata) < 3)
{
Print("Zero Bardata");
//Vol_Delta_Init(); // reinitialize Indicator
//VOLUMES_SetData(); // resend server request
return (0); // exit
}
// ---
td_index = ArraySize(TIME_Array);
index = (double)StrToTime (bardata[0]);
ask_value = StringToDouble (bardata[1]);
bid_value = StringToDouble (bardata[2])*(ReverseChart_SET?-1:1);


if(index==0) continue;
iBase = ArrayBsearchCorrect(TIME_Array, index );
if(iBase >= 0) { td_index=iBase; }
if(td_index >= ArraySize(TIME_Array))
{
ArrayResize(TIME_Array, td_index+1);
ArrayResize(VOLUME_Array, td_index+1);
ArrayResize(DELTA_Array, td_index+1);
}
else
{
if((VOLUME_Array[td_index]) > (ask_value) && td_index >= ArraySize(TIME_Array)-2)
{ ask_value = VOLUME_Array[td_index]; bid_value = DELTA_Array[td_index];}
}

TIME_Array [td_index] = (datetime)index;
VOLUME_Array[td_index] = ask_value;
DELTA_Array [td_index] = bid_value;

}
valid=ArraySize(TIME_Array);

if (valid>0)
{
SortDictionary(TIME_Array,VOLUME_Array,DELTA_Array );
int lastindex = ArraySize(TIME_Array);
last_loaded=TIME_Array[lastindex-1];
if(last_loaded>Time[0])last_loaded=Time[0];
VOLUMES_INIT = true;
}
else return(0);

}
return (1);
}
int VOLUMES_GetOnline() {

static int prnt_v_0, prnt_d_0, prnt_t_0, prnt_v_1, prnt_d_1, prnt_t_1;

string response="";
int length=0;
string key="";
string mydata="";
int block=0;
//if(Period()>60) return 0;
response = Online_Data(length, indicator_client);
if(length == 0) { return 0; }
if(ArraySize(TIME_Array)<4) { return 0; }
int key_i=StringFind(response, ":");
key = StringSubstr(response,0,key_i);
mydata = StringSubstr(response,key_i+1);
int compare_minutes = 0;



string result[];
string bardata[];
if(key == indicator_client)
{
StringSplit(mydata,StringGetCharacter("!",0),resul t);

if(!GMT_SET)
{
StringSplit(result[2],StringGetCharacter(";",0),bardata);
if(VOLUME_Array[ArraySize(VOLUME_Array)-3] == StringToDouble(bardata[1])) // 3-rd bar in stream is 3rd in series
{
StringSplit(result[0],StringGetCharacter(";",0),bardata);
compare_minutes = int( (double)(TIME_Array[ArraySize(TIME_Array)-1]) - StringToDouble(bardata[0]) );
GMT = int(compare_minutes / 3600);
GMT_SET=0;
} else
if(VOLUME_Array[ArraySize(VOLUME_Array)-2] == StringToDouble(bardata[1])) // 3-rd bar in stream is 3rd in series
{
compare_minutes = int( (double)(TIME_Array[ArraySize(TIME_Array)-2]) - StringToDouble(bardata[0]) );
GMT = int(compare_minutes / 3600);
GMT_SET=0;
}
}

StringSplit(result[0],StringGetCharacter(";",0),bardata);
UpdateArray(TIME_Array, VOLUME_Array,DELTA_Array, StringToDouble(bardata[0])+3600*GMT, StringToDouble(bardata[1]),StringToDouble(bardata[2]));
//if(prnt_t_0 != StrToInteger(bardata[0])+3600*GMT) {prnt_t_0 = StrToInteger(bardata[0])+3600*GMT; Print("Time_0 ",TimeToString(StrToInteger(bardata[0])+3600*GMT));}
//if(prnt_v_0 != StrToInteger(bardata[1])) {prnt_v_0 = StrToInteger(bardata[1]); Print(" / Vol_0 ", bardata[1]);}
//if(prnt_d_0 != StrToInteger(bardata[2])) {prnt_d_0 = StrToInteger(bardata[2]); Print(" / Delta_0 ", bardata[2]);}

StringSplit(result[1],StringGetCharacter(";",0),bardata);
UpdateArray(TIME_Array, VOLUME_Array,DELTA_Array, StringToDouble(bardata[0])+3600*GMT, StringToDouble(bardata[1]),StringToDouble(bardata[2]));
//if(prnt_t_1 != StrToInteger(bardata[0])+3600*GMT) {prnt_t_1 = StrToInteger(bardata[0])+3600*GMT; Print("Time_1 ",TimeToString(StrToInteger(bardata[0])+3600*GMT));}
//if(prnt_v_1 != StrToInteger(bardata[1])) {prnt_v_1 = StrToInteger(bardata[1]); Print(" / Vol_1 ", bardata[1]);}
//if(prnt_d_1 != StrToInteger(bardata[2])) {prnt_d_1 = StrToInteger(bardata[2]); Print(" / Delta_1 ", bardata[2]);}
}
return 1;
}
int VOLUME_by_index(int ix, bool BrokehHour=true) {
if(ArraySize(TIME_Array)<2) return 0;
if(ArraySize(Time)<=ix) return 0;

int iBase = ArrayBsearchCorrect(TIME_Array, Time[ix] );

if (iBase < 0 && Period() >= PERIOD_M5 && BrokehHour) { iBase = ArrayBsearchCorrect(TIME_Array, Time[ix] - 1*60 ); } // 1 Min BrokenHour
if (iBase < 0 && Period() >= PERIOD_M5 && BrokehHour) { iBase = ArrayBsearchCorrect(TIME_Array, Time[ix] - 2*60 ); } // 1 Min BrokenHour
if (iBase < 0 && Period() >= PERIOD_M5 && BrokehHour) { iBase = ArrayBsearchCorrect(TIME_Array, Time[ix] - 3*60 ); } // 1 Min BrokenHour
if (iBase < 0 && Period() >= PERIOD_M5 && BrokehHour) { iBase = ArrayBsearchCorrect(TIME_Array, Time[ix] - 4*60 ); } // 1 Min BrokenHour
if (iBase < 0 && Period() >= PERIOD_M15 && BrokehHour) { iBase = ArrayBsearchCorrect(TIME_Array, Time[ix] - 5*60 ); } // 5 Min BrokenHour
if (iBase < 0 && Period() >= PERIOD_H1 && BrokehHour) { iBase = ArrayBsearchCorrect(TIME_Array, Time[ix] - 30*60 ); } // 35 Min BrokenHour / ES
if (iBase < 0 && Period() >= PERIOD_H1 && BrokehHour) { iBase = ArrayBsearchCorrect(TIME_Array, Time[ix] - 35*60 ); } // 35 Min BrokenHour / ES
if (iBase < 0 && Period() >= PERIOD_H4 && BrokehHour) { iBase = ArrayBsearchCorrect(TIME_Array, Time[ix] - 60*60 ); } // 60 Min BrokenHour / ES
if (iBase < 0 && Period() >= PERIOD_H4 && BrokehHour) { iBase = ArrayBsearchCorrect(TIME_Array, Time[ix] + 60*60 ); } // 60 Min BrokenHour / ES
if (iBase < 0 && Period() >= PERIOD_H4 && BrokehHour) { iBase = ArrayBsearchCorrect(TIME_Array, Time[ix] + 2*60*60 ); } // 120 Min BrokenHour / ES
if (iBase < 0 && Period() >= PERIOD_W1 && BrokehHour) { iBase = ArrayBsearchCorrect(TIME_Array, Time[ix] + 24*60*60); } // 35 Min BrokenHour / ES


if (iBase >= 0)
{
return (int)VOLUME_Array[iBase];
}

return 0;
}
int DELTA_by_index (int ix, bool BrokehHour=true) {
if(ArraySize(TIME_Array)<2) return 0;
if(ArraySize(Time)<=ix) return 0;

int iBase = ArrayBsearchCorrect(TIME_Array, Time[ix] );

if (iBase < 0 && Period() >= PERIOD_M5 && BrokehHour) { iBase = ArrayBsearchCorrect(TIME_Array, Time[ix] - 1*60 ); } // 1 Min BrokenHour
if (iBase < 0 && Period() >= PERIOD_M5 && BrokehHour) { iBase = ArrayBsearchCorrect(TIME_Array, Time[ix] - 2*60 ); } // 1 Min BrokenHour
if (iBase < 0 && Period() >= PERIOD_M5 && BrokehHour) { iBase = ArrayBsearchCorrect(TIME_Array, Time[ix] - 3*60 ); } // 1 Min BrokenHour
if (iBase < 0 && Period() >= PERIOD_M5 && BrokehHour) { iBase = ArrayBsearchCorrect(TIME_Array, Time[ix] - 4*60 ); } // 1 Min BrokenHour
if (iBase < 0 && Period() >= PERIOD_M15 && BrokehHour) { iBase = ArrayBsearchCorrect(TIME_Array, Time[ix] - 5*60 ); } // 5 Min BrokenHour
if (iBase < 0 && Period() >= PERIOD_H1 && BrokehHour) { iBase = ArrayBsearchCorrect(TIME_Array, Time[ix] - 30*60 ); } // 35 Min BrokenHour / ES
if (iBase < 0 && Period() >= PERIOD_H1 && BrokehHour) { iBase = ArrayBsearchCorrect(TIME_Array, Time[ix] - 35*60 ); } // 35 Min BrokenHour / ES
if (iBase < 0 && Period() >= PERIOD_H4 && BrokehHour) { iBase = ArrayBsearchCorrect(TIME_Array, Time[ix] - 60*60 ); } // 60 Min BrokenHour / ES
if (iBase < 0 && Period() >= PERIOD_H4 && BrokehHour) { iBase = ArrayBsearchCorrect(TIME_Array, Time[ix] + 60*60 ); } // 60 Min BrokenHour / ES
if (iBase < 0 && Period() >= PERIOD_H4 && BrokehHour) { iBase = ArrayBsearchCorrect(TIME_Array, Time[ix] + 2*60*60 ); } // 120 Min BrokenHour / ES
if (iBase < 0 && Period() >= PERIOD_W1 && BrokehHour) { iBase = ArrayBsearchCorrect(TIME_Array, Time[ix] + 24*60*60); } // 35 Min BrokenHour / ES


if (iBase >= 0)
{
return (int)DELTA_Array[iBase];
}

return 0;
}
void Testing_Write_file_Vol_Delta_by_Month() {

if(!IsTesting()) return;
int it, dt, vol, del;
string f_name, f_handle, yyy, mmm, date;
yyy = IntegerToString(Year());
if(Month() < 10) mmm = "0"+ IntegerToString(Month()); else mmm = Month();
f_name = Symbol() +"\\"+ IntegerToString(yyy) +"_"+ mmm +".csv"; if(FileIsExist(f_name)) return; // exit if file already exist

f_handle = FileOpen(f_name, FILE_READ|FILE_WRITE|FILE_CSV);
for(it = 0; it < ArraySize(TIME_Array); it ++)
{
dt = TIME_Array[it];
date = TimeToString(dt);
if(it < ArraySize(VOLUME_Array)) vol = VOLUME_Array[it];
if(it < ArraySize(DELTA_Array)) del = DELTA_Array [it];
if(f_handle > 0) FileWrite(f_handle, date, dt, vol, del);
}
FileClose(f_handle);
}
void Testing_Load_file_Vol_Delta_by_Month() {

string f_name, yyy, mmm, date; int f_handle;
yyy = IntegerToString(Year());
if(Month() < 10) mmm = "0"+ IntegerToString(Month()); else mmm = Month();
f_name = Symbol() +"\\"+ IntegerToString(yyy) +"_"+ mmm +".csv";

f_handle = FileOpen(f_name, FILE_READ|FILE_WRITE|FILE_CSV);
while(!FileIsEnding(f_handle))
{
ArrayResize(TIME_Array, ArraySize(TIME_Array) +1);
ArrayResize(VOLUME_Array, ArraySize(VOLUME_Array) +1);
ArrayResize(DELTA_Array, ArraySize(DELTA_Array) +1);

date = FileReadString(f_handle);
TIME_Array [ArraySize(TIME_Array) -1] = FileReadString(f_handle);
VOLUME_Array[ArraySize(VOLUME_Array) -1] = FileReadString(f_handle);
DELTA_Array [ArraySize(DELTA_Array) -1] = FileReadString(f_handle);
}
FileClose(f_handle);
}

deniss
21.07.2020, 09:51
InitDLL(INIT_DLL_result); // in the next version you dont have use this function
if(INIT_DLL_result==-1) { Print("Error during DLL init. ") ; ExpertRemove();}


Если Вы будете подключать библотеку premiumt_mt4_v5x3.dll то эти две строки можно закомментировать.

aorekhov@rambler.ru
29.07.2020, 16:24
Доработал советник.
Теперь Metatrader GMT можно задавать в параметрах советника. Добавленна возможность записи объема и дельты в отдельный файл на каждый отдельный день.
Это дает возможность очень быстро создавать индикаторы для оценки возможных торговых стратегий. Шаблоны советника и индикатора приложены.
Также в качестве примера приложен индикатор объема с подсветкой событий: для положительного бара и отрицательной дельты и обратно. Индикатор работает только с историческими данными и может запускатся на графике резултата после прогона тестера. Родные индикаторы у меня не все и не всегда запускались в этом случае.
В принцыпе в файл можно записывать и другую информацию для дальнейшего считывания этих данных для анализа через индикатор.
Если будут интересные идеи могу попробывать их рализовать.

aorekhov@rambler.ru
29.07.2020, 16:27
Советник работает на M1, M5, M15, M30, H1, H4

aorekhov@rambler.ru
29.07.2020, 16:28
//+------------------------------------------------------------------+
//| Volume & Delta Expert template.mq4 |
//| |
//| Alex. 20.07.2020 |
//+------------------------------------------------------------------+
#property strict

//################################################## ################## //+----------------- CLUSTERDELTA VOLUM DATA --------------------------+

#import "premium_mt4_v4x1.dll"
int InitDLL(int &);
string Receive_Information(int &, string);
int Send_Query(int &, string, string, int, string, string, string,
string, string, string, int, string, string, string,int);
#import


#import "online_mt4_v4x1.dll"
int Online_Init(int&, string, int);
string Online_Data(int&,string);
int Online_Subscribe(int &, string, string, int, string, string, string,
string, string, string, int, string, string, string,int);
#import


datetime TIME_Array[]; // Array for TIME
double VOLUME_Array[]; // Array of Volumes, indexes of array are corelated to TIME_ARRAY
double DELTA_Array[]; // Array of Deltas, indexes of array are corelated to TIME_ARRAY
datetime last_loaded = 0;
string indicator_client;
bool VOLUMES_INIT, ReverseChart_SET = false; // not used in expert


int Days_in_History;
datetime Custom_Start_time, Custom_End_time;

int INIT_DLL_result;



int GMT_SET=1;
// int GMT =3;
string MetaTrader_GMT; //= "+3"; // Change if GMT is different for both

input int GMT = 3; // MetaTrader_GMT
input string Ticker = "AUTO";
input bool Daily_File = true; // Make Daily Volume & Delta file


//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit() {

// --- Volume & Delta ---
GlobalVariableDel(indicator_client);
if(GMT > 0) MetaTrader_GMT = "+" + IntegerToString(GMT);
if(GMT <= 0) MetaTrader_GMT = IntegerToString(GMT);


InitDLL(INIT_DLL_result); // in the next version you dont have use this function
if(INIT_DLL_result==-1) { Print("Error during DLL init. ") ; ExpertRemove();}

do // DO NOT CHANGE THIS CODE & DATA --- Volume & Delta
{
indicator_client =
"CDPA" + StringSubstr(DoubleToString(TimeLocal(),0),7,3)+""+DoubleToStr(MathAbs((MathRand()+3)%10),0);
} while (GlobalVariableCheck(indicator_client));
GlobalVariableTemp(indicator_client);

if(!IsTesting())
{
Custom_Start_time = D'2017.01.01 00:00'; // Indicator parameters to load 14 last days
Custom_End_time = D'2017.01.01 00:00';
Days_in_History = 14;
Online_Init(INIT_DLL_result, AccountCompany(), AccountNumber());
}
Vol_Delta_Cycle_Load();


//--- create timer
if(!IsTesting()) EventSetMillisecondTimer(100);

//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason) {
EventKillTimer();
GlobalVariableDel(indicator_client);

for(int it = 1; it < 10; it ++) Print(Time[it]," / Vol ",VOLUME_by_index(it)," / Del ",DELTA_by_index(it)); // just yo check vol & delta is working
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick() {

static int mmm, ddd, mn, vol, del; int vol_t, del_t; datetime dt;

if(IsTesting() && mmm != Month()) {mmm = Month(); Testing_Load_ind_Vol_Del();}
if(IsTesting() && ddd != Day()) {ddd = Day(); if(Daily_File) Testing_Write_ind_Vol_Del_Daily();}

if(!IsTesting())
{
vol_t = VOLUME_by_index(1); del_t = DELTA_by_index(1);
if(mn != Minute()) {mn = Minute(); vol = vol_t; del = del_t; Print("Vol ",vol," // Del ",del);}
if(vol_t != vol || del_t != del) {vol = vol_t; del = del_t; Print("Update: Vol ",vol," // Del ",del);}
}
}
//+------------------------------------------------------------------+
//| Timer function |
//+------------------------------------------------------------------+
void OnTimer() {
uchar static Timer, Timer_V;
bool static Get_new_Vol = false;

if(TimeHour(TimeCurrent()) < 1) return; // Do not download DPOC data before 1:00 (if set)
if(!IsTesting())
{
Timer ++;
if(TimeSeconds(TimeCurrent()) == 59) {VOLUMES_GetOnline();}
else Timer_V ++;
{
Timer_V ++;
if(Timer_V >= 10)
{
Timer_V = 0; VOLUMES_GetOnline();
if(Get_new_Vol) { if(VOLUMES_GetData()) Get_new_Vol = false;}
}
}
if(Timer >= 50) { VOLUMES_SetData(); Timer = 0; Get_new_Vol = true;}
}

}
//+------------------------------------------------------------------+



void Testing_Load_ind_Vol_Del() {

ulong Timer_uSEC;
int it, MM_0, MM_1, YY_0, YY_1, temp, cc;
string mm_0, mm_1;
int temp_1_Vol[], temp_2_Vol[], temp_1_Del[], temp_2_Del[];
datetime temp_1_Time[], temp_2_Time[];

ArrayFree(temp_1_Time); ArrayFree(temp_1_Vol); ArrayFree(temp_1_Del);
ArrayFree(temp_2_Time); ArrayFree(temp_2_Vol); ArrayFree(temp_2_Del);
ArrayFree(TIME_Array); ArrayFree(VOLUME_Array); ArrayFree(DELTA_Array);

string f_name, f_handle, yyy, mmm;
yyy = IntegerToString(Year());
if(Month() < 10) mmm = "0"+ IntegerToString(Month()); else mmm = Month();
f_name = Symbol() +"\\"+ Period() +"\\"+ yyy +"_"+ mmm +".csv";
if(IsTesting() && FileIsExist(f_name)) {Testing_Load_file_Vol_Delta_by_Month(); return;}
ArrayFree(TIME_Array); ArrayFree(VOLUME_Array); ArrayFree(DELTA_Array); // Reset Array for Vol & Delta: load 1st part
MM_0 = Month() -1; YY_0 = Year(); MM_1 = Month(); YY_1 = YY_0;
if(MM_0 == 0) {MM_0 = 12; YY_0 -= 1;}
if(MM_0 < 10) mm_0 = "0"+ IntegerToString(MM_0); else mm_0 = IntegerToString(MM_0);
if(MM_1 < 10) mm_1 = "0"+ IntegerToString(MM_1); else mm_1 = IntegerToString(MM_1);

Custom_Start_time = StringToTime(IntegerToString(YY_0) +"."+ mm_0 +".12");
Custom_End_time = StringToTime(IntegerToString(YY_1) +"."+ mm_1 +".01");
Days_in_History = 0;
Print("Load indicator data for period: ",TimeToString(Custom_Start_time)," - ",TimeToString(Custom_End_time));
Vol_Delta_Cycle_Load(); if(!VOLUMES_INIT) {Print("Indicator Volume & Delta Data not loaded, exit"); ExpertRemove();}

ArrayResize(temp_1_Time, ArraySize(TIME_Array));
ArrayResize(temp_1_Vol , ArraySize(TIME_Array));
ArrayResize(temp_1_Del, ArraySize(TIME_Array));
for(it = 0; it < ArraySize(TIME_Array); it ++)
{
if(TimeMonth(TIME_Array[it]) == MM_1) continue;
temp_1_Time[it] = TIME_Array[it];
if(it < ArraySize(VOLUME_Array)) temp_1_Vol[it] = VOLUME_Array[it];
if(it < ArraySize(DELTA_Array)) temp_1_Del[it] = DELTA_Array [it];
}

ArrayFree(TIME_Array); ArrayFree(VOLUME_Array); ArrayFree(DELTA_Array); // Reset Array for Vol & Delta: Load 2nd part
MM_0 = Month(); YY_0 = Year(); MM_1 = Month() +1; YY_1 = YY_0;
if(MM_1 == 13) {MM_1 = 1; YY_1 += 1;}
if(MM_0 < 10) mm_0 = "0"+ IntegerToString(MM_0); else mm_0 = IntegerToString(MM_0);
if(MM_1 < 10) mm_1 = "0"+ IntegerToString(MM_1); else mm_1 = IntegerToString(MM_1);
Custom_Start_time = StringToTime(IntegerToString(YY_0) +"."+ mm_0 +".01");
Custom_End_time = StringToTime(IntegerToString(YY_1) +"."+ mm_1 +".01");
Days_in_History = 0;
Print("Load indicator data for period: ",TimeToString(Custom_Start_time)," - ",TimeToString(Custom_End_time));
Vol_Delta_Cycle_Load(); if(!VOLUMES_INIT) {Print("Indicator Volume & Delta Data not loaded, exit"); ExpertRemove();}

ArrayResize(temp_2_Time, ArraySize(TIME_Array));
ArrayResize(temp_2_Vol, ArraySize(TIME_Array));
ArrayResize(temp_2_Del, ArraySize(TIME_Array));
for(it = 0; it < ArraySize(TIME_Array); it ++)
{
if(TimeMonth(TIME_Array[it]) < MM_0) continue;
temp_2_Time[it] = TIME_Array[it];
if(it < ArraySize(VOLUME_Array)) temp_2_Vol[it] = VOLUME_Array[it];
if(it < ArraySize(DELTA_Array)) temp_2_Del[it] = DELTA_Array [it];
}



ArrayFree(TIME_Array); ArrayFree(VOLUME_Array); ArrayFree(DELTA_Array); // Reset Array for Vol & Delta: merge 1st & 2nd parts
for(it = 0; it < ArraySize(temp_1_Time); it ++)
{
ArrayResize(TIME_Array, ArraySize(TIME_Array) +1); TIME_Array [it] = temp_1_Time[it];
ArrayResize(VOLUME_Array, ArraySize(VOLUME_Array) +1); VOLUME_Array[it] = temp_1_Vol [it];
ArrayResize(DELTA_Array, ArraySize(DELTA_Array) +1); DELTA_Array [it] = temp_1_Del [it];
}

temp = ArraySize(temp_1_Time);
for(it = 0; it < ArraySize(temp_2_Time); it ++)
{
ArrayResize(TIME_Array, ArraySize(TIME_Array) +1); TIME_Array [it +temp] = temp_2_Time[it];
ArrayResize(VOLUME_Array, ArraySize(VOLUME_Array) +1); VOLUME_Array[it +temp] = temp_2_Vol [it];
ArrayResize(DELTA_Array, ArraySize(DELTA_Array) +1); DELTA_Array [it +temp] = temp_2_Del [it];
}

Testing_Write_file_Vol_Delta_by_Month(); // save merged data to file

}
void Vol_Delta_Init() {

indicator_client =
"CDPA" + StringSubstr(DoubleToString(TimeLocal(),0),7,3)+""+DoubleToStr(MathAbs((MathRand()+3)%10),0);
}
void Vol_Delta_Cycle_Load() {

ulong Timer_uSEC;
int it, itt, c;

for(itt = 0; itt < 5; itt ++) // 5 attempt with reinitialization
{
Vol_Delta_Init(); Print("initialization Vol & Delta client # ",itt +1);
for(it = 0; it < 3; it ++) // 3 attempt to load single request
{
Timer_uSEC = GetMicrosecondCount(); // ---------- send server request
for(c = 1; c <= 3; c ++)
{
last_loaded = 0;
if(VOLUMES_SetData() < 0) // Server request data
{
while(!IsStopped() && GetMicrosecondCount() < (Timer_uSEC + 5000000 *c)) { for( int cc = 0; cc < 100; cc ++)}
Print("Volume - send server request #",c);
}
else break;
}

Timer_uSEC = GetMicrosecondCount(); // ---------- check for loaded data
for(c = 1; c <= 5; c ++)
{
ArrayFree(TIME_Array); ArrayFree(VOLUME_Array); ArrayFree(DELTA_Array);
if(VOLUMES_GetData() == 0) // Check is data ready ???
{
while(!IsStopped() && GetMicrosecondCount() < (Timer_uSEC + 5000000 * c)) for( int cc = 0; cc < 100; cc ++); // pause before next try
}
else
{ if(!VOLUMES_INIT)
{ while(!IsStopped() && GetMicrosecondCount() < (Timer_uSEC + 5000000 *c)) for( int cc = 0; cc < 100; cc ++); }}
Print("Volume - check for loaded data #",c);
if(VOLUMES_INIT) { Print("Volume Loaded # ",it); break;}
}
if(VOLUMES_INIT) break;
}
if(VOLUMES_INIT) break;
}

}
int ArrayBsearchCorrect(datetime &array[], double value,
int count = WHOLE_ARRAY, int start = 0,
int direction = MODE_ASCEND) {
if(ArraySize(array)==0) return(-1);
int i = ArrayBsearch(array, (datetime)value, count, start, direction);
if (value != array[i])
{
i = -1;
}
return (i);
}
void SortDictionary(datetime &keys[], double &values[], double &values2[], int sortDirection = MODE_ASCEND) {
datetime keyCopy[];
double valueCopy[];
double valueCopy2[];
ArrayCopy(keyCopy, keys);
ArrayCopy(valueCopy, values);
ArrayCopy(valueCopy2, values2);
ArraySort(keys, WHOLE_ARRAY, 0, sortDirection);
for (int i = 0; i < MathMin(ArraySize(keys), ArraySize(values)); i++)
{
values[ArrayBsearch(keys, keyCopy[i])] = valueCopy[i];
values2[ArrayBsearch(keys, keyCopy[i])] = valueCopy2[i];
}
}
void UpdateArray(datetime& td[],double& ad[], double& bd[], double dtp, double dta, double dtb) {
datetime indexx = (datetime)dtp;

int i=ArraySize(td);
int iBase = ArrayBsearchCorrect(td, indexx );

if (iBase >= 0) { i=iBase; }

if(i>=ArraySize(td))
{
ArrayResize(td, i+1);
ArrayResize(ad, i+1);
ArrayResize(bd, i+1);
} else {
if(ad[i]>dta && i>=ArraySize(td)-2) { dta=ad[i]; dtb=bd[i]; }
}

td[i]= (datetime)dtp;
ad[i]= dta;
bd[i]= dtb;
}
int VOLUMES_SetData() {

datetime Time_Current;
datetime Time_bar_arr;

if(IsTesting())
{
Time_Current = Custom_End_time;
Time_bar_arr = Custom_End_time;
}
else
{
Time_Current = TimeCurrent();
Time_bar_arr = Time[0];
}


int k=0,i;

string Instrument = Ticker;
string ver="4.1";



i = Send_Query(k,indicator_client,
Symbol(), Period(),
TimeToStr(Time_Current), TimeToStr(Time_bar_arr),
Instrument,TimeToStr(last_loaded),MetaTrader_GMT,v er,
Days_in_History,TimeToStr(Custom_Start_time),TimeT oStr(Custom_End_time),
AccountCompany(),AccountNumber());

if (i < 0) { Alert ("Error during query registration"); return -1; }

if(!IsTesting())
{
i = Online_Subscribe(k,indicator_client,
Symbol(), Period(),
TimeToStr(TimeCurrent()), TimeToStr(Time[0]),
Instrument, TimeToStr(last_loaded),MetaTrader_GMT,ver,
Days_in_History,TimeToStr(Custom_Start_time),TimeT oStr(Custom_End_time),
AccountCompany(),AccountNumber()); //
}

VOLUMES_INIT = false;
return 1;
}
int VOLUMES_GetData() {

string response="";
int length=0;
int valid=0;
int len=0,td_index;
int i=0;
double index;
int iBase=0;
double ask_value=0, bid_value=0;
string result[];
string bardata[];
string MessageFromServer;

// get query from dLL
response = Receive_Information(length, indicator_client);
if (length==0) { return 0; }

if(StringLen(response)>1)
{
len=StringSplit(response,StringGetCharacter("\n",0),result);
if(!len) { return 0; }
MessageFromServer=result[0];

for(i=1;i<len;i++)
{
if(StringLen(result[i])==0) continue;
StringSplit (result[i],StringGetCharacter(";",0),bardata);
// --- my check
if(ArraySize(bardata) < 3)
{
Print("Zero Bardata");
//Vol_Delta_Init(); // reinitialize Indicator
//VOLUMES_SetData(); // resend server request
return (0); // exit
}
// ---
td_index = ArraySize(TIME_Array);
index = (double)StrToTime (bardata[0]);
ask_value = StringToDouble (bardata[1]);
bid_value = StringToDouble (bardata[2])*(ReverseChart_SET?-1:1);


if(index==0) continue;
iBase = ArrayBsearchCorrect(TIME_Array, index );
if(iBase >= 0) { td_index=iBase; }
if(td_index >= ArraySize(TIME_Array))
{
ArrayResize(TIME_Array, td_index+1);
ArrayResize(VOLUME_Array, td_index+1);
ArrayResize(DELTA_Array, td_index+1);
}
else
{
if((VOLUME_Array[td_index]) > (ask_value) && td_index >= ArraySize(TIME_Array)-2)
{ ask_value = VOLUME_Array[td_index]; bid_value = DELTA_Array[td_index];}
}

TIME_Array [td_index] = (datetime)index;
VOLUME_Array[td_index] = ask_value;
DELTA_Array [td_index] = bid_value;

}
valid=ArraySize(TIME_Array);

if (valid>0)
{
SortDictionary(TIME_Array,VOLUME_Array,DELTA_Array );
int lastindex = ArraySize(TIME_Array);
last_loaded=TIME_Array[lastindex-1];
if(last_loaded>Time[0])last_loaded=Time[0];
VOLUMES_INIT = true;
}
else return(0);

}
return (1);
}
int VOLUMES_GetOnline() {

static int prnt_v_0, prnt_d_0, prnt_t_0, prnt_v_1, prnt_d_1, prnt_t_1;

string response="";
int length=0;
string key="";
string mydata="";
int block=0;
//if(Period()>60) return 0;
response = Online_Data(length, indicator_client);
if(length == 0) { return 0; }
if(ArraySize(TIME_Array)<4) { return 0; }
int key_i=StringFind(response, ":");
key = StringSubstr(response,0,key_i);
mydata = StringSubstr(response,key_i+1);
int compare_minutes = 0;



string result[];
string bardata[];
if(key == indicator_client)
{
StringSplit(mydata,StringGetCharacter("!",0),result);

/*
if(!GMT_SET)
{
StringSplit(result[2],StringGetCharacter(";",0),bardata);
if(VOLUME_Array[ArraySize(VOLUME_Array)-3] == StringToDouble(bardata[1])) // 3-rd bar in stream is 3rd in series
{
StringSplit(result[0],StringGetCharacter(";",0),bardata);
compare_minutes = int( (double)(TIME_Array[ArraySize(TIME_Array)-1]) - StringToDouble(bardata[0]) );
GMT = int(compare_minutes / 3600);
GMT_SET=0;
} else
if(VOLUME_Array[ArraySize(VOLUME_Array)-2] == StringToDouble(bardata[1])) // 3-rd bar in stream is 3rd in series
{
compare_minutes = int( (double)(TIME_Array[ArraySize(TIME_Array)-2]) - StringToDouble(bardata[0]) );
GMT = int(compare_minutes / 3600);
GMT_SET=0;
}
} */

StringSplit(result[0],StringGetCharacter(";",0),bardata);
UpdateArray(TIME_Array, VOLUME_Array,DELTA_Array, StringToDouble(bardata[0])+3600*GMT, StringToDouble(bardata[1]),StringToDouble(bardata[2]));
//if(prnt_t_0 != StrToInteger(bardata[0])+3600*GMT) {prnt_t_0 = StrToInteger(bardata[0])+3600*GMT; Print("Time_0 ",TimeToString(StrToInteger(bardata[0])+3600*GMT));}
//if(prnt_v_0 != StrToInteger(bardata[1])) {prnt_v_0 = StrToInteger(bardata[1]); Print(" / Vol_0 ", bardata[1]);}
//if(prnt_d_0 != StrToInteger(bardata[2])) {prnt_d_0 = StrToInteger(bardata[2]); Print(" / Delta_0 ", bardata[2]);}

StringSplit(result[1],StringGetCharacter(";",0),bardata);
UpdateArray(TIME_Array, VOLUME_Array,DELTA_Array, StringToDouble(bardata[0])+3600*GMT, StringToDouble(bardata[1]),StringToDouble(bardata[2]));
//if(prnt_t_1 != StrToInteger(bardata[0])+3600*GMT) {prnt_t_1 = StrToInteger(bardata[0])+3600*GMT; Print("Time_1 ",TimeToString(StrToInteger(bardata[0])+3600*GMT));}
//if(prnt_v_1 != StrToInteger(bardata[1])) {prnt_v_1 = StrToInteger(bardata[1]); Print(" / Vol_1 ", bardata[1]);}
//if(prnt_d_1 != StrToInteger(bardata[2])) {prnt_d_1 = StrToInteger(bardata[2]); Print(" / Delta_1 ", bardata[2]);}
}
return 1;
}
int VOLUME_by_index(int ix, bool BrokehHour=true) {
if(ArraySize(TIME_Array)<2) return 0;
if(ArraySize(Time)<=ix) return 0;

int iBase = ArrayBsearchCorrect(TIME_Array, Time[ix] );

if (iBase < 0 && Period() >= PERIOD_M5 && BrokehHour) { iBase = ArrayBsearchCorrect(TIME_Array, Time[ix] - 1*60 ); } // 1 Min BrokenHour
if (iBase < 0 && Period() >= PERIOD_M5 && BrokehHour) { iBase = ArrayBsearchCorrect(TIME_Array, Time[ix] - 2*60 ); } // 1 Min BrokenHour
if (iBase < 0 && Period() >= PERIOD_M5 && BrokehHour) { iBase = ArrayBsearchCorrect(TIME_Array, Time[ix] - 3*60 ); } // 1 Min BrokenHour
if (iBase < 0 && Period() >= PERIOD_M5 && BrokehHour) { iBase = ArrayBsearchCorrect(TIME_Array, Time[ix] - 4*60 ); } // 1 Min BrokenHour
if (iBase < 0 && Period() >= PERIOD_M15 && BrokehHour) { iBase = ArrayBsearchCorrect(TIME_Array, Time[ix] - 5*60 ); } // 5 Min BrokenHour
if (iBase < 0 && Period() >= PERIOD_H1 && BrokehHour) { iBase = ArrayBsearchCorrect(TIME_Array, Time[ix] - 30*60 ); } // 35 Min BrokenHour / ES
if (iBase < 0 && Period() >= PERIOD_H1 && BrokehHour) { iBase = ArrayBsearchCorrect(TIME_Array, Time[ix] - 35*60 ); } // 35 Min BrokenHour / ES
if (iBase < 0 && Period() >= PERIOD_H4 && BrokehHour) { iBase = ArrayBsearchCorrect(TIME_Array, Time[ix] - 60*60 ); } // 60 Min BrokenHour / ES
if (iBase < 0 && Period() >= PERIOD_H4 && BrokehHour) { iBase = ArrayBsearchCorrect(TIME_Array, Time[ix] + 60*60 ); } // 60 Min BrokenHour / ES
if (iBase < 0 && Period() >= PERIOD_H4 && BrokehHour) { iBase = ArrayBsearchCorrect(TIME_Array, Time[ix] + 2*60*60 ); } // 120 Min BrokenHour / ES
if (iBase < 0 && Period() >= PERIOD_W1 && BrokehHour) { iBase = ArrayBsearchCorrect(TIME_Array, Time[ix] + 24*60*60); } // 35 Min BrokenHour / ES


if (iBase >= 0)
{
return (int)VOLUME_Array[iBase];
}

return 0;
}
int DELTA_by_index (int ix, bool BrokehHour=true) {
if(ArraySize(TIME_Array)<2) return 0;
if(ArraySize(Time)<=ix) return 0;

int iBase = ArrayBsearchCorrect(TIME_Array, Time[ix] );

if (iBase < 0 && Period() >= PERIOD_M5 && BrokehHour) { iBase = ArrayBsearchCorrect(TIME_Array, Time[ix] - 1*60 ); } // 1 Min BrokenHour
if (iBase < 0 && Period() >= PERIOD_M5 && BrokehHour) { iBase = ArrayBsearchCorrect(TIME_Array, Time[ix] - 2*60 ); } // 1 Min BrokenHour
if (iBase < 0 && Period() >= PERIOD_M5 && BrokehHour) { iBase = ArrayBsearchCorrect(TIME_Array, Time[ix] - 3*60 ); } // 1 Min BrokenHour
if (iBase < 0 && Period() >= PERIOD_M5 && BrokehHour) { iBase = ArrayBsearchCorrect(TIME_Array, Time[ix] - 4*60 ); } // 1 Min BrokenHour
if (iBase < 0 && Period() >= PERIOD_M15 && BrokehHour) { iBase = ArrayBsearchCorrect(TIME_Array, Time[ix] - 5*60 ); } // 5 Min BrokenHour
if (iBase < 0 && Period() >= PERIOD_H1 && BrokehHour) { iBase = ArrayBsearchCorrect(TIME_Array, Time[ix] - 30*60 ); } // 35 Min BrokenHour / ES
if (iBase < 0 && Period() >= PERIOD_H1 && BrokehHour) { iBase = ArrayBsearchCorrect(TIME_Array, Time[ix] - 35*60 ); } // 35 Min BrokenHour / ES
if (iBase < 0 && Period() >= PERIOD_H4 && BrokehHour) { iBase = ArrayBsearchCorrect(TIME_Array, Time[ix] - 60*60 ); } // 60 Min BrokenHour / ES
if (iBase < 0 && Period() >= PERIOD_H4 && BrokehHour) { iBase = ArrayBsearchCorrect(TIME_Array, Time[ix] + 60*60 ); } // 60 Min BrokenHour / ES
if (iBase < 0 && Period() >= PERIOD_H4 && BrokehHour) { iBase = ArrayBsearchCorrect(TIME_Array, Time[ix] + 2*60*60 ); } // 120 Min BrokenHour / ES
if (iBase < 0 && Period() >= PERIOD_W1 && BrokehHour) { iBase = ArrayBsearchCorrect(TIME_Array, Time[ix] + 24*60*60); } // 35 Min BrokenHour / ES


if (iBase >= 0)
{
return (int)DELTA_Array[iBase];
}

return 0;
}
void Testing_Write_file_Vol_Delta_by_Month() {

if(!IsTesting()) return;
int it, dt, vol, del;
string f_name, f_handle, yyy, mmm, date;
yyy = IntegerToString(Year());
if(Month() < 10) mmm = "0"+ IntegerToString(Month()); else mmm = Month();
f_name = Symbol() +"\\"+ Period() +"\\"+ yyy +"_"+ mmm +".csv"; if(FileIsExist(f_name)) return; // exit if file already exist

f_handle = FileOpen(f_name, FILE_READ|FILE_WRITE|FILE_CSV);
for(it = 0; it < ArraySize(TIME_Array); it ++)
{
dt = TIME_Array[it];
date = TimeToString(dt);
if(it < ArraySize(VOLUME_Array)) vol = VOLUME_Array[it];
if(it < ArraySize(DELTA_Array)) del = DELTA_Array [it];
if(f_handle > 0) FileWrite(f_handle, date, dt, vol, del);
}
FileClose(f_handle);
}
void Testing_Load_file_Vol_Delta_by_Month() {

string f_name, yyy, mmm, date; int f_handle;
yyy = IntegerToString(Year());
if(Month() < 10) mmm = "0"+ IntegerToString(Month()); else mmm = Month();
f_name = Symbol() +"\\"+ Period() +"\\"+ yyy +"_"+ mmm +".csv";

f_handle = FileOpen(f_name, FILE_READ|FILE_WRITE|FILE_CSV);
while(!FileIsEnding(f_handle))
{
ArrayResize(TIME_Array, ArraySize(TIME_Array) +1);
ArrayResize(VOLUME_Array, ArraySize(VOLUME_Array) +1);
ArrayResize(DELTA_Array, ArraySize(DELTA_Array) +1);

date = FileReadString(f_handle);
TIME_Array [ArraySize(TIME_Array) -1] = FileReadString(f_handle);
VOLUME_Array[ArraySize(VOLUME_Array) -1] = FileReadString(f_handle);
DELTA_Array [ArraySize(DELTA_Array) -1] = FileReadString(f_handle);
}
FileClose(f_handle);
}

void Testing_Write_ind_Vol_Del_Daily() {

string yyy, mmm, ddd, hh, mm;
string vol_f, del_f, time_f, date_f, datetime_f;
string file_name;
int ix, step, f_handle;
datetime it;


if(Month() < 10) mmm = "0"+ IntegerToString(Month()); else mmm = Month();
if(Day() < 10) ddd = "0"+ IntegerToString(Day()); else ddd = Day();
yyy = IntegerToString(Year());


file_name = Symbol() +"\\"+ Period() +"\\"+ yyy +"\\"+ mmm +"\\"+ ddd + "_ID.csv";
if(FileIsExist(file_name)) return;
f_handle = FileOpen(file_name, FILE_READ|FILE_WRITE|FILE_CSV);

if(Period() == 1) step = 60;
if(Period() == 5) step = 300;
if(Period() == 15) step = 900;
if(Period() == 30) step = 1800;
if(Period() == 60) step = 3600;
if(Period() == 240) step = 14400;
if(Period() > 240) {Print("D1 TimeFrame not allowed"); ExpertRemove();}
for(it = iTime(NULL,PERIOD_D1,0); it > 0; it += step)
{
if(TimeDay(it) != Day()) return;
ix = ArrayBsearchCorrect(TIME_Array,it);
if(ix > 0)
{
if(TimeHour (it) <= 9) hh = "0" + IntegerToString(TimeHour(it));
else hh = IntegerToString(TimeHour(it));
if(TimeMinute (it) <= 9) mm = "0" + IntegerToString(TimeMinute(it));
else mm = IntegerToString(TimeMinute(it));

datetime_f = IntegerToString((int)TIME_Array[ix]);
date_f = yyy +"."+ mmm +"."+ ddd;
time_f = hh +":"+ mm;

vol_f = IntegerToString(VOLUME_Array[ix]); del_f = IntegerToString(DELTA_Array[ix]);
if(f_handle > 0) FileWrite(f_handle, datetime_f, date_f, time_f, vol_f, del_f);
}
}
FileClose(f_handle);
}

aorekhov@rambler.ru
29.07.2020, 16:30
//+------------------------------------------------------------------+
//| Tester Indicator Template.mq4 |
//| |
//| Alex 2020 |
//+------------------------------------------------------------------+
//#property copyright "Copyright © 2013, Fox.RM"


//---- indicator settings
#property strict
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_color1 Blue



input string File_ID = "_ID.csv"; // file ID


//--- CSV_data ---
datetime Time_Arr [1440];
int Vol_Arr [1440];
int Del_Arr [1440];

int Vol, Del;

//---- indicator buffers
double vol[];;

//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit() {
IndicatorShortName("");

SetIndexBuffer(0,vol);
SetIndexLabel(0,"Vol");
SetIndexStyle(0,DRAW_LINE);




//---- initialization done
return(INIT_SUCCEEDED);
}

void OnDeinit(const int reason) {}
//+------------------------------------------------------------------+
//| Awesome Oscillator |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[]) {

static int curr_ddd;
int it, ix, ddd;

for(it = rates_total -1; it > 0; it --)
{
ddd = TimeDay(Time[it]);
if(curr_ddd != ddd) {curr_ddd = ddd; Data_to_Arr_from_File(Time[it], File_ID);}

Volume_Delta(it); Indicator_Calc(it);
}
return(rates_total);
}
//+------------------------------------------------------------------+

void Indicator_Calc(int ii) {

vol[ii] = Vol;
}
void Volume_Delta(int ii) {

int ix = ArrayBsearchCorrect(Time_Arr,Time[ii]);
if(ix > 0) {Vol = Vol_Arr[ix]; Del = Del_Arr[ix];}
}
void Data_to_Arr_from_File(datetime dt, string id) {

int yyy, mmm, ddd, it, f_handle;
string f_yyy, f_mmm, f_ddd, file_name, nm_folder;

ArrayInitialize(Time_Arr,0); ArrayInitialize(Del_Arr,0);

yyy = TimeYear (dt); f_yyy = IntegerToString(yyy);
mmm = TimeMonth(dt); f_mmm = IntegerToString(mmm); if(mmm <= 9) f_mmm = "0" + IntegerToString(mmm);
ddd = TimeDay (dt); f_ddd = IntegerToString(ddd); if(ddd <= 9) f_ddd = "0" + IntegerToString(ddd);

file_name = Symbol() +"\\"+ Period() +"\\"+ f_yyy +"\\"+ f_mmm +"\\"+ f_ddd + id;
if(!FileIsExist(file_name)) {Print("Data file not found"); OnDeinit(0);}

f_handle = FileOpen(file_name, FILE_READ|FILE_WRITE|FILE_CSV);
if(f_handle < 0) {Print("Invalid file handle"); OnDeinit(0);}
else
{
for(it = 0; it < 1440; it ++)
{
Time_Arr[it] = FileReadString(f_handle);
FileReadString(f_handle); FileReadString(f_handle);
Vol_Arr [it] = FileReadString(f_handle);
Del_Arr [it] = FileReadString(f_handle);

//if(FileIsEnding(f_handle)) {FileClose(f_handle); Print("File Read completed ",it," // file name - ",file_name); break;}
}
}
FileClose(f_handle);
Arrat_to_Sort(Time_Arr, Vol_Arr, Del_Arr);
}
void Arrat_to_Sort(datetime &keys[], int &vol[], int &del[], int sortDirection = MODE_ASCEND) {

datetime keyCopy[];
int vol_Copy[];
int del_Copy[];
int vol_av_Copy[];
float HL_Copy[];
float OC_Copy[];
float HL_x_Copy[];
float OL_x_Copy[];
float OH_x_Copy[];

ArrayCopy(keyCopy, keys);
ArrayCopy(vol_Copy, vol);
ArrayCopy(del_Copy, del);


ArraySort(keys, WHOLE_ARRAY, 0, sortDirection);
for (int i = 0; i < ArraySize(keys); i++)
{
vol [ArrayBsearch(keys, keyCopy[i])] = vol_Copy [i];
del [ArrayBsearch(keys, keyCopy[i])] = del_Copy [i];
}
}

int ArrayBsearchCorrect(datetime &array[], double value,
int count = WHOLE_ARRAY, int start = 0,
int direction = MODE_ASCEND) { //MODE_ASCEND, MODE_DESCEND) {
if(ArraySize(array)==0) return(-1);
int i = ArrayBsearch(array, (datetime)value, count, start, direction);
if (value != array[i])
{
i = -1;
}
return (i);
}

aorekhov@rambler.ru
29.07.2020, 16:34
//+------------------------------------------------------------------+
//| Tester Indicator - Volume (delta_clr).mq4 |
//| |
//| Alex 2020 |
//+------------------------------------------------------------------+

//---- indicator settings
#property strict
#property indicator_separate_window
#property indicator_buffers 3
#property indicator_color1 DarkGray
#property indicator_color2 Lime
#property indicator_color3 OrangeRed

#property indicator_width1 1
#property indicator_width2 2
#property indicator_width3 2


input string File_ID = "_ID.csv"; // file ID


//--- CSV_data ---
datetime Time_Arr [1440];
int Vol_Arr [1440];
int Del_Arr [1440];

int Vol, Del;

//---- indicator buffers
double vol[], vol_up[], vol_dn[];

//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit() {
IndicatorShortName("");

SetIndexBuffer(0,vol);
SetIndexBuffer(1,vol_up);
SetIndexBuffer(2,vol_dn);


SetIndexStyle(0,DRAW_HISTOGRAM);
SetIndexStyle(1,DRAW_HISTOGRAM);
SetIndexStyle(2,DRAW_HISTOGRAM);




//---- initialization done
return(INIT_SUCCEEDED);
}

void OnDeinit(const int reason) {}
//+------------------------------------------------------------------+
//| Awesome Oscillator |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[]) {

static int curr_ddd;
int it, ix, ddd;

for(it = rates_total -1; it > 0; it --)
{
ddd = TimeDay(Time[it]);
if(curr_ddd != ddd) {curr_ddd = ddd; Data_to_Arr_from_File(Time[it], File_ID);}

Volume_Delta(it); Indicator_Calc(it);
}
return(rates_total);
}
//+------------------------------------------------------------------+

void Indicator_Calc(int ii) {

if(Close[ii] > Open[ii] && Del < 0) {vol_up[ii] = Vol; return;}
if(Close[ii] < Open[ii] && Del > 0) {vol_dn[ii] = Vol; return;}
vol[ii] = Vol;
}
void Volume_Delta(int ii) {

int ix = ArrayBsearchCorrect(Time_Arr,Time[ii]);
if(ix > 0) {Vol = Vol_Arr[ix]; Del = Del_Arr[ix];}
}
void Data_to_Arr_from_File(datetime dt, string id) {

int yyy, mmm, ddd, it, f_handle;
string f_yyy, f_mmm, f_ddd, file_name, nm_folder;

ArrayInitialize(Time_Arr,0); ArrayInitialize(Del_Arr,0);

yyy = TimeYear (dt); f_yyy = IntegerToString(yyy);
mmm = TimeMonth(dt); f_mmm = IntegerToString(mmm); if(mmm <= 9) f_mmm = "0" + IntegerToString(mmm);
ddd = TimeDay (dt); f_ddd = IntegerToString(ddd); if(ddd <= 9) f_ddd = "0" + IntegerToString(ddd);

file_name = Symbol() +"\\"+ Period() +"\\"+ f_yyy +"\\"+ f_mmm +"\\"+ f_ddd + id;
if(!FileIsExist(file_name)) {Print("Data file not found"); OnDeinit(0);}

f_handle = FileOpen(file_name, FILE_READ|FILE_WRITE|FILE_CSV);
if(f_handle < 0) {Print("Invalid file handle"); OnDeinit(0);}
else
{
for(it = 0; it < 1440; it ++)
{
Time_Arr[it] = FileReadString(f_handle);
FileReadString(f_handle); FileReadString(f_handle);
Vol_Arr [it] = FileReadString(f_handle);
Del_Arr [it] = FileReadString(f_handle);

//if(FileIsEnding(f_handle)) {FileClose(f_handle); Print("File Read completed ",it," // file name - ",file_name); break;}
}
}
FileClose(f_handle);
Arrat_to_Sort(Time_Arr, Vol_Arr, Del_Arr);
}
void Arrat_to_Sort(datetime &keys[], int &vol[], int &del[], int sortDirection = MODE_ASCEND) {

datetime keyCopy[];
int vol_Copy[];
int del_Copy[];
int vol_av_Copy[];
float HL_Copy[];
float OC_Copy[];
float HL_x_Copy[];
float OL_x_Copy[];
float OH_x_Copy[];

ArrayCopy(keyCopy, keys);
ArrayCopy(vol_Copy, vol);
ArrayCopy(del_Copy, del);


ArraySort(keys, WHOLE_ARRAY, 0, sortDirection);
for (int i = 0; i < ArraySize(keys); i++)
{
vol [ArrayBsearch(keys, keyCopy[i])] = vol_Copy [i];
del [ArrayBsearch(keys, keyCopy[i])] = del_Copy [i];
}
}

int ArrayBsearchCorrect(datetime &array[], double value,
int count = WHOLE_ARRAY, int start = 0,
int direction = MODE_ASCEND) { //MODE_ASCEND, MODE_DESCEND) {
if(ArraySize(array)==0) return(-1);
int i = ArrayBsearch(array, (datetime)value, count, start, direction);
if (value != array[i])
{
i = -1;
}
return (i);
}

aorekhov@rambler.ru
29.07.2020, 16:41
Советник записывает дневные файлы только в режиме тестирования. Поэтому необходимо папку "Символа" скопировать из папки files Тестера в папку files MQL4. Каждый таймфрейм записывается в разные папки, поэтому можно создавать и хранить данные для разных таймфреймов одновременно.

aorekhov@rambler.ru
29.07.2020, 23:58
Файлы советника и индикаторов прикреплены.
11473
11474
11475

aorekhov@rambler.ru
05.08.2020, 20:34
Замечен баги:
1. на М1 и М5 на большом интервале истории перестают записываться ежемесячно файлы объемов/делты. Не понятно с чем это связано. Чобы получить файлы с 2018 пришлось делить весь интервал на 3 части. После загрызки всех файлов можно работать со всем интервалом целиком.
2. на М1 и М5 не создаются по понедельникам дневные фаилы которые я использую для индикаторов в тестере.
На М15, М30, Н1, Н4 проблем нет. Если есть толковые програмисты просьба подправить код.

Bream
12.09.2020, 05:41
Can I use these indicator files on mt5?

aorekhov@rambler.ru
13.09.2020, 13:19
Hi
The short answer is probably not. I'm not coding for mt5 and don't know how to make it compatible.
The key point for this topic is not just creating new indicators. This topic is to help creating Experts using Volume and Delta data and ability to check trading strategy on history. Therefore Indicator Template and just example of one Indicator is made to use them on Visual Test Expert result. You can put this indicators chart on after run Expert test and do result analysis.
This Indicator also not fit for real time trading, as I sad before it have to be used only on history.

Bream
19.09.2020, 12:19
Hi,

thank you for your response and sorry i was not clear, i imported the indicator into mt5, but when i run the back testing, it is blank.

I got a response from ClusterDelta with the following about this issue:

"the one of the main feature of ClusterDelta indicators is asynchronous calls to DLL. It allows indicators to get remote data into the terminal without freezing the main thread but it has some difficulties like you have in backtesting.
To use an indicator in backtesting you should call it and wait for the data. After you have to use just cached data. I offer indicators in source code so a better decision is to implement some part of code that downloads data from the server.
This part should download data into cache and after you may use it in backtesting. To be honest I never did it in MT so I can not advise the best solution.

Please check this topics:
http://forum.clusterdelta.com/showthread.php/9715
http://forum.clusterdelta.com/showthread.php/9809-Volume-Data-in-Experts "

is it is possible but unfortunately i not skilled enough to do this. i was hoping someone has created an Expert Advisor that pulls the history to allow the indicators to work during back testing.

if anyone can help would be greatly appreciated.

aorekhov@rambler.ru
21.09.2020, 10:57
Hi,

thank you for your response and sorry i was not clear, i imported the indicator into mt5, but when i run the back testing, it is blank.

I got a response from ClusterDelta with the following about this issue:

"the one of the main feature of ClusterDelta indicators is asynchronous calls to DLL. It allows indicators to get remote data into the terminal without freezing the main thread but it has some difficulties like you have in backtesting.
To use an indicator in backtesting you should call it and wait for the data. After you have to use just cached data. I offer indicators in source code so a better decision is to implement some part of code that downloads data from the server.
This part should download data into cache and after you may use it in backtesting. To be honest I never did it in MT so I can not advise the best solution.

Please check this topics:
http://forum.clusterdelta.com/showthread.php/9715
http://forum.clusterdelta.com/showthread.php/9809-Volume-Data-in-Experts "

is it is possible but unfortunately i not skilled enough to do this. i was hoping someone has created an Expert Advisor that pulls the history to allow the indicators to work during back testing.

if anyone can help would be greatly appreciated.

Hi
I did this Expert exactly for this reason. As well it can be used for real trading. In last Expert version I add option to make daily Vol & Delta data file. And this data is easy to use as source for indicator. I can suggest you to run Expert in MT4 to get daily Vol & Delta data files. Then Just copy files in MT5. Then in your indicator you need to add option to read data from this file at time of each day beginning. In my Indicator I just fill the Volume & Delta Array [hh:mm]. Later in indicator calculation just take the data According to bar time.
Just be aware that for some reason my Expert can stop writing data in files on long history for M1 and M5 timeframes. In this case just run the Expert from date with last recorded data (do not forget to delete last recorded file, as data in it is not complete). I had to split 2018 till now period on 3 parts to get full history data. This need only for 1st time to collect all data. As soon as data is written to files Expert can work on all history period.

aorekhov@rambler.ru
09.10.2020, 09:26
Добавил инвертирование данных по парам USDJPY, USDCAD, USDCHF в формат форекса, ask / bid меняются местами. И в уже в этом виде данные записываются в файл объемов дельты. Теперь эти файлы данных для этих валютных пар можно использовать для тестирования советника из темы "FootPrint в торговом роботе".


11502

alex_vpluse
26.01.2021, 13:44
Добавил инвертирование данных по парам USDJPY, USDCAD, USDCHF в формат форекса, ask / bid меняются местами. И в уже в этом виде данные записываются в файл объемов дельты. Теперь эти файлы данных для этих валютных пар можно использовать для тестирования советника из темы "FootPrint в торговом роботе".


11502

Блин, таки беда у этого шаблона со скачиванием данных за последние недели. Изначально в середине декабря 2020 запустил эксперта и он корректно скачал данные с начала 2019 по середину декабря 2020. На этих данных по дельте и объему я и тестировал советники.
Сейчас пытаюсь скачать данные с середины декабря 2020 по текущий момент и ни в какую. Вот тут \tester\files просто создает пустые файлы.
Пробовал удалять всю историю и запускать эксперта заново, чтобы он скачал всю историю с начала 2019 по текущий момент. В итоге снова скачивает только по середину декабря 2020, а дальше создает пустые файлы.

alex_vpluse
26.01.2021, 23:25
А вообще, мистика какая-то. Ни в какую не подтягивает данные за период с 15 декабря 2020 по 15 января 2021.
Удаляй не удаляй данные за последний месяц, ничего не помогает. Даже на другом ноутбуке пробовал запускать, на котором никогда не использовались индикаторы clusterdelta. Какой-то заколдованный - до и после указанной даты данные подтягивает, а тут слепое пятно. Причем слепое пятно по всем инструментам и по всем брокерам и на разных компьютерах

ihaar
18.03.2021, 09:01
приветствую
очень не хватает краткой инструкции в пару предложений (aka "for Dummies") что куда положить (1), как запустить (2) и где искать текстовики (3).
был бы очень признателен

aorekhov@rambler.ru
18.03.2021, 13:13
приветствую
очень не хватает краткой инструкции в пару предложений (aka "for Dummies") что куда положить (1), как запустить (2) и где искать текстовики (3).
был бы очень признателен

здравствуйте

Если вас интересуют только файлы данных то до 2020 можно скачать тут http://my.clusterdelta.com/files и http://my.clusterdelta.com/files2. OHLC там имеется. Но в них есть проблемы с хронологией записей, в некоторые месяцы последний день месяца идет перед первым. У меня были проблемы с импортом в МТ 4, пришлось править ручками. За 2021 там данных к сожалению нет. Можно скачать данным експертом.

Файлы записываются только в режиме тестирования. По завершению тестирования находятся в папке терминал по пути \tester\files. Чобы открыть папку терминала в мену "File" выбираем "Open Data Folder". Данные будут в папке символом протестированной валюты. Если ехсперт уже тестировался в этом месяце то файл с данными за последний месяц надо удалить перед новым запуском тестирования что бы обновить данные в фаиле. Ввиду специфики ТЗ для чего это создавалось каждый файл содержит данные текучего месяца и последние 2 недели предыдушего месяца.

1 версия советника записывала данные в файл в оригинале как для фючерсов, 2-я в файле данные уже инвертированны для CAD, CHF, JPY в формате форекса (бид и аск поменялись местами). Дааные OHLC в файл не записываются так как в потоке данных они отсутствуют а OHLC от форекс брокера смысла не имеет.

Автоматического обновления данных нет. Как уже говорилось данные записываются только режиме тестирования, более того файл последнего месяца нужно удалять для обновления данных.

PS. Обратите внимание на замеченные баги мною выявленные:

Замечен баги:
1. на М1 и М5 на большом интервале истории перестают записываться ежемесячно файлы объемов/делты. Не понятно с чем это связано. Чобы получить файлы с 2018 пришлось делить весь интервал на 3 части. После загрызки всех файлов можно работать со всем интервалом целиком.
2. на М1 и М5 не создаются по понедельникам дневные фаилы которые я использую для индикаторов в тестере.
На М15, М30, Н1, Н4 проблем нет. Если есть толковые програмисты просьба подправить код.

jesus.gomez.rdm@gmail.com
01.07.2021, 18:42
Hello,

I have downloaded "Volume & Delta template Expert v2.mq4" and compiled it with my current volume indicator <#import "clusterdelta_v5x2.dll">

It compiled with 0 errors and 35 warnings.

However, when I start expert, I got following errors:


2021.07.01 17:44:55.307 DE30,M1: 1 tick events (0 bars, 26639 bar states) processed in 0:00:00.000 (total time 0:00:00.016)
2021.07.01 17:44:55.307 2021.06.29 01:02:00 Volume & Delta template Expert v2 DE30,M1: not initialized
2021.07.01 17:44:55.307 2021.06.29 01:02:00 Volume & Delta template Expert v2 DE30,M1: unresolved import function call
2021.07.01 17:44:55.307 2021.06.29 01:02:00 Cannot find 'InitDLL' in 'clusterdelta_v5x2.dll'
2021.07.01 17:44:55.307 2021.06.29 00:00:00 Volume & Delta template Expert v2 inputs: GMT=3; Daily_File=1;
2021.07.01 17:44:55.301 TestGenerator: current spread 120 used
2021.07.01 17:44:55.300 ClusterDelta_#Volumes_Alert DE30,M1: incorrect start position 0 for ArrayMaximum function
2021.07.01 17:44:55.300 ClusterDelta_#Volumes_Alert DE30,M1: incorrect start position 0 for ArrayMaximum function
2021.07.01 17:44:55.265 Custom indicator ClusterDelta_#Volumes_Alert DE30,M1: loaded successfully
2021.07.01 17:44:55.255 Tester: template 'C:\Users\jgomez\AppData\Roaming\MetaQuotes\Termin al\24FF2268752179BE735F8A8A001BFE6E\templates\test er.tpl' applied


Can anyone have a look in order to make this expert working with latest version of premium volume indicator?

Thanx in advance

deniss
02.07.2021, 10:23
Hello,

I have downloaded "Volume & Delta template Expert v2.mq4" and compiled it with my current volume indicator <#import "clusterdelta_v5x2.dll">

It compiled with 0 errors and 35 warnings.

However, when I start expert, I got following errors:


2021.07.01 17:44:55.307 DE30,M1: 1 tick events (0 bars, 26639 bar states) processed in 0:00:00.000 (total time 0:00:00.016)
2021.07.01 17:44:55.307 2021.06.29 01:02:00 Volume & Delta template Expert v2 DE30,M1: not initialized
2021.07.01 17:44:55.307 2021.06.29 01:02:00 Volume & Delta template Expert v2 DE30,M1: unresolved import function call
2021.07.01 17:44:55.307 2021.06.29 01:02:00 Cannot find 'InitDLL' in 'clusterdelta_v5x2.dll'
2021.07.01 17:44:55.307 2021.06.29 00:00:00 Volume & Delta template Expert v2 inputs: GMT=3; Daily_File=1;
2021.07.01 17:44:55.301 TestGenerator: current spread 120 used
2021.07.01 17:44:55.300 ClusterDelta_#Volumes_Alert DE30,M1: incorrect start position 0 for ArrayMaximum function
2021.07.01 17:44:55.300 ClusterDelta_#Volumes_Alert DE30,M1: incorrect start position 0 for ArrayMaximum function
2021.07.01 17:44:55.265 Custom indicator ClusterDelta_#Volumes_Alert DE30,M1: loaded successfully
2021.07.01 17:44:55.255 Tester: template 'C:\Users\jgomez\AppData\Roaming\MetaQuotes\Termin al\24FF2268752179BE735F8A8A001BFE6E\templates\test er.tpl' applied


Can anyone have a look in order to make this expert working with latest version of premium volume indicator?

Thanx in advance

Have you checked these calls with DLL ver 4.1 ?

jesus.gomez.rdm@gmail.com
06.07.2021, 16:23
Hello,

No, I didn't. I got premium indicator v5.2, no choice for 4.1.
How can I download it? Is there any solution for latest version of premium indicator?

jesus.gomez.rdm@gmail.com
06.07.2021, 16:23
Hello,

No, I didn't. I got premium indicator v5.2, no choice for 4.1.
How can I download it? Is there any solution for latest version of premium indicator?

ROONEY
26.07.2021, 04:18
Greetings, first of all a special thanks and recognition to aorekhov@rambler.ru and Deniss for supplying the files to integrate the volumes to an EA, I have been working with those files to integrate my futures strategy with indexes SP500, DAX, NQ, they are phenomenal, however I had a problem that they did not always start and remain in a loop, especially in low time periods of 1m, 5m, 15m, I found that being in America there are time periods of difference between the date and time of the server and the Local date and time, substantially large, in the code the local time is used both to control the reading periodicity and for the creation of the records in the cluster, this caused me conflicts due to the time difference, what I did was replace all TimeLocal instructions with TimeCurrent, to standardize all control and register values ??and with this the problem I had was solved. If someone has the same problem or something similar you could check this to see if it solves your problem. I am also working on passing the code to MQL5 since I want to test it with Real Futures beyond CFDs and the brokers that work with Real Futures work with MQL5 and not with MQL4, I hope I can convert the code provided by aorekhov @ rambler. ru and place it as a collaboration here.

ROONEY
26.07.2021, 21:07
Greetings Again .. Another fix that I had to do, is that for the Online Option, put an adjustment so that GMT will accept the value 0 (Zero) and internally it is replaced by AUTO, since it was desynchronized when using the time adjustment corresponding to the time zone in which I am, in this way using the AUTO value, which is the same that the indicators use as such, the desynchronization does not occur and it works perfectly. I hope this information will serve you, since for me getting this errors in the operation was quite complicated and once solved it works wonderfully.

trenado.miguel@gmail.com
09.03.2022, 03:20
Hi. I'm new to the forum. I wonder if I can ask in english. I am trying to write my first EA and I would like to get volume data for DAX. I get an "array out of range" error in line 106 trying to run Tester_Ind_ClusterDelta. I had to change the .dll import to clusterdelta_v5x2.dll.

Any help would be really appreciate.

Thank you in advance.