SonnyPanel/SonnyPanelGood/EA/aline.mq5
sbruyneeel df7002ab95
2026-01-28 14:50:18 +01:00

159 lines
No EOL
9.5 KiB
MQL5

#property strict
#include <Trade/Trade.mqh>
CTrade trade;
//--- object names
string BTN_NAME = "CreateLineButton";
string LINE_NAME = "EntryLine";
//--- trend settings
input int TrendPeriod = 50;
int ma_handle = INVALID_HANDLE;
//+------------------------------------------------------------------+
//| Expert initialization |
//+------------------------------------------------------------------+
int OnInit()
{
CreateButton();
ma_handle = iMA(_Symbol, _Period, TrendPeriod, 0, MODE_SMA, PRICE_CLOSE);
if(ma_handle == INVALID_HANDLE)
{
Print("MA handle creation failed");
return INIT_FAILED;
}
return INIT_SUCCEEDED;
}
//+------------------------------------------------------------------+
//| Expert deinitialization |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
ObjectDelete(0, BTN_NAME);
ObjectDelete(0, LINE_NAME);
}
//+------------------------------------------------------------------+
//| Create button |
//+------------------------------------------------------------------+
void CreateButton()
{
if(ObjectFind(0, BTN_NAME) != -1)
return;
if(!ObjectCreate(0, BTN_NAME, OBJ_BUTTON, 0, 0, 0))
{
Print("Failed to create button");
return;
}
ObjectSetInteger(0, BTN_NAME, OBJPROP_XDISTANCE, 10);
ObjectSetInteger(0, BTN_NAME, OBJPROP_YDISTANCE, 20);
ObjectSetInteger(0, BTN_NAME, OBJPROP_XSIZE, 140);
ObjectSetInteger(0, BTN_NAME, OBJPROP_YSIZE, 30);
ObjectSetString(0, BTN_NAME, OBJPROP_TEXT, "Add Entry Line");
ObjectSetInteger(0, BTN_NAME, OBJPROP_COLOR, clrWhite);
ObjectSetInteger(0, BTN_NAME, OBJPROP_BGCOLOR, clrBlue);
ObjectSetInteger(0, BTN_NAME, OBJPROP_BORDER_COLOR, clrBlack);
}
//+------------------------------------------------------------------+
//| Create draggable horizontal line |
//+------------------------------------------------------------------+
void CreateEntryLine()
{
if(ObjectFind(0, LINE_NAME) != -1)
return;
double price = SymbolInfoDouble(_Symbol, SYMBOL_BID);
if(!ObjectCreate(0, LINE_NAME, OBJ_HLINE, 0, 0, price))
{
Print("Failed to create line");
return;
}
ObjectSetInteger(0, LINE_NAME, OBJPROP_COLOR, clrRed);
ObjectSetInteger(0, LINE_NAME, OBJPROP_WIDTH, 2);
ObjectSetInteger(0, LINE_NAME, OBJPROP_SELECTABLE, true);
ObjectSetInteger(0, LINE_NAME, OBJPROP_SELECTED, true);
}
//+------------------------------------------------------------------+
//| Chart event handler |
//+------------------------------------------------------------------+
void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam)
{
if(id == CHARTEVENT_OBJECT_CLICK)
{
Print("ChartEvent: clicked object = ", sparam);
if(sparam == BTN_NAME)
{
Print("Button clicked → creating line");
CreateEntryLine();
}
}
}
//+------------------------------------------------------------------+
//| Trend direction using MA |
//+------------------------------------------------------------------+
int GetTrendDirection()
{
if(ma_handle == INVALID_HANDLE)
return 0;
double ma_buf[1];
if(CopyBuffer(ma_handle, 0, 0, 1, ma_buf) != 1)
return 0;
double ma = ma_buf[0];
double price = SymbolInfoDouble(_Symbol, SYMBOL_BID);
if(price > ma) return 1; // uptrend
if(price < ma) return -1; // downtrend
return 0;
}
//+------------------------------------------------------------------+
//| OnTick: keep UI alive + trade logic |
//+------------------------------------------------------------------+
void OnTick()
{
// In tester, chart can reset → ensure button exists
if(ObjectFind(0, BTN_NAME) == -1)
CreateButton();
if(ObjectFind(0, LINE_NAME) == -1)
return;
double linePrice = ObjectGetDouble(0, LINE_NAME, OBJPROP_PRICE);
double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
int trend = GetTrendDirection();
if(trend == 0)
return;
if((trend == 1 && ask >= linePrice) || (trend == -1 && bid <= linePrice))
{
double lot = 0.1;
if(trend == 1)
{
Print("Buying at line touch");
trade.Buy(lot, _Symbol);
}
else
{
Print("Selling at line touch");
trade.Sell(lot, _Symbol);
}
ObjectDelete(0, LINE_NAME);
}
}