Code: Select all
void ShouldTradesBeClosed()
{
//Examine baskets of trades for possible closure
if (OpenTrades == 0)
return;//Nothing to do
//int tries = 0;
bool CloseTrades = false;
double pips = 0;//The pips upl of the highest buy or lowest sell
double loss = 0;//Convers pips to a positive value for comparison with (DistanceBetweenTrades / factor)
double profit = 0;//Cash upl of the side being calculated to see if they can combine to close a loser on the other side
int TradesToClose = 0;
bool result = false;
int cc = 0;
double HighestTradeCash = 0;
double LowestTradeCash = 0;
//Look for basket closure.
//Hedged basket
if (HedgedBasketPips > 0)
if (PipsUpl >= HedgedBasket)
{
CloseAllTrades(AllTrades);
if (ForceTradeClosure)
CloseAllTrades(AllTrades);
return;
}//if (PipsUpl >= HedgedBasket)
//Un-hedged
if (ClearBasketPips > 0)
if (PipsUpl >= ClearBasket)
{
CloseAllTrades(AllTrades);
if (ForceTradeClosure)
CloseAllTrades(AllTrades);
return;
}//if (PipsUpl >= HedgedBasket)
//Emergency stop loss
if (!CloseEnough(EmergencyStopLossPercentageOfBalance, 0))
if (CashUpl < 0)
if ((CashUpl) <= EmergencyStopLoss)
{
CloseAllTrades(AllTrades);
if (ForceTradeClosure)
CloseAllTrades(AllTrades);
return;
}//if ((CashUpl * -1) <= EmergencyStopLoss)
//Close the worst trade if stop loss is hit
if (!CloseEnough(PartialEmergencyStopLossPercentOfBalance, 0))
{
double PartialEmergencyStopLoss = AccountBalance() * (PartialEmergencyStopLossPercentOfBalance / 100) *-1;
if ((CashUpl) <= PartialEmergencyStopLoss)
{
// find the worst losing trade which is either going to be the highest buy or the lowest sell:
if (OrderSelect(HighestBuyTicketNo, SELECT_BY_TICKET, MODE_TRADES) )
double HighestBuyCash = OrderSwap() + OrderCommission() + OrderProfit();
if (OrderSelect(LowestSellTicketNo, SELECT_BY_TICKET, MODE_TRADES) )
double LowestSellCash = OrderSwap() + OrderCommission() + OrderProfit();
if ((HighestBuyCash < LowestSellCash)) // the buy is the worst trade
{
if (OrderSelect(HighestBuyTicketNo, SELECT_BY_TICKET, MODE_TRADES) )
{
result = CloseOrder(HighestBuyTicketNo);
if(result)Print("Closed highest buy at partial emergency stop level");
if (!result)
{
CountOpenTrades(); // just in case it's a ticket number issue.
return;
}//if (!result)
}//if (OrderSelect(HighestBuyTicketNo, SELECT_BY_TICKET, MODE_TRADES) )
}//if ((HighestBuyCash < LowestSellCash))
else
{
if (OrderSelect(LowestSellTicketNo, SELECT_BY_TICKET, MODE_TRADES) )
{
result = CloseOrder(LowestSellTicketNo);
if(result)Print("Closed lowest sell at partial emergency stop level");
if (!result)
{
CountOpenTrades(); // just in case it's a ticket number issue.
return;
}//if (!result)
}//if (OrderSelect(LowestSellTicketNo, SELECT_BY_TICKET, MODE_TRADES) )
}//else
}//if ((CashUpl) <= PartialEmergencyStopLoss)
}//if (!CloseEnough(PartialEmergencyStopLossPercentOfBalance, 0))
CloseTrades = false;
//Look for a simple offset opportunity of a losing buy at the
//top of the pile by the winner at the bottom.
if (MarketBuysCount > 3)//Impossible with < 4
{
//Do we have a losing buy?
if (OrderSelect(HighestBuyTicketNo, SELECT_BY_TICKET, MODE_TRADES) )
{
//Calculate the pips upl of the highest, and so latest, buy
pips = CalculateTradeProfitInPips(OP_BUY);
if (pips < 0)//Only continue if it is losing
{
loss = (pips * -1);//Turn the loss into a positive number for the comparison
if (loss >= DistanceBetweenTrades)//Only continue if losing by at least 1 grid level
{
HighestTradeCash = OrderSwap() + OrderCommission() + OrderProfit();
if (OrderSelect(LowestBuyTicketNo, SELECT_BY_TICKET, MODE_TRADES) )
LowestTradeCash = OrderSwap() + OrderCommission() + OrderProfit();
//Make sure we are closing at an overall cash profit
if ((HighestTradeCash + LowestTradeCash) > 0)
{
//The higest buy trade is losing by at least one grid level, so close it and the lowest buy
if (OrderSelect(HighestBuyTicketNo, SELECT_BY_TICKET, MODE_TRADES) )
{
result = CloseOrder(HighestBuyTicketNo);
if (!result)
{
return;
}//if (!result)
}//if (OrderSelect(HighestBuyTicketNo, SELECT_BY_TICKET, MODE_TRADES) )
if (OrderSelect(LowestBuyTicketNo, SELECT_BY_TICKET, MODE_TRADES) )
{
result = false;
while (!result)
{
result = CloseOrder(LowestBuyTicketNo);
}//while (!result)
}//if (OrderSelect(LowestBuyTicketNo, SELECT_BY_TICKET, MODE_TRADES) )
CountOpenTrades();
return;
}//if ((HighestTradeCash + LowestTradeCash) > 0)
}//if (loss >= DistanceBetweenTrades)
}//if (pips < 0)
}//if (OrderSelect(HighestBuyTicketNo, SELECT_BY_TICKET, MODE_TRADES) )
}//if (MarketBuysCount > 3)
//Look for a simple offset opportunity of a losing buy at the
//top of the pile by the winner at the bottom.
if (MarketSellsCount > 3)//Impossible with < 3
{
//Do we have a losing buy?
if (OrderSelect(LowestSellTicketNo, SELECT_BY_TICKET, MODE_TRADES) )
{
//Calculate the pips upl of the lowest, and so latest, sell
pips = CalculateTradeProfitInPips(OP_SELL);
if (pips < 0)//Only continue if it is losing
{
loss = (pips * -1);//Turn the loss into a positive number for the comparison
if (loss >= DistanceBetweenTrades)//Only continue if losing by at least 1 grid level
{
LowestTradeCash = OrderSwap() + OrderCommission() + OrderProfit();
if (OrderSelect(HighestSellTicketNo, SELECT_BY_TICKET, MODE_TRADES) )
HighestTradeCash = OrderSwap() + OrderCommission() + OrderProfit();
if ((HighestTradeCash + LowestTradeCash) > 0)
{
if (OrderSelect(LowestSellTicketNo, SELECT_BY_TICKET, MODE_TRADES) )
{
result = CloseOrder(LowestSellTicketNo);
if (!result)
{
return;
}//if (!result)
}//if (OrderSelect(LowestSellTicketNo, SELECT_BY_TICKET, MODE_TRADES) )
if (OrderSelect(HighestSellTicketNo, SELECT_BY_TICKET, MODE_TRADES) )
{
result = false;
while (!result)
{
result = CloseOrder(HighestSellTicketNo);
}//while (!result)
}//if (OrderSelect(HighestSellTicketNo, SELECT_BY_TICKET, MODE_TRADES) )
CountOpenTrades();
return;
}//if ((HighestTradeCash + LowestTradeCash) > 0)
}//if (loss >= DistanceBetweenTrades)
}//if (pips < 0)
}//if (OrderSelect(LowestSellTicketNo, SELECT_BY_TICKET, MODE_TRADES) )
}//if (MarketSellsCount > 3)
////////////////////////////////////////////////////////////////////////
//Got this far, so see if the combined winners on one side can combine
//to close a loser on the other side.
if (Hedged)
{
double CashLoss = 0;
double CashProfit = 0;
int NoOfTrades = 0;
bool ClosePossible = false;
int ClosureTickets[];
ArrayInitialize(ClosureTickets, -1);
//Can we offset some buy trades against the lowest losing sell trade
if (BuyCashUpl > 0)//The buy side of the hedge must be profitable overall
if (MarketBuysCount >= 3)//Must be sufficient trades open to start offsetting
if (OrderSelect(LowestSellTicketNo, SELECT_BY_TICKET, MODE_TRADES))//Select the lowest sell
{
CashLoss = (OrderSwap() + OrderCommission() + OrderProfit());//Calculate its cash position
if (CashLoss < 0)//Is it losing?
{
CashLoss*= -1;//Convert to a positive for comparison with the profit on the other side
//Calculate the profit on the other side of the hedge
for (cc = MarketBuysCount; cc > 0; cc--)
{
if (OrderSelect(FifoBuyTicket[cc - 1][TradeTicket], SELECT_BY_TICKET, MODE_TRADES) )
{
CashProfit+= (OrderSwap() + OrderCommission() + OrderProfit());
if (CashProfit > 0)
if (!CloseEnough(CashProfit, 0) )
{
NoOfTrades++;
ArrayResize(ClosureTickets, NoOfTrades);
ClosureTickets[NoOfTrades - 1] = OrderTicket();
}//if (!CloseEnough(CashProfit, 0) )
}//if (OrderSelect(FifoBuyTicket[cc - 1][ticket], SELECT_BY_TICKET, MODE_TRADES) )
//Is the profit big enough to close the trade on the other side of the hedge?
if (CashProfit >= CashLoss)
{
//Yippee
ClosePossible = true;
break;
}//if (CashProfit >= CashLoss)
}//for (int cc = MarketBuysCount; cc >= 0; cc--)
//Are there closures to make?
if (ClosePossible)
{
ForceTradeClosure = true;
while (ForceTradeClosure)
{
ForceTradeClosure = false;
if (OrderSelect(LowestSellTicketNo, SELECT_BY_TICKET, MODE_TRADES) )
{
result = CloseOrder(LowestSellTicketNo);
if (!result)
ForceTradeClosure = true;
}//if (OrderSelect(LowestSellTicketNo, SELECT_BY_TICKET, MODE_TRADES) )
for (cc = ArraySize(ClosureTickets) - 1; cc >= 0; cc--)
{
if (OrderSelect(ClosureTickets[cc], SELECT_BY_TICKET, MODE_TRADES))
{
result = CloseOrder(ClosureTickets[cc]);
if (!result)
{
ForceTradeClosure = true;
cc++;
}//if (!result)
}//if (OrderSelect(ClosureTickets[cc], SELECT_BY_TICKET, MODE_TRADES))
}//for (cc = ArraySize(ClosureTickets); cc >= 0; cc--)
}//while (ForceTradeClosure)
CountOpenTrades();
return;
}//if (ClosePossible)
}//if (CashLoss < 0)
}//if (OrderSelect(LowestSellTicketNo, SELECT_BY_TICKET, MODE_TRADES))
CashLoss = 0;
CashProfit = 0;
NoOfTrades = 0;
ClosePossible = false;
ArrayResize(ClosureTickets, 0);
ArrayInitialize(ClosureTickets, -1);
//Can we offset some sell trades against the highest losing buy trade
if (SellCashUpl > 0)//The sell side of the hedge must be profitable overall
if (MarketSellsCount >= 3)//Must be sufficient trades open to start offsetting
if (OrderSelect(HighestBuyTicketNo, SELECT_BY_TICKET, MODE_TRADES))//Select the highest buy
{
CashLoss = (OrderSwap() + OrderCommission() + OrderProfit());//Calculate its cash position
if (CashLoss < 0)//Is it losing?
{
CashLoss*= -1;//Convert to a positive for comparison with the profit on the other side
//Calculate the profit on the other side of the hedge
for (cc = 0; cc < MarketSellsCount; cc++)
{
if (OrderSelect(FifoSellTicket[cc][TradeTicket], SELECT_BY_TICKET, MODE_TRADES) )
{
CashProfit+= (OrderSwap() + OrderCommission() + OrderProfit());
if (CashProfit > 0)
if (!CloseEnough(CashProfit, 0) )
{
NoOfTrades++;
ArrayResize(ClosureTickets, NoOfTrades);
ClosureTickets[NoOfTrades - 1] = OrderTicket();
}//if (!CloseEnough(CashProfit, 0) )
}//if (OrderSelect(FifoSellTicket[cc1][TradeTicket], SELECT_BY_TICKET, MODE_TRADES) )
//Is the profit big enough to close the trade on the other side of the hedge?
if (CashProfit >= CashLoss)
{
//Yippee
ClosePossible = true;
break;
}//if (CashProfit >= CashLoss)
}//for (cc = 0; cc < MarketSellsCount - 1; cc++)
//Are there closures to make?
if (ClosePossible)
{
ForceTradeClosure = true;
while (ForceTradeClosure)
{
ForceTradeClosure = false;
if (OrderSelect(HighestBuyTicketNo, SELECT_BY_TICKET, MODE_TRADES) )
{
result = CloseOrder(HighestBuyTicketNo);
if (!result)
ForceTradeClosure = true;
}//if (OrderSelect(HighestBuyTicketNo, SELECT_BY_TICKET, MODE_TRADES) )
for (cc = ArraySize(ClosureTickets) - 1; cc >= 0; cc--)
{
if (OrderSelect(ClosureTickets[cc], SELECT_BY_TICKET, MODE_TRADES))
{
result = CloseOrder(ClosureTickets[cc]);
if (!result)
{
ForceTradeClosure = true;
cc++;
}//if (!result)
}//if (OrderSelect(ClosureTickets[cc], SELECT_BY_TICKET, MODE_TRADES))
}//for (cc = ArraySize(ClosureTickets); cc >= 0; cc--)
}//while (ForceTradeClosure)
CountOpenTrades();
return;
}//if (ClosePossible)
}//if (CashLoss < 0)
}//if (OrderSelect(HighestBuyTicketNo, SELECT_BY_TICKET, MODE_TRADES))
}//if (Hedged)
}//void ShouldTradesBeClosed()