- Can I have help on How to call iCustom indicator from my EA mql4. I have been trying to tell my EA to send orders when the price riches UniqueprcLineup or UniqueprcLinedown.
- Coding help
- How To Explain the difference between this indicators draw and the line chart
There are several issues that would take considerable time to fix properly.
NOTE: Traders and coders are working for free:
- if it is interesting for them personally, or
- if it is interesting for many members on this forum.
Freelance section of the forum should be used in most of the cases.
Trading applications for MetaTrader 5 to order
- 2025.10.13
- www.mql5.com
The largest freelance service with MQL5 application developers
Hi, my suggest:
//+------------------------------------------------------------------+ //| SimpleLinregRSI_v4_improved.mq5 | //| Improved by PEDRO GOMES | //+------------------------------------------------------------------+ #property indicator_chart_window #property indicator_buffers 2 #property indicator_color1 Gold #property indicator_color2 Crimson #property indicator_width1 2 #property indicator_width2 2 //--- Input Parameters --- // Indicator Settings input int LinregPeriod = 18; // Período da Regressão Linear input int RSIPeriod = 14; // Período do RSI input double RSIOverbought = 70.0; // Nível de sobrecompra do RSI input double RSIOversold = 30.0; // Nível de sobrevenda do RSI input int EMA_Smoothing = 3; // Suavização EMA para a linha de regressão // Multi-Timeframe (MTF) Filter input ENUM_TIMEFRAMES HTF = PERIOD_H1; // Timeframe superior para filtro de tendência input bool UseMTFTrend = true; // Ativar filtro de tendência MTF // Display Options input color ColorUp = clrGold; // Cor para tendência de alta input color ColorDown = clrCrimson; // Cor para tendência de baixa input int LineWidth = 2; // Largura da linha do indicador input bool ShowRawAndSmoothed = false; // Mostrar linhas bruta e suavizada (não implementado diretamente, usar DrawSmoothedOnly) input bool DrawSmoothedOnly = true; // Mostrar apenas a linha suavizada // Alert and Notification Settings input bool EnableAlerts = true; // Ativar alertas pop-up input bool EnablePush = false; // Ativar notificações push input bool EnableEmail = false; // Ativar notificações por e-mail input string AlertSound = "alert.wav"; // Ficheiro de som para alertas input string EmailTo = ""; // Endereço de e-mail para notificações // CSV Export Settings input bool EnableCSVExport = false; // Ativar exportação para CSV input string CSVFileName = "SimpleLinreg_signals_XAU_TF15.csv"; // Nome do ficheiro CSV // Performance and Calculation Settings input int MaxBarsToProcess = 2000; // Número máximo de barras a processar input bool UseIncremental = true; // Usar cálculo incremental //--- Indicator Buffers --- double UpBuf[]; double DnBuf[]; //--- Handles and Arrays for Calculations --- double ArrClose[]; double ArrRSI[]; double HTF_Close[]; int hRSI; //--- Global Variables for Optimization --- double linreg_sumX; double linreg_sumX2; double linreg_denom; //+------------------------------------------------------------------+ //| Utility Functions | //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| Calcula um passo da Média Móvel Exponencial (EMA). | //+------------------------------------------------------------------+ double EMA_Step(double prev, double value, int period) { if(period <= 1) return value; double k = 2.0 / (period + 1.0); return prev + k * (value - prev); } //+------------------------------------------------------------------+ //| Calcula o valor da Regressão Linear num índice específico. | //+------------------------------------------------------------------+ double CalcLinRegAt(const double &price[], int i, int period) { if(i < period - 1) return price[i]; // Não há dados suficientes para o cálculo double sumY = 0.0; double sumXY = 0.0; for(int k = 0; k < period; k++) { double x = (double)k; double y = price[i - k]; sumY += y; sumXY += x * y; } // Usar os valores pré-calculados de sumX, sumX2 e denom if(linreg_denom == 0.0) return price[i]; // Evitar divisão por zero double slope = (period * sumXY - linreg_sumX * sumY) / linreg_denom; double intercept = (sumY - slope * linreg_sumX) / (double)period; return slope * (period - 1) + intercept; } //+------------------------------------------------------------------+ //| Obtém a tendência do timeframe superior usando Regressão Linear. | //+------------------------------------------------------------------+ int GetHTFTrend() { if(!UseMTFTrend) return 0; int needed = LinregPeriod + 1; // Precisamos de LinregPeriod + 1 barras para calcular a LR em 'i' e 'i-1' if(ArraySize(HTF_Close) < needed) ArrayResize(HTF_Close, needed); if(CopyClose(_Symbol, HTF, 0, needed, HTF_Close) <= 0) return 0; ArraySetAsSeries(HTF_Close, true); double cur_linreg = CalcLinRegAt(HTF_Close, 0, LinregPeriod); double prev_linreg = CalcLinRegAt(HTF_Close, 1, LinregPeriod); if(cur_linreg > prev_linreg) return 1; // Tendência de alta if(cur_linreg < prev_linreg) return -1; // Tendência de baixa return 0; // Tendência neutra ou indefinida } //+------------------------------------------------------------------+ //| Verifica a existência de um ficheiro no diretório MQL5/Files. | //+------------------------------------------------------------------+ bool FileExistsInCommon(string filename) { int handle = FileOpen(filename, FILE_READ|FILE_ANSI|FILE_COMMON); if(handle == INVALID_HANDLE) return false; FileClose(handle); return true; } //+------------------------------------------------------------------+ //| Escreve uma linha para um ficheiro CSV. Cria o ficheiro se não | //| existir e adiciona um cabeçalho. | //+------------------------------------------------------------------+ void WriteCSV(string filename, string line) { int handle = FileOpen(filename, FILE_WRITE|FILE_READ|FILE_CSV|FILE_COMMON); if(handle == INVALID_HANDLE) { // Se a abertura falhar, tenta criar o ficheiro com permissão de escrita handle = FileOpen(filename, FILE_WRITE|FILE_CSV|FILE_COMMON); if(handle == INVALID_HANDLE) { Print("Erro ao abrir/criar ficheiro CSV: ", filename); return; } } FileSeek(handle, 0, SEEK_END); FileWriteString(handle, line); FileClose(handle); } //+------------------------------------------------------------------+ //| Initialization Function | //+------------------------------------------------------------------+ int OnInit() { IndicatorSetInteger(INDICATOR_DIGITS, _Digits); SetIndexBuffer(0, UpBuf, INDICATOR_DATA); SetIndexBuffer(1, DnBuf, INDICATOR_DATA); PlotIndexSetInteger(0, PLOT_DRAW_TYPE, DRAW_LINE); PlotIndexSetInteger(1, PLOT_DRAW_TYPE, DRAW_LINE); PlotIndexSetInteger(0, PLOT_LINE_COLOR, ColorUp); PlotIndexSetInteger(1, PLOT_LINE_COLOR, ColorDown); PlotIndexSetInteger(0, PLOT_LINE_WIDTH, LineWidth); PlotIndexSetInteger(1, PLOT_LINE_WIDTH, LineWidth); // Inicializar o handle do RSI hRSI = iRSI(_Symbol, PERIOD_CURRENT, RSIPeriod, PRICE_CLOSE); if(hRSI == INVALID_HANDLE) { Print("Erro ao obter handle do RSI. Erro: ", GetLastError()); return(INIT_FAILED); } // Pré-calcular valores para a Regressão Linear (constantes para um dado período) linreg_sumX = 0.0; linreg_sumX2 = 0.0; for(int k = 0; k < LinregPeriod; k++) { linreg_sumX += (double)k; linreg_sumX2 += (double)k * (double)k; } linreg_denom = (LinregPeriod * linreg_sumX2 - linreg_sumX * linreg_sumX); if(linreg_denom == 0.0) linreg_denom = 1.0; // Evitar divisão por zero, embora improvável com LinregPeriod > 1 // Configurar cabeçalho CSV se a exportação estiver ativada e o ficheiro não existir if(EnableCSVExport) { if(!FileExistsInCommon(CSVFileName)) { string hdr = "Time;Symbol;TF;Signal;Price;RSI;LinReg;Notes\n"; WriteCSV(CSVFileName, hdr); } } return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Calculation Function | //+------------------------------------------------------------------+ int OnCalculate(const int rates_total, const int prev_calculated, const datetime &time[], const double &prOpen[], const double &prHigh[], const double &prLow[], const double &prClose[], const long &tick_volume[], const long &volume[], const int &spread[]) { // Validar dados mínimos if(rates_total < LinregPeriod + 2) return(0); int limit; if(UseIncremental && prev_calculated > 1) { limit = rates_total - prev_calculated; // Calcular apenas as novas barras } else { limit = rates_total; // Recalcular tudo } // Ajustar o início do cálculo para o período da regressão linear int start_calc_idx = MathMax(LinregPeriod, rates_total - limit); // Redimensionar arrays e copiar dados if(ArraySize(ArrClose) < rates_total) ArrayResize(ArrClose, rates_total); if(ArraySize(ArrRSI) < rates_total) ArrayResize(ArrRSI, rates_total); if(CopyClose(_Symbol, PERIOD_CURRENT, 0, rates_total, ArrClose) <= 0) return(prev_calculated); if(CopyBuffer(hRSI, 0, 0, rates_total, ArrRSI) <= 0) return(prev_calculated); ArraySetAsSeries(ArrClose, true); ArraySetAsSeries(ArrRSI, true); // Redimensionar buffers do indicador if(ArraySize(UpBuf) < rates_total) ArrayResize(UpBuf, rates_total); if(ArraySize(DnBuf) < rates_total) ArrayResize(DnBuf, rates_total); ArraySetAsSeries(UpBuf, true); ArraySetAsSeries(DnBuf, true); // Limpar buffers para as barras não calculadas ou anteriores for(int i = 0; i < start_calc_idx; i++) { UpBuf[i] = EMPTY_VALUE; DnBuf[i] = EMPTY_VALUE; } static int lastSignal = 0; // Manter o último sinal para evitar repetições de alerta double prev_smoothed_linreg = 0.0; // Variável para a suavização EMA bool first_smooth_calc = true; // Flag para a primeira inicialização da EMA // Obter tendência do timeframe superior uma vez por cálculo int htfTrend = GetHTFTrend(); // Loop principal de cálculo for(int idx = start_calc_idx; idx < rates_total; idx++) { // Calcular Regressão Linear atual double current_linreg = CalcLinRegAt(ArrClose, idx, LinregPeriod); // Calcular Regressão Linear anterior (para determinar a direção) double previous_linreg = CalcLinRegAt(ArrClose, idx - 1, LinregPeriod); double display_linreg = current_linreg; if(EMA_Smoothing > 1) { if(first_smooth_calc) { // Encontrar o último valor suavizado válido ou inicializar com o valor atual if(idx > 0 && UpBuf[idx-1] != EMPTY_VALUE) { prev_smoothed_linreg = UpBuf[idx-1]; } else if (idx > 0 && DnBuf[idx-1] != EMPTY_VALUE) { prev_smoothed_linreg = DnBuf[idx-1]; } else { prev_smoothed_linreg = current_linreg; } first_smooth_calc = false; } display_linreg = EMA_Step(prev_smoothed_linreg, current_linreg, EMA_Smoothing); prev_smoothed_linreg = display_linreg; } bool isUp = (current_linreg > previous_linreg); bool isDown = (current_linreg < previous_linreg); // Aplicar filtro MTF if(UseMTFTrend && htfTrend != 0) { if(htfTrend == 1 && isDown) isUp = false; // Se MTF é alta, ignorar sinais de baixa if(htfTrend == -1 && isUp) isDown = false; // Se MTF é baixa, ignorar sinais de alta } // Verificar condições do RSI double rsiVal = ArrRSI[idx]; bool rsiOkUp = (rsiVal < RSIOverbought); bool rsiOkDown = (rsiVal > RSIOversold); // Atribuir valores aos buffers do indicador if(isUp && rsiOkUp) { UpBuf[idx] = (DrawSmoothedOnly ? display_linreg : current_linreg); DnBuf[idx] = EMPTY_VALUE; } else if(isDown && rsiOkDown) { DnBuf[idx] = (DrawSmoothedOnly ? display_linreg : current_linreg); UpBuf[idx] = EMPTY_VALUE; } else { UpBuf[idx] = EMPTY_VALUE; DnBuf[idx] = EMPTY_VALUE; } // Lógica de Alerta e Notificação (apenas para a barra mais recente) if(idx == rates_total - 1) // Apenas para a barra atual (índice 0 na série temporal) { int thisSignal = 0; if(isUp && rsiOkUp) thisSignal = 1; // Sinal de Compra else if(isDown && rsiOkDown) thisSignal = -1; // Sinal de Venda // Evitar alertas repetidos para o mesmo sinal if(thisSignal != lastSignal && thisSignal != 0) { string signal_type = (thisSignal == 1 ? "BUY" : "SELL"); string alert_message = "SimpleLinregRSI: " + signal_type + " signal on " + _Symbol + " TF=" + EnumToString(Period()); if(EnableAlerts) { Alert(alert_message); if(StringLen(AlertSound) > 0) PlaySound(AlertSound); } if(EnablePush) SendNotification(alert_message); if(EnableEmail && StringLen(EmailTo) > 0) { string subj = "SimpleLinregRSI signal " + _Symbol; string body = "Signal=" + signal_type + " Price=" + DoubleToString(ArrClose[idx], _Digits) + " RSI=" + DoubleToString(rsiVal, 2); SendMail(subj, body); } if(EnableCSVExport) { string line = TimeToString(TimeCurrent(), TIME_DATE|TIME_MINUTES) + ";" + _Symbol + ";" + EnumToString(Period()) + ";" + signal_type + ";" + DoubleToString(ArrClose[idx], _Digits) + ";" + DoubleToString(rsiVal, 2) + ";" + DoubleToString(current_linreg, _Digits) + ";\n"; WriteCSV(CSVFileName, line); } lastSignal = thisSignal; } } } return(rates_total); }
You are missing trading opportunities:
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
Registration
Log in
You agree to website policy and terms of use
If you do not have an account, please register