Plotting arrows on chart

 

Hello, thanks for the opportunity to post on the forum!

I am working on an indicator to plot arrows onto a chart based on a local CSV file - i can read the CSV file, have the insertions set up but it's just inserting in one place rather than multiple?


My CSV format is;


1.75793,BUY,2024.11.22 3:45:00,GBPCAD,M3

71.931,SELL,2024.11.12 22:00:00,BCOUSD,H4

194.496,BUY,2024.11.22 7:24:00,GBPJPY,M3

194.152,SELL,2024.11.22 4:24:00,GBPJPY,M3

194.278,BUY,2024.11.22 1:18:00,GBPJPY,M3

I have a snippet of code below. Can anyone see the problem? Is the date format correct? I can't find the issue!?


#property copyright "Your Name"
#property link      "https://www.example.com"
#property version   "1.00"
#property strict
#property indicator_chart_window

#include <Utils/File.mqh>

// Input parameters for the CSV file path
input string InpFilePath = "trade_signal3.csv";
input color BuyColor = clrGreen;
input color SellColor = clrRed;
input int ArrowCode = 159;  // Arrow symbol
input int ArrowSize = 2;    // Arrow size

// Global variables
int fileHandle;
string signalObjectPrefix = "SignalIndicator_";

// Custom function to convert string period to MT4 period
int ConvertPeriodToMT4Period(string periodString) {
    periodString = UpperCase(periodString);
    
    if(periodString == "M1")  return PERIOD_M1;
    if(periodString == "M5")  return PERIOD_M5;
    if(periodString == "M15") return PERIOD_M15;
    if(periodString == "M30") return PERIOD_M30;
    if(periodString == "H1")  return PERIOD_H1;
    if(periodString == "H4")  return PERIOD_H4;
    if(periodString == "D1")  return PERIOD_D1;
    if(periodString == "W1")  return PERIOD_W1;
    if(periodString == "MN1") return PERIOD_MN1;
    
    return PERIOD_CURRENT;
}

// Custom function to convert string to uppercase
string UpperCase(string str) {
    // Alternative method to convert to uppercase
    string result = "";
    for(int i = 0; i < StringLen(str); i++) {
        char ch = str[i];
        if(ch >= 'a' && ch <= 'z')
            result += CharToString(ch - 32);
        else
            result += CharToString(ch);
    }
    return result;
}

// Function to plot signal icon
void PlotSignalIcon(datetime signalTime, double price, string signalType) {
    // Generate unique object name
 
    string objectName = signalObjectPrefix + TimeToString(signalTime);
    
    // Determine icon properties based on signal type
    color signalColor;
    int signalDirection;
    
    if(UpperCase(signalType) == "BUY") {
        signalColor = BuyColor;
        signalDirection = ANCHOR_TOP;
    }
    else if(UpperCase(signalType) == "SELL") {
        signalColor = SellColor;
        signalDirection = ANCHOR_BOTTOM;
    }
    else {
        return;  // Invalid signal type
    }
    
    // Create signal object
    if(ObjectCreate(0, objectName, OBJ_ARROW, 0, signalTime, price)) {
        ObjectSetInteger(0, objectName, OBJPROP_COLOR, signalColor);
        ObjectSetInteger(0, objectName, OBJPROP_ARROWCODE, ArrowCode);
        ObjectSetInteger(0, objectName, OBJPROP_WIDTH, ArrowSize);
        ObjectSetInteger(0, objectName, OBJPROP_ANCHOR, signalDirection);
    }
}

// Initialization function
int OnInit() {
    // Clear any previous signal objects
    ClearPreviousSignals();
    
    return(INIT_SUCCEEDED);
}

// Deinitialization function
void OnDeinit(const int reason) {
    // Clear signal objects when indicator is removed
    ClearPreviousSignals();
}

// Function to clear previous signal objects
void ClearPreviousSignals() {
    // Use explicit ObjectsTotal() call with two parameters
    for(int i = ObjectsTotal(ChartID(), 0, OBJ_ARROW) - 1; i >= 0; i--) {
        string objName = ObjectName(ChartID(), i, OBJ_ARROW);
        if(StringSubstr(objName, 0, StringLen(signalObjectPrefix)) == signalObjectPrefix) {
            ObjectDelete(ChartID(), objName);
        }
    }
}

// Indicator calculation 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[]) {
    
    // Open the CSV file]
    
 
   CsvFile csv(InpFilePath,FILE_READ,FILE_CSV);

   for(int i=1; !csv.end(); i++)
     {
      do
        {
    
        
        string parts[];
        int totalParts = StringSplit(csv.readString(), ',', parts);

           if(totalParts >= 5) {
               // Parse CSV line
               double price = StringToDouble(parts[0]);
               string signal = parts[1];
               datetime signalTimes = parts[2];
               datetime signalTime = StringToTime(parts[2]);
               string instrument = parts[3];
               string granularity = parts[4];
               datetime var1=StrToTime(signalTime);
               // Check if the signal matches current chart
               if(instrument == Symbol() && 
                  ConvertPeriodToMT4Period(granularity) == Period()) {
                  Print(price);
                  PlotSignalIcon(signalTime, price, signal);
               }
            }
            
        }
      while(!csv.isLineEnding());
     } 
    // Close the file
    FileClose(fileHandle);
    
    return(rates_total);
}
 

I did not check everything in your code but for one thing:

You are attaching arrows to current chart all the time while the CSV lines refer to different charts.

 
  1. terryby: I can't find the issue!?

    Use the debugger or print out your variables, including _LastError and prices and find out why. Do you really expect us to debug your code for you?
              Code debugging - Developing programs - MetaEditor Help
              Error Handling and Logging in MQL5 - MQL5 Articles (2015)
              Tracing, Debugging and Structural Analysis of Source Code - MQL5 Articles (2011)
              Introduction to MQL5: How to write simple Expert Advisor and Custom Indicator - MQL5 Articles (2010)

  2. Yashar Seyyedin #: You are attaching arrows to current chart all the time while the CSV lines refer to different charts.
    Wrong. Code checks for proper symbol and TF.
                   if(instrument == Symbol() && 
                      ConvertPeriodToMT4Period(granularity) == Period()) {