Здравствуйте уважаемые форумчане. Попытался совместить два индикатора в одном. Но рисует только одну линию. Подскажите пожалуйста где надо подправить код.
//---- номер версии индикатора #property version"1.00" //---- отрисовка индикатора в главном окне #property indicator_chart_window #property indicator_chart_window
//---- количество индикаторных буферов #property indicator_buffers2 //---- использовано всего одно графическое построение #property indicator_plots2 //+-----------------------------------+ //| объявление констант | //+-----------------------------------+ #define RESET 0// Константа для возврата терминалу команды на пересчёт индикатора //+-----------------------------------+ //| Параметры отрисовки индикатора | //+-----------------------------------+ //---- отрисовка индикатора в виде линии #property indicator_type1 DRAW_LINE #property indicator_type2 DRAW_LINE //---- в качестве цвета бычей линии индикатора использован красный цвет #property indicator_color1 Red #property indicator_color2 Yellow
//---- линия индикатора - непрерывная кривая #property indicator_style1 STYLE_SOLID #property indicator_style2 STYLE_SOLID //---- толщина линии индикатора равна 3 #property indicator_width1 3 #property indicator_width2 3 //---- отображение лэйбы индикатора #property indicator_label1 "Geo_ShowOpenMonthLevel" #property indicator_label2 "Geo_ShowOpenWeekLevel" //+-----------------------------------+ //| ВХОДНЫЕ ПАРАМЕТРЫ ИНДИКАТОРА | //+-----------------------------------+ inputint Shift=0; // сдвиг индикатора по горизонтали в барах //+-----------------------------------+ //---- индикаторный буфер double IndBuffer1[]; double IndBuffer2[]; //---- Объявление целых переменных начала отсчёта данных int min_rates_total; //+------------------------------------------------------------------+ //| Geo_ShowOpenDayLevel indicator initialization function | //+------------------------------------------------------------------+ voidOnInit() { //---- Инициализация переменных начала отсчёта данных min_rates_total=3; //---- превращение динамического массива в индикаторный буфер SetIndexBuffer(0,IndBuffer1,INDICATOR_DATA); SetIndexBuffer(1,IndBuffer2,INDICATOR_DATA); //---- осуществление сдвига индикатора по горизонтали на Shift PlotIndexSetInteger(0,PLOT_SHIFT,Shift); PlotIndexSetInteger(1,PLOT_SHIFT,Shift); //---- осуществление сдвига начала отсчёта отрисовки индикатора // PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,2); // PlotIndexSetInteger(1,PLOT_DRAW_BEGIN,2); //---- установка значений индикатора, которые не будут видимы на графике // PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,EMPTY_VALUE); // PlotIndexSetDouble(1,PLOT_EMPTY_VALUE,EMPTY_VALUE); //---- индексация элементов в буфере как в таймсерии ArraySetAsSeries(IndBuffer1,true); ArraySetAsSeries(IndBuffer2,true); //---- инициализации переменной для короткого имени индикатора string shortname; StringConcatenate(shortname,"Geo_ShowOpenDayLevel( Shift = ",Shift,")"); //--- создание имени для отображения в отдельном подокне и во всплывающей подсказке IndicatorSetString(INDICATOR_SHORTNAME,shortname); //--- определение точности отображения значений индикатора IndicatorSetInteger(INDICATOR_DIGITS,_Digits+1); //---- завершение инициализации } //+------------------------------------------------------------------+ //| Geo_ShowOpenDayLevel iteration function | //+------------------------------------------------------------------+ intOnCalculate( constint rates_total, // количество истории в барах на текущем тике constint prev_calculated,// количество истории в барах на предыдущем тике constdatetime &time[], constdouble &open[], constdouble& high[], // ценовой массив максимумов цены для расчёта индикатора constdouble& low[], // ценовой массив минимумов цены для расчёта индикатора constdouble &close[], constlong &tick_volume[], constlong &volume[], constint &spread[] ) { //---- проверка количества баров на достаточность для расчёта if(rates_total<min_rates_total||Period()>PERIOD_D1) return(RESET);
//---- Объявление целых переменных int limit,bar; //---- Объявление переменных с плавающей точкой double DOpen[1]; datetime DTime[1]; staticuint LastCountBar;
//---- расчёты необходимого количества копируемых данных и //стартового номера limit для цикла пересчёта баров if(prev_calculated>rates_total || prev_calculated<=0)// проверка на первый старт расчёта индикатора { limit=rates_total-min_rates_total-1; // стартовый номер для расчёта всех баров LastCountBar=rates_total; } else limit=int(LastCountBar)+rates_total-prev_calculated; // стартовый номер для расчёта новых баров
//---- индексация элементов в массивах как в таймсериях ArraySetAsSeries(time,true);
//---- Основной цикл расчёта индикатора for(bar=limit; bar>=0 && !IsStopped(); bar--) { LastCountBar=bar; //---- обнулим содержимое индикаторных буферов до расчёта IndBuffer1[bar]=EMPTY_VALUE; IndBuffer2[bar]=EMPTY_VALUE; //---- копируем вновь появившиеся данные в массив if(CopyTime(Symbol(),PERIOD_MN1,time[bar],1,DTime)<=0) return(RESET); if(CopyTime(Symbol(),PERIOD_W1, time[bar],1,DTime)<=0) return(RESET); if(time[bar]>=DTime[0] && time[bar+1]<DTime[0]) { //---- копируем вновь появившиеся данные в массив if(CopyOpen(Symbol(),PERIOD_MN1,time[bar],1,DOpen)<=0) return(RESET); if(CopyOpen(Symbol(),PERIOD_W1, time[bar],1,DOpen)<=0) return(RESET); //---- Загрузка полученных значений в индикаторные буферы IndBuffer1[bar]=DOpen[0]; IndBuffer2[bar]=DOpen[0]; }
私ならこうする。
Alexey Kozitsyn:
一見すると、私なら違うやり方をしていたかもしれませんね。
。
提案されたバリエーションに感謝し、調査してみます。私はただ、新しい配列を作成しないようにしたかっただけです。なぜ私のコードでArrayCopyが 正しく動作しないのか理解できません?
最後の最後で、関数の中で1つの変数を指定するのを忘れていたことが判明しました - コピーする要素の数です。デフォルトでは、配列全体がコピーされます(count=WHOLE_ARRAY)。
ご提案ありがとうございます。私はただ、新しい配列を作成しないようにしたかっただけです。なぜ私のコードでArrayCopyが正しく 機能しないのか理解できません?
わからない、どのバリエーションが早く効くかわからない。結局のところ、配列の中にゼロの値があることが多ければ多いほど、配列を次々にコピーしていくことになります。
そこには最後の1つの値だけがコピーされる。速度については - 確認していないのでわかりませんが - とりあえず、コードが大きくなりすぎないようにしてほしいです - 念のため......。
//---- номер версии индикатора
#property version "1.00"
//---- отрисовка индикатора в главном окне
#property indicator_chart_window
#property indicator_chart_window
//---- количество индикаторных буферов
#property indicator_buffers 2
//---- использовано всего одно графическое построение
#property indicator_plots 2
//+-----------------------------------+
//| объявление констант |
//+-----------------------------------+
#define RESET 0 // Константа для возврата терминалу команды на пересчёт индикатора
//+-----------------------------------+
//| Параметры отрисовки индикатора |
//+-----------------------------------+
//---- отрисовка индикатора в виде линии
#property indicator_type1 DRAW_LINE
#property indicator_type2 DRAW_LINE
//---- в качестве цвета бычей линии индикатора использован красный цвет
#property indicator_color1 Red
#property indicator_color2 Yellow
//---- линия индикатора - непрерывная кривая
#property indicator_style1 STYLE_SOLID
#property indicator_style2 STYLE_SOLID
//---- толщина линии индикатора равна 3
#property indicator_width1 3
#property indicator_width2 3
//---- отображение лэйбы индикатора
#property indicator_label1 "Geo_ShowOpenMonthLevel"
#property indicator_label2 "Geo_ShowOpenWeekLevel"
//+-----------------------------------+
//| ВХОДНЫЕ ПАРАМЕТРЫ ИНДИКАТОРА |
//+-----------------------------------+
input int Shift=0; // сдвиг индикатора по горизонтали в барах
//+-----------------------------------+
//---- индикаторный буфер
double IndBuffer1[];
double IndBuffer2[];
//---- Объявление целых переменных начала отсчёта данных
int min_rates_total;
//+------------------------------------------------------------------+
//| Geo_ShowOpenDayLevel indicator initialization function |
//+------------------------------------------------------------------+
void OnInit()
{
//---- Инициализация переменных начала отсчёта данных
min_rates_total=3;
//---- превращение динамического массива в индикаторный буфер
SetIndexBuffer(0,IndBuffer1,INDICATOR_DATA);
SetIndexBuffer(1,IndBuffer2,INDICATOR_DATA);
//---- осуществление сдвига индикатора по горизонтали на Shift
PlotIndexSetInteger(0,PLOT_SHIFT,Shift);
PlotIndexSetInteger(1,PLOT_SHIFT,Shift);
//---- осуществление сдвига начала отсчёта отрисовки индикатора
// PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,2);
// PlotIndexSetInteger(1,PLOT_DRAW_BEGIN,2);
//---- установка значений индикатора, которые не будут видимы на графике
// PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,EMPTY_VALUE);
// PlotIndexSetDouble(1,PLOT_EMPTY_VALUE,EMPTY_VALUE);
//---- индексация элементов в буфере как в таймсерии
ArraySetAsSeries(IndBuffer1,true);
ArraySetAsSeries(IndBuffer2,true);
//---- инициализации переменной для короткого имени индикатора
string shortname;
StringConcatenate(shortname,"Geo_ShowOpenDayLevel( Shift = ",Shift,")");
//--- создание имени для отображения в отдельном подокне и во всплывающей подсказке
IndicatorSetString(INDICATOR_SHORTNAME,shortname);
//--- определение точности отображения значений индикатора
IndicatorSetInteger(INDICATOR_DIGITS,_Digits+1);
//---- завершение инициализации
}
//+------------------------------------------------------------------+
//| Geo_ShowOpenDayLevel iteration function |
//+------------------------------------------------------------------+
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[]
)
{
//---- проверка количества баров на достаточность для расчёта
if(rates_total<min_rates_total||Period()>PERIOD_D1) return(RESET);
//---- Объявление целых переменных
int limit,bar;
//---- Объявление переменных с плавающей точкой
double DOpen[1];
datetime DTime[1];
static uint LastCountBar;
//---- расчёты необходимого количества копируемых данных и
//стартового номера limit для цикла пересчёта баров
if(prev_calculated>rates_total || prev_calculated<=0)// проверка на первый старт расчёта индикатора
{
limit=rates_total-min_rates_total-1; // стартовый номер для расчёта всех баров
LastCountBar=rates_total;
}
else limit=int(LastCountBar)+rates_total-prev_calculated; // стартовый номер для расчёта новых баров
//---- индексация элементов в массивах как в таймсериях
ArraySetAsSeries(time,true);
//---- Основной цикл расчёта индикатора
for(bar=limit; bar>=0 && !IsStopped(); bar--)
{
LastCountBar=bar;
//---- обнулим содержимое индикаторных буферов до расчёта
IndBuffer1[bar]=EMPTY_VALUE;
IndBuffer2[bar]=EMPTY_VALUE;
//---- копируем вновь появившиеся данные в массив
if(CopyTime(Symbol(),PERIOD_MN1,time[bar],1,DTime)<=0) return(RESET);
if(CopyTime(Symbol(),PERIOD_W1, time[bar],1,DTime)<=0) return(RESET);
if(time[bar]>=DTime[0] && time[bar+1]<DTime[0])
{
//---- копируем вновь появившиеся данные в массив
if(CopyOpen(Symbol(),PERIOD_MN1,time[bar],1,DOpen)<=0) return(RESET);
if(CopyOpen(Symbol(),PERIOD_W1, time[bar],1,DOpen)<=0) return(RESET);
//---- Загрузка полученных значений в индикаторные буферы
IndBuffer1[bar]=DOpen[0];
IndBuffer2[bar]=DOpen[0];
}
if(IndBuffer1[bar+1]!=EMPTY_VALUE && IndBuffer1[bar]==EMPTY_VALUE) IndBuffer1[bar]=IndBuffer1[bar+1];
if(IndBuffer2[bar+1]!=EMPTY_VALUE && IndBuffer2[bar]==EMPTY_VALUE) IndBuffer2[bar]=IndBuffer2[bar+1];
}
//----
return(rates_total);
}
こんにちは。MQL4 EAのコードで、注文を開く際のルールをどのように記述すればよいか教えてください:市場にある特定のマジックナンバーの注文がなければ、EAは主アルゴリズムに従って何も開きません。
ループ内のすべての成行注文とそのウィザードを確認します。もし、そのようなマジックを持つ教団が存在するならば・・・。
このループがどのようにコードに実装されているのか、教えてください。
このループをコードでどう書くか教えてください。
もう少し後です。携帯から書いています。