0% found this document useful (0 votes)
175 views

Hedge V03

The document contains code for an Expert Advisor used for hedging trades on the MetaTrader 5 platform. It analyzes trends using ADX and opens buy and sell positions and stop orders according to the trend analysis. It also closes all positions if certain profit targets or balance limits are reached.

Uploaded by

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

Hedge V03

The document contains code for an Expert Advisor used for hedging trades on the MetaTrader 5 platform. It analyzes trends using ADX and opens buy and sell positions and stop orders according to the trend analysis. It also closes all positions if certain profit targets or balance limits are reached.

Uploaded by

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

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

//| HedgeV03.mq5 |
//| Jay |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Jay"
#property link "https://www.mql5.com"
#property version "1.00"

//\[] {} ||

#include <Trade/Trade.mqh>
CTrade *trade;

input ENUM_TIMEFRAMES InpTimeframe=PERIOD_CURRENT; // Timeframe


for trend analysis
input double InpLotsize = 0.01; // Lotsize
input double InpLotMultiplier = 2; // Lotsize multiplier
input int InpPeriod = 5; // Period for market move calculation
input int InpTakeProfitPips = 50; // Take Profit in Pips
input int InpStopLossPips = 100; // Stop Loss in Pips
input int InpHedgeDistPips = 50; // Hedge Distance in Pips
input string InpTradeComment = __FILE__; // Trade Comment
input ulong InpMagicNumber = 20202020; // EA Magic Number
input int InpADXPeriod = 14; // ADX Period
input int InpADXValue = 20; // ADX tolerance limit

double takeProfit = 0;
double stopLoss = 0;
double Ask = 0;
double Bid = 0;
double openPrice=0;
double orderTP=0;
double hedgeDist=0;
double mfactor=1;

bool upTrend = false;


bool downTrend = false;

int HandleADX;
double ADXBuffer[];

static double maximumAccountBalance=0;

//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit(){
trade = new CTrade();
trade.SetExpertMagicNumber(InpMagicNumber);

switch(_Digits){
case(4):
mfactor = 1;
break;
case(5):
mfactor = 10;
break;
default:
mfactor = 1;
break;
}

takeProfit = NormalizeDouble((InpTakeProfitPips)*mfactor*_Point, _Digits);


//orderTP = takeProfit;
orderTP = NormalizeDouble((InpTakeProfitPips*2)*mfactor*_Point, _Digits);
hedgeDist = NormalizeDouble((InpHedgeDistPips)*mfactor*_Point, _Digits);
stopLoss = NormalizeDouble(InpStopLossPips*mfactor*_Point, _Digits);

maximumAccountBalance = AccountInfoDouble(ACCOUNT_BALANCE);

HandleADX = iADX(_Symbol,InpTimeframe, InpADXPeriod);


if(HandleADX==INVALID_HANDLE) return(INIT_FAILED);

ArraySetAsSeries(ADXBuffer, true);

return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason){
if(HandleADX!=INVALID_HANDLE) IndicatorRelease(HandleADX);
delete trade;
}

//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick(){

//if(!NewBar()) return;

bool signalOpenBuy = false;


bool signalOpenSell = false;
bool signalCloseBuy = false;
bool signalCloseSell = false;

double sellStopPrice=0;
double buyStopPrice=0;

double totalBuyProfit = 0;
double totalSellProfit = 0;
double totalProfit = 0;

int cnt = CopyBuffer(HandleADX, 0, 0, 3, ADXBuffer);

Ask = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits);
Bid = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits);

datetime now = TimeLocal();


static double todaysProfit = 0;
static string today = "";
static double todaysBalance = 0;

if(today==TimeToString(TimeLocal(),TIME_DATE)) // date has not changed yet


todaysProfit = AccountInfoDouble(ACCOUNT_EQUITY)-todaysBalance;
else{
todaysBalance = AccountInfoDouble(ACCOUNT_BALANCE); //Reset starting
balance of the day
todaysProfit = 0; //Reset today's profit to ZERO.
today = TimeToString(TimeLocal(),TIME_DATE);
}

if(maximumAccountBalance<AccountInfoDouble(ACCOUNT_BALANCE))
maximumAccountBalance=AccountInfoDouble(ACCOUNT_BALANCE);

double highestPrice=iHigh(_Symbol,InpTimeframe,1);
double lowestPrice=iLow(_Symbol,InpTimeframe,1);
double highestClose=iClose(_Symbol,InpTimeframe,1);
double lowestClose=iClose(_Symbol,InpTimeframe,1);

double avgHLC1 = (iHigh(_Symbol,InpTimeframe,1) +


iLow(_Symbol,InpTimeframe,1) + iClose(_Symbol,InpTimeframe,1))/3;
double highestAvgHLC = avgHLC1;
double lowestAvgHLC = avgHLC1;

