//+------------------------------------------------------------------+
//|                                      SignalBitwisePerceptron.mqh |
//|                                  Copyright 2026, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#include <Expert\ExpertSignal.mqh>
// wizard description start
//+------------------------------------------------------------------+
//| Description of the class                                         |
//| Title=Signals of Bitwise Perceptron                              |
//| Type=SignalAdvanced                                              |
//| Name=Bitwise Perceptron Classifier                               |
//| ShortName=BitPercept                                             |
//| Class=CSignalBitwisePerceptron                                   |
//| Page=signal_bitpercept                                           |
//| Parameter=Map,int,0,Vectorized Map                               |
//| Parameter=Threshold,double,0.0,Activation Threshold              |
//+------------------------------------------------------------------+
// wizard description end
//+------------------------------------------------------------------+
//| Class CSignalBitwisePerceptron.                                  |
//| Purpose: Generator of trade signals based on a 64-bit vectorized |
//|          market state and a Perceptron Classifier.               |
//| Is derived from the CExpertSignal class.                         |
//+------------------------------------------------------------------+
class CSignalBitwisePerceptron : public CExpertSignal
  {
protected:
   //--- adjusted parameters
   ulong             m_map;            //--- Vectorized Map Filter
   double            m_threshold;      //--- Activation threshold for the perceptron

   //--- perceptron parameters
   double            m_weights[64];    //--- Array of 64 synaptic weights
   double            m_bias;           //--- Network bias

   //--- "weights" of market models (0-100)
   int               m_pattern_0;      //--- model 0 "Composite pattern match"

public:
                     CSignalBitwisePerceptron(void);
                    ~CSignalBitwisePerceptron(void);

   //--- methods of setting adjustable parameters
   void              Map(ulong value)                  { m_map = value;                 }
   void              Threshold(double value)           { m_threshold = value;           }

   //--- methods of adjusting "weights" of market models
   void              Pattern_0(int value)              { m_pattern_0 = value;           }

   //--- method of verification of settings
   virtual bool      ValidationSettings(void);

   //--- method of creating timeseries
   virtual bool      InitIndicators(CIndicators *indicators);

   //--- methods of checking if the market models are formed
   virtual int       LongCondition(void);
   virtual int       ShortCondition(void);

protected:
   //--- custom methods for high-speed bitwise logic
   ulong             GetVectorizedState(int start_index);
   double            PerceptronInference(ulong state);
   bool              LoadPreTrainedWeights(void);
  };
//+------------------------------------------------------------------+
//| Constructor                                                      |
//+------------------------------------------------------------------+
CSignalBitwisePerceptron::CSignalBitwisePerceptron(void) : m_threshold(0.0),
   m_pattern_0(100),
   m_bias(0.0)
  {
//--- initialization of protected data
   m_used_series = USE_SERIES_HIGH + USE_SERIES_LOW + USE_SERIES_OPEN + USE_SERIES_CLOSE;
//--- load weights (in a production environment, this would read from a file/ONNX)
   LoadPreTrainedWeights();
  }
//+------------------------------------------------------------------+
//| Destructor                                                       |
//+------------------------------------------------------------------+
CSignalBitwisePerceptron::~CSignalBitwisePerceptron(void)
  {
  }
//+------------------------------------------------------------------+
//| Validation settings protected data.                              |
//+------------------------------------------------------------------+
bool CSignalBitwisePerceptron::ValidationSettings(void)
  {
//--- validation settings of additional filters
   if(!CExpertSignal::ValidationSettings())
      return(false);
//--- ok
   return(true);
  }
//+------------------------------------------------------------------+
//| Create indicators.                                               |
//+------------------------------------------------------------------+
bool CSignalBitwisePerceptron::InitIndicators(CIndicators *indicators)
  {
//--- check pointer
   if(indicators == NULL)
      return(false);
//--- initialization of timeseries of additional filters
   if(!CExpertSignal::InitIndicators(indicators))
      return(false);
//--- ok
   return(true);
  }
//+------------------------------------------------------------------+
//| Load pre-trained weights for the Perceptron                      |
//+------------------------------------------------------------------+
bool CSignalBitwisePerceptron::LoadPreTrainedWeights(void)
  {
//--- Dummy initialization for demonstration.
//--- In practice, load weights optimized for composite pattern combinations.
   m_bias = 0.05;
   for(int i = 0; i < 64; i++)
     {
      //--- Alternating dummy weights
      m_weights[i] = (i % 2 == 0) ? 0.01 : -0.01;
     }
   return(true);
  }
//+------------------------------------------------------------------+
//| Bitwise Vectorization: Pack 64 periods into a uint64             |
//+------------------------------------------------------------------+
ulong CSignalBitwisePerceptron::GetVectorizedState(int start_index)
  {
   ulong state = 0;
//--- Loop through the last 64 bars.
//--- If Close > Open (Bullish), set the bit to 1. Else, leave as 0.
   for(int i = 0; i < 64; i++)
     {
      if(Close(start_index + i) > Open(start_index + i))
        {
         //--- Shift 1 by 'i' positions and perform bitwise OR
         state |= ((ulong)1 << i);
        }
     }
   return(state);
  }
//+------------------------------------------------------------------+
//| Perceptron Inference: Hardware-level dot product calculation     |
//+------------------------------------------------------------------+
double CSignalBitwisePerceptron::PerceptronInference(ulong state)
  {
   double sum = m_bias;
//--- Iterate through the 64-bit integer
   for(int i = 0; i < 64; i++)
     {
      //--- Use bitwise AND to check if the i-th bit is set to 1
      if((state & ((ulong)1 << i)) != 0)
        {
         //--- If bit is 1, add the corresponding weight to the sum
         sum += m_weights[i];
        }
     }
   return(sum);
  }
//+------------------------------------------------------------------+
//| "Voting" that price will grow.                                   |
//+------------------------------------------------------------------+
int CSignalBitwisePerceptron::LongCondition(void)
  {
   int result = 0;
   int idx   = StartIndex();
//--- 1. Fetch the 64-bit vectorized market state
   ulong current_state = GetVectorizedState(idx);
   if(!(m_map & (1 << current_state)))
     {
      result = m_pattern_0; //--- Signal number 0 (100% weight)
     }
//--- 2. Run the Perceptron inference
   double activation = PerceptronInference(current_state);
//--- 3. Check against threshold
   if(activation > m_threshold && m_threshold > 0.0)
     {
      result /= 2;
      //--- The perceptron has identified a bullish composite combination
      if(IS_PATTERN_USAGE(0))
         result = m_pattern_0; //--- Signal number 0 (100% weight)
     }
   return(result);
  }
//+------------------------------------------------------------------+
//| "Voting" that price will fall.                                   |
//+------------------------------------------------------------------+
int CSignalBitwisePerceptron::ShortCondition(void)
  {
   int result = 0;
   int idx   = StartIndex();
//--- 1. Fetch the 64-bit vectorized market state
   ulong current_state = GetVectorizedState(idx);
   if(!(!(m_map & (1 << current_state))))
     {
      result = m_pattern_0; //--- Signal number 0 (100% weight)
     }
//--- 2. Run the Perceptron inference
   double activation = PerceptronInference(current_state);
//--- 3. Check against threshold (assuming negative threshold for shorts)
   if(activation < -m_threshold && m_threshold > 0.0)
     {
      result /= 2;
      //--- The perceptron has identified a bearish composite combination
      if(IS_PATTERN_USAGE(0))
         result = m_pattern_0; //--- Signal number 0 (100% weight)
     }
   return(result);
  }
//+------------------------------------------------------------------+
