Лента последних комментариев


0
Не понял, где это. Отскриншотить можете?
avatar

marattmb

  • 25 декабря 2024, 05:03
+1
доброе утро, скоро НГ. )))
avatar

igrun

  • 25 декабря 2024, 04:58
0
нажми на квадоатик в верхнем левом углу,
там все заполни как надо и будет тебе счастье
avatar

igrun

  • 25 декабря 2024, 04:26
0
но Андрей это дополнение к индикатору,
я потому и спрашиваю что допустим 300 рублей за предыдущую правку,
500 рублей ну ни мне ни тебе за эту правку.
и того 800 реблей, сделаешь индикатор?
avatar

igrun

  • 25 декабря 2024, 04:23
0
пока советник писать не надо,
только индикатор подправить — чтобы он был завершен.
avatar

igrun

  • 25 декабря 2024, 00:29
0
Ставит автоматом. Карту скинул в личку
avatar

AM2

  • 25 декабря 2024, 00:16
0
скока буит стоить?


Сделать входы на отбой пробой по индикатору?
1000р.
avatar

AM2

  • 25 декабря 2024, 00:14
0
1000р.
avatar

AM2

  • 25 декабря 2024, 00:05
0
Спасибо на хлеб не намажешь))
Пишите сразу сумму, которую готовы заплатить.
avatar

verta81

  • 24 декабря 2024, 23:28
0
Создание советника для MetaTrader 4 (MT4), который будет использовать отбой от круглых уровней, требует учета специфики цены актива, включая количество знаков до и после запятой. Это важно, так как разные активы могут иметь различную точность ценовых данных. Например, валютная пара EURUSD может отображаться с точностью до пяти знаков после запятой (например, 1.23456), тогда как другие инструменты могут иметь другую точность.

Вот примерный алгоритм создания такого советника:

### Шаг 1: Определение количества знаков

Для начала нужно определить количество знаков до и после запятой у конкретного инструмента. В MT4 есть встроенная функция Digits, которая возвращает количество знаков после запятой для текущего символа (инструмента).

int digits = Digits(); // Получаем количество знаков после запятой

### Шаг 2: Идентификация круглого уровня

Круглый уровень – это цена, заканчивающаяся на ноль или несколько нулей. Чтобы проверить, является ли текущий уровень круглым, можно воспользоваться следующей логикой:

double currentPrice = SymbolInfoDouble(Symbol(), SYMBOL_BID); // Текущая цена
int intPart = (int)currentPrice; // Целая часть цены
double fracPart = currentPrice — intPart; // Дробная часть цены

bool isRoundLevel = false;
if(fracPart == 0) {
isRoundLevel = true; // Если дробная часть равна нулю, то это круглый уровень
}

### Шаг 3: Учет количества знаков после запятой

Так как количество знаков после запятой влияет на определение круглого уровня, можно модифицировать проверку следующим образом:

// Округляем дробную часть до нужного количества знаков
fracPart = NormalizeDouble(fracPart, digits);

if(fracPart == 0) {
isRoundLevel = true; // Если дробная часть равна нулю, то это круглый уровень
}

Функция NormalizeDouble округляет число до указанного количества знаков после запятой.

### Шаг 4: Реализация стратегии отбоя

Теперь, когда мы можем определять круглые уровни, можно реализовать стратегию отбоя. Вот упрощенный пример:

void OnTick() {
double currentPrice = SymbolInfoDouble(Symbol(), SYMBOL_BID);
int digits = Digits();
int intPart = (int)currentPrice;
double fracPart = currentPrice — intPart;
fracPart = NormalizeDouble(fracPart, digits);

if(fracPart == 0) { // Если текущий уровень круглый
// Проверяем условия для отбоя
if(currentPrice > previousPrice) {
// Отбой вниз
OpenSell();
} else {
// Отбой вверх
OpenBuy();
}
}
}

В этом примере OpenSell() и OpenBuy() являются функциями, открывающими сделки на продажу и покупку соответственно. Вы можете заменить их своими собственными функциями открытия ордеров.

### Заключение

Этот подход позволяет учесть особенности цены актива при создании советника для работы с круглыми уровнями. Важно помнить о необходимости тестирования вашего советника на исторических данных перед использованием его в реальной торговле.
avatar

igrun

  • 24 декабря 2024, 22:04
0
Ну да… Валюты автоматом ставит?
avatar

Asch

  • 24 декабря 2024, 18:02