for(int i=1; i<=InpPeriod; i++){


double avgHLC = (iHigh(_Symbol,InpTimeframe,i) +
iLow(_Symbol,InpTimeframe,i) + iClose(_Symbol,InpTimeframe,i))/3;
if(avgHLC > highestAvgHLC) highestAvgHLC=avgHLC;
if(avgHLC < lowestAvgHLC) lowestAvgHLC=avgHLC;

if(iHigh(_Symbol,InpTimeframe,i)>highestPrice) highestPrice =
iHigh(_Symbol,InpTimeframe,i);
if(iLow(_Symbol,InpTimeframe,i)<lowestPrice) lowestPrice =
iLow(_Symbol,InpTimeframe,i);
if(iClose(_Symbol,InpTimeframe,i)>highestClose) highestClose =
iClose(_Symbol,InpTimeframe,i);
if(iClose(_Symbol,InpTimeframe,i)<lowestClose) lowestClose =
iClose(_Symbol,InpTimeframe,i);
}

upTrend = false; downTrend =false;


//if(iHigh(_Symbol,InpTimeframe,0)>highestPrice &&
iClose(_Symbol,InpTimeframe,0)>highestClose) upTrend=true;
//if(iLow(_Symbol,InpTimeframe,0)<lowestPrice &&
iClose(_Symbol,InpTimeframe,0)<lowestClose) downTrend=true;

if(iHigh(_Symbol,InpTimeframe,0)>highestPrice && ADXBuffer[0]>InpADXValue)


upTrend=true;
if(iLow(_Symbol,InpTimeframe,0)<lowestPrice && ADXBuffer[0]>InpADXValue)
downTrend=true;

//if(avgHLC1>highestAvgHLC && ADXBuffer[0]>InpADXValue) upTrend=true;


//if(avgHLC1<lowestAvgHLC && ADXBuffer[0]>InpADXValue) downTrend=true;

//Fetch no. of BUY and SELL positions, open prices & lotsize of the last BUY or
SELL order
double lastBuyLot = 0;
double lastSellLot = 0;

int nBuyPositions = 0; // Number of Buy positions


int nSellPositions = 0; // Number of Sell positions

int nBuyStopOrders = 0; // Number of Buystop orders


int nSellStopOrders = 0; // Number of Sellstop orders

ulong lastBuyTicket = 0;
ulong lastSellTicket = 0;

ulong lastBuyStopTicket = 0;
ulong lastSellStopTicket = 0;

double lastBuyStopLot = 0;
double lastSellStopLot = 0;

for (int i=PositionsTotal()-1; i>=0 ; i--){


ulong myTicket = PositionGetTicket(i);
if (PositionSelectByTicket(myTicket) &&
PositionGetString(POSITION_SYMBOL)==_Symbol &&
PositionGetInteger(POSITION_MAGIC)==InpMagicNumber){
if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY) {
nBuyPositions++;
if (PositionGetDouble(POSITION_VOLUME) > lastBuyLot){
lastBuyLot = PositionGetDouble(POSITION_VOLUME);
lastBuyTicket = myTicket;
}
}
if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL){
nSellPositions++;
if (PositionGetDouble(POSITION_VOLUME) > lastSellLot){
lastSellLot = PositionGetDouble(POSITION_VOLUME);
lastSellTicket = myTicket;
}
}
}
}

for (int i=OrdersTotal()-1; i>=0; i--){


ulong myTicket = OrderGetTicket(i);
if (OrderSelect(myTicket) && OrderGetString(ORDER_SYMBOL)==_Symbol &&
OrderGetInteger(ORDER_MAGIC)==InpMagicNumber){
if(OrderGetInteger(ORDER_TYPE)==ORDER_TYPE_BUY_STOP){
nBuyStopOrders++;
lastBuyStopTicket = myTicket;
lastBuyStopLot=OrderGetDouble(ORDER_VOLUME_INITIAL);
}
if(OrderGetInteger(ORDER_TYPE)==ORDER_TYPE_SELL_STOP){
nSellStopOrders++;
lastSellStopTicket = myTicket;
lastSellStopLot=OrderGetDouble(ORDER_VOLUME_INITIAL);
}
}
}

bool closeAllPositions=false;
if((PositionSelectByTicket(lastBuyTicket) &&
Ask>PositionGetDouble(POSITION_PRICE_OPEN)+takeProfit) ||
(PositionSelectByTicket(lastSellTicket) &&
Bid<PositionGetDouble(POSITION_PRICE_OPEN)-takeProfit)){
closeAllPositions = true;
}

