Hello Mr.Tools, I hope you are well. can you help me fix the errors in this code? THANKS
//+------------------------------------------------------------------+
//| Schaff Trend Cycle.mq5
//| Original author: Mladen
//| Modified by: [Your Name] (Adding subscription system, arrows, and notifications)
//| Adapted for MetaTrader 5
//+------------------------------------------------------------------+
#property copyright "Copyright 2017, mladen"
#property link "mladenfx@gmail.com"
#property description "Schaff Trend Cycle with subscription and alerts"
#property version "1.01"
#property indicator_separate_window
#property indicator_buffers 8
#property indicator_plots 3
// Indicator plot properties
#property indicator_label1 "Schaff Trend Cycle"
#property indicator_type1 DRAW_COLOR_LINE
#property indicator_color1 clrSilver,clrLimeGreen,clrOrange
#property indicator_width1 2
#property indicator_label2 "Up Arrow"
#property indicator_type2 DRAW_ARROW
#property indicator_color2 clrLimeGreen
#property indicator_width2 2
#property indicator_style2 STYLE_SOLID
#property indicator_arrow2 233 // Up arrow symbol
#property indicator_label3 "Down Arrow"
#property indicator_type3 DRAW_ARROW
#property indicator_color3 clrOrange
#property indicator_width3 2
#property indicator_style3 STYLE_SOLID
#property indicator_arrow3 234 // Down arrow symbol
// Input parameters for the Schaff Trend Cycle
input int SchaffPeriod = 32; // Schaff period
input int FastEma = 23; // Fast EMA period
input int SlowEma = 50; // Slow EMA period
input double SmoothPeriod = 3; // Smoothing period
input ENUM_APPLIED_PRICE Price = PRICE_CLOSE; // Applied price
// Subscription settings
input datetime ExpirationDate = D'2024.12.31'; // Expiration date
input string AllowedAccountNumber = "12345678"; // Account number
// Indicator buffers
double val[], valc[], macd[], fastk1[], fastd1[], fastk2[];
double UpArrows[], DownArrows[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
// Bind buffers
SetIndexBuffer(0, val, INDICATOR_DATA);
SetIndexBuffer(1, valc, INDICATOR_COLOR_INDEX);
SetIndexBuffer(2, macd, INDICATOR_CALCULATIONS);
SetIndexBuffer(3, fastk1, INDICATOR_CALCULATIONS);
SetIndexBuffer(4, fastk2, INDICATOR_CALCULATIONS);
SetIndexBuffer(5, fastd1, INDICATOR_CALCULATIONS);
SetIndexBuffer(6, UpArrows, INDICATOR_DATA);
SetIndexBuffer(7, DownArrows, INDICATOR_DATA);
IndicatorSetString(INDICATOR_SHORTNAME, "Schaff Trend Cycle ("+(string)SchaffPeriod+","+(string)FastEma+","+(string)SlowEma+","+(string)SmoothPeriod+")");
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration 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[])
{
// Check subscription by expiration date
if (ExpirationDate < TimeCurrent()) {
Alert("Indicator subscription expired!");
return(0);
}
// Check subscription by account number
if (AccountInfoInteger(ACCOUNT_LOGIN) != StrToInteger(AllowedAccountNumber)) {
Alert("This indicator is not authorized for this account number!");
return(0);
}
if (Bars(_Symbol, _Period) < rates_total) return (-1);
double alpha = 2.0 / (1.0 + SmoothPeriod);
int i = (int)MathMax(prev_calculated - 1, 0);
for (; i < rates_total && !_StopFlag; i++) {
double price = getPrice(Price, open, close, high, low, i, rates_total);
macd = iEma(price, FastEma, i, rates_total, 0) - iEma(price, SlowEma, i, rates_total, 1);
int start = MathMax(i - SchaffPeriod + 1, 0);
double lowMacd = macd[ArrayMinimum(macd, start, SchaffPeriod)];
double highMacd = macd[ArrayMaximum(macd, start, SchaffPeriod)] - lowMacd;
fastk1 = (highMacd > 0) ? 100 * ((macd - lowMacd) / highMacd) : (i > 0) ? fastk1 : 0;
fastd1 = (i > 0) ? fastd1 + alpha * (fastk1 - fastd1) : fastk1;
double lowStoch = fastd1[ArrayMinimum(fastd1, start, SchaffPeriod)];
double highStoch = fastd1[ArrayMaximum(fastd1, start, SchaffPeriod)] - lowStoch;
fastk2 = (highStoch > 0) ? 100 * ((fastd1[i] - lowStoch) / highStoch) : (i > 0) ? fastk2[i - 1] : 0;
val[i] = (i > 0) ? val[i - 1] + alpha * (fastk2[i] - val[i - 1]) : fastk2[i];
valc[i] = (i > 0) ? (val[i] > val[i - 1]) ? 1 : (val[i] < val[i - 1]) ? 2 : 0 : 0;
// Adding arrows for trend changes
if (i > 0) {
if (val[i] > val[i - 1] && val[i - 1] <= val[i - 2]) {
UpArrows[i] = val[i];
DownArrows[i] = EMPTY_VALUE;
if (i == rates_total - 1) {
Alert("Buy Signal Detected!");
SendNotification("Buy Signal Detected on " + Symbol());
Print("Buy Signal at: " + TimeToString(time[i], TIME_DATE | TIME_MINUTES));
}
} else if (val[i] < val[i - 1] && val[i - 1] >= val[i - 2]) {
DownArrows[i] = val[i];
UpArrows[i] = EMPTY_VALUE;
if (i == rates_total - 1) {
Alert("Sell Signal Detected!");
SendNotification("Sell Signal Detected on " + Symbol());
Print("Sell Signal at: " + TimeToString(time[i], TIME_DATE | TIME_MINUTES));
}
} else {
UpArrows[i] = EMPTY_VALUE;
DownArrows[i] = EMPTY_VALUE;
}
}
}
return (i);
}
//+------------------------------------------------------------------+
//| Custom function for calculating EMA |
//+------------------------------------------------------------------+
double workEma[][2];
double iEma(double price, double period, int r, int _bars, int instanceNo = 0)
{
if (ArrayRange(workEma, 0) != _bars) ArrayResize(workEma, _bars);
workEma[r][instanceNo] = price;
if (r > 0 && period > 1)
workEma[r][instanceNo] = workEma[r - 1][instanceNo] + (2.0 / (1.0 + period)) * (price - workEma[r - 1][instanceNo]);
return (workEma[r][instanceNo]);
}
//+------------------------------------------------------------------+
//| Custom function to get the price |
//+------------------------------------------------------------------+
#define _pricesInstances 1
#define _pricesSize 4
double workHa[][_pricesInstances * _pricesSize];
double getPrice(int tprice, const double &open[], const double &close[], const double &high[], const double &low[], int i, int _bars, int instanceNo = 0)
{
if (tprice >= pr_haclose) {
if (ArrayRange(workHa, 0) != _bars) ArrayResize(workHa, _bars);
instanceNo *= _pricesSize;
double haOpen;
if (i > 0)
haOpen = (workHa[i - 1][instanceNo + 2] + workHa[i - 1][instanceNo + 3]) / 2.0;
else
haOpen = (open[i] + close[i]) / 2;
double haClose = (open[i] + high[i] + low[i] + close[i]) / 4.0;
double haHigh = MathMax(high[i], MathMax(haOpen, haClose));
double haLow = MathMin(low[i], MathMin(haOpen, haClose));
if (haOpen < haClose) {
workHa[i][instanceNo + 0] = haLow;
workHa[i][instanceNo + 1] = haHigh;
} else {
workHa[i][instanceNo + 0] = haHigh;
workHa[i][instanceNo + 1] = haLow;
}
workHa[i][instanceNo + 2] = haOpen;
workHa[i][instanceNo + 3] = haClose;
switch (tprice) {
case pr_haclose:
return (haClose);
case pr_haopen:
return (haOpen);
case pr_hahigh:
return (haHigh);
case pr_halow:
return (haLow);
case pr_hamedian:
return ((haHigh + haLow) / 2.0);
case pr_hamedianb:
return ((haOpen + haClose) / 2.0);
case pr_hatypical:
return ((haHigh + haLow + haClose) / 3.0);
case pr_haweighted:
return ((haHigh + haLow + haClose + haClose) / 4.0);
case pr_haaverage:
return ((haHigh + haLow + haClose + haOpen) / 4.0);
case pr_hatbiased:
if (haClose > haOpen)
return ((haHigh + haClose) / 2.0);
else
return ((haLow + haClose) / 2.0);
case pr_hatbiased2:
if (haClose > haOpen) return (haHigh);
if (haClose < haOpen) return (haLow);
return (haClose);
}
}
switch (tprice) {
case pr_close:
return (close[i]);
case pr_open:
return (open[i]);
case pr_high:
return (high[i]);
case pr_low:
return (low[i]);
case pr_median:
return ((high[i] + low[i]) / 2.0);
case pr_medianb:
return ((open[i] + close[i]) / 2.0);
case pr_typical:
return ((high[i] + low[i] + close[i]) / 3.0);
case pr_weighted:
return ((high[i] + low[i] + close[i] + close[i]) / 4.0);
case pr_average:
return ((high[i] + low[i] + close[i] + open[i]) / 4.0);
case pr_tbiased:
if (close[i] > open[i])
return ((high[i] + close[i]) / 2.0);
else
return ((low[i] + close[i]) / 2.0);
case pr_tbiased2:
if (close[i] > open[i]) return (high[i]);
if (close[i] < open[i]) return (low[i]);
return (close[i]);
}
return (0);
}