USER
i made changes as below but stll getting errors:
#property strict
// Define missing constant
#define CHARTEVENT_OBJECT_END_EDIT 12
//+------------------------------------------------------------------+
//| GUI Panel Class |
//+------------------------------------------------------------------+
class CPanel
{
private:
string m_name;
int m_width;
public:
void Create(string name, int width)
{
m_name = name;
m_width = width;
ObjectCreate(0, m_name, OBJ_RECTANGLE_LABEL, 0, 0, 0);
ObjectSetInteger(0, m_name, OBJPROP_XDISTANCE, 1);
ObjectSetInteger(0, m_name, OBJPROP_YDISTANCE, 20);
ObjectSetInteger(0, m_name, OBJPROP_XSIZE, 360);
ObjectSetInteger(0, m_name, OBJPROP_YSIZE, 275);
ObjectSetInteger(0, m_name, OBJPROP_BGCOLOR, clrBlack);
ObjectSetInteger(0, m_name, OBJPROP_BORDER_TYPE, BORDER_FLAT);
}
void AddLabel(string objName, string text, int x, int y, color clr)
{
ObjectCreate(0, m_name+"_"+objName, OBJ_LABEL, 0, 0, 0);
ObjectSetString(0, m_name+"_"+objName, OBJPROP_TEXT, text);
ObjectSetInteger(0, m_name+"_"+objName, OBJPROP_XDISTANCE, x);
ObjectSetInteger(0, m_name+"_"+objName, OBJPROP_YDISTANCE, y);
ObjectSetInteger(0, m_name+"_"+objName, OBJPROP_COLOR, clr);
}
void AddEdit(string objName, string text, int x, int y, int width)
{
ObjectCreate(0, m_name+"_"+objName, OBJ_EDIT, 0, 0, 0);
ObjectSetString(0, m_name+"_"+objName, OBJPROP_TEXT, text);
ObjectSetInteger(0, m_name+"_"+objName, OBJPROP_XDISTANCE, x);
ObjectSetInteger(0, m_name+"_"+objName, OBJPROP_YDISTANCE, y);
ObjectSetInteger(0, m_name+"_"+objName, OBJPROP_XSIZE, width);
ObjectSetInteger(0, m_name+"_"+objName, OBJPROP_YSIZE, 20);
}
void AddButton(string objName, string text, int x, int y, int width, int height, color bgColor, color textColor)
{
ObjectCreate(0, m_name+"_"+objName, OBJ_BUTTON, 0, 0, 0);
ObjectSetString(0, m_name+"_"+objName, OBJPROP_TEXT, text);
ObjectSetInteger(0, m_name+"_"+objName, OBJPROP_XDISTANCE, x);
ObjectSetInteger(0, m_name+"_"+objName, OBJPROP_YDISTANCE, y);
ObjectSetInteger(0, m_name+"_"+objName, OBJPROP_XSIZE, width);
ObjectSetInteger(0, m_name+"_"+objName, OBJPROP_YSIZE, height);
ObjectSetInteger(0, m_name+"_"+objName, OBJPROP_BGCOLOR, bgColor);
ObjectSetInteger(0, m_name+"_"+objName, OBJPROP_COLOR, textColor);
}
void UpdateLabel(string objName, string text, color clr)
{
ObjectSetString(0, m_name+"_"+objName, OBJPROP_TEXT, text);
ObjectSetInteger(0, m_name+"_"+objName, OBJPROP_COLOR, clr);
}
string GetEditValue(string objName)
{
return ObjectGetString(0, m_name+"_"+objName, OBJPROP_TEXT);
}
void Destroy()
{
ObjectsDeleteAll(0, m_name);
}
};
//+------------------------------------------------------------------+
//| Volume Indicator Class (Candle Volume Display) |
//+------------------------------------------------------------------+
class CVolumeIndicator
{
private:
// Volume tracking
long buy_volume;
long sell_volume;
long current_candle_buy;
long current_candle_sell;
long maxPositiveDiff;
long maxNegativeDiff;
double basePrice;
double maxUpMove;
double maxDownMove;
// Display settings
int panel_x;
int panel_y;
color panel_color;
color buy_color;
color sell_color;
color diff_color;
int max_candles_to_show;
// Candle tracking
datetime last_candle_time;
double prevPrice;
// Label management
struct CandleData {
long buy;
long sell;
datetime time;
};
CandleData candle_history[];
// Current candle label prefix
string current_candle_label_prefix;
// Movement label
string movementLabelName;
string maxUpMoveLabelName;
string maxDownMoveLabelName;
string moveDiffLabelName;
public:
void Create(int x, int y, color p_color, color b_color, color s_color, int max_candles = 24)
{
panel_x = x;
panel_y = y;
panel_color = p_color;
buy_color = b_color;
sell_color = s_color;
diff_color = clrWhite;
max_candles_to_show = max_candles;
current_candle_label_prefix = "CurrentVol_";
movementLabelName = "MovementLabel";
maxUpMoveLabelName = "MaxUpMoveLabel";
maxDownMoveLabelName = "MaxDownMoveLabel";
moveDiffLabelName = "MoveDiffLabel";
ArrayResize(candle_history, max_candles_to_show);
ResetCounters();
CreateMainPanel();
}
void CreateMainPanel()
{
// Create the main panel object
ObjectCreate(0, "MainPanel", OBJ_RECTANGLE_LABEL, 0, 0, 0);
ObjectSetInteger(0, "MainPanel", OBJPROP_XDISTANCE, panel_x);
ObjectSetInteger(0, "MainPanel", OBJPROP_YDISTANCE, panel_y);
ObjectSetInteger(0, "MainPanel", OBJPROP_XSIZE, 300);
ObjectSetInteger(0, "MainPanel", OBJPROP_YSIZE, 200);
ObjectSetInteger(0, "MainPanel", OBJPROP_BGCOLOR, panel_color);
ObjectSetInteger(0, "MainPanel", OBJPROP_BORDER_TYPE, BORDER_FLAT);
// Add labels to the main panel
ObjectCreate(0, "BuyVolumeLabel", OBJ_LABEL, 0, 0, 0);
ObjectSetString(0, "BuyVolumeLabel", OBJPROP_TEXT, "Total Buy: 0");
ObjectSetInteger(0, "BuyVolumeLabel", OBJPROP_XDISTANCE, panel_x + 10);
ObjectSetInteger(0, "BuyVolumeLabel", OBJPROP_YDISTANCE, panel_y + 10);
ObjectSetInteger(0, "BuyVolumeLabel", OBJPROP_COLOR, buy_color);
ObjectCreate(0, "SellVolumeLabel", OBJ_LABEL, 0, 0, 0);
ObjectSetString(0, "SellVolumeLabel", OBJPROP_TEXT, "Total Sell: 0");
ObjectSetInteger(0, "SellVolumeLabel", OBJPROP_XDISTANCE, panel_x + 10);
ObjectSetInteger(0, "SellVolumeLabel", OBJPROP_YDISTANCE, panel_y + 30);
ObjectSetInteger(0, "SellVolumeLabel", OBJPROP_COLOR, sell_color);
ObjectCreate(0, "TotalDiffLabel", OBJ_LABEL, 0, 0, 0);
ObjectSetString(0, "TotalDiffLabel", OBJPROP_TEXT, "Total Diff: 0");
ObjectSetInteger(0, "TotalDiffLabel", OBJPROP_XDISTANCE, panel_x + 10);
ObjectSetInteger(0, "TotalDiffLabel", OBJPROP_YDISTANCE, panel_y + 50);
ObjectSetInteger(0, "TotalDiffLabel", OBJPROP_COLOR, diff_color);
ObjectCreate(0, "MaxPosDiffLabel", OBJ_LABEL, 0, 0, 0);
ObjectSetString(0, "MaxPosDiffLabel", OBJPROP_TEXT, "Max +Diff: 0");
ObjectSetInteger(0, "MaxPosDiffLabel", OBJPROP_XDISTANCE, panel_x + 10);
ObjectSetInteger(0, "MaxPosDiffLabel", OBJPROP_YDISTANCE, panel_y + 70);
ObjectSetInteger(0, "MaxPosDiffLabel", OBJPROP_COLOR, buy_color);
ObjectCreate(0, "MaxNegDiffLabel", OBJ_LABEL, 0, 0, 0);
ObjectSetString(0, "MaxNegDiffLabel", OBJPROP_TEXT, "Max -Diff: 0");
ObjectSetInteger(0, "MaxNegDiffLabel", OBJPROP_XDISTANCE, panel_x + 10);
ObjectSetInteger(0, "MaxNegDiffLabel", OBJPROP_YDISTANCE, panel_y + 90);
ObjectSetInteger(0, "MaxNegDiffLabel", OBJPROP_COLOR, sell_color);
ObjectCreate(0, movementLabelName, OBJ_LABEL, 0, 0, 0);
ObjectSetString(0, movementLabelName, OBJPROP_TEXT, "Movement: 0 points");
ObjectSetInteger(0, movementLabelName, OBJPROP_XDISTANCE, panel_x + 10);
ObjectSetInteger(0, movementLabelName, OBJPROP_YDISTANCE, panel_y + 110);
ObjectSetInteger(0, movementLabelName, OBJPROP_COLOR, diff_color);
ObjectCreate(0, maxUpMoveLabelName, OBJ_LABEL, 0, 0, 0);
ObjectSetString(0, maxUpMoveLabelName, OBJPROP_TEXT, "Max Up Move: 0 points");
ObjectSetInteger(0, maxUpMoveLabelName, OBJPROP_XDISTANCE, panel_x + 10);
ObjectSetInteger(0, maxUpMoveLabelName, OBJPROP_YDISTANCE, panel_y + 130);
ObjectSetInteger(0, maxUpMoveLabelName, OBJPROP_COLOR, diff_color);
ObjectCreate(0, maxDownMoveLabelName, OBJ_LABEL, 0, 0, 0);
ObjectSetString(0, maxDownMoveLabelName, OBJPROP_TEXT, "Max Down Move: 0 points");
ObjectSetInteger(0, maxDownMoveLabelName, OBJPROP_XDISTANCE, panel_x + 10);
ObjectSetInteger(0, maxDownMoveLabelName, OBJPROP_YDISTANCE, panel_y + 150);
ObjectSetInteger(0, maxDownMoveLabelName, OBJPROP_COLOR, diff_color);
ObjectCreate(0, moveDiffLabelName, OBJ_LABEL, 0, 0, 0);
ObjectSetString(0, moveDiffLabelName, OBJPROP_TEXT, "Move Diff: 0 points");
ObjectSetInteger(0, moveDiffLabelName, OBJPROP_XDISTANCE, panel_x + 10);
ObjectSetInteger(0, moveDiffLabelName, OBJPROP_YDISTANCE, panel_y + 170);
ObjectSetInteger(0, moveDiffLabelName, OBJPROP_COLOR, diff_color);
}
void ResetCounters(datetime startDate = 0)
{
buy_volume = 0;
sell_volume = 0;
current_candle_buy = 0;
current_candle_sell = 0;
maxPositiveDiff = 0;
maxNegativeDiff = 0;
basePrice = SymbolInfoDouble(_Symbol, SYMBOL_BID);
maxUpMove = 0;
maxDownMove = 0;
last_candle_time = 0;
prevPrice = 0;
// Clear candle history
for(int i = 0; i < max_candles_to_show; i++)
{
candle_history[i].buy = 0;
candle_history[i].sell = 0;
candle_history[i].time = 0;
}
if(startDate > 0)
{
int totalBars = iBars(_Symbol, PERIOD_CURRENT);
int startBar = iBarShift(_Symbol, PERIOD_CURRENT, startDate, true);
if(startBar == -1) startBar = totalBars - 1;
double prevClose = 0;
bool firstBar = true;
for(int i = startBar; i >= 0; i--)
{
datetime barTime = iTime(_Symbol, PERIOD_CURRENT, i);
if(barTime < startDate) continue;
double close = iClose(_Symbol, PERIOD_CURRENT, i);
if(!firstBar)
{
if(close > prevClose)
buy_volume++;
else if(close < prevClose)
sell_volume++;
}
else
{
basePrice = close;
firstBar = false;
}
long currentDiff = buy_volume - sell_volume;
if(currentDiff > maxPositiveDiff)
maxPositiveDiff = currentDiff;
if(currentDiff < maxNegativeDiff)
maxNegativeDiff = currentDiff;
double movement = (close - basePrice) / Point;
if(movement > maxUpMove)
maxUpMove = movement;
else if(-movement > maxDownMove)
maxDownMove = -movement;
prevClose = close;
}
prevPrice = prevClose;
}
// Delete existing labels
ObjectDelete(0, current_candle_label_prefix+"B");
ObjectDelete(0, current_candle_label_prefix+"S");
ObjectDelete(0, current_candle_label_prefix+"D");
}
void Update()
{
double lastPrice = SymbolInfoDouble(_Symbol, SYMBOL_LAST);
// Update volumes
if(prevPrice > 0)
{
if(lastPrice > prevPrice)
{
buy_volume++;
current_candle_buy++;
}
else if(lastPrice < prevPrice)
{
sell_volume++;
current_candle_sell++;
}
}
prevPrice = lastPrice;
// Calculate movement in points and pips
double point = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
double movement = (lastPrice - basePrice) / point;
// Update max up and down movement
if (movement > maxUpMove)
maxUpMove = movement;
if (movement < -maxDownMove)
maxDownMove = -movement;
// Update max positive and negative differences
long totalDiff = buy_volume - sell_volume;
if(totalDiff > maxPositiveDiff)
maxPositiveDiff = totalDiff;
if(totalDiff < maxNegativeDiff)
maxNegativeDiff = totalDiff;
// Format labels
string buyText = "Total Buy: " + IntegerToString(buy_volume);
string sellText = "Total Sell: " + IntegerToString(sell_volume);
string diffSign = (buy_volume - sell_volume) >= 0 ? "+" : "";
string diffText = "Total Diff: " + diffSign + IntegerToString(MathAbs(buy_volume - sell_volume));
string maxPosText = "Max +Diff: " + IntegerToString(maxPositiveDiff);
string maxNegText = "Max -Diff: " + IntegerToString(MathAbs(maxNegativeDiff));
string movementText = "Movement: " + DoubleToString(movement, 1) + " points ";
string maxUpMoveText = "Max Up Move: " + DoubleToString(maxUpMove, 1) + " points ";
string maxDownMoveText = "Max Down Move: " + DoubleToString(maxDownMove, 1) + " points ";
string moveDiffText = "Move Diff: " + DoubleToString(maxUpMove + maxDownMove, 1) + " points ";
// Update colors based on difference
if((buy_volume - sell_volume) > 0)
ObjectSetInteger(0, "TotalDiffLabel", OBJPROP_COLOR, buy_color);
else if((buy_volume - sell_volume) < 0)
ObjectSetInteger(0, "TotalDiffLabel", OBJPROP_COLOR, sell_color);
else
ObjectSetInteger(0, "TotalDiffLabel", OBJPROP_COLOR, diff_color);
// Update movement label color based on movement direction
if (movement > 0)
ObjectSetInteger(0, movementLabelName, OBJPROP_COLOR, clrLimeGreen);
else if (movement < 0)
ObjectSetInteger(0, movementLabelName, OBJPROP_COLOR, clrRed);
else
ObjectSetInteger(0, movementLabelName, OBJPROP_COLOR, diff_color);
// Update all labels
ObjectSetString(0, "BuyVolumeLabel", OBJPROP_TEXT, buyText);
ObjectSetString(0, "SellVolumeLabel", OBJPROP_TEXT, sellText);
ObjectSetString(0, "TotalDiffLabel", OBJPROP_TEXT, diffText);
ObjectSetString(0, "MaxPosDiffLabel", OBJPROP_TEXT, maxPosText);
ObjectSetString(0, "MaxNegDiffLabel", OBJPROP_TEXT, maxNegText);
ObjectSetString(0, movementLabelName, OBJPROP_TEXT, movementText);
ObjectSetString(0, maxUpMoveLabelName, OBJPROP_TEXT, maxUpMoveText);
ObjectSetString(0, maxDownMoveLabelName, OBJPROP_TEXT, maxDownMoveText);
ObjectSetString(0, moveDiffLabelName, OBJPROP_TEXT, moveDiffText);
// Update current candle labels
UpdateCurrentCandleDisplay();
// Add label on current candle
DisplayCurrentCandleVolume();
}
void DisplayCurrentCandleVolume()
{
int bar_index = 0; // Current candle
double high = iHigh(_Symbol, PERIOD_CURRENT, bar_index);
datetime time = iTime(_Symbol, PERIOD_CURRENT, bar_index);
// Calculate price position (above candle high)
int window = 0; // Main chart window
// Calculate the x-coordinate based on the chart's properties
int chartWidth = ChartGetInteger(0, CHART_WIDTH_IN_PIXELS);
int visibleBars = ChartGetInteger(0, CHART_VISIBLE_BARS);
double timeDiff = (TimeCurrent() - time) / PeriodSeconds(PERIOD_CURRENT);
//int x = chartWidth - (int)(timeDiff * chartWidth / visibleBars);
long x = chartWidth - (long)(timeDiff * chartWidth / visibleBars);
// Introduce offsets to move the label
int x_offset = 50; // Adjust this value to move the label further left or right
int y_offset = 100; // Adjust this value to move the label further up or down
x -= x_offset;
// Convert price to y-coordinate
int y = (int)((ChartGetDouble(0, CHART_PRICE_MAX, window) - high) /
(ChartGetDouble(0, CHART_PRICE_MAX, window) - ChartGetDouble(0, CHART_PRICE_MIN, window)) *
ChartGetInteger(0, CHART_HEIGHT_IN_PIXELS, window));
// Adjust y-coordinate with offset
y -= y_offset;
// Calculate difference
long diff = current_candle_buy - current_candle_sell;
string diff_sign = diff >= 0 ? "+" : "";
// Create current candle volume display
CreateSmallLabel(current_candle_label_prefix+"B", "B:"+IntegerToString(current_candle_buy), x, y, buy_color);
CreateSmallLabel(current_candle_label_prefix+"S", "S:"+IntegerToString(current_candle_sell), x, y+15, sell_color);
CreateSmallLabel(current_candle_label_prefix+"D", "D:"+diff_sign+IntegerToString(diff), x, y+30,
diff >= 0 ? buy_color : sell_color);
}
void UpdateCandleDisplays()
{
// Clear existing candle displays
ObjectsDeleteAll(0, "CandleVol_");
// Display volume for each historical candle
for(int i = 0; i < max_candles_to_show; i++)
{
if(candle_history[i].time > 0)
{
DisplayCandleVolume(i, candle_history[i].buy, candle_history[i].sell, candle_history[i].time);
}
}
}
void DisplayCandleVolume(int index, long buy_vol, long sell_vol, datetime candle_time)
{
int bar_index = iBarShift(_Symbol, PERIOD_CURRENT, candle_time);
if(bar_index < 0) return;
double high = iHigh(_Symbol, PERIOD_CURRENT, bar_index);
double low = iLow(_Symbol, PERIOD_CURRENT, bar_index);
datetime time = iTime(_Symbol, PERIOD_CURRENT, bar_index);
// Calculate price position (above candle high)
int window = 0; // Main chart window
// Calculate the x-coordinate based on the chart's properties
int chartWidth = ChartGetInteger(0, CHART_WIDTH_IN_PIXELS);
int visibleBars = ChartGetInteger(0, CHART_VISIBLE_BARS);
double timeDiff = (TimeCurrent() - time) / PeriodSeconds(PERIOD_CURRENT);
//int x = chartWidth - (int)(timeDiff * chartWidth / visibleBars);
long x = chartWidth - (long)(timeDiff * chartWidth / visibleBars);
// Introduce offsets to move the label
int x_offset = 50;
int y_offset = 100;
x -= x_offset;
// Convert price to y-coordinate
int y = (int)((ChartGetDouble(0, CHART_PRICE_MAX, window) - high) /
(ChartGetDouble(0, CHART_PRICE_MAX, window) - ChartGetDouble(0, CHART_PRICE_MIN, window)) *
ChartGetInteger(0, CHART_HEIGHT_IN_PIXELS, window));
// Adjust y-coordinate with offset
y -= y_offset;
// Calculate difference
long diff = buy_vol - sell_vol;
string diff_sign = diff >= 0 ? "+" : "";
// Create candle volume display
string prefix = "CandleVol_"+IntegerToString(index)+"_";
CreateSmallLabel(prefix+"B", "B:"+IntegerToString(buy_vol), x, y, buy_color);
CreateSmallLabel(prefix+"S", "S:"+IntegerToString(sell_vol), x, y+15, sell_color);
CreateSmallLabel(prefix+"D", "D:"+diff_sign+IntegerToString(diff), x, y+30,
diff >= 0 ? buy_color : sell_color);
}
void CreateSmallLabel(string name, string text, int x, int y, color clr)
{
ObjectCreate(0, name, OBJ_LABEL, 0, 0, 0);
ObjectSetString(0, name, OBJPROP_TEXT, text);
ObjectSetInteger(0, name, OBJPROP_XDISTANCE, x);
ObjectSetInteger(0, name, OBJPROP_YDISTANCE, y);
ObjectSetInteger(0, name, OBJPROP_COLOR, clr);
ObjectSetInteger(0, name, OBJPROP_FONTSIZE, 8);
ObjectSetInteger(0, name, OBJPROP_ANCHOR, CORNER_LEFT_UPPER);
}
void UpdateCurrentCandleDisplay()
{
long candleDiff = current_candle_buy - current_candle_sell;
string diffSign = candleDiff >= 0 ? "+" : "";
ObjectSetString(0, "CurrentBuyLabel", OBJPROP_TEXT, "Current Candle Buy: "+IntegerToString(current_candle_buy));
ObjectSetString(0, "CurrentSellLabel", OBJPROP_TEXT, "Current Candle Sell: "+IntegerToString(current_candle_sell));
ObjectSetString(0, "CurrentDiffLabel", OBJPROP_TEXT, "Current Diff: "+diffSign+IntegerToString(candleDiff));
ObjectSetInteger(0, "CurrentDiffLabel", OBJPROP_COLOR, candleDiff >= 0 ? buy_color : sell_color);
}
void Destroy()
{
// Delete all objects
string main_labels[] = {
"BuyVolumeLabel", "SellVolumeLabel", "TotalDiffLabel",
"MaxPosDiffLabel", "MaxNegDiffLabel",
"CurrentBuyLabel", "CurrentSellLabel", "CurrentDiffLabel",
"SepLabel", movementLabelName, maxUpMoveLabelName, maxDownMoveLabelName, moveDiffLabelName
};
for(int i = 0; i < ArraySize(main_labels); i++)
ObjectDelete(0, main_labels[i]);
ObjectsDeleteAll(0, "CandleVol_");
ObjectsDeleteAll(0, current_candle_label_prefix);
}
};
//+------------------------------------------------------------------+
//| Global Variables |
//+------------------------------------------------------------------+
CPanel gui;
CVolumeIndicator volumeIndicator;
double currentLotSize = 0.05;
int currentSlippage = 3;
int numberOfTrades = 1;
double currentStopLoss = 200.0;
double currentTakeProfit = 75.0;
double currentTrailingStop = 0.0;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
// Create trading panel
gui.Create("TradingPanel", 180);
gui.AddLabel("title", "Trading Terminal", 5, 20, clrWhite);
gui.AddLabel("lotLabel", "Lot Size:", 5, 40, clrWhite);
gui.AddEdit("lotEdit", DoubleToString(currentLotSize, 2), 100, 38, 80);
gui.AddLabel("tradesLabel", "No. of Trades:", 5, 70, clrWhite);
gui.AddEdit("tradesEdit", IntegerToString(numberOfTrades), 100, 68, 80);
gui.AddLabel("slippageLabel", "Slippage (points):", 5, 100, clrWhite);
gui.AddEdit("slippageEdit", IntegerToString(currentSlippage), 100, 98, 80);
gui.AddLabel("slLabel", "Stop Loss :", 5, 130, clrWhite);
gui.AddEdit("slEdit", DoubleToString(currentStopLoss, 1), 100, 128, 80);
gui.AddLabel("tpLabel", "Take Profit :", 5, 160, clrWhite);
gui.AddEdit("tpEdit", DoubleToString(currentTakeProfit, 1), 100, 158, 80);
gui.AddLabel("tsLabel", "Trailing Stop :", 5, 190, clrWhite);
gui.AddEdit("tsEdit", DoubleToString(currentTrailingStop, 1), 100, 188, 80);
// Add Start Date input
gui.AddLabel("startDateLabel", "Start Date (YYYY.MM.DD HH:MM):", 5, 220, clrWhite);
gui.AddEdit("startDateEdit", "2024.01.01 00:00", 100, 218, 150);
gui.AddButton("btnBuy", "BUY", 10, 250, 85, 30, clrLime, clrWhite);
gui.AddButton("btnSell", "SELL", 105, 250, 85, 30, clrRed, clrWhite);
gui.AddButton("btnBuySell", "BUY & SELL", 10, 290, 170, 30, clrBlue, clrWhite);
gui.AddLabel("status", "Ready", 10, 330, clrWhite);
// Create volume indicator
volumeIndicator.Create(200, 20, clrBlack, clrLime, clrRed);
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
gui.Destroy();
volumeIndicator.Destroy();
}
//+------------------------------------------------------------------+
//| Chart event handler |
//+------------------------------------------------------------------+
void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam)
{
if(id == CHARTEVENT_OBJECT_CLICK)
{
currentLotSize = StringToDouble(gui.GetEditValue("lotEdit"));
numberOfTrades = (int)StringToInteger(gui.GetEditValue("tradesEdit"));
currentSlippage = (int)StringToInteger(gui.GetEditValue("slippageEdit"));
currentStopLoss = StringToDouble(gui.GetEditValue("slEdit"));
currentTakeProfit = StringToDouble(gui.GetEditValue("tpEdit"));
currentTrailingStop = StringToDouble(gui.GetEditValue("tsEdit"));
if(sparam == "TradingPanel_btnBuy")
{
double price = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
for(int i = 0; i < numberOfTrades; i++)
{
if(!ExecuteTrade(ORDER_TYPE_BUY, currentLotSize, price, currentSlippage, 123456, currentStopLoss, currentTakeProfit, currentTrailingStop))
{
gui.UpdateLabel("status", "Buy order failed", clrRed);
return;
}
}
gui.UpdateLabel("status", "Buy orders executed", clrLime);
}
else if(sparam == "TradingPanel_btnSell")
{
double price = SymbolInfoDouble(_Symbol, SYMBOL_BID);
for(int i = 0; i < numberOfTrades; i++)
{
if(!ExecuteTrade(ORDER_TYPE_SELL, currentLotSize, price, currentSlippage, 123456, currentStopLoss, currentTakeProfit, currentTrailingStop))
{
gui.UpdateLabel("status", "Sell order failed", clrRed);
return;
}
}
gui.UpdateLabel("status", "Sell orders executed", clrRed);
}
else if(sparam == "TradingPanel_btnBuySell")
{
double askPrice = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
double bidPrice = SymbolInfoDouble(_Symbol, SYMBOL_BID);
bool buySuccess = true;
bool sellSuccess = true;
for(int i = 0; i < numberOfTrades; i++)
{
if(!ExecuteTrade(ORDER_TYPE_BUY, currentLotSize, askPrice, currentSlippage, 123456, currentStopLoss, currentTakeProfit, currentTrailingStop))
{
buySuccess = false;
break;
}
}
for(int i = 0; i < numberOfTrades; i++)
{
if(!ExecuteTrade(ORDER_TYPE_SELL, currentLotSize, bidPrice, currentSlippage, 123456, currentStopLoss, currentTakeProfit, currentTrailingStop))
{
sellSuccess = false;
break;
}
}
if(buySuccess && sellSuccess)
gui.UpdateLabel("status", "Buy & Sell orders executed", clrBlue);
else if (!buySuccess && !sellSuccess)
gui.UpdateLabel("status", "Both Buy & Sell failed", clrRed);
else if (!buySuccess)
gui.UpdateLabel("status", "Buy failed, Sell succeeded", clrOrange);
else
gui.UpdateLabel("status", "Sell failed, Buy succeeded", clrOrange);
}
}
else if(id == CHARTEVENT_OBJECT_END_EDIT)
{
if(sparam == "TradingPanel_startDateEdit")
{
string dateStr = gui.GetEditValue("startDateEdit");
datetime startDate = StringToTime(dateStr);
if(startDate == 0)
{
gui.UpdateLabel("status", "Invalid date. Use YYYY.MM.DD HH:MM", clrRed);
return;
}
volumeIndicator.ResetCounters(startDate);
gui.UpdateLabel("status", "Data loaded from "+dateStr, clrGreen);
}
}
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
volumeIndicator.Update();
}
//+------------------------------------------------------------------+
//| ExecuteTrade function (now uses POINTS instead of PIPS) |
//+------------------------------------------------------------------+
bool ExecuteTrade(ENUM_ORDER_TYPE type, double lot, double price, int slippage_points, ulong magic_number,
double stopLossPoints, double takeProfitPoints, double trailingStopPoints)
{
if (lot <= 0 || price <= 0)
{
Print("Invalid trade parameters: lot size = ", lot, ", price = ", price);
return false;
}
MqlTradeRequest request;
ZeroMemory(request);
request.action = TRADE_ACTION_DEAL;
request.symbol = _Symbol;
request.volume = lot;
request.type = type;
request.price = NormalizeDouble(price, (int)SymbolInfoInteger(_Symbol, SYMBOL_DIGITS));
request.deviation = slippage_points;
request.magic = magic_number;
double point = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
int digits = (int)SymbolInfoInteger(_Symbol, SYMBOL_DIGITS);
double sl = 0, tp = 0;
// Get broker's minimum stop level
int stopLevelPoints = (int)SymbolInfoInteger(_Symbol, SYMBOL_TRADE_STOPS_LEVEL);
double stopLevel = stopLevelPoints * point;
//--- Calculate Stop Loss using POINTS
if (stopLossPoints > 0)
{
double sl_distance = stopLossPoints * point;
if (sl_distance >= stopLevel)
{
sl = (type == ORDER_TYPE_BUY) ? price - sl_distance : price + sl_distance;
sl = NormalizeDouble(sl, digits);
request.sl = sl;
}
else
{
Print("Stop Loss too close to market. Minimum required: ", stopLevelPoints, " points.");
}
}
//--- Calculate Take Profit using POINTS
if (takeProfitPoints > 0)
{
double tp_distance = takeProfitPoints * point;
if (tp_distance >= stopLevel)
{
tp = (type == ORDER_TYPE_BUY) ? price + tp_distance : price - tp_distance;
tp = NormalizeDouble(tp, digits);
request.tp = tp;
}
else
{
Print("Take Profit too close to market. Minimum required: ", stopLevelPoints, " points.");
}
}
//--- Try supported filling modes
ENUM_ORDER_TYPE_FILLING filling_modes[] = {ORDER_FILLING_IOC, ORDER_FILLING_RETURN, ORDER_FILLING_FOK};
MqlTradeResult result;
ZeroMemory(result);
for (int i = 0; i < ArraySize(filling_modes); i++)
{
request.type_filling = filling_modes[i];
if (OrderSend(request, result))
{
Print("Trade executed successfully. Order ID: ", result.order, ", using filling mode: ", request.type_filling);
Print("Price: ", price, ", SL: ", sl, ", TP: ", tp, " (Inputs were in POINTS)");
return true;
}
else
{
Print("Trade failed with filling mode ", request.type_filling, ": ", GetRetcodeDescription(result.retcode));
}
}
Print("All filling modes failed.");
return false;
}
//+------------------------------------------------------------------+
//| Error code translator |
//+------------------------------------------------------------------+
string GetRetcodeDescription(int retcode)
{
switch(retcode)
{
case 10004: return "Requote";
case 10006: return "Order rejected";
case 10007: return "Order canceled";
case 10008: return "Order placed";
case 10009: return "Order completed";
case 10010: return "Order partially completed";
case 10014: return "Invalid volume";
case 10015: return "Invalid price";
case 10016: return "Invalid stops";
case 10017: return "Trade is disabled";
case 10018: return "Market closed";
case 10019: return "No prices";
case 10020: return "Too many requests";
default: return "Unknown error code: " + IntegerToString(retcode);
}
}
error:
'onclick-new-test.mq5' 1
';' - open parenthesis expected onclick-new-test.mq5 266 58
possible loss of data due to type conversion from 'long' to 'int' onclick-new-test.mq5 380 22
possible loss of data due to type conversion from 'long' to 'int' onclick-new-test.mq5 381 23
possible loss of data due to type conversion from 'datetime' to 'double' onclick-new-test.mq5 382 23
possible loss of data due to type conversion from 'long' to 'int' onclick-new-test.mq5 404 99
possible loss of data due to type conversion from 'long' to 'int' onclick-new-test.mq5 405 100
possible loss of data due to type conversion from 'long' to 'int' onclick-new-test.mq5 406 95
possible loss of data due to type conversion from 'long' to 'int' onclick-new-test.mq5 438 23
possible loss of data due to type conversion from 'long' to 'int' onclick-new-test.mq5 439 24
possible loss of data due to type conversion from 'datetime' to 'double' onclick-new-test.mq5 440 24
possible loss of data due to type conversion from 'long' to 'int' onclick-new-test.mq5 463 68
possible loss of data due to type conversion from 'long' to 'int' onclick-new-test.mq5 464 69
possible loss of data due to type conversion from 'long' to 'int' onclick-new-test.mq5 465 75
1 errors, 12 warnings 2 13