DataCandles é uma estrutura. A matriz onde escrevemos os candelabros da história é matriz[]. Portanto, precisamos de fazer com que a sua indexação coincida com a indexação de castiçais na tabela. Ou seja, a célula zero da matriz[] corresponderá aos castiçais mais próximos da data actual.
Isto é, 1. copiamos castiçais em array[], 2. fazemos uma série cronológica, e depois lemos valores a partir dela para a estrutura.
Pode fazer sem array[] - basta escrever dados directamente do gráfico na estrutura, mas eu sugeri isto para compatibilidade com Cinco - permite copiar directamente apenas no indicador usando alto[i], baixo[i] e outros dados, mas no script ou Expert Advisor, teremos primeiro de copiar o intervalo de história necessário para o array, o que eu fiz.
Portanto, este é um erro que deve ser comunicado a "Erros, Erros, Perguntas".
Aqui está um guião de verificação, que mostra a hora da cópia dos castiçais em zero e últimas células de matriz[]:
//+------------------------------------------------------------------+//| TestCopy.mq4 |//| Copyright 2016, Artem A. Trishkin, Skype artmedia70 |//| https://login.mql5.com/ru/users/artmedia70 |//+------------------------------------------------------------------+#property copyright"Copyright 2016, Artem A. Trishkin, Skype artmedia70"#property link"https://login.mql5.com/ru/users/artmedia70"#property version"1.00"#property strict#property script_show_inputsenum enumYN
{
enYes=1, // Да
enNo=0, // Нет
};
//--- input parametersinputint Search_Period=10; // Количество копируемых свечейint searchPeriod=(Search_Period<1)?1:Search_Period;
inputint Delta=2; // Количество пунктов допускаint delta=(Delta<0)?0:Delta;
input enumYN AsSeries=enYes; // Массив array как таймсерияMqlRates array[]; // Массив структур для копирования Open, High, Low, Close, Timestruct DataCandle // Структура для хранения всех совпадений
{
int number_matched; // Количество совпаденийMqlRates reference_candle; // Данные эталонной свечиMqlRates matched_candles[]; // Массив свечей, совпадающих с эталонной по нужному критерию
};
DataCandle dataCandle[]; // Массив структур данных свечей и их совпадений//+------------------------------------------------------------------+//| Script program start function |//+------------------------------------------------------------------+voidOnStart()
{
//---int copy_bars=(int)fmin(Search_Period,Bars(Symbol(),Period())); // количество копируемых свечейint copied=CopyRates(Symbol(),PERIOD_CURRENT,1,copy_bars,array); // копируем данныеif(copied>0) { // если скопировалиArraySetAsSeries(array,AsSeries); // задаём массив как таймсерию или нетArrayResize(dataCandle,copied); // задаём размер структуры равным числу скопированных данныхZeroMemory(dataCandle); // Обнуляем данные в структуре//--- основной цикл по "эталонным" свечам в массиве array. Их параметры будем искать в доп. циклеfor(int i=0; i<copy_bars-1; i++) { // цикл по скопированным данным от начала до "на один меньше размера массива"
dataCandle[i].reference_candle.high=array[i].high; // ищем этот high
dataCandle[i].reference_candle.low=array[i].low; // запомнили low для сравнения
dataCandle[i].reference_candle.time=array[i].time; // запомнили time для вывода в журнал//--- поиск совпадений с эталонной свечой, индексируемой индексом основного цикла iint size=0; // размер массива совпадающих свечейArrayResize(dataCandle[i].matched_candles,size); // Размер массива совпадений в ноль
dataCandle[i].number_matched=size; // Инициализируем количество совпадений нулём//--- теперь ищем совпадения по high свечей в цикле j с high эталонной свечи с индексом ifor(int j=0; j<copy_bars; j++) { // в цикле от i+1 до copy_barsif(j==i) continue; // пропустим свечу "саму себя"//--- если совпадают high эталонной свечи (i) и свечи с индексом j (с допуском на величину Point)if(NormalizeDouble(delta*Point()-fabs(array[i].high-array[j].high),Digits())>=0) {
size++;
ArrayResize(dataCandle[i].matched_candles,size); // увеличим размер массива совпадающих свечей
dataCandle[i].number_matched=size; // запишем количество совпадений
dataCandle[i].matched_candles[size-1].high=array[j].high; // запишем в массив high совпадающей свечи
dataCandle[i].matched_candles[size-1].low=array[j].low; // запишем в массив low совпадающей свечи
dataCandle[i].matched_candles[size-1].time=array[j].time; // запишем в массив время совпадающей свечи//Print("Время свечи ",i," :",TimeToString(dataCandle[i].reference_candle.time=array[i].time),", high=",DoubleToString(dataCandle[i].reference_candle.high=array[i].high,Digits()),". Совпадение со свечой ",TimeToString(dataCandle[i].matched_candles[size-1].time=array[j].time),", её high ",DoubleToString(dataCandle[i].matched_candles[size-1].high=array[j].high,Digits()),". Совпадений: ",(string)dataCandle[i].number_matched);
}
}
}
}
//--- Посмотрим чего понаписали в массивыAlert("Array is series: ",ArrayIsSeries(array),
"\ntime array[0]: ",TimeToString(array[0].time,TIME_DATE|TIME_MINUTES),
"\ntime array[",string(searchPeriod-1),"]: ",TimeToString(array[ArraySize(array)-1].time,TIME_DATE|TIME_MINUTES));
for(int i=0; i<ArraySize(dataCandle)-1; i++) {
string refs_txt="";
string matched_txt="";
refs_txt="Свеча "+IntegerToString(i,2,'0')+": время "+TimeToString(dataCandle[i].reference_candle.time)+", high: "+DoubleToString(dataCandle[i].reference_candle.high,Digits())+" имеет совпадений: "+(string)dataCandle[i].number_matched+" шт. ";
if(dataCandle[i].number_matched>0) {
for(int j=0; j<ArraySize(dataCandle[i].matched_candles); j++) {
matched_txt="Совпадение "+IntegerToString(j+1)+": "+TimeToString(dataCandle[i].matched_candles[j].time)+", high: "+DoubleToString(dataCandle[i].matched_candles[j].high,Digits());
}
}
Print(refs_txt,matched_txt);
}
}
//+------------------------------------------------------------------+
Verifiquei-o - sempre falso, mas o tempo está correcto: se no início do guião seleccionar Array array como série cronológica "Sim", então:
Array is series: false
time array[0]: 2016.05.1221:00
time array[9]: 2016.05.1212:00
Se seleccionar "Não", então:
Array is series: false
time array[0]: 2016.05.1212:00
time array[9]: 2016.05.1221:00
os tempos dos castiçais escritos no array são invertidos, o que significa que o ArraySetAsSeriess() funciona correctamente, mas o ArrayIsSeries() não funciona, sai sempre falso, o que já escrevi para o fio de bug acima.
Oh, esta programação. Mais para dentro da floresta....
Compreenda, não precisa de saber a direcção da matriz. O algoritmo está à procura de repetições. Portanto, não importa em que ordem as barras são processadas.
Vasiliy Sokolov: Compreenda, não precisa de saber a direcção da matriz. O algoritmo está à procura de repetições. Portanto, não importa em que ordem as barras são processadas.
faz. Afinal, preciso de saber quais os castiçais que formaram um fósforo e com o preço mais próximo do preço actual tomar o preço Baixo.
Andrey Koldorkin: de que precisa. Porque depois preciso de descobrir que castiçais formaram um fósforo e tirar o preço Baixo do mais próximo do preço actual.
Há um tempo de vela na estrutura para isto, pelo qual pode encontrar a vela mais próxima do tempo que precisar.
E não é necessário produzir os números dos castiçais - eles não coincidem com os números reais dos bares. Porque nós preenchemos a matriz, e os índices na matriz pertencem apenas ao número do castiçal na matriz, não na tabela.
Verifiquei o que produz - sempre falso, mas a hora está correcta: se seleccionar Array array como série temporal "Sim" ao executar o guião, então:
Se seleccionar "Não", então:
Os tempos dos castiçais escritos no array são invertidos, o que significa que o ArraySetAsSeriess() funciona correctamente, mas o ArrayIsSeries() não funciona, sai sempre falso, o que já escrevi para o fio de bug acima.
e depois acrescentou números de castiçais para auto-verificação:
Alerta("Array é série: ",ArrayIsSeries(array),
"\nCandle "+IntegerToString(0,2,'0')+" time array[0]: ",TimeToString(array[0].time,TIME_DATE|TIME_MINUTES),
"\nSwitch "+IntegerToString(searchperiod-1,2,'0')+" time array[",string(searchperiod-1),"]:",TimeToString(array[ArraySize(array)-1].time,TIME_DATE|TIME_MINUTES));
Artyom Trishkin: Para o fazer, existe um tempo de vela na estrutura, através do qual se pode encontrar a vela mais próxima do tempo que necessitar.
Bem, mesmo assim. acontece que a direcção muda com uma linha de código. não vai complicar o processo. Mas enquanto eu estou apenas a tentar perceber o que se passa, pelo menos os castiçais na minha cabeça e máquina estarão na mesma ordem ))
ArraySetAsSeries(array,true); //somente, apenas colocar true
e depois acrescentou números de castiçais para auto-verificação:
Alerta("Array é série: ",ArrayIsSeries(array),
"\nCandle "+IntegerToString(0,2,'0')+" time array[0]: ",TimeToString(array[0].time,TIME_DATE|TIME_MINUTES),
"\nSwitch "+IntegerToString(searchperiod-1,2,'0')+" time array[",string(searchperiod-1),"]:",TimeToString(array[ArraySize(array)-1].time,TIME_DATE|TIME_MINUTES));
Dá o seguinte resultado:
Array é série: falso
Vela 00 matriz de tempo[0]: 2016.05.12 22:00
Vela 09 matriz temporal[9]: 2016.05.12 13:00
Está a usar mql4? Se assim for, descubra o número do castiçal a partir do seu tempo, que está escrito na estrutura. iBarShift() irá ajudá-lo.
DataCandles é uma estrutura. A matriz onde escrevemos os candelabros da história é matriz[]. Portanto, precisamos de fazer com que a sua indexação coincida com a indexação de castiçais na tabela. Ou seja, a célula zero da matriz[] corresponderá aos castiçais mais próximos da data actual.
Isto é, 1. copiamos castiçais em array[], 2. fazemos uma série cronológica, e depois lemos valores a partir dela para a estrutura.
Pode fazer sem array[] - basta escrever dados directamente do gráfico na estrutura, mas eu sugeri isto para compatibilidade com Cinco - permite copiar directamente apenas no indicador usando alto[i], baixo[i] e outros dados, mas no script ou Expert Advisor, teremos primeiro de copiar o intervalo de história necessário para o array, o que eu fiz.
Alerta (série);
como esta?
Ambos os alertas ainda retornam falsos
Alerta (série);
como esta?
Ambos os alertas ainda retornam falsos
Portanto, este é um erro que deve ser comunicado a "Erros, Erros, Perguntas".
Aqui está um guião de verificação, que mostra a hora da cópia dos castiçais em zero e últimas células de matriz[]:
Portanto, este é um erro que deve ser comunicado a "Erros, insectos, perguntas".
Aqui está um guião de verificação, que mostra a hora da cópia dos castiçais em zero e últimas células de matriz[]:
Produz isto:
Array é série: falso
matriz temporal[0]: 2016.05.12 21:00
matriz temporal[9]: 2016.05.12 12:00
É o que se passa:
Array é série: falso
matriz temporal[0]: 2016.05.12 21:00
matriz temporal[9]: 2016.05.12 12:00
Verifiquei-o - sempre falso, mas o tempo está correcto: se no início do guião seleccionar Array array como série cronológica "Sim", então:
Se seleccionar "Não", então:
os tempos dos castiçais escritos no array são invertidos, o que significa que o ArraySetAsSeriess() funciona correctamente, mas o ArrayIsSeries() não funciona, sai sempre falso, o que já escrevi para o fio de bug acima.
Oh, esta programação. Mais para dentro da floresta....
Compreenda, não precisa de saber a direcção da matriz. O algoritmo está à procura de repetições. Portanto, não importa em que ordem as barras são processadas.
de que precisa. Porque depois preciso de descobrir que castiçais formaram um fósforo e tirar o preço Baixo do mais próximo do preço actual.
Há um tempo de vela na estrutura para isto, pelo qual pode encontrar a vela mais próxima do tempo que precisar.
E não é necessário produzir os números dos castiçais - eles não coincidem com os números reais dos bares. Porque nós preenchemos a matriz, e os índices na matriz pertencem apenas ao número do castiçal na matriz, não na tabela.
Verifiquei o que produz - sempre falso, mas a hora está correcta: se seleccionar Array array como série temporal "Sim" ao executar o guião, então:
Se seleccionar "Não", então:
Os tempos dos castiçais escritos no array são invertidos, o que significa que o ArraySetAsSeriess() funciona correctamente, mas o ArrayIsSeries() não funciona, sai sempre falso, o que já escrevi para o fio de bug acima.
Modifiquei ligeiramente o código:
ArraySetAsSeries(array,true); //somente, apenas colocar true
e depois acrescentou números de castiçais para auto-verificação:
Alerta("Array é série: ",ArrayIsSeries(array),
"\nCandle "+IntegerToString(0,2,'0')+" time array[0]: ",TimeToString(array[0].time,TIME_DATE|TIME_MINUTES),
"\nSwitch "+IntegerToString(searchperiod-1,2,'0')+" time array[",string(searchperiod-1),"]:",TimeToString(array[ArraySize(array)-1].time,TIME_DATE|TIME_MINUTES));
Dá o seguinte resultado:
Array é série: falso
Vela 00 matriz de tempo[0]: 2016.05.12 22:00
Vela 09 matriz temporal[9]: 2016.05.12 13:00
Para o fazer, existe um tempo de vela na estrutura, através do qual se pode encontrar a vela mais próxima do tempo que necessitar.
Mudei um pouco o código:
ArraySetAsSeries(array,true); //somente, apenas colocar true
e depois acrescentou números de castiçais para auto-verificação:
Alerta("Array é série: ",ArrayIsSeries(array),
"\nCandle "+IntegerToString(0,2,'0')+" time array[0]: ",TimeToString(array[0].time,TIME_DATE|TIME_MINUTES),
"\nSwitch "+IntegerToString(searchperiod-1,2,'0')+" time array[",string(searchperiod-1),"]:",TimeToString(array[ArraySize(array)-1].time,TIME_DATE|TIME_MINUTES));
Dá o seguinte resultado:
Array é série: falso
Vela 00 matriz de tempo[0]: 2016.05.12 22:00
Vela 09 matriz temporal[9]: 2016.05.12 13:00