/*
//DON'T RISK TOO MUCH MONEY
//if((MathMax(nBuyPositions, nSellPositions)>3 &&
AccountInfoDouble(ACCOUNT_PROFIT)>0) ||
AccountInfoDouble(ACCOUNT_EQUITY)<todaysBalance*0.90)
if(AccountInfoDouble(ACCOUNT_EQUITY)<todaysBalance*0.90){
Print("10% loss limit reached...... Closing all positions");
closeAllPositions=true;
}
*/
if(closeAllPositions){
ulong myTicket;
for (int i=PositionsTotal()-1; i>=0 ; i--){ //Close all open positions
myTicket = PositionGetTicket(i);
if (PositionSelectByTicket(myTicket) &&
PositionGetString(POSITION_SYMBOL)==_Symbol &&
PositionGetInteger(POSITION_MAGIC)==InpMagicNumber)
closePosition(myTicket);
}

for (int i=OrdersTotal()-1; i>=0; i--){ //Delete all pending STOP orders
myTicket = OrderGetTicket(i);
if (OrderSelect(myTicket) && OrderGetString(ORDER_SYMBOL)==_Symbol
&& OrderGetInteger(ORDER_MAGIC)==InpMagicNumber)
deletePendingOrder(myTicket);
}
//Print("Closing all positions");
return;
}

//===============================================================
================================================================
===========

double stopLotSize = 0;
double stopOpenPrice = 0;

