0% found this document useful (0 votes)
9 views7 pages

Martingale

Uploaded by

ajisukasurga
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
9 views7 pages

Martingale

Uploaded by

ajisukasurga
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 7

//+------------------------------------------------------------------+

//| Custom Buy Sell EA with Martingale & Stats |


//+------------------------------------------------------------------+
#property strict
#property version "1.10"
#property copyright "OpenAI Enhanced Version"
#property link "https://www.mql5.com"

//--- input parameters


input group "Signal Settings"
input int DominanceThreshold = 3;
input ENUM_TIMEFRAMES SignalTimeframe = PERIOD_M1;

input group "Risk Management"


input double LotSize = 0.01;
input int TakeProfitPips = 1000;
input int StopLossPips = 2000;
input int TrailingStopPips = 200;
input int TrailingStartPips = 1200;

input group "Alert Settings"


input bool EnableAlerts = true;

//--- global variables


datetime lastCandleTime = 0;

double CurrentLot = 0.0;


int MartingaleLevel = 0;
int MaxMartingaleLevel = 8;

int TotalWins = 0;
int TotalLosses = 0;
int TotalTrades = 0;
double TotalProfitUSD = 0.0;
double TotalLossUSD = 0.0;

string lotFileName = "martingale_lot.txt";


string statsFile = "martingale_stats.txt";

//+------------------------------------------------------------------+
//| Expert initialization |
//+------------------------------------------------------------------+
int OnInit()
{
LoadLotFromFile();
LoadStatsFromFile();
PrintStats();
return INIT_SUCCEEDED;
}

//+------------------------------------------------------------------+
//| Expert tick |
//+------------------------------------------------------------------+
void OnTick()
{
datetime currentCandleTime = iTime(_Symbol, _Period, 0);
if(currentCandleTime == lastCandleTime)
return;
lastCandleTime = currentCandleTime;

UpdateLotBasedOnLastTrade();
CheckForSignals();
ManageTrailingStop();
DisplayStatsOnChart();
}

//+------------------------------------------------------------------+
//| Check for trading signals |
//+------------------------------------------------------------------+
void CheckForSignals()
{
double open[], close[];
ArraySetAsSeries(open, true);
ArraySetAsSeries(close, true);

if(CopyOpen(_Symbol, SignalTimeframe, 0, 5, open) < 5 ||


CopyClose(_Symbol, SignalTimeframe, 0, 5, close) < 5)
return;

int bullishCount = 0;
int bearishCount = 0;

for(int i = 1; i <= 4; i++)


{
if(close[i] > open[i]) bullishCount++;
else if(close[i] < open[i]) bearishCount++;
}

if(bullishCount >= DominanceThreshold)


PlaceOrder(ORDER_TYPE_BUY);

if(bearishCount >= DominanceThreshold)


PlaceOrder(ORDER_TYPE_SELL);
}

//+------------------------------------------------------------------+
//| Place market order |
//+------------------------------------------------------------------+
void PlaceOrder(ENUM_ORDER_TYPE orderType)
{
if(PositionSelect(_Symbol))
{
Print("Position already open for ", _Symbol);
return;
}

double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);


double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
double price = (orderType == ORDER_TYPE_BUY) ? ask : bid;

double stopLoss = 0, takeProfit = 0;


if(orderType == ORDER_TYPE_BUY)
{
stopLoss = price - StopLossPips * _Point;
takeProfit = price + TakeProfitPips * _Point;
}
else
{
stopLoss = price + StopLossPips * _Point;
takeProfit = price - TakeProfitPips * _Point;
}

MqlTradeRequest request = {};


request.action = TRADE_ACTION_DEAL;
request.symbol = _Symbol;
request.volume = CurrentLot;
request.type = orderType;
request.price = price;
request.sl = stopLoss;
request.tp = takeProfit;
request.deviation = 10;
request.magic = 12345;
request.comment = "M1_Dominance_Martingale";

MqlTradeResult result = {};


if(!OrderSend(request, result))
{
Print("OrderSend failed. Code: ", result.retcode);
}
else if(EnableAlerts)
{
Alert("Order placed: ", EnumToString(orderType), " at ", price);
}
}

//+------------------------------------------------------------------+
//| Trailing stop management |
//+------------------------------------------------------------------+
void ManageTrailingStop()
{
if(TrailingStopPips <= 0 || !PositionSelect(_Symbol)) return;

ulong ticket = PositionGetInteger(POSITION_TICKET);


double entryPrice = PositionGetDouble(POSITION_PRICE_OPEN);
int posType = (int)PositionGetInteger(POSITION_TYPE);
double currentPrice = (posType == POSITION_TYPE_BUY) ?
SymbolInfoDouble(_Symbol, SYMBOL_BID) :
SymbolInfoDouble(_Symbol, SYMBOL_ASK);

double profitPips = MathAbs((currentPrice - entryPrice) / _Point);


if(profitPips < TrailingStartPips) return;

double currentSL = PositionGetDouble(POSITION_SL);


double newSL = 0;

if(posType == POSITION_TYPE_BUY)
{
newSL = currentPrice - TrailingStopPips * _Point;
if(newSL > currentSL)
ModifyPosition(ticket, newSL);
}
else
{
newSL = currentPrice + TrailingStopPips * _Point;
if(newSL < currentSL || currentSL == 0)
ModifyPosition(ticket, newSL);
}
}

