|
@@ -34,6 +34,7 @@ input double lotSize = 0.01; /
|
|
|
input bool enableBasketTP = true; // Enable Basket TP
|
|
input bool enableBasketTP = true; // Enable Basket TP
|
|
|
input double basketTakeProfit = 1.0; // Basket Take Profit
|
|
input double basketTakeProfit = 1.0; // Basket Take Profit
|
|
|
input int maxOpenPositions = 3; // Maximum number of Combinations
|
|
input int maxOpenPositions = 3; // Maximum number of Combinations
|
|
|
|
|
+input int miniHoldTimeSec = 120; // Mini time in (seconds) to hold trades closing before checking TP
|
|
|
|
|
|
|
|
|
|
|
|
|
string goldPairs[];
|
|
string goldPairs[];
|
|
@@ -298,40 +299,42 @@ void checkBasketTakeProfit()
|
|
|
{
|
|
{
|
|
|
if(newTradeStore[i].buyTicket != -1 && newTradeStore[i].sellTicket != -1)
|
|
if(newTradeStore[i].buyTicket != -1 && newTradeStore[i].sellTicket != -1)
|
|
|
{
|
|
{
|
|
|
- double combinationProfit = 0;
|
|
|
|
|
-
|
|
|
|
|
- if(PositionSelectByTicket(newTradeStore[i].buyTicket))
|
|
|
|
|
- {
|
|
|
|
|
- Print("Ticket:",newTradeStore[i].buyTicket);
|
|
|
|
|
- Print("Profit:",PositionGetDouble(POSITION_PROFIT), " Swap:",PositionGetDouble(POSITION_SWAP));
|
|
|
|
|
- combinationProfit += PositionGetDouble(POSITION_PROFIT) + PositionGetDouble(POSITION_SWAP) ;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- if(PositionSelectByTicket(newTradeStore[i].sellTicket))
|
|
|
|
|
|
|
+ if(miniTimeBeforeClosing(newTradeStore[i].buyTicket, newTradeStore[i].sellTicket))
|
|
|
{
|
|
{
|
|
|
-
|
|
|
|
|
- Print("Ticket:",newTradeStore[i].sellTicket);
|
|
|
|
|
- Print("Profit:",PositionGetDouble(POSITION_PROFIT), " Swap:",PositionGetDouble(POSITION_SWAP));
|
|
|
|
|
- combinationProfit += PositionGetDouble(POSITION_PROFIT) + PositionGetDouble(POSITION_SWAP);
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ double combinationProfit = 0;
|
|
|
|
|
|
|
|
- if(combinationProfit >= basketTakeProfit)
|
|
|
|
|
- {
|
|
|
|
|
- Print("Combination TP hit: Closing trades. Profit = ", combinationProfit);
|
|
|
|
|
|
|
+ if(PositionSelectByTicket(newTradeStore[i].buyTicket))
|
|
|
|
|
+ {
|
|
|
|
|
+ Print("Ticket:",newTradeStore[i].buyTicket);
|
|
|
|
|
+ Print("Profit:",PositionGetDouble(POSITION_PROFIT), " Swap:",PositionGetDouble(POSITION_SWAP));
|
|
|
|
|
+ combinationProfit += PositionGetDouble(POSITION_PROFIT) + PositionGetDouble(POSITION_SWAP) ;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- if(!trade.PositionClose(newTradeStore[i].buyTicket))
|
|
|
|
|
|
|
+ if(PositionSelectByTicket(newTradeStore[i].sellTicket))
|
|
|
{
|
|
{
|
|
|
- Print(" Error Closing Buy Trade : ", newTradeStore[i].buyTicket," ",GetLastError());
|
|
|
|
|
|
|
+ Print("Ticket:",newTradeStore[i].sellTicket);
|
|
|
|
|
+ Print("Profit:",PositionGetDouble(POSITION_PROFIT), " Swap:",PositionGetDouble(POSITION_SWAP));
|
|
|
|
|
+ combinationProfit += PositionGetDouble(POSITION_PROFIT) + PositionGetDouble(POSITION_SWAP);
|
|
|
}
|
|
}
|
|
|
- else
|
|
|
|
|
- Print("Buy Trade Closed: ", newTradeStore[i].buyTicket);
|
|
|
|
|
|
|
|
|
|
- if(!trade.PositionClose(newTradeStore[i].sellTicket))
|
|
|
|
|
|
|
+ if(combinationProfit >= basketTakeProfit)
|
|
|
{
|
|
{
|
|
|
- Print(" Error Closing Sell Trade : ", newTradeStore[i].sellTicket," ",GetLastError());
|
|
|
|
|
|
|
+ Print("Combination TP hit: Closing trades. Profit = ", combinationProfit);
|
|
|
|
|
+
|
|
|
|
|
+ if(!trade.PositionClose(newTradeStore[i].buyTicket))
|
|
|
|
|
+ {
|
|
|
|
|
+ Print(" Error Closing Buy Trade : ", newTradeStore[i].buyTicket," ",GetLastError());
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ Print("Buy Trade Closed: ", newTradeStore[i].buyTicket);
|
|
|
|
|
+
|
|
|
|
|
+ if(!trade.PositionClose(newTradeStore[i].sellTicket))
|
|
|
|
|
+ {
|
|
|
|
|
+ Print(" Error Closing Sell Trade : ", newTradeStore[i].sellTicket," ",GetLastError());
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ Print("Sell Trade Closed: ", newTradeStore[i].sellTicket);
|
|
|
}
|
|
}
|
|
|
- else
|
|
|
|
|
- Print("Sell Trade Closed: ", newTradeStore[i].sellTicket);
|
|
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -438,5 +441,38 @@ bool canTradeSymbol(string symbol1, string symbol2, ENUM_POSITION_TYPE type1, EN
|
|
|
//+------------------------------------------------------------------+
|
|
//+------------------------------------------------------------------+
|
|
|
//| |
|
|
//| |
|
|
|
//+------------------------------------------------------------------+
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
+bool miniTimeBeforeClosing(ulong buyTicket, ulong sellTicket)
|
|
|
|
|
+ {
|
|
|
|
|
+ datetime currentTime = TimeCurrent();
|
|
|
|
|
+ datetime buyTime = 0;
|
|
|
|
|
+ datetime sellTime = 0;
|
|
|
|
|
+
|
|
|
|
|
+ if(PositionSelectByTicket(buyTicket))
|
|
|
|
|
+ {
|
|
|
|
|
+ buyTime = (datetime)PositionGetInteger(POSITION_TIME);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if(PositionSelectByTicket(sellTicket))
|
|
|
|
|
+ {
|
|
|
|
|
+ sellTime = (datetime)PositionGetInteger(POSITION_TIME);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ datetime comboOpenTime = (buyTime > sellTime) ? buyTime : sellTime;
|
|
|
|
|
+ int secondsHeld = (int)(currentTime - comboOpenTime);
|
|
|
|
|
+
|
|
|
|
|
+ if(secondsHeld >= miniHoldTimeSec)
|
|
|
|
|
+ {
|
|
|
|
|
+ Print("Minimum time REACHED (", secondsHeld, "s) ");
|
|
|
|
|
+ return true;
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ int secondsRemaining = miniHoldTimeSec - secondsHeld;
|
|
|
|
|
+ Print("Minimum time NOT reached (", secondsHeld, "/", miniHoldTimeSec, "s) ",
|
|
|
|
|
+ secondsRemaining, "s remaining");
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+//+------------------------------------------------------------------+
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
//+------------------------------------------------------------------+
|