576 lines
21 KiB
Text
576 lines
21 KiB
Text
//+------------------------------------------------------------------+
| |||
//| COMPLETE REVERSAL BOT - 127.8% + 61.8% STRATEGY |
| |||
//| Multi-Timeframe: 15M Setup | 5M Precision | 1H Trend Filter |
| |||
//| Indicators: Stoch RSI + CCI Dual Divergence |
| |||
//+------------------------------------------------------------------+
| |||
#property strict
| |||
| |||
// === INPUT PARAMETERS ===
| |||
input double FirstEntryLots = 0.03; // 127.8% entry size
| |||
input double SecondEntryLots = 0.02; // 61.8% add-on size
| |||
input int SLPips = 10; // Base SL in pips
| |||
input double MaxSpread = 3.0; // Max spread filter
| |||
input int MomentumThreshold = 70; // Min momentum score
| |||
input double Fib1278 = 1.278; // First entry fib level
| |||
input double Fib618 = 0.618; // Second entry fib level
| |||
| |||
enum EntryStyle {
| |||
STYLE_AGGRESSIVE, // Enter on touch/wick
| |||
STYLE_CONSERVATIVE // Enter on close confirmation
| |||
};
| |||
input EntryStyle EntryMode = STYLE_CONSERVATIVE;
| |||
| |||
enum TradePhase {
| |||
PHASE_NONE,
| |||
PHASE_1278_LONG,
| |||
PHASE_618_ADDON
| |||
};
| |||
| |||
// === GLOBAL VARIABLES ===
| |||
TradePhase currentPhase = PHASE_NONE;
| |||
| |||
struct SetupData {
| |||
double swingHigh;
| |||
double swingLow;
| |||
double fib1278Level;
| |||
double entry1278Price;
| |||
double newSwingHigh;
| |||
double pullbackLow;
| |||
bool swingEstablished;
| |||
};
| |||
SetupData activeSetup;
| |||
| |||
datetime last5MBar = 0;
| |||
| |||
//+------------------------------------------------------------------+
| |||
//| EXPERT INITIALIZATION |
| |||
//+------------------------------------------------------------------+
| |||
int OnInit()
| |||
{
| |||
if(StringFind(Symbol(), "Volatility") == -1)
| |||
{
| |||
Alert("This EA is designed for Synthetic Indices!");
| |||
return(INIT_FAILED);
| |||
}
| |||
return(INIT_SUCCEEDED);
| |||
}
| |||
| |||
//+------------------------------------------------------------------+
| |||
//| MAIN TICK FUNCTION |
| |||
//+------------------------------------------------------------------+
| |||
void OnTick()
| |||
{
| |||
// Spread filter
| |||
if(SymbolInfoInteger(Symbol(), SYMBOL_SPREAD) > MaxSpread * 10) return;
| |||
| |||
// Time filter
| |||
MqlDateTime dt;
| |||
TimeToStruct(TimeCurrent(), dt);
| |||
if(dt.min < 5 || dt.min > 55) return;
| |||
| |||
// Check for new 5M bar
| |||
datetime current5MBar = iTime(Symbol(), PERIOD_M5, 0);
| |||
if(current5MBar != last5MBar)
| |||
{
| |||
last5MBar = current5MBar;
| |||
| |||
// Entry logic
| |||
if(PositionsTotal() == 0 || !HasOpenPosition("1278"))
| |||
{
| |||
switch(currentPhase)
| |||
{
| |||
case PHASE_NONE:
| |||
Check1278LongEntry();
| |||
break;
| |||
case PHASE_1278_LONG:
| |||
CheckForPullbackSetup();
| |||
break;
| |||
case PHASE_618_ADDON:
| |||
Check618AddonEntry();
| |||
break;
| |||
}
| |||
}
| |||
}
| |||
| |||
// Manage positions
| |||
if(PositionsTotal() > 0)
| |||
ManagePositions();
| |||
}
| |||
| |||
//+------------------------------------------------------------------+
| |||
//| 127.8% LONG ENTRY |
| |||
//+------------------------------------------------------------------+
| |||
void Check1278LongEntry()
| |||
{
| |||
// 15M Setup
| |||
int highestBar15M = iHighest(Symbol(), PERIOD_M15, MODE_HIGH, 30, 1);
| |||
int lowestBar15M = iLowest(Symbol(), PERIOD_M15, MODE_LOW, 30, 1);
| |||
| |||
activeSetup.swingHigh = iHigh(Symbol(), PERIOD_M15, highestBar15M);
| |||
activeSetup.swingLow = iLow(Symbol(), PERIOD_M15, lowestBar15M);
| |||
| |||
double range15M = activeSetup.swingHigh - activeSetup.swingLow;
| |||
activeSetup.fib1278Level = activeSetup.swingHigh - (range15M * Fib1278);
| |||
| |||
double low15M_0 = iLow(Symbol(), PERIOD_M15, 0);
| |||
double tolerance15M = 5 * SymbolInfoDouble(Symbol(), SYMBOL_POINT) * 10;
| |||
| |||
if(!(low15M_0 <= activeSetup.fib1278Level + tolerance15M)) return;
| |||
| |||
// 1H Trend filter
| |||
if(GetTrendDirection(PERIOD_H1) == -1) return;
| |||
| |||
// Divergence check
| |||
if(!BullishDivergenceOnTimeframe(PERIOD_M15)) return;
| |||
| |||
// Momentum score
| |||
if(CalculateMomentumScore() < MomentumThreshold) return;
| |||
| |||
// 5M Precision entry
| |||
if(Check5MPrecisionEntry())
| |||
{
| |||
Print("127.8% entry executed!");
| |||
}
| |||
}
| |||
| |||
//+------------------------------------------------------------------+
| |||
//| 5M PRECISION ENTRY WITH STYLE SWITCH |
| |||
//+------------------------------------------------------------------+
| |||
bool Check5MPrecisionEntry()
| |||
{
| |||
double low5M_0 = iLow(Symbol(), PERIOD_M5, 0);
| |||
double low5M_1 = iLow(Symbol(), PERIOD_M5, 1);
| |||
double close5M_0 = iClose(Symbol(), PERIOD_M5, 0);
| |||
double close5M_1 = iClose(Symbol(), PERIOD_M5, 1);
| |||
double open5M_0 = iOpen(Symbol(), PERIOD_M5, 0);
| |||
double high5M_0 = iHigh(Symbol(), PERIOD_M5, 0);
| |||
double high5M_1 = iHigh(Symbol(), PERIOD_M5, 1);
| |||
| |||
double tolerance5M = 3 * SymbolInfoDouble(Symbol(), SYMBOL_POINT) * 10;
| |||
| |||
if(!(low5M_0 <= activeSetup.fib1278Level + tolerance5M ||
| |||
low5M_1 <= activeSetup.fib1278Level + tolerance5M)) return false;
| |||
| |||
// AGGRESSIVE MODE
| |||
if(EntryMode == STYLE_AGGRESSIVE)
| |||
{
| |||
bool quickBounce = (low5M_0 <= activeSetup.fib1278Level + tolerance5M && close5M_0 > open5M_0);
| |||
bool longWick = ((MathMin(close5M_0, open5M_0) - low5M_0) > MathAbs(close5M_0 - open5M_0) * 1.5);
| |||
| |||
double stochMain[];
| |||
ArraySetAsSeries(stochMain, true);
| |||
int stochHandle = iStochastic(Symbol(), PERIOD_M5, 14, 3, 3, MODE_SMA, STO_LOWHIGH);
| |||
CopyBuffer(stochHandle, 0, 0, 2, stochMain);
| |||
bool stochTurning = (stochMain[0] > stochMain[1] && stochMain[1] < 30);
| |||
| |||
int aggSignals = (quickBounce ? 1 : 0) + (longWick ? 1 : 0) + (stochTurning ? 1 : 0);
| |||
if(aggSignals >= 2)
| |||
return Execute5MEntry("1278_5M_Aggressive", 8);
| |||
}
| |||
| |||
// CONSERVATIVE MODE
| |||
else
| |||
{
| |||
bool bullishClose = (close5M_0 > open5M_0);
| |||
bool abovePrevious = (close5M_0 > high5M_1);
| |||
| |||
double microResistance = iHigh(Symbol(), PERIOD_M5, iHighest(Symbol(), PERIOD_M5, MODE_HIGH, 3, 1));
| |||
bool brokeResistance = (close5M_0 > microResistance);
| |||
| |||
double stochMain[], stochSignal[];
| |||
ArraySetAsSeries(stochMain, true);
| |||
ArraySetAsSeries(stochSignal, true);
| |||
int stochHandle = iStochastic(Symbol(), PERIOD_M5, 14, 3, 3, MODE_SMA, STO_LOWHIGH);
| |||
CopyBuffer(stochHandle, 0, 0, 2, stochMain);
| |||
CopyBuffer(stochHandle, 1, 0, 2, stochSignal);
| |||
bool stochCross = (stochMain[0] > stochSignal[0] && stochMain[1] <= stochSignal[1]);
| |||
| |||
double cci[];
| |||
ArraySetAsSeries(cci, true);
| |||
int cciHandle = iCCI(Symbol(), PERIOD_M5, 20, PRICE_TYPICAL);
| |||
CopyBuffer(cciHandle, 0, 0, 2, cci);
| |||
bool cciCross = (cci[0] > cci[1] && cci[1] < -100);
| |||
| |||
int confSignals = (bullishClose ? 1 : 0) + (abovePrevious ? 1 : 0) +
| |||
(brokeResistance ? 1 : 0) + (stochCross ? 1 : 0) + (cciCross ? 1 : 0);
| |||
| |||
if(confSignals >= 3)
| |||
return Execute5MEntry("1278_5M_Conservative", 6);
| |||
}
| |||
| |||
return false;
| |||
}
| |||
| |||
//+------------------------------------------------------------------+
| |||
//| EXECUTE 5M ENTRY |
| |||
//+------------------------------------------------------------------+
| |||
bool Execute5MEntry(string comment, int slPips)
| |||
{
| |||
double entryPrice = SymbolInfoDouble(Symbol(), SYMBOL_ASK);
| |||
double sl = NormalizeDouble(entryPrice - slPips * SymbolInfoDouble(Symbol(), SYMBOL_POINT) * 10, _Digits);
| |||
double tp = NormalizeDouble(activeSetup.swingHigh, _Digits);
| |||
double lots = (EntryMode == STYLE_AGGRESSIVE) ? FirstEntryLots * 0.9 : FirstEntryLots;
| |||
| |||
if(ExecuteTrade(ORDER_TYPE_BUY, lots, sl, tp, comment))
| |||
{
| |||
currentPhase = PHASE_1278_LONG;
| |||
activeSetup.entry1278Price = entryPrice;
| |||
activeSetup.swingEstablished = false;
| |||
return true;
| |||
}
| |||
return false;
| |||
}
| |||
| |||
//+------------------------------------------------------------------+
| |||
//| CHECK FOR PULLBACK SETUP (AFTER 127.8% MOVES UP) |
| |||
//+------------------------------------------------------------------+
| |||
void CheckForPullbackSetup()
| |||
{
| |||
if(!HasOpenPosition("1278")) { ResetToPhaseNone(); return; }
| |||
| |||
double recentHigh = iHigh(Symbol(), PERIOD_M5, iHighest(Symbol(), PERIOD_M5, MODE_HIGH, 15, 0));
| |||
double moveUp = recentHigh - activeSetup.entry1278Price;
| |||
double minMove = 20 * SymbolInfoDouble(Symbol(), SYMBOL_POINT) * 10;
| |||
| |||
if(moveUp >= minMove)
| |||
{
| |||
activeSetup.newSwingHigh = recentHigh;
| |||
activeSetup.swingEstablished = true;
| |||
currentPhase = PHASE_618_ADDON;
| |||
Print("Swing established at ", recentHigh, " - waiting for 61.8% pullback");
| |||
}
| |||
}
| |||
| |||
//+------------------------------------------------------------------+
| |||
//| 61.8% ADD-ON ENTRY |
| |||
//+------------------------------------------------------------------+
| |||
void Check618AddonEntry()
| |||
{
| |||
if(!activeSetup.swingEstablished) return;
| |||
| |||
double upMove = activeSetup.newSwingHigh - activeSetup.entry1278Price;
| |||
double fib618Level = activeSetup.newSwingHigh - (upMove * Fib618);
| |||
double fib786Level = activeSetup.newSwingHigh - (upMove * 0.786);
| |||
| |||
double close15M = iClose(Symbol(), PERIOD_M15, 0);
| |||
double low15M = iLow(Symbol(), PERIOD_M15, 0);
| |||
double tolerance = 5 * SymbolInfoDouble(Symbol(), SYMBOL_POINT) * 10;
| |||
| |||
if(!(low15M <= fib618Level + tolerance && low15M >= fib786Level - tolerance)) return;
| |||
| |||
if(!Check5M_618Entry(fib618Level, fib786Level)) return;
| |||
| |||
double entryPrice = SymbolInfoDouble(Symbol(), SYMBOL_ASK);
| |||
double sl = NormalizeDouble(activeSetup.entry1278Price - 5 * SymbolInfoDouble(Symbol(), SYMBOL_POINT) * 10, _Digits);
| |||
double tp = NormalizeDouble(activeSetup.newSwingHigh + (upMove * 0.5), _Digits);
| |||
| |||
if(ExecuteTrade(ORDER_TYPE_BUY, SecondEntryLots, sl, tp, "618_Addon"))
| |||
{
| |||
activeSetup.pullbackLow = low15M;
| |||
Print("61.8% add-on executed at ", entryPrice);
| |||
}
| |||
}
| |||
| |||
//+------------------------------------------------------------------+
| |||
//| 5M 61.8% ENTRY WITH STYLE |
| |||
//+------------------------------------------------------------------+
| |||
bool Check5M_618Entry(double fib618, double fib786)
| |||
{
| |||
double close5M_0 = iClose(Symbol(), PERIOD_M5, 0);
| |||
double close5M_1 = iClose(Symbol(), PERIOD_M5, 1);
| |||
double low5M_0 = iLow(Symbol(), PERIOD_M5, 0);
| |||
double low5M_1 = iLow(Symbol(), PERIOD_M5, 1);
| |||
double open5M_0 = iOpen(Symbol(), PERIOD_M5, 0);
| |||
double high5M_1 = iHigh(Symbol(), PERIOD_M5, 1);
| |||
| |||
double tolerance = 3 * SymbolInfoDouble(Symbol(), SYMBOL_POINT) * 10;
| |||
| |||
bool inZone = (low5M_0 <= fib618 + tolerance && low5M_0 >= fib786 - tolerance);
| |||
if(!inZone) return false;
| |||
| |||
if(EntryMode == STYLE_AGGRESSIVE)
| |||
{
| |||
bool doubleBottom = (MathAbs(low5M_0 - low5M_1) < tolerance * 2);
| |||
bool quickBounce = (low5M_0 <= fib618 && close5M_0 > open5M_0);
| |||
bool hammer = ((MathMin(close5M_0, open5M_0) - low5M_0) > MathAbs(close5M_0 - open5M_0) * 2);
| |||
| |||
int aggCount = (doubleBottom ? 1 : 0) + (quickBounce ? 1 : 0) + (hammer ? 1 : 0);
| |||
return (aggCount >= 2);
| |||
}
| |||
else
| |||
{
| |||
double low5M_2 = iLow(Symbol(), PERIOD_M5, 2);
| |||
bool higherLow = (low5M_0 > low5M_1 && low5M_1 > low5M_2);
| |||
bool closeStrong = (close5M_0 > high5M_1);
| |||
| |||
double microRes = iHigh(Symbol(), PERIOD_M5, iHighest(Symbol(), PERIOD_M5, MODE_HIGH, 5, 1));
| |||
bool brokeRes = (close5M_0 > microRes);
| |||
bool momentumOK = BullishDivergenceOnTimeframe(PERIOD_M5);
| |||
| |||
int confCount = (higherLow ? 1 : 0) + (closeStrong ? 1 : 0) + (brokeRes ? 1 : 0) + (momentumOK ? 1 : 0);
| |||
return (confCount >= 3);
| |||
}
| |||
}
| |||
| |||
//+------------------------------------------------------------------+
| |||
//| DIVERGENCE CHECKER (Stoch RSI + CCI) |
| |||
//+------------------------------------------------------------------+
| |||
bool BullishDivergenceOnTimeframe(ENUM_TIMEFRAMES tf)
| |||
{
| |||
double low1 = iLow(Symbol(), tf, 5);
| |||
double low2 = iLow(Symbol(), tf, 1);
| |||
if(low2 >= low1) return false;
| |||
| |||
double stochMain[];
| |||
ArraySetAsSeries(stochMain, true);
| |||
int stochHandle = iStochastic(Symbol(), tf, 14, 3, 3, MODE_SMA, STO_LOWHIGH);
| |||
if(CopyBuffer(stochHandle, 0, 0, 10, stochMain) < 10) return false;
| |||
| |||
double cci[];
| |||
ArraySetAsSeries(cci, true);
| |||
int cciHandle = iCCI(Symbol(), tf, 20, PRICE_TYPICAL);
| |||
if(CopyBuffer(cciHandle, 0, 0, 10, cci) < 10) return false;
| |||
| |||
return (stochMain[1] > stochMain[5] && cci[1] > cci[5]);
| |||
}
| |||
| |||
//+------------------------------------------------------------------+
| |||
//| MOMENTUM SCORE |
| |||
//+------------------------------------------------------------------+
| |||
int CalculateMomentumScore()
| |||
{
| |||
int score = 0;
| |||
| |||
double rsi = iRSI(Symbol(), PERIOD_M15, 14, PRICE_CLOSE, 0);
| |||
if(rsi < 30) score += (int)MathMin((30 - rsi) * 1.2, 25);
| |||
| |||
double open = iOpen(Symbol(), PERIOD_M15, 0);
| |||
double high = iHigh(Symbol(), PERIOD_M15, 0);
| |||
double low = iLow(Symbol(), PERIOD_M15, 0);
| |||
double close = iClose(Symbol(), PERIOD_M15, 0);
| |||
| |||
double body = MathAbs(close - open);
| |||
double lowerWick = MathMin(close, open) - low;
| |||
if(body > 0 && lowerWick / body > 2.0) score += 25;
| |||
| |||
double stochMain[];
| |||
ArraySetAsSeries(stochMain, true);
| |||
int stochHandle = iStochastic(Symbol(), PERIOD_M15, 14, 3, 3, MODE_SMA, STO_LOWHIGH);
| |||
CopyBuffer(stochHandle, 0, 0, 1, stochMain);
| |||
if(stochMain[0] < 15) score += 20;
| |||
| |||
double cci[];
| |||
ArraySetAsSeries(cci, true);
| |||
int cciHandle = iCCI(Symbol(), PERIOD_M15, 20, PRICE_TYPICAL);
| |||
CopyBuffer(cciHandle, 0, 0, 1, cci);
| |||
if(cci[0] < -150) score += 20;
| |||
else if(cci[0] < -100) score += 10;
| |||
| |||
double vwap = iMA(Symbol(), PERIOD_M15, 20, 0, MODE_SMA, PRICE_TYPICAL, 0);
| |||
double distance = MathAbs(close - vwap) / vwap * 100;
| |||
score += (int)MathMin(distance * 2, 10);
| |||
| |||
return score;
| |||
}
| |||
| |||
//+------------------------------------------------------------------+
| |||
//| TREND DIRECTION |
| |||
//+------------------------------------------------------------------+
| |||
int GetTrendDirection(ENUM_TIMEFRAMES tf)
| |||
{
| |||
double ma50 = iMA(Symbol(), tf, 50, 0, MODE_SMA, PRICE_CLOSE, 0);
| |||
double ma200 = iMA(Symbol(), tf, 200, 0, MODE_SMA, PRICE_CLOSE, 0);
| |||
double close = iClose(Symbol(), tf, 0);
| |||
| |||
if(close > ma50 && ma50 > ma200) return 1;
| |||
if(close < ma50 && ma50 < ma200) return -1;
| |||
return 0;
| |||
}
| |||
| |||
//+------------------------------------------------------------------+
| |||
//| POSITION MANAGEMENT |
| |||
//+------------------------------------------------------------------+
| |||
void ManagePositions()
| |||
{
| |||
bool has1278 = false, has618 = false;
| |||
double avgEntry = 0, totalLots = 0;
| |||
| |||
for(int i = PositionsTotal() - 1; i >= 0; i--)
| |||
{
| |||
ulong ticket = PositionGetTicket(i);
| |||
if(ticket <= 0) continue;
| |||
if(PositionGetString(POSITION_SYMBOL) != Symbol()) continue;
| |||
| |||
string comment = PositionGetString(POSITION_COMMENT);
| |||
int posType = (int)PositionGetInteger(POSITION_TYPE);
| |||
double lots = PositionGetDouble(POSITION_VOLUME);
| |||
double openPrice = PositionGetDouble(POSITION_PRICE_OPEN);
| |||
| |||
if(StringFind(comment, "1278") != -1) has1278 = true;
| |||
if(StringFind(comment, "618") != -1) has618 = true;
| |||
| |||
avgEntry += openPrice * lots;
| |||
totalLots += lots;
| |||
| |||
ManageSinglePosition(ticket, posType, openPrice);
| |||
}
| |||
| |||
if(totalLots > 0) avgEntry /= totalLots;
| |||
| |||
if(has1278 && has618)
| |||
ManageAveragedPosition(avgEntry, totalLots);
| |||
| |||
if(!has1278 && !has618 && currentPhase != PHASE_NONE)
| |||
ResetToPhaseNone();
| |||
}
| |||
| |||
//+------------------------------------------------------------------+
| |||
//| SINGLE POSITION MANAGEMENT |
| |||
//+------------------------------------------------------------------+
| |||
void ManageSinglePosition(ulong ticket, int posType, double openPrice)
| |||
{
| |||
double currentSL = PositionGetDouble(POSITION_SL);
| |||
double currentTP = PositionGetDouble(POSITION_TP);
| |||
| |||
double currentPrice = (posType == POSITION_TYPE_BUY) ?
| |||
SymbolInfoDouble(Symbol(), SYMBOL_BID) :
| |||
SymbolInfoDouble(Symbol(), SYMBOL_ASK);
| |||
| |||
double profitPips = MathAbs(currentPrice - openPrice) /
| |||
(SymbolInfoDouble(Symbol(), SYMBOL_POINT) * 10);
| |||
| |||
// Break even at 15 pips
| |||
if(profitPips >= 15 && currentSL == 0)
| |||
{
| |||
double newSL = openPrice + 2 * SymbolInfoDouble(Symbol(), SYMBOL_POINT) * 10;
| |||
ModifyPosition(ticket, NormalizeDouble(newSL, _Digits), currentTP);
| |||
}
| |||
}
| |||
| |||
//+------------------------------------------------------------------+
| |||
//| AVERAGED POSITION MANAGEMENT |
| |||
//+------------------------------------------------------------------+
| |||
void ManageAveragedPosition(double avgPrice, double totalLots)
| |||
{
| |||
for(int i = PositionsTotal() - 1; i >= 0; i--)
| |||
{
| |||
ulong ticket = PositionGetTicket(i);
| |||
if(ticket <= 0) continue;
| |||
if(PositionGetString(POSITION_SYMBOL) != Symbol()) continue;
| |||
| |||
int posType = (int)PositionGetInteger(POSITION_TYPE);
| |||
double currentSL = PositionGetDouble(POSITION_SL);
| |||
double currentTP = PositionGetDouble(POSITION_TP);
| |||
| |||
double currentPrice = SymbolInfoDouble(Symbol(), SYMBOL_BID);
| |||
double profitPips = MathAbs(currentPrice - avgPrice) /
| |||
(SymbolInfoDouble(Symbol(), SYMBOL_POINT) * 10);
| |||
| |||
// Breakeven both at +10 pips averaged
| |||
if(profitPips >= 10 && currentSL < avgPrice)
| |||
{
| |||
double newSL = avgPrice + 2 * SymbolInfoDouble(Symbol(), SYMBOL_POINT) * 10;
| |||
ModifyPosition(ticket, NormalizeDouble(newSL, _Digits), currentTP);
| |||
}
| |||
| |||
// Trail at structure when +40 pips
| |||
if(profitPips >= 40)
| |||
{
| |||
double newSL = GetStructureLevel(PERIOD_M15);
| |||
double buffer = 3 * SymbolInfoDouble(Symbol(), SYMBOL_POINT) * 10;
| |||
| |||
if(newSL > currentSL)
| |||
ModifyPosition(ticket, NormalizeDouble(newSL - buffer, _Digits), currentTP);
| |||
}
| |||
}
| |||
}
| |||
| |||
//+------------------------------------------------------------------+
| |||
//| GET STRUCTURE LEVEL |
| |||
//+------------------------------------------------------------------+
| |||
double GetStructureLevel(ENUM_TIMEFRAMES tf)
| |||
{
| |||
int lowest = iLowest(Symbol(), tf, MODE_LOW, 10, 1);
| |||
return iLow(Symbol(), tf, lowest);
| |||
}
| |||
| |||
//+------------------------------------------------------------------+
| |||
//| EXECUTE TRADE |
| |||
//+------------------------------------------------------------------+
| |||
bool ExecuteTrade(int direction, double lots, double sl, double tp, string comment)
| |||
{
| |||
MqlTradeRequest request = {};
| |||
MqlTradeResult result = {};
| |||
| |||
double price = (direction == ORDER_TYPE_SELL) ?
| |||
SymbolInfoDouble(Symbol(), SYMBOL_BID) :
| |||
SymbolInfoDouble(Symbol(), SYMBOL_ASK);
| |||
| |||
request.action = TRADE_ACTION_DEAL;
| |||
request.symbol = Symbol();
| |||
request.volume = lots;
| |||
request.type = direction;
| |||
request.price = price;
| |||
request.sl = sl;
| |||
request.tp = tp;
| |||
request.deviation = 10;
| |||
request.magic = 123456;
| |||
request.comment = comment;
| |||
| |||
if(!OrderSend(request, result))
| |||
{
| |||
Print("OrderSend failed: ", GetLastError());
| |||
return false;
| |||
}
| |||
return true;
| |||
}
| |||
| |||
//+------------------------------------------------------------------+
| |||
//| MODIFY POSITION |
| |||
//+------------------------------------------------------------------+
| |||
bool ModifyPosition(ulong ticket, double sl, double tp)
| |||
{
| |||
MqlTradeRequest request = {};
| |||
MqlTradeResult result = {};
| |||
| |||
request.action = TRADE_ACTION_SLTP;
| |||
request.position = ticket;
| |||
request.symbol = Symbol();
| |||
request.sl = sl;
| |||
request.tp = tp;
| |||
| |||
return OrderSend(request, result);
| |||
}
| |||
| |||
//+------------------------------------------------------------------+
| |||
//| CHECK IF HAS OPEN POSITION |
| |||
//+------------------------------------------------------------------+
| |||
bool HasOpenPosition(string keyword)
| |||
{
| |||
for(int i = PositionsTotal() - 1; i >= 0; i--)
| |||
{
| |||
ulong ticket = PositionGetTicket(i);
| |||
if(ticket <= 0) continue;
| |||
if(PositionGetString(POSITION_SYMBOL) != Symbol()) continue;
| |||
| |||
string comment = PositionGetString(POSITION_COMMENT);
| |||
if(StringFind(comment, keyword) != -1) return true;
| |||
}
| |||
return false;
| |||
}
| |||
| |||
//+------------------------------------------------------------------+
| |||
//| RESET SETUP |
| |||
//+------------------------------------------------------------------+
| |||
void ResetToPhaseNone()
| |||
{
| |||
currentPhase = PHASE_NONE;
| |||
activeSetup.swingHigh = 0;
| |||
activeSetup.swingLow = 0;
| |||
activeSetup.fib1278Level = 0;
| |||
activeSetup.entry1278Price = 0;
| |||
activeSetup.newSwingHigh = 0;
| |||
activeSetup.swingEstablished = false;
| |||
Print("Setup reset - hunting for new 127.8% opportunity");
| |||
}
| |||
//+------------------------------------------------------------------+
|