if(nBuyPositions>0){ //Place SELLSTOP order at hedge distance below last


BUY position
if(PositionSelectByTicket(lastBuyTicket)){
if(nSellStopOrders==0) { // If no SELLSTOP order exists
stopOpenPrice = MathMin(PositionGetDouble(POSITION_PRICE_OPEN)-
hedgeDist, Bid);
if(nSellPositions==0 && nBuyPositions==1) //If there is a single BUY
order
stopLotSize = 3*PositionGetDouble(POSITION_VOLUME);
else
stopLotSize = InpLotMultiplier*PositionGetDouble(POSITION_VOLUME);

if(nSellPositions==0 || lastBuyLot>lastSellLot)
if(!
trade.SellStop(stopLotSize,stopOpenPrice,_Symbol,stopOpenPrice+stopLoss,stopO
penPrice-orderTP,0,0,InpTradeComment))
Print("SELLSTOP failed. Return code=",trade.ResultRetcode(), ". Code
description: ",trade.ResultRetcodeDescription());
}
}
}
if(nSellPositions>0) { //Place BUYSTOP order at hedge distance above last
SELL position
if(PositionSelectByTicket(lastSellTicket)){
if(nBuyStopOrders==0) { // If no BUYSTOP order exists
stopOpenPrice = MathMax(PositionGetDouble(POSITION_PRICE_OPEN)
+hedgeDist, Ask);
if(nSellPositions==1 && nBuyPositions==0) //If there is a single SELL
order
stopLotSize = 3*PositionGetDouble(POSITION_VOLUME);
else
stopLotSize = InpLotMultiplier*PositionGetDouble(POSITION_VOLUME);

if(nBuyPositions==0 || lastSellLot>lastBuyLot)
if(!trade.BuyStop(stopLotSize,stopOpenPrice,_Symbol,stopOpenPrice-
stopLoss,stopOpenPrice+orderTP,0,0,InpTradeComment))
Print("BUYSTOP failed. Return code=",trade.ResultRetcode(), ". Code
description: ",trade.ResultRetcodeDescription());
}
}
}

double initialLotsize = InpLotsize;


if(nBuyPositions==0 && nSellPositions==0){
if(OrderSelect(lastBuyStopTicket))
deletePendingOrder(lastBuyStopTicket);

if(OrderSelect(lastSellStopTicket))
deletePendingOrder(lastSellStopTicket);

//if(upTrend){
if(upTrend || lastProfitableDealType()==DEAL_TYPE_SELL){
if(!trade.Buy(initialLotsize,_Symbol, Ask, Ask-stopLoss, Ask+orderTP,
InpTradeComment))
Print("BUY trade failed. Return code=",trade.ResultRetcode(), ". Code
description: ",trade.ResultRetcodeDescription(), " Ask = ", Ask );
}
else
//if(downTrend){ //Downtrend - place a SELL order
if(downTrend || lastProfitableDealType()==DEAL_TYPE_BUY){
if(!trade.Sell(initialLotsize,_Symbol, Bid,Bid+stopLoss,Bid-orderTP,
InpTradeComment))
Print("SELL trade failed. Return code=",trade.ResultRetcode(), ". Code
description: ",trade.ResultRetcodeDescription(), " Bid = ", Bid);
}
}

Comment("\nUpTrend = ", upTrend, " DownTrend = ", downTrend, " ADX Value = ",
NormalizeDouble(ADXBuffer[0],0),
"\nTakeProfit = ", InpTakeProfitPips, " Stoploss = ", InpStopLossPips, " Hedge
Distance = " ,InpHedgeDistPips, " Initial Lotsize = ", initialLotsize,
"\nHighest avgHLC = ", NormalizeDouble(highestAvgHLC,_Digits), " lowest
avgHLC = ", NormalizeDouble(lowestAvgHLC,_Digits),
" AvgHLC1 = ", NormalizeDouble(avgHLC1,_Digits),
"\nHighest Price = ", NormalizeDouble(highestPrice,_Digits), " Lowest Price =
", NormalizeDouble(lowestPrice,_Digits),
"\n",
"\n",
"\n#Buy Positions= ", nBuyPositions, " #SELLSTOP orders = ",
nSellStopOrders, " LastBuyLot = ", lastBuyLot, " SellStop Lot = ", lastSellStopLot,
"\n#Sell Positions = ", nSellPositions, " #BUYSTOP orders = ",
nBuyStopOrders, ", LastSellLot = ", lastSellLot, " BuyStop Lot = ", lastBuyStopLot,
"\n",
"\nDate", today, " Opening Balance = ", todaysBalance, " Day's profit = ",
NormalizeDouble(todaysProfit,2),
" Profit in % - ", NormalizeDouble(todaysProfit*100/todaysBalance, 2),
"\n",
"\nAccount balance = ",
NormalizeDouble(AccountInfoDouble(ACCOUNT_BALANCE),2), " Maximum
Account Balance = ", maximumAccountBalance,
"\nAccount equity = ",
NormalizeDouble(AccountInfoDouble(ACCOUNT_EQUITY),2),
"\nAccount Profit = ",
NormalizeDouble(AccountInfoDouble(ACCOUNT_PROFIT),2),
"\nLast Profitable Deal Type = ", lastProfitableDealType(),
"\n"
);

return;
}

//======================================= CLOSE A POSITION


================================================================
===============================
void closePosition(ulong myTicket){
int Retries=0;
while(!trade.PositionClose(myTicket) && Retries <=5){
Print("Failed to close position ", myTicket, " Return
code=",trade.ResultRetcode(), ". Code description:
",trade.ResultRetcodeDescription());
Sleep(6000);
Retries++;
}
}

//======================================= DELETE BUYSTOP or


SELLSTOP orders
================================================================
==============
void deletePendingOrder(ulong myTicket){
if(!trade.OrderDelete(myTicket))
Print("Failed to delete STOP order ", myTicket, " Return
code=",trade.ResultRetcode(), ". Code description:
",trade.ResultRetcodeDescription());
}

void trailStopLoss(ulong myTicket){


double newStopLoss = 0;

if(PositionSelectByTicket(myTicket)){
double CurrentStopLoss = PositionGetDouble(POSITION_SL);
if (PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY){
newStopLoss = Ask-stopLoss/2;
if (CurrentStopLoss==0 || CurrentStopLoss<newStopLoss) //New stop
loss if price has gone up
if(!trade.PositionModify(myTicket,
newStopLoss,PositionGetDouble(POSITION_TP)))
Print("TrailStop - Failed to modify BUY position ", myTicket, " Return
code=",trade.ResultRetcode(), ". Code description:
",trade.ResultRetcodeDescription());
}
if (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL) {
newStopLoss = Bid+stopLoss/2;
if (CurrentStopLoss==0 || CurrentStopLoss>newStopLoss) //New stop
loss if price has gone down
if(!trade.PositionModify(myTicket,newStopLoss,
PositionGetDouble(POSITION_TP)))
Print("TrailStop - Failed to modify SELL position ", myTicket, " Return
code=",trade.ResultRetcode(), ". Code description:
",trade.ResultRetcodeDescription());
}
}
}

//Find direction of last profitable trade

ENUM_DEAL_TYPE lastProfitableDealType(){
HistorySelect(TimeCurrent()-86400, TimeCurrent()); // Order history for last 24
hours.
ulong myTicket;
for(int i = HistoryDealsTotal()-1; i>=0; i--){
myTicket=HistoryDealGetTicket(i);
if(HistoryDealGetString(myTicket,DEAL_SYMBOL)==_Symbol &&
HistoryDealGetInteger(myTicket,DEAL_MAGIC)==InpMagicNumber)
if(HistoryDealGetDouble(myTicket, DEAL_PROFIT) > 0 &&
HistoryDealGetInteger(myTicket,DEAL_ENTRY)==DEAL_ENTRY_OUT) //Deal
triggered by TakeProfit
return HistoryDealGetInteger(myTicket, DEAL_TYPE);
}
return DEAL_TYPE_CORRECTION;
}

You might also like