TP 300, (optimize of TP 2000)
unknown
plain_text
3 months ago
15 kB
10
Indexable
//+------------------------------------------------------------------+
//| HedgingGrid_v4.mq5 |
//| CODE GOC NGUYEN BAN + Magic Number + Daily Reset |
//| KHONG thay doi bat ky tham so nao cua code goc |
//+------------------------------------------------------------------+
#property copyright "Hedging Grid v4"
#property version "4.00"
#property strict
#include <Trade\Trade.mqh>
#include <Trade\DealInfo.mqh>
CTrade trade;
CDealInfo m_deal;
//+------------------------------------------------------------------+
//| INPUTS - Chi them Magic va Daily Reset |
//+------------------------------------------------------------------+
input int InpMagic = 999777; // Magic Number
input double InpEntryVol = 0.01; // Lot (nhu code goc)
input double InpReverseDist = 1.0; // Dao chieu khi lo $ (code goc = 1)
input double InpSL_Dist = 1.0; // SL cach entry $ (code goc = 1)
input double InpExpectedTP = 300.0; // TP equity/ngay (giam de hit nhanh hon)
input double InpExpectedSL = 500.0; // SL equity/ngay (rong hon TP de cho EA hoi phuc)
input bool InpDailyReset = true; // [MOI] Reset moi ngay
input bool InpStartBuy = true; // Bat dau bang BUY
input int InpMaxPositions = 30; // [MOI] Gioi han so lenh toi da
//+------------------------------------------------------------------+
//| GLOBALS - Giong code goc |
//+------------------------------------------------------------------+
bool IsBuy;
double EntryVol;
double BID = 0;
double ASK = 0;
bool flag = true;
bool trading = true;
double initBalance = 0;
bool NEED_TO_CLOSE_ALL = false;
double lowestBalance = 0;
int total = 0;
// [MOI] Daily tracking
datetime g_todayDate = 0;
double g_dayStartBal = 0;
int g_totalDays = 0;
int g_daysTP = 0;
int g_daysSL = 0;
//+------------------------------------------------------------------+
int OnInit()
{
trade.SetExpertMagicNumber(InpMagic);
trade.SetDeviationInPoints(50);
IsBuy = InpStartBuy;
EntryVol = InpEntryVol;
initBalance = AccountInfoDouble(ACCOUNT_BALANCE);
lowestBalance = initBalance;
trading = true;
NEED_TO_CLOSE_ALL = false;
total = 0;
// Init daily
g_todayDate = 0;
g_dayStartBal = initBalance;
MqlTick tick;
if(SymbolInfoTick(_Symbol, tick))
{
BID = tick.bid;
ASK = tick.ask;
Print(BID, " | ", ASK);
// Mo lenh dau tien (nhu code goc)
if(IsBuy && PositionsTotal() == 0)
{
Print("Buy");
trade.Buy(EntryVol, _Symbol, ASK, ASK - InpSL_Dist);
}
}
Print("=============================================");
Print(" HEDGING GRID v4 | CODE GOC + DAILY RESET");
Print(" Lot: ", EntryVol, " | Reverse: $", InpReverseDist);
Print(" TP: $", InpExpectedTP, " | SL: $", InpExpectedSL);
Print(" Daily Reset: ", InpDailyReset);
Print("=============================================");
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
Print("========= TONG KET =========");
Print("THE INIT BALANCE IS: ", initBalance);
Print("THE LOWEST BALANCE IS: ", lowestBalance);
Print("Max Position: ", total);
Print("Total Days: ", g_totalDays);
Print("Days TP: ", g_daysTP);
Print("Days SL: ", g_daysSL);
Print("Final Balance: ", AccountInfoDouble(ACCOUNT_BALANCE));
}
//+------------------------------------------------------------------+
//| [MOI] Check ngay moi va reset |
//+------------------------------------------------------------------+
void CheckDailyReset()
{
if(!InpDailyReset) return;
MqlDateTime dt;
TimeCurrent(dt);
datetime today = (datetime)(TimeCurrent() - dt.hour*3600 - dt.min*60 - dt.sec);
if(today == g_todayDate) return;
// === NGAY MOI ===
if(g_todayDate > 0)
{
// Log ngay cu
double endBal = AccountInfoDouble(ACCOUNT_BALANCE);
Print("[DAY END] Balance: $", DoubleToString(endBal,2),
" | Day PnL: $", DoubleToString(endBal - g_dayStartBal, 2));
}
g_todayDate = today;
g_dayStartBal = AccountInfoDouble(ACCOUNT_BALANCE);
g_totalDays++;
// Reset trang thai giao dich (nhu khi moi khoi dong EA)
trading = true;
NEED_TO_CLOSE_ALL = false;
IsBuy = InpStartBuy;
EntryVol = InpEntryVol;
if(g_dayStartBal < lowestBalance)
lowestBalance = g_dayStartBal;
Print("[NEW DAY] #", g_totalDays,
" | Balance: $", DoubleToString(g_dayStartBal, 2));
}
//+------------------------------------------------------------------+
//| OnTick - LOGIC CODE GOC NGUYEN BAN |
//+------------------------------------------------------------------+
void OnTick()
{
// [MOI] Check ngay moi
CheckDailyReset();
if(PositionsTotal() > total)
total = PositionsTotal();
double balance = AccountInfoDouble(ACCOUNT_BALANCE);
double profit = AccountInfoDouble(ACCOUNT_PROFIT);
// [MOI] Dung dayStartBal thay vi initBalance
double refBal = InpDailyReset ? g_dayStartBal : initBalance;
// TP check (nhu code goc)
if(balance + profit >= refBal + InpExpectedTP || NEED_TO_CLOSE_ALL)
{
trading = false;
CloseAllCurrentPosition();
if(InpDailyReset && !NEED_TO_CLOSE_ALL)
{
g_daysTP++;
Print("[DAILY TP] +$", DoubleToString(balance + profit - refBal, 2));
}
NEED_TO_CLOSE_ALL = true;
}
// SL check (nhu code goc)
if(balance + profit <= refBal - InpExpectedSL || NEED_TO_CLOSE_ALL)
{
if(!NEED_TO_CLOSE_ALL) // Chi dem 1 lan
{
trading = false;
CloseAllCurrentPosition();
if(InpDailyReset)
{
g_daysSL++;
Print("[DAILY SL] -$", DoubleToString(refBal - (balance + profit), 2));
}
NEED_TO_CLOSE_ALL = true;
}
}
if(lowestBalance > balance)
lowestBalance = balance;
if(!trading) return;
// === LOGIC CODE GOC NGUYEN BAN ===
CheckCurrentPositionPL();
}
//+------------------------------------------------------------------+
//| OnTradeTransaction - CODE GOC NGUYEN BAN + Magic filter |
//+------------------------------------------------------------------+
void OnTradeTransaction(const MqlTradeTransaction& trans,
const MqlTradeRequest& request,
const MqlTradeResult& result)
{
ENUM_TRADE_TRANSACTION_TYPE type = trans.type;
if(type == TRADE_TRANSACTION_DEAL_ADD)
{
if(HistoryDealSelect(trans.deal))
m_deal.Ticket(trans.deal);
else
return;
// [MOI] Filter magic
long dealMagic = HistoryDealGetInteger(trans.deal, DEAL_MAGIC);
if(dealMagic != InpMagic) return;
long reason = -1;
if(!m_deal.InfoInteger(DEAL_REASON, reason)) return;
if((ENUM_DEAL_REASON)reason == DEAL_REASON_SL)
{
Print("Stop loss activated for position ==> ", trans.position);
if(!trading) return; // [MOI] Khong mo lenh khi da dung
// [MOI] Check gioi han lenh
int slPos = 0;
for(int j = 0; j < PositionsTotal(); j++)
{
ulong t = PositionGetTicket(j);
if(t > 0 && PositionGetInteger(POSITION_MAGIC) == InpMagic)
slPos++;
}
if(slPos >= InpMaxPositions)
{
Print("[LIMIT] Max pos after SL, skip");
return;
}
// LOGIC CODE GOC: mo lenh nguoc chieu khi bi SL
MqlTick tick;
if(SymbolInfoTick(_Symbol, tick))
{
if(!IsBuy)
{
if(trade.Buy(EntryVol, _Symbol, tick.ask, tick.ask - InpSL_Dist))
Print("Reverse Buy after SL. Price: ", tick.ask);
else
RetryTrade(true);
}
else
{
if(trade.Sell(EntryVol, _Symbol, tick.bid, tick.bid + InpSL_Dist))
Print("Reverse Sell after SL. Price: ", tick.bid);
else
RetryTrade(false);
}
}
}
}
}
//+------------------------------------------------------------------+
//| CloseAll - CODE GOC + Magic filter |
//+------------------------------------------------------------------+
void CloseAllCurrentPosition()
{
for(int i = PositionsTotal() - 1; i >= 0; i--)
{
if(PositionGetTicket(i) > 0)
{
ulong ticket = PositionGetTicket(i);
if(PositionSelectByTicket(ticket))
{
// [MOI] Chi dong lenh cua EA nay
if(PositionGetInteger(POSITION_MAGIC) != InpMagic) continue;
if(PositionGetString(POSITION_SYMBOL) != _Symbol) continue;
string symbol = PositionGetString(POSITION_SYMBOL);
double volume = PositionGetDouble(POSITION_VOLUME);
long posType = PositionGetInteger(POSITION_TYPE);
double posProfit = PositionGetDouble(POSITION_PROFIT);
if(posType == POSITION_TYPE_BUY)
{
if(!trade.PositionClose(ticket, -1))
Print("Failed to close BUY: ", GetLastError());
else
Print("CLOSING BUY: ", symbol, " vol: ", volume,
", profit: ", posProfit);
}
else if(posType == POSITION_TYPE_SELL)
{
if(!trade.PositionClose(ticket, -1))
Print("Failed to close SELL: ", GetLastError());
else
Print("CLOSING SELL: ", symbol, " vol: ", volume,
", profit: ", posProfit);
}
}
}
}
}
//+------------------------------------------------------------------+
//| CheckCurrentPositionPL - CODE GOC NGUYEN BAN + Magic filter |
//+------------------------------------------------------------------+
void CheckCurrentPositionPL()
{
ulong latestTicket = 0;
datetime latestTime = 0;
double latestEntryPrice = 0;
long latestType = -1;
double latestVolume = 0;
double latestProfit = 0;
double currentPrice = 0;
for(int i = 0; i < PositionsTotal(); i++)
{
ulong ticket = PositionGetTicket(i);
if(ticket > 0)
{
if(PositionSelectByTicket(ticket))
{
// [MOI] Filter Magic + Symbol
if(PositionGetInteger(POSITION_MAGIC) != InpMagic) continue;
if(PositionGetString(POSITION_SYMBOL) != _Symbol) continue;
datetime openTime = (datetime)PositionGetInteger(POSITION_TIME);
if(openTime > latestTime)
{
latestTicket = ticket;
latestTime = openTime;
latestEntryPrice = PositionGetDouble(POSITION_PRICE_OPEN);
latestType = PositionGetInteger(POSITION_TYPE);
latestVolume = PositionGetDouble(POSITION_VOLUME);
latestProfit = PositionGetDouble(POSITION_PROFIT);
currentPrice = (latestType == POSITION_TYPE_BUY)
? SymbolInfoDouble(_Symbol, SYMBOL_BID)
: SymbolInfoDouble(_Symbol, SYMBOL_ASK);
}
}
}
}
if(latestTicket != 0)
{
MqlTick tick;
if(SymbolInfoTick(_Symbol, tick))
{
BID = tick.bid;
ASK = tick.ask;
// LOGIC CODE GOC NGUYEN BAN: check reverse
bool mustReverse = (!IsBuy
? latestEntryPrice - currentPrice
: currentPrice - latestEntryPrice) <= -InpReverseDist;
if(mustReverse && flag)
{
flag = false;
// [MOI] Check gioi han lenh
int myPos = 0;
for(int j = 0; j < PositionsTotal(); j++)
{
ulong t = PositionGetTicket(j);
if(t > 0 && PositionGetInteger(POSITION_MAGIC) == InpMagic
&& PositionGetString(POSITION_SYMBOL) == _Symbol)
myPos++;
}
if(myPos >= InpMaxPositions)
{
Print("[LIMIT] ", myPos, " positions, khong mo them");
flag = true;
return;
}
if(latestType == POSITION_TYPE_BUY)
{
IsBuy = false;
if(trade.Sell(EntryVol, _Symbol, BID, BID + InpSL_Dist))
Print("SELL: Reverse vol: ", EntryVol, ", SL: ", BID + InpSL_Dist);
else
Print("Failed REVERSE SELL. Error: ", GetLastError());
}
else
{
IsBuy = true;
if(trade.Buy(EntryVol, _Symbol, ASK, ASK - InpSL_Dist))
Print("BUY: Reverse vol: ", EntryVol, ", SL: ", ASK - InpSL_Dist);
else
Print("Failed REVERSE BUY. Error: ", GetLastError());
}
flag = true;
}
}
}
else
{
// Khong co lenh -> mo moi (nhu code goc)
Print("No open position. Creating new order");
MqlTick tick;
if(SymbolInfoTick(_Symbol, tick))
{
BID = tick.bid;
ASK = tick.ask;
if(IsBuy && PositionsTotal() == 0)
{
if(trade.Buy(EntryVol, _Symbol, ASK, ASK - InpSL_Dist))
Print("New BUY: ", ASK, " SL: ", ASK - InpSL_Dist);
}
else if(!IsBuy && PositionsTotal() == 0)
{
if(trade.Sell(EntryVol, _Symbol, BID, BID + InpSL_Dist))
Print("New SELL: ", BID, " SL: ", BID + InpSL_Dist);
}
}
}
}
//+------------------------------------------------------------------+
//| Retry - Don gian hon code goc (chi retry 3 lan) |
//+------------------------------------------------------------------+
bool RetryTrade(bool isBuy, int maxAttempts = 3)
{
bool success = false;
int attempt = 0;
while(!success && attempt < maxAttempts)
{
attempt++;
MqlTick tick;
if(SymbolInfoTick(_Symbol, tick))
{
if(isBuy)
success = trade.Buy(EntryVol, _Symbol, tick.ask, tick.ask - InpSL_Dist);
else
success = trade.Sell(EntryVol, _Symbol, tick.bid, tick.bid + InpSL_Dist);
}
if(!success)
{
Print("Retry #", attempt, " failed. Error: ", GetLastError());
Sleep(200);
}
}
return success;
}
//+------------------------------------------------------------------+Editor is loading...
Leave a Comment