//+------------------------------------------------------------------+
//| Modify SL only |
//+------------------------------------------------------------------+
void ModifyPosition(ulong ticket, double newSL)
{
MqlTradeRequest request = {};
request.action = TRADE_ACTION_SLTP;
request.position = ticket;
request.sl = newSL;
request.tp = 0;

MqlTradeResult result = {};


if(!OrderSend(request, result))
Print("Modify SL failed. Code: ", result.retcode);
else if(EnableAlerts)
Alert("Stop Loss modified to ", newSL);
}

//+------------------------------------------------------------------+
//| Update Martingale Lot |
//+------------------------------------------------------------------+
void UpdateLotBasedOnLastTrade()
{
// Select last week history
datetime fromTime = TimeCurrent() - 7 * 86400;
datetime toTime = TimeCurrent();

if(!HistorySelect(fromTime, toTime))
return;

ulong lastTicket = 0;
datetime lastTime = 0;

int dealsTotal = HistoryDealsTotal();


for(int i = dealsTotal - 1; i >= 0; i--)
{
ulong ticket = HistoryDealGetTicket(i);
if(HistoryDealGetString(ticket, DEAL_SYMBOL) != _Symbol)
continue;
datetime dealTime = (datetime)HistoryDealGetInteger(ticket, DEAL_TIME);
if(dealTime > lastTime)
{
lastTime = dealTime;
lastTicket = ticket;
}
}

if(lastTicket == 0)
{
CurrentLot = LotSize;
MartingaleLevel = 0;
return;
}

double profit = HistoryDealGetDouble(lastTicket, DEAL_PROFIT);


TotalTrades++;

if(profit >= 0)
{
TotalWins++;
TotalProfitUSD += profit;
MartingaleLevel = 0;
CurrentLot = LotSize;
}
else
{
TotalLosses++;
TotalLossUSD += profit;
if(MartingaleLevel < MaxMartingaleLevel)
MartingaleLevel++;
CurrentLot = LotSize * MathPow(2, MartingaleLevel);
}

// Safety cap max lot size (adjust as needed)


if(CurrentLot > 10.0)
CurrentLot = 10.0;

SaveLotToFile();
SaveStatsToFile();
PrintStats();
}

//+------------------------------------------------------------------+
//| File Save/Load |
//+------------------------------------------------------------------+
void SaveLotToFile()
{
int file = FileOpen(lotFileName, FILE_WRITE|FILE_TXT);
if(file != INVALID_HANDLE)
{
FileWrite(file, DoubleToString(CurrentLot, 2));
FileWrite(file, IntegerToString(MartingaleLevel));
FileClose(file);
}
}

void LoadLotFromFile()
{
int file = FileOpen(lotFileName, FILE_READ|FILE_TXT);
if(file != INVALID_HANDLE)
{
string l = FileReadString(file);
string lv = FileReadString(file);
FileClose(file);
CurrentLot = StringToDouble(l);
MartingaleLevel = StringToInteger(lv);
if(CurrentLot <= 0) CurrentLot = LotSize;
}
else
{
CurrentLot = LotSize;
MartingaleLevel = 0;
}
}
void SaveStatsToFile()
{
int file = FileOpen(statsFile, FILE_WRITE|FILE_TXT);
if(file != INVALID_HANDLE)
{
FileWrite(file, TotalTrades);
FileWrite(file, TotalWins);
FileWrite(file, TotalLosses);
FileWrite(file, TotalProfitUSD);
FileWrite(file, TotalLossUSD);
FileClose(file);
}
}

void LoadStatsFromFile()
{
int file = FileOpen(statsFile, FILE_READ|FILE_TXT);
if(file != INVALID_HANDLE)
{
TotalTrades = FileReadInteger(file);
TotalWins = FileReadInteger(file);
TotalLosses = FileReadInteger(file);
TotalProfitUSD = FileReadDouble(file);
TotalLossUSD = FileReadDouble(file);
FileClose(file);
}
}

//+------------------------------------------------------------------+
//| Print Statistik ke Log |
//+------------------------------------------------------------------+
void PrintStats()
{
double winRate = (TotalTrades > 0) ? (100.0 * TotalWins / TotalTrades) : 0.0;
PrintFormat("Martingale Stats: Trades=%d Wins=%d Losses=%d WinRate=%.2f%%
Profit=%.2f Loss=%.2f Lot=%.2f Level=%d",
TotalTrades, TotalWins, TotalLosses, winRate, TotalProfitUSD,
TotalLossUSD, CurrentLot, MartingaleLevel);
}

//+------------------------------------------------------------------+
//| Display statistik di chart |
//+------------------------------------------------------------------+
void DisplayStatsOnChart()
{
double winRate = (TotalTrades > 0) ? (100.0 * TotalWins / TotalTrades) : 0.0;

string dashboard =
"📊 Martingale Stats\n" +
"Total Trades: " + IntegerToString(TotalTrades) + "\n" +
"Wins: " + IntegerToString(TotalWins) +
" | Losses: " + IntegerToString(TotalLosses) + "\n" +
"Win Rate: " + DoubleToString(winRate, 2) + "%\n" +
"Profit: $" + DoubleToString(TotalProfitUSD, 2) +
" | Loss: $" + DoubleToString(TotalLossUSD, 2) + "\n" +
"Current Lot: " + DoubleToString(CurrentLot, 2) +
" (Level " + IntegerToString(MartingaleLevel) + ")";
Comment(dashboard);
}
//+------------------------------------------------------------------+

You might also like