+1
таким образом устроит?



avatar

AM2

  • 24 декабря 2024, 15:35
0
Всё что есть.
avatar

Asch

  • 24 декабря 2024, 14:40
0


Образовалась временнAя коробка.
Делим ее пополам. Имеем три линии-цены. Цена находится между внешними линиями. И чаще линии ближе stoplevel.
Поэтому, отложками здесь сработать практически не возможно. Надо открывать ордера по пересечению линий.
Ценой Bid или Ask — варианты на рассмотрение.

Далее ожидаем три события:
— пересечение вехней линии снизу вверх (сверху вниз — не реагируем);
— пересечение нижней линии сверху вниз (снизу вверх — не реагируем);
— пересечение средней линии сверху вниз или снизу вверх;

Так как будем работать с двумя полосами (верхней и нижней), для упрощения логики предлагаю Ордера,
соответствующие им, отличить по magik number. Например верхняя полоса — Magic, а нижняя — Magic+1.

Итак — три события.

— Если цена пробила верхнюю линию, то открываем OP_BUY с Magic. Лот определяется по следующим параметрам:
если сумма лотов OP_SELL с Magic равна нулю, то лот равен стартовому лоту;
если сумма лотов OP_SELL с Magic больше нуля, то суммарный лот OP_BUY с Magic должен оказаться
в два раза больше, чем сумма лотов OP_SELL с Magic. Если меньше — добавляем до удвоенной суммы.
Lot(OP_BUY,Magic) = SummLot(OP_SELL,Magic)*2 — SummLot(OP_BUY,Magic);

Прошу заметить: при колебаниях цены, если цена пробила верхнюю линию сверху вниз, мы ничего не делаем.
— При пробитии нижней линии сверху вниз открыватся OP_SELL аналогично пересечению верхней, но с Magic+1.
Lot(OP_SELL, Magic+1) = SummLot(OP_BUY, Magic+1)*2 — SummLot(OP_SELL, Magic+1);

— С пересечением средней линии все гораздо интереснее:
Открываются два ордера. OP_BUY с Magic+1 и OP_SELL с Magic.

Лоты определяются в следующем порядке:

— если цена пробила среднюю линию снизу вверх, то

Для OP_BUY с Magic+1
* если суммарный лот OP_SELL с Magic+1 равен нулю,
то лот OP_BUY с Magic+1 равен удвоенному стартовому лоту.
* Если цена также пробила среднюю линию снизу вверх, но суммарный лот OP_SELL с Magic+1 больше нуля,
то суммарный лот OP_BUY с Magic+1 должен оказаться в два раза больше, чем сумма лотов OP_SELL с Magic+1.
Если меньше — добавляем до удвоенной суммы. Если равна — ничего не делаем.
Lot(OP_BUY, Magic+1) = SummLot(OP_SELL, Magic+1)*2 — SummLot(OP_BUY, Magic+1);

