Zenith-FX/FOREX_TRADER/Include/BinaryEncoder.mqh
copilot-swe-agent[bot] 94e367d44d Add quantum helper include files
Co-authored-by: simonokwundue-ops <243668919+simonokwundue-ops@users.noreply.github.com>
2025-11-14 06:51:50 +00:00

349 行
9.6 KiB
MQL5

//+------------------------------------------------------------------+
//| BinaryEncoder.mqh |
//| Price-to-Binary Encoding Functions |
//| For Quantum-Compatible Market Analysis |
//+------------------------------------------------------------------+
#property copyright "ForexTrader Quantum EA"
#property link "https://github.com/simonokwundue-ops/Experienced-FX-Trader"
#property version "1.00"
#property strict
//+------------------------------------------------------------------+
//| Binary Price Encoder Class |
//+------------------------------------------------------------------+
class CBinaryEncoder
{
public:
//--- Encode price movements to binary string
static string EncodePriceMovements(const double &prices[], int count)
{
if(count < 2) return "";
string binary = "";
for(int i = 1; i < count; i++)
{
// 1 if price increased, 0 if decreased or equal
binary += (prices[i] > prices[i-1]) ? "1" : "0";
}
return binary;
}
//--- Encode MqlRates array to binary
static string EncodeRates(const MqlRates &rates[], int count = -1)
{
int size = (count > 0) ? count : ArraySize(rates);
if(size < 2) return "";
string binary = "";
// Process from oldest to newest
for(int i = size - 2; i >= 0; i--)
{
binary += (rates[i].close > rates[i+1].close) ? "1" : "0";
}
return binary;
}
//--- Encode with volatility weighting
static string EncodeWithVolatility(const MqlRates &rates[], int count = -1)
{
int size = (count > 0) ? count : ArraySize(rates);
if(size < 2) return "";
string binary = "";
double avgRange = CalculateAverageRange(rates, size);
for(int i = size - 2; i >= 0; i--)
{
double priceChange = rates[i].close - rates[i+1].close;
double candleRange = rates[i].high - rates[i].low;
// Weight by volatility significance
if(MathAbs(priceChange) > avgRange * 0.3)
{
// Significant move
binary += (priceChange > 0) ? "1" : "0";
}
else
{
// Small move - consider as continuation
if(i < size - 2)
binary += binary[StringLen(binary) - 1]; // Copy previous
else
binary += "0";
}
}
return binary;
}
//--- Decode binary string to probability
static double DecodeToProbability(const string binary)
{
int length = StringLen(binary);
if(length == 0) return 0.5;
int ones = 0;
for(int i = 0; i < length; i++)
{
if(StringGetCharacter(binary, i) == '1')
ones++;
}
return (double)ones / length;
}
//--- Calculate pattern frequency
static double CalculatePatternFrequency(const string binary, const string pattern)
{
int binaryLen = StringLen(binary);
int patternLen = StringLen(pattern);
if(patternLen == 0 || patternLen > binaryLen)
return 0;
int matches = 0;
int possibleMatches = binaryLen - patternLen + 1;
for(int i = 0; i < possibleMatches; i++)
{
string segment = StringSubstr(binary, i, patternLen);
if(segment == pattern)
matches++;
}
return (double)matches / possibleMatches;
}
//--- Extract recent pattern
static string ExtractRecentPattern(const string binary, int length)
{
int binaryLen = StringLen(binary);
if(length > binaryLen) length = binaryLen;
return StringSubstr(binary, 0, length);
}
//--- Calculate pattern entropy
static double CalculatePatternEntropy(const string binary)
{
int length = StringLen(binary);
if(length < 2) return 0;
// Count consecutive patterns
int changes = 0;
for(int i = 1; i < length; i++)
{
if(StringGetCharacter(binary, i) != StringGetCharacter(binary, i-1))
changes++;
}
// Entropy measure: more changes = higher entropy
return (double)changes / (length - 1);
}
//--- Detect trend in binary sequence
static int DetectTrend(const string binary, int lookback = 20)
{
int length = StringLen(binary);
if(length == 0) return 0;
if(lookback > length) lookback = length;
string recent = StringSubstr(binary, 0, lookback);
int ones = 0;
for(int i = 0; i < lookback; i++)
{
if(StringGetCharacter(recent, i) == '1')
ones++;
}
double ratio = (double)ones / lookback;
if(ratio > 0.60) return 1; // Uptrend
else if(ratio < 0.40) return -1; // Downtrend
else return 0; // No clear trend
}
//--- Calculate momentum score
static double CalculateMomentumScore(const string binary, int period = 10)
{
int length = StringLen(binary);
if(length < period) period = length;
if(period == 0) return 0;
string recent = StringSubstr(binary, 0, period);
int ones = 0;
for(int i = 0; i < period; i++)
{
if(StringGetCharacter(recent, i) == '1')
ones++;
}
// Score from -1 (strong down) to +1 (strong up)
return (2.0 * ones / period) - 1.0;
}
//--- Find similar patterns in history
static double FindHistoricalSimilarity(const string currentPattern,
const string historical,
int patternLength)
{
if(patternLength > StringLen(currentPattern))
patternLength = StringLen(currentPattern);
string pattern = StringSubstr(currentPattern, 0, patternLength);
int histLength = StringLen(historical);
if(patternLength > histLength)
return 0;
double maxSimilarity = 0;
// Scan historical data for similar patterns
for(int i = 0; i <= histLength - patternLength; i++)
{
string segment = StringSubstr(historical, i, patternLength);
double similarity = CalculateSimilarity(pattern, segment);
if(similarity > maxSimilarity)
maxSimilarity = similarity;
}
return maxSimilarity;
}
//--- Calculate similarity between two binary strings
static double CalculateSimilarity(const string binary1, const string binary2)
{
int len1 = StringLen(binary1);
int len2 = StringLen(binary2);
if(len1 != len2) return 0;
if(len1 == 0) return 0;
int matches = 0;
for(int i = 0; i < len1; i++)
{
if(StringGetCharacter(binary1, i) == StringGetCharacter(binary2, i))
matches++;
}
return (double)matches / len1;
}
//--- Pad binary string to specified length
static string PadBinary(const string binary, int targetLength, bool padLeft = true)
{
int currentLength = StringLen(binary);
if(currentLength >= targetLength)
return binary;
string padding = "";
for(int i = 0; i < targetLength - currentLength; i++)
{
padding += "0";
}
return padLeft ? (padding + binary) : (binary + padding);
}
//--- Convert binary string to integer
static long BinaryToInteger(const string binary)
{
int length = StringLen(binary);
if(length == 0 || length > 63) return 0; // Prevent overflow
long result = 0;
long power = 1;
for(int i = length - 1; i >= 0; i--)
{
if(StringGetCharacter(binary, i) == '1')
result += power;
power *= 2;
}
return result;
}
//--- Convert integer to binary string
static string IntegerToBinary(long value, int minLength = 8)
{
if(value < 0) value = 0;
string binary = "";
if(value == 0)
{
binary = "0";
}
else
{
while(value > 0)
{
binary = ((value % 2 == 1) ? "1" : "0") + binary;
value /= 2;
}
}
// Pad to minimum length
return PadBinary(binary, minLength, true);
}
//--- Helper: Calculate average range
static double CalculateAverageRange(const MqlRates &rates[], int count)
{
if(count < 1) return 0;
double totalRange = 0;
for(int i = 0; i < count; i++)
{
totalRange += (rates[i].high - rates[i].low);
}
return totalRange / count;
}
//--- Compress binary using run-length encoding (for storage/comparison)
static string CompressBinary(const string binary)
{
int length = StringLen(binary);
if(length == 0) return "";
string compressed = "";
ushort currentChar = StringGetCharacter(binary, 0);
int count = 1;
for(int i = 1; i < length; i++)
{
ushort nextChar = StringGetCharacter(binary, i);
if(nextChar == currentChar)
{
count++;
}
else
{
compressed += IntegerToString(count) + ShortToString(currentChar);
currentChar = nextChar;
count = 1;
}
}
// Add final run
compressed += IntegerToString(count) + ShortToString(currentChar);
return compressed;
}
};
//+------------------------------------------------------------------+