//+------------------------------------------------------------------+
//|                                          Project 32 BIN FILE.mq5 |
//|                                             Abioye Israel Pelumi |
//|                             https://linktr.ee/abioyeisraelpelumi |
//+------------------------------------------------------------------+
#property copyright "Abioye Israel Pelumi"
#property link      "https://linktr.ee/abioyeisraelpelumi"
#property version   "1.00"

//--- Input parameters (user-adjustable settings)
input int TP = 150;
input int SL = 80;
input double L_multiplier = 1.0;
input int RSI_threshold = 55;
input int Max_trades = 3;

//+------------------------------------------------------------------+
//| SessionParams Struct                                             |
//| Holds parameters, metadata, performance, and checksum            |
//+------------------------------------------------------------------+
struct SessionParams
  {
   //--- Versioning & Metadata
   int               version_count;   // Current version number
   datetime          saved_at;        // Time the record was saved

   //--- Adjustable Parameters
   int               take_profit;
   int               stop_loss;
   double            lot_multiplier;
   int               rsi_threshold;
   int               max_trades;

   //--- Performance Metrics
   double            profit_factor;
   double            win_rate;
   double            max_drawdown;
   double            avg_rrr;

   //--- Data Integrity
   uint              checksum;        // Used to verify data consistency
  };

//--- Global variables
SessionParams params;
string filename = "parameters.bin";
int handle;
int file_size;
int struct_size;
int total_versions;
int last_version_offset;
uint Prev_checksum;

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//--- Open or create the binary file
   handle = FileOpen(filename, FILE_READ|FILE_WRITE|FILE_BIN|FILE_COMMON);
//--- Check if file access failed
   if(handle == INVALID_HANDLE)
     {
      Print("ERROR: Cannot access file. Error: ", GetLastError());
      return;
     }

//--- Get current file size
   file_size = (int)FileSize(handle);

//--- If file is empty, create first version
   if(file_size == 0)
     {
      Print("INFO: New file detected. Writing default parameters...");

      //--- Load input values into struct
      params.version_count     = 1;
      params.saved_at          = TimeCurrent();
      params.take_profit       = TP;
      params.stop_loss         = SL;
      params.lot_multiplier    = L_multiplier;
      params.rsi_threshold     = RSI_threshold;
      params.max_trades        = Max_trades;

      //--- Initialize performance values
      params.profit_factor     = 0.0;
      params.win_rate          = 0.0;
      params.max_drawdown      = 0.0;
      params.avg_rrr           = 0.0;
      params.checksum          = 0;

      //--- Compute checksum
      uint result_f = 0;
      result_f ^= (uint)params.take_profit;
      result_f ^= (uint)params.stop_loss;
      result_f ^= (uint)(params.lot_multiplier * 1000);
      result_f ^= (uint)params.rsi_threshold;
      result_f ^= (uint)params.max_trades;
  
      params.checksum = result_f;

      //--- Print current parameters
      Print("========================================");
      Print("INFO: CURRENT PARAMETERS (Loaded)");
      Print("========================================");
      Print("Version       : ", params.version_count);
      Print("Saved At      : ", TimeToString(params.saved_at, TIME_DATE|TIME_SECONDS));
      Print("Take Profit   : ", params.take_profit);
      Print("Stop Loss     : ", params.stop_loss);
      Print("Lot Multiplier: ", params.lot_multiplier);
      Print("RSI Threshold : ", params.rsi_threshold);
      Print("Max Trades    : ", params.max_trades);
      Print("Profit Factor : ", params.profit_factor);
      Print("Win Rate      : ", params.win_rate, "%");
      Print("Max Drawdown  : ", params.max_drawdown);
      Print("Avg RRR       : ", params.avg_rrr);
      Print("Checksum      : ", params.checksum);

      //--- Save first version
      FileWriteStruct(handle, params);
      FileClose(handle);
      Print("SUCCESS: Created parameter file with version 1.");
     }
   else
     {
      //--- Determine number of stored versions
      struct_size = sizeof(SessionParams);
      total_versions = file_size / struct_size;

      //--- Move pointer to last stored version
      last_version_offset = (total_versions - 1) * struct_size;
      FileSeek(handle, last_version_offset, SEEK_SET);

      //--- Read last version
      SessionParams pre_v_params;
      FileReadStruct(handle, pre_v_params);

      //--- Recalculate checksum of last version
      uint result = 0;
      result ^= (uint)pre_v_params.take_profit;
      result ^= (uint)pre_v_params.stop_loss;
      result ^= (uint)(pre_v_params.lot_multiplier * 1000);
      result ^= (uint)pre_v_params.rsi_threshold;
      result ^= (uint)pre_v_params.max_trades;
      Prev_checksum = result;

      //--- Update parameters with current inputs
      pre_v_params.take_profit    = TP;
      pre_v_params.stop_loss      = SL;
      pre_v_params.lot_multiplier = L_multiplier;
      pre_v_params.rsi_threshold  = RSI_threshold;
      pre_v_params.max_trades     = Max_trades;

      //--- Compute new checksum
      uint result_new = 0;
      result_new ^= (uint)pre_v_params.take_profit;
      result_new ^= (uint)pre_v_params.stop_loss;
      result_new ^= (uint)(pre_v_params.lot_multiplier * 1000);
      result_new ^= (uint)pre_v_params.rsi_threshold;
      result_new ^= (uint)pre_v_params.max_trades;
      pre_v_params.checksum = result_new;

      //--- If checksum differs, parameters have changed
      if(pre_v_params.checksum != Prev_checksum)
        {
         //--- Move to end of file to append new version
         FileSeek(handle, 0, SEEK_END);

         //--- Update version metadata
         pre_v_params.version_count += 1;
         pre_v_params.saved_at = TimeCurrent();

         //--- Save new version
         FileWriteStruct(handle, pre_v_params);

         //--- Print updated parameters
         Print("========================================");
         Print("INFO: NEW SAVED PARAMETERS (Loaded)");
         Print("========================================");
         Print("Version       : ", pre_v_params.version_count);
         Print("Saved At      : ", TimeToString(pre_v_params.saved_at, TIME_DATE|TIME_SECONDS));
         Print("Take Profit   : ", pre_v_params.take_profit);
         Print("Stop Loss     : ", pre_v_params.stop_loss);
         Print("Lot Multiplier: ", pre_v_params.lot_multiplier);
         Print("RSI Threshold : ", pre_v_params.rsi_threshold);
         Print("Max Trades    : ", pre_v_params.max_trades);
         Print("Profit Factor : ", pre_v_params.profit_factor);
         Print("Win Rate      : ", pre_v_params.win_rate, "%");
         Print("Max Drawdown  : ", pre_v_params.max_drawdown);
         Print("Avg RRR       : ", pre_v_params.avg_rrr);
         Print("Checksum      : ", pre_v_params.checksum);
         Print("SUCCESS: Created parameter file with version ", pre_v_params.version_count);
        }
      //--- Close file after operations
      FileClose(handle);
     }
  }
//+------------------------------------------------------------------+