Для OP_SELL с Magic
* если суммарный лот OP_BUY с Magic равен нулю,
то лот OP_SELL с Magic просто равен стартовому лоту.
* Если цена также пробила среднюю линию снизу вверх, но суммарный лот OP_BUY с Magic больше нуля,
то суммарный лот OP_SELL с Magic должен оказаться в два раза больше, чем сумма лотов OP_BUY с Magic.
Если меньше — добавляем до удвоенной суммы. Если равна — ничего не делаем.
Lot((OP_SELL, Magic) = SummLot(OP_BUY, Magic)*2 — SummLot(OP_SELL, Magic);

— если цена пробила среднюю линию сверху вниз, то

тоже открываем два ордера OP_BUY с Magic+1 и OP_SELL с Magic,
только лоты рассчитываются симметрично наоборот.

Для лучшего понимания:

каждая полоса имеет свои ордера со своими мagic. Снизу полосы ордера на продажу. Сверху — на покупку.
Наша задача следить, чтобы лотов на границах полосы суммарно было в два раза больше, чем
на противоположной границе этой же полосы. Нюансы только в начале открытия ордеров каждой полосы.

А вообщето выше практически написан код советника.
Подправить только в код mql4. Ну и индюк, конечно. Хотя можно и без него.

Получение прибыли и ограничение убытков в следующий раз, если комe-то будет интересно.
Можно простоограничиться тралом прибили-убытка. Но есь варианты и поинтереснее.
avatar

kvashnin007

  • 24 декабря 2024, 13:42
0
Индюк поинтереснее.

#property version     "2.00"
//------------------------------------------------------------------
#property indicator_chart_window
#property indicator_buffers 4
#property indicator_color1  clrGainsboro
#property indicator_color2  clrGainsboro
#property indicator_color3  clrRoyalBlue
#property indicator_color4  clrRed
#property strict
//---
input string    inpStartTime = "00:00";      // Start time
input string    inpEndTime   = "04:00";      // Ending time
//---
double  fillu[],filld[],limu[],limd[],histou[],histod[],histoc[];
//------------------------------------------------------------------
int OnInit()
{  
      IndicatorBuffers(7);
      SetIndexBuffer(0,fillu); SetIndexStyle(0,DRAW_LINE,EMPTY,2);
      SetIndexBuffer(1,filld); SetIndexStyle(1,DRAW_LINE,EMPTY,2);
      SetIndexBuffer(2,limu);  SetIndexStyle(2,DRAW_LINE,EMPTY,2);
      SetIndexBuffer(3,limd);  SetIndexStyle(3,DRAW_LINE,EMPTY,2);
      SetIndexBuffer(4,histoc);
      SetIndexBuffer(5,histod); 
      SetIndexBuffer(6,histou);
      IndicatorShortName("Channel "+inpStartTime+" "+inpEndTime+" Breakout Lite");
      
      if (_Period>=PERIOD_D1)
         {
         Alert("Indicator can work on time frames less than daily only");  return(INIT_FAILED);
         }
   return(INIT_SUCCEEDED);
}
//------------------------------------------------------------------
void OnDeinit(const int reason) { }
//------------------------------------------------------------------
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[])
{
      int i,counted_bars = prev_calculated;
      if(counted_bars < 0) return(-1);
      if(counted_bars > 0) counted_bars--;
            int limit=MathMin(rates_total-counted_bars,rates_total-1);
      
      int _secondsStart = (int)StringToTime("1970.01.01 "+inpStartTime);
      int _secondsEnd   = (int)StringToTime("1970.01.01 "+inpEndTime);
      for (i=limit;i>=0; i--)
         {
         datetime _startTime = StringToTime(TimeToString(Time[i],TIME_DATE))+_secondsStart;
         datetime _endTime   = StringToTime(TimeToString(Time[i],TIME_DATE))+_secondsEnd;
         double max = ((i<Bars-1) ? limu[i+1] : High[i]), min = ((i<Bars-1) ? limd[i+1] : Low[i]);
         
         if (_startTime<= Time[i] && _endTime>=Time[i])
            {
            max = High[i];
            min =  Low[i];
            for (int k=1; i+k>=0 && Time[i+k]>=_startTime; k++)
               {
               max = fmax(max,High[i+k]);
               min = fmin(min,Low[i+k]);
               }
            }                           
         limu[i] = max;
         limd[i] = min;
                 
         if (_startTime<=Time[i] && _endTime>=Time[i])
            { 
            fillu[i]  = max;            
            filld[i]  = min;
            histou[i] = EMPTY_VALUE;
            histod[i] = EMPTY_VALUE; 
            }
         else 
            {  
            fillu[i]  = (limu[i]+limd[i])*0.5;
            filld[i]  = (limu[i]+limd[i])*0.5;
            histoc[i] = (i<Bars-1) ? (Close[i]>limu[i]) ? 1 : (Close[i]<limd[i]) ? -1 : (Close[i]<limu[i] && Close[i]>limd[i]) ? 0 : histoc[i+1] : 0;  
            if (histoc[i] == 1) 
               { 
               histou[i] = High[i]; 
               histod[i] = Low[i]; 
               }
            if (histoc[i] ==-1) 
               { 
               histod[i] = High[i]; 
               histou[i] = Low[i];
               }      
            }  
         }      
   return(rates_total);
}
//-----------------------------------------------------------------
avatar

kvashnin007

  • 24 декабря 2024, 09:29
0
есть нормальный исходник? не ломаный. Глаза сломались читая такое((
avatar

verta81

  • 23 декабря 2024, 21:41
0
В настройках индикатора нет перемещения а хотелось бы… В строке sOutput прописываются валюты которые отображать на графике. Можно ли добавить функцию авто при которой индюк брал валюты только с текущей пары?
avatar

Asch

  • 23 декабря 2024, 17:42
0
напишите тз полностью, а так так всегда только вершина айсберга.
двигать метки можно:

avatar

AM2

  • 23 декабря 2024, 17:06