931 lines
32 KiB
MQL5
931 lines
32 KiB
MQL5
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| GoldSmartEA_Final.mq5 |
|
||
|
|
//| Erstellt für Dubai Trader|
|
||
|
|
//| XAUUSD - MT5 - Vollautomatisch - Final |
|
||
|
|
//| Version 2.0 |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
#property copyright "GoldSmartEA Final"
|
||
|
|
#property version "2.00"
|
||
|
|
#property strict
|
||
|
|
|
||
|
|
#include <Trade\Trade.mqh>
|
||
|
|
#include <Trade\PositionInfo.mqh>
|
||
|
|
|
||
|
|
CTrade trade;
|
||
|
|
CPositionInfo posInfo;
|
||
|
|
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| INPUT PARAMETER |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
|
||
|
|
input group "=== LOTS & PYRAMIDE ==="
|
||
|
|
input double Lot_Entry = 0.05; // Entry Lot (3x geöffnet)
|
||
|
|
input double Lot_Recovery1 = 0.10; // Recovery 1 Lot (2x bei -70 Pips)
|
||
|
|
input double Lot_Recovery2 = 0.20; // Recovery 2 Lot (1x bei -100 Pips)
|
||
|
|
input double TP1_Pips = 40.0; // Take Profit 1 (alle schließen hier)
|
||
|
|
input double TP2_Pips = 80.0; // Take Profit 2 (falls alleine offen)
|
||
|
|
input double TP3_Pips = 200.0; // Take Profit 3 (letzter Trade)
|
||
|
|
input double Trailing_Start = 30.0; // Trailing ab X Pips
|
||
|
|
input double Trailing_Step = 10.0; // Trailing Schritt
|
||
|
|
|
||
|
|
input group "=== RECOVERY EINSTELLUNGEN ==="
|
||
|
|
input int Recovery1_Pips = 70; // Recovery 1 bei -X Pips
|
||
|
|
input int Recovery2_Pips = 100; // Recovery 2 bei -X Pips
|
||
|
|
input int MinConfirmations = 3; // Mindest Bestätigungen (von 4)
|
||
|
|
|
||
|
|
input group "=== PARTIAL PROFIT LOCK ==="
|
||
|
|
input double Partial1_Pips = 30.0; // Erste Teilschließung bei X Pips
|
||
|
|
input double Partial1_Percent = 30.0; // % der Position schließen
|
||
|
|
input double Partial2_Pips = 60.0; // Zweite Teilschließung
|
||
|
|
input double Partial2_Percent = 30.0; // % der Position schließen
|
||
|
|
|
||
|
|
input group "=== RISK MANAGEMENT ==="
|
||
|
|
input double DailyLossStop = 10.0; // Tagesverlust Stop %
|
||
|
|
input double PartialCloseAt = 5.0; // Notfall Partial Close %
|
||
|
|
input double SpreadMaxPips = 5.0; // Max Spread in Pips
|
||
|
|
input double MinBodyRatio = 0.3; // Min Kerzenkörper Ratio
|
||
|
|
|
||
|
|
input group "=== SESSION FILTER (Dubai GMT+4) ==="
|
||
|
|
input int Asia_Start = 1; // Asia Start (01:00)
|
||
|
|
input int Asia_End = 9; // Asia Ende (09:00)
|
||
|
|
input int NY_Start = 18; // NY Start nach News (18:00)
|
||
|
|
input int NY_End = 23; // NY Ende (23:00)
|
||
|
|
input int News_Block_Start = 16; // News Sperre Start
|
||
|
|
input int News_Block_Mins = 30; // News Sperre Minuten
|
||
|
|
input bool No_Friday_Eve = true; // Freitag Abend gesperrt
|
||
|
|
input int Friday_Stop = 20; // Freitag Stop Uhrzeit
|
||
|
|
input bool Close_Before_NY = true; // Asia Trades vor NY schließen
|
||
|
|
input bool Close_Before_WE = true; // Trades vor Wochenende schließen
|
||
|
|
|
||
|
|
input group "=== INDIKATOREN ==="
|
||
|
|
input int EMA_Fast = 20; // EMA Fast
|
||
|
|
input int EMA_Slow = 50; // EMA Slow
|
||
|
|
input int EMA_H4 = 200; // H4 Trend EMA
|
||
|
|
input int RSI_Period = 14; // RSI Periode
|
||
|
|
input double RSI_OB = 75.0; // RSI Überkauft (für Recovery)
|
||
|
|
input double RSI_OS = 25.0; // RSI Überverkauft (für Recovery)
|
||
|
|
input int ATR_Period = 14; // ATR Periode
|
||
|
|
input double ATR_SL_Multi = 1.5; // ATR Stop Loss Multiplikator
|
||
|
|
input double ATR_TP_Multi = 3.0; // ATR Take Profit Multiplikator
|
||
|
|
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| GLOBALE VARIABLEN |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
double PipSize = 0.1;
|
||
|
|
double DailyStartBalance = 0;
|
||
|
|
bool DailyStopReached = false;
|
||
|
|
bool EmergencyPartial = false;
|
||
|
|
datetime LastBarTime = 0;
|
||
|
|
int LastDay = -1;
|
||
|
|
|
||
|
|
// Indikatoren Handles
|
||
|
|
int H_EMA_Fast, H_EMA_Slow, H_EMA_H4, H_RSI, H_ATR;
|
||
|
|
int H_EMA_Fast_H4, H_RSI_H4;
|
||
|
|
|
||
|
|
// Asian Range
|
||
|
|
double AsianHigh = 0;
|
||
|
|
double AsianLow = 0;
|
||
|
|
bool AsianRangeSet = false;
|
||
|
|
|
||
|
|
// Trade Tracking
|
||
|
|
ulong EntryTickets[3]; // 3 Entry Trades
|
||
|
|
ulong R1Tickets[2]; // 2 Recovery 1 Trades
|
||
|
|
ulong R1Ticket2; // 1 Recovery 2 Trade
|
||
|
|
bool R1Opened = false;
|
||
|
|
bool R2Opened = false;
|
||
|
|
bool TP1Hit = false;
|
||
|
|
|
||
|
|
// Partial Close Tracking
|
||
|
|
bool Partial1Done = false;
|
||
|
|
bool Partial2Done = false;
|
||
|
|
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| INITIALISIERUNG |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
int OnInit()
|
||
|
|
{
|
||
|
|
PipSize = _Point * 10;
|
||
|
|
|
||
|
|
// H1 Indikatoren
|
||
|
|
H_EMA_Fast = iMA(_Symbol, PERIOD_H1, EMA_Fast, 0, MODE_EMA, PRICE_CLOSE);
|
||
|
|
H_EMA_Slow = iMA(_Symbol, PERIOD_H1, EMA_Slow, 0, MODE_EMA, PRICE_CLOSE);
|
||
|
|
H_RSI = iRSI(_Symbol, PERIOD_H1, RSI_Period, PRICE_CLOSE);
|
||
|
|
H_ATR = iATR(_Symbol, PERIOD_H1, ATR_Period);
|
||
|
|
|
||
|
|
// H4 Indikatoren
|
||
|
|
H_EMA_Fast_H4 = iMA(_Symbol, PERIOD_H4, EMA_Fast, 0, MODE_EMA, PRICE_CLOSE);
|
||
|
|
H_EMA_H4 = iMA(_Symbol, PERIOD_H4, EMA_H4, 0, MODE_EMA, PRICE_CLOSE);
|
||
|
|
H_RSI_H4 = iRSI(_Symbol, PERIOD_H4, RSI_Period, PRICE_CLOSE);
|
||
|
|
|
||
|
|
if(H_EMA_Fast == INVALID_HANDLE || H_EMA_Slow == INVALID_HANDLE ||
|
||
|
|
H_RSI == INVALID_HANDLE || H_ATR == INVALID_HANDLE ||
|
||
|
|
H_EMA_H4 == INVALID_HANDLE)
|
||
|
|
{
|
||
|
|
Print("❌ Fehler Indikatoren!");
|
||
|
|
return INIT_FAILED;
|
||
|
|
}
|
||
|
|
|
||
|
|
DailyStartBalance = AccountInfoDouble(ACCOUNT_BALANCE);
|
||
|
|
trade.SetExpertMagicNumber(789456);
|
||
|
|
ArrayInitialize(EntryTickets, 0);
|
||
|
|
ArrayInitialize(R1Tickets, 0);
|
||
|
|
R1Ticket2 = 0;
|
||
|
|
|
||
|
|
Print("✅ GoldSmartEA Final gestartet | Balance: $", DailyStartBalance);
|
||
|
|
return INIT_SUCCEEDED;
|
||
|
|
}
|
||
|
|
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| DEINIT |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
void OnDeinit(const int reason)
|
||
|
|
{
|
||
|
|
IndicatorRelease(H_EMA_Fast);
|
||
|
|
IndicatorRelease(H_EMA_Slow);
|
||
|
|
IndicatorRelease(H_RSI);
|
||
|
|
IndicatorRelease(H_ATR);
|
||
|
|
IndicatorRelease(H_EMA_Fast_H4);
|
||
|
|
IndicatorRelease(H_EMA_H4);
|
||
|
|
IndicatorRelease(H_RSI_H4);
|
||
|
|
}
|
||
|
|
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| HAUPTFUNKTION |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
void OnTick()
|
||
|
|
{
|
||
|
|
// Täglichen Reset checken
|
||
|
|
CheckDailyReset();
|
||
|
|
|
||
|
|
// Tagesverlust gecheckt
|
||
|
|
if(DailyStopReached)
|
||
|
|
{
|
||
|
|
CloseAllTrades();
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
if(CheckDailyLoss())
|
||
|
|
{
|
||
|
|
Print("🚨 TAGESVERLUST LIMIT! EA stoppt heute.");
|
||
|
|
DailyStopReached = true;
|
||
|
|
CloseAllTrades();
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Session Ende Management
|
||
|
|
ManageSessionClose();
|
||
|
|
|
||
|
|
// Notfall Partial Close
|
||
|
|
CheckEmergencyPartial();
|
||
|
|
|
||
|
|
// Trailing Stop
|
||
|
|
ManageTrailingStop();
|
||
|
|
|
||
|
|
// Partial Profit Lock
|
||
|
|
ManagePartialProfitLock();
|
||
|
|
|
||
|
|
// TP1 Check → alle schließen
|
||
|
|
CheckTP1Hit();
|
||
|
|
|
||
|
|
// Recovery Trades
|
||
|
|
CheckRecovery();
|
||
|
|
|
||
|
|
// Neue H1 Kerze abwarten
|
||
|
|
datetime currentBar = iTime(_Symbol, PERIOD_H1, 0);
|
||
|
|
if(currentBar == LastBarTime) return;
|
||
|
|
LastBarTime = currentBar;
|
||
|
|
|
||
|
|
// Asian Range updaten
|
||
|
|
UpdateAsianRange();
|
||
|
|
|
||
|
|
// Session erlaubt?
|
||
|
|
if(!IsSessionAllowed()) return;
|
||
|
|
|
||
|
|
// Spread okay?
|
||
|
|
if(!IsSpreadOkay()) return;
|
||
|
|
|
||
|
|
// Schon Trades offen?
|
||
|
|
if(CountMyTrades() >= 3) return;
|
||
|
|
|
||
|
|
// Nur neue Trades wenn keine Entry Trades offen
|
||
|
|
if(HasOpenEntryTrades()) return;
|
||
|
|
|
||
|
|
// Signal holen
|
||
|
|
int signal = GetSignal();
|
||
|
|
|
||
|
|
if(signal == 1)
|
||
|
|
{
|
||
|
|
OpenEntryTrades(ORDER_TYPE_BUY);
|
||
|
|
}
|
||
|
|
else if(signal == -1)
|
||
|
|
{
|
||
|
|
OpenEntryTrades(ORDER_TYPE_SELL);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| SIGNAL BERECHNUNG - Kombiniert H1 + H4 |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
int GetSignal()
|
||
|
|
{
|
||
|
|
// H1 Daten
|
||
|
|
double emaFast[], emaSlow[], rsi[], atr[];
|
||
|
|
ArraySetAsSeries(emaFast, true);
|
||
|
|
ArraySetAsSeries(emaSlow, true);
|
||
|
|
ArraySetAsSeries(rsi, true);
|
||
|
|
ArraySetAsSeries(atr, true);
|
||
|
|
|
||
|
|
if(CopyBuffer(H_EMA_Fast, 0, 0, 4, emaFast) < 4) return 0;
|
||
|
|
if(CopyBuffer(H_EMA_Slow, 0, 0, 4, emaSlow) < 4) return 0;
|
||
|
|
if(CopyBuffer(H_RSI, 0, 0, 4, rsi) < 4) return 0;
|
||
|
|
if(CopyBuffer(H_ATR, 0, 0, 2, atr) < 2) return 0;
|
||
|
|
|
||
|
|
// H4 Trend Filter
|
||
|
|
double emaH4Fast[], emaH4[];
|
||
|
|
ArraySetAsSeries(emaH4Fast, true);
|
||
|
|
ArraySetAsSeries(emaH4, true);
|
||
|
|
if(CopyBuffer(H_EMA_Fast_H4, 0, 0, 2, emaH4Fast) < 2) return 0;
|
||
|
|
if(CopyBuffer(H_EMA_H4, 0, 0, 2, emaH4) < 2) return 0;
|
||
|
|
|
||
|
|
// Kerzen H1
|
||
|
|
double close[], open[], high[], low[];
|
||
|
|
ArraySetAsSeries(close, true);
|
||
|
|
ArraySetAsSeries(open, true);
|
||
|
|
ArraySetAsSeries(high, true);
|
||
|
|
ArraySetAsSeries(low, true);
|
||
|
|
|
||
|
|
if(CopyClose(_Symbol, PERIOD_H1, 0, 4, close) < 4) return 0;
|
||
|
|
if(CopyOpen(_Symbol, PERIOD_H1, 0, 4, open) < 4) return 0;
|
||
|
|
if(CopyHigh(_Symbol, PERIOD_H1, 0, 4, high) < 4) return 0;
|
||
|
|
if(CopyLow(_Symbol, PERIOD_H1, 0, 4, low) < 4) return 0;
|
||
|
|
|
||
|
|
// H4 Trend Richtung
|
||
|
|
bool h4Bullish = emaH4Fast[1] > emaH4[1];
|
||
|
|
bool h4Bearish = emaH4Fast[1] < emaH4[1];
|
||
|
|
|
||
|
|
// Letzte geschlossene Kerze
|
||
|
|
double c0 = close[1], o0 = open[1], h0 = high[1], l0 = low[1];
|
||
|
|
double c1 = close[2], o1 = open[2];
|
||
|
|
double body0 = MathAbs(c0 - o0);
|
||
|
|
double range0 = h0 - l0;
|
||
|
|
double wick_down = (o0 > c0) ? (c0 - l0) : (o0 - l0); // Unterer Docht
|
||
|
|
double wick_up = (o0 > c0) ? (h0 - o0) : (h0 - c0); // Oberer Docht
|
||
|
|
|
||
|
|
// Kerze stark genug?
|
||
|
|
if(range0 < atr[1] * 0.3) return 0;
|
||
|
|
|
||
|
|
// Asian Range Breakout Signal
|
||
|
|
bool asianBreakoutBuy = AsianRangeSet && close[1] > AsianHigh && close[2] <= AsianHigh;
|
||
|
|
bool asianBreakoutSell = AsianRangeSet && close[1] < AsianLow && close[2] >= AsianLow;
|
||
|
|
|
||
|
|
// Runde Levels (Support/Resistance)
|
||
|
|
double roundLevel = MathRound(close[1] / 50.0) * 50.0;
|
||
|
|
bool nearRoundLevel = MathAbs(close[1] - roundLevel) < 5.0 * PipSize;
|
||
|
|
|
||
|
|
// ===== BUY SIGNAL =====
|
||
|
|
bool ema_bull = emaFast[1] > emaSlow[1]; // EMA Aufwärts
|
||
|
|
bool rsi_bull = rsi[2] < 45 && rsi[1] > 45; // RSI dreht hoch
|
||
|
|
bool bull_engulf = c0 > o0 && c0 > c1 && o0 < o1; // Bullisch Engulfing
|
||
|
|
bool bull_doji = wick_down > body0 * 2.0 && c0 > o0; // Langer Docht unten
|
||
|
|
bool liq_sweep_bull = l0 < low[2] && c0 > open[2]; // Liquidity Sweep
|
||
|
|
|
||
|
|
int buyScore = 0;
|
||
|
|
if(h4Bullish) buyScore++;
|
||
|
|
if(ema_bull) buyScore++;
|
||
|
|
if(rsi_bull) buyScore++;
|
||
|
|
if(bull_engulf || bull_doji || liq_sweep_bull) buyScore++;
|
||
|
|
if(asianBreakoutBuy || nearRoundLevel) buyScore++;
|
||
|
|
|
||
|
|
// ===== SELL SIGNAL =====
|
||
|
|
bool ema_bear = emaFast[1] < emaSlow[1]; // EMA Abwärts
|
||
|
|
bool rsi_bear = rsi[2] > 55 && rsi[1] < 55; // RSI dreht runter
|
||
|
|
bool bear_engulf = c0 < o0 && c0 < c1 && o0 > o1; // Bearisch Engulfing
|
||
|
|
bool bear_doji = wick_up > body0 * 2.0 && c0 < o0; // Langer Docht oben
|
||
|
|
bool liq_sweep_bear = h0 > high[2] && c0 < open[2]; // Liquidity Sweep
|
||
|
|
|
||
|
|
int sellScore = 0;
|
||
|
|
if(h4Bearish) sellScore++;
|
||
|
|
if(ema_bear) sellScore++;
|
||
|
|
if(rsi_bear) sellScore++;
|
||
|
|
if(bear_engulf || bear_doji || liq_sweep_bear) sellScore++;
|
||
|
|
if(asianBreakoutSell || nearRoundLevel) sellScore++;
|
||
|
|
|
||
|
|
// Mindestens 3 von 5 Bestätigungen
|
||
|
|
if(buyScore >= 3 && buyScore > sellScore) return 1;
|
||
|
|
if(sellScore >= 3 && sellScore > buyScore) return -1;
|
||
|
|
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| RECOVERY BESTÄTIGUNGEN |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
int GetRecoveryConfirmations(int direction)
|
||
|
|
{
|
||
|
|
double rsi[], rsiH4[];
|
||
|
|
ArraySetAsSeries(rsi, true);
|
||
|
|
ArraySetAsSeries(rsiH4, true);
|
||
|
|
|
||
|
|
if(CopyBuffer(H_RSI, 0, 0, 3, rsi) < 3) return 0;
|
||
|
|
if(CopyBuffer(H_RSI_H4, 0, 0, 3, rsiH4) < 3) return 0;
|
||
|
|
|
||
|
|
double high[], low[], close[], open[];
|
||
|
|
ArraySetAsSeries(high, true);
|
||
|
|
ArraySetAsSeries(low, true);
|
||
|
|
ArraySetAsSeries(close, true);
|
||
|
|
ArraySetAsSeries(open, true);
|
||
|
|
|
||
|
|
if(CopyHigh(_Symbol, PERIOD_H1, 0, 3, high) < 3) return 0;
|
||
|
|
if(CopyLow(_Symbol, PERIOD_H1, 0, 3, low) < 3) return 0;
|
||
|
|
if(CopyClose(_Symbol, PERIOD_H1, 0, 3, close) < 3) return 0;
|
||
|
|
if(CopyOpen(_Symbol, PERIOD_H1, 0, 3, open) < 3) return 0;
|
||
|
|
|
||
|
|
double emaH4Fast[], emaH4[];
|
||
|
|
ArraySetAsSeries(emaH4Fast, true);
|
||
|
|
ArraySetAsSeries(emaH4, true);
|
||
|
|
if(CopyBuffer(H_EMA_Fast_H4, 0, 0, 2, emaH4Fast) < 2) return 0;
|
||
|
|
if(CopyBuffer(H_EMA_H4, 0, 0, 2, emaH4) < 2) return 0;
|
||
|
|
|
||
|
|
int confirmations = 0;
|
||
|
|
double body = MathAbs(close[1] - open[1]);
|
||
|
|
double range = high[1] - low[1];
|
||
|
|
double wick_down = MathMin(open[1], close[1]) - low[1];
|
||
|
|
double wick_up = high[1] - MathMax(open[1], close[1]);
|
||
|
|
|
||
|
|
if(direction == 1) // BUY Recovery
|
||
|
|
{
|
||
|
|
if(rsi[1] < RSI_OS) confirmations++; // RSI extrem überverkauft
|
||
|
|
if(wick_down > body * 2.0) confirmations++; // Langer Docht unten
|
||
|
|
if(emaH4Fast[1] > emaH4[1]) confirmations++; // H4 noch bullisch
|
||
|
|
if(close[1] > open[1] && close[1] > close[2]) confirmations++; // Bullische Erholungskerze
|
||
|
|
}
|
||
|
|
else // SELL Recovery
|
||
|
|
{
|
||
|
|
if(rsi[1] > RSI_OB) confirmations++; // RSI extrem überkauft
|
||
|
|
if(wick_up > body * 2.0) confirmations++; // Langer Docht oben
|
||
|
|
if(emaH4Fast[1] < emaH4[1]) confirmations++; // H4 noch bearisch
|
||
|
|
if(close[1] < open[1] && close[1] < close[2]) confirmations++; // Bearische Erholungskerze
|
||
|
|
}
|
||
|
|
|
||
|
|
return confirmations;
|
||
|
|
}
|
||
|
|
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| 3 ENTRY TRADES ÖFFNEN |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
void OpenEntryTrades(ENUM_ORDER_TYPE type)
|
||
|
|
{
|
||
|
|
double atr[];
|
||
|
|
ArraySetAsSeries(atr, true);
|
||
|
|
if(CopyBuffer(H_ATR, 0, 0, 2, atr) < 2) return;
|
||
|
|
|
||
|
|
double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
|
||
|
|
double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
|
||
|
|
double atrVal = atr[1];
|
||
|
|
|
||
|
|
// Dynamischer SL und TP basierend auf ATR
|
||
|
|
double sl_distance = atrVal * ATR_SL_Multi;
|
||
|
|
double tp1_dist = TP1_Pips * PipSize;
|
||
|
|
double tp2_dist = TP2_Pips * PipSize;
|
||
|
|
double tp3_dist = TP3_Pips * PipSize;
|
||
|
|
|
||
|
|
ArrayInitialize(EntryTickets, 0);
|
||
|
|
R1Opened = false;
|
||
|
|
R2Opened = false;
|
||
|
|
TP1Hit = false;
|
||
|
|
Partial1Done = false;
|
||
|
|
Partial2Done = false;
|
||
|
|
|
||
|
|
for(int i = 0; i < 3; i++)
|
||
|
|
{
|
||
|
|
double tp_dist;
|
||
|
|
if(i == 0) tp_dist = tp1_dist;
|
||
|
|
else if(i == 1) tp_dist = tp2_dist;
|
||
|
|
else tp_dist = tp3_dist;
|
||
|
|
|
||
|
|
double sl, tp, price;
|
||
|
|
|
||
|
|
if(type == ORDER_TYPE_BUY)
|
||
|
|
{
|
||
|
|
price = ask;
|
||
|
|
sl = NormalizeDouble(price - sl_distance, _Digits);
|
||
|
|
tp = NormalizeDouble(price + tp_dist, _Digits);
|
||
|
|
if(trade.Buy(Lot_Entry, _Symbol, price, sl, tp, "GS_Entry_" + IntegerToString(i+1)))
|
||
|
|
{
|
||
|
|
EntryTickets[i] = trade.ResultOrder();
|
||
|
|
Print("✅ BUY Entry ", i+1, " | TP: +", (int)(tp_dist/PipSize), " Pips");
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
price = bid;
|
||
|
|
sl = NormalizeDouble(price + sl_distance, _Digits);
|
||
|
|
tp = NormalizeDouble(price - tp_dist, _Digits);
|
||
|
|
if(trade.Sell(Lot_Entry, _Symbol, price, sl, tp, "GS_Entry_" + IntegerToString(i+1)))
|
||
|
|
{
|
||
|
|
EntryTickets[i] = trade.ResultOrder();
|
||
|
|
Print("✅ SELL Entry ", i+1, " | TP: +", (int)(tp_dist/PipSize), " Pips");
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| TP1 CHECK → ALLE SCHLIESSEN |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
void CheckTP1Hit()
|
||
|
|
{
|
||
|
|
if(TP1Hit) return;
|
||
|
|
if(EntryTickets[0] == 0) return;
|
||
|
|
|
||
|
|
// Prüfe ob Trade 1 (TP1) geschlossen wurde durch Gewinn
|
||
|
|
bool trade1Closed = !PositionSelectByTicket(EntryTickets[0]);
|
||
|
|
|
||
|
|
if(trade1Closed && EntryTickets[0] != 0)
|
||
|
|
{
|
||
|
|
// Prüfe ob es durch TP geschlossen wurde (nicht SL)
|
||
|
|
if(IsClosedByTP(EntryTickets[0]))
|
||
|
|
{
|
||
|
|
TP1Hit = true;
|
||
|
|
Print("🎯 TP1 erreicht! Schließe alle Trades...");
|
||
|
|
CloseAllMyTrades();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| Prüfen ob Trade durch TP geschlossen |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
bool IsClosedByTP(ulong ticket)
|
||
|
|
{
|
||
|
|
if(HistoryDealSelect(ticket)) return false;
|
||
|
|
|
||
|
|
HistorySelect(TimeCurrent() - 86400, TimeCurrent());
|
||
|
|
int deals = HistoryDealsTotal();
|
||
|
|
for(int i = deals - 1; i >= 0; i--)
|
||
|
|
{
|
||
|
|
ulong dealTicket = HistoryDealGetTicket(i);
|
||
|
|
if(HistoryDealGetInteger(dealTicket, DEAL_POSITION_ID) == ticket)
|
||
|
|
{
|
||
|
|
double profit = HistoryDealGetDouble(dealTicket, DEAL_PROFIT);
|
||
|
|
return profit > 0;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| RECOVERY TRADES |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
void CheckRecovery()
|
||
|
|
{
|
||
|
|
if(EntryTickets[0] == 0) return;
|
||
|
|
|
||
|
|
// Richtung der Entry Trades bestimmen
|
||
|
|
int direction = 0;
|
||
|
|
for(int i = 0; i < 3; i++)
|
||
|
|
{
|
||
|
|
if(EntryTickets[i] != 0 && PositionSelectByTicket(EntryTickets[i]))
|
||
|
|
{
|
||
|
|
direction = (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) ? 1 : -1;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if(direction == 0) return;
|
||
|
|
|
||
|
|
// Durchschnittlicher Verlust der Entry Trades in Pips
|
||
|
|
double avgLossPips = GetAverageLossPips();
|
||
|
|
|
||
|
|
// Recovery 1: Bei -70 Pips
|
||
|
|
if(!R1Opened && avgLossPips >= Recovery1_Pips)
|
||
|
|
{
|
||
|
|
int confirmations = GetRecoveryConfirmations(direction);
|
||
|
|
if(confirmations >= MinConfirmations)
|
||
|
|
{
|
||
|
|
Print("🔄 Recovery 1 öffnen | Verlust: ", avgLossPips, " Pips | Bestätigungen: ", confirmations);
|
||
|
|
OpenRecoveryTrades(direction, 1);
|
||
|
|
R1Opened = true;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
Print("⏳ Recovery 1 warten | Nur ", confirmations, "/", MinConfirmations, " Bestätigungen");
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// Recovery 2: Bei -100 Pips
|
||
|
|
if(R1Opened && !R2Opened && avgLossPips >= Recovery2_Pips)
|
||
|
|
{
|
||
|
|
int confirmations = GetRecoveryConfirmations(direction);
|
||
|
|
if(confirmations >= MinConfirmations)
|
||
|
|
{
|
||
|
|
Print("🔄 Recovery 2 öffnen | Verlust: ", avgLossPips, " Pips | Bestätigungen: ", confirmations);
|
||
|
|
OpenRecoveryTrades(direction, 2);
|
||
|
|
R2Opened = true;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| Recovery Trades öffnen |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
void OpenRecoveryTrades(int direction, int level)
|
||
|
|
{
|
||
|
|
double atr[];
|
||
|
|
ArraySetAsSeries(atr, true);
|
||
|
|
if(CopyBuffer(H_ATR, 0, 0, 2, atr) < 2) return;
|
||
|
|
|
||
|
|
double sl_dist = atr[1] * ATR_SL_Multi;
|
||
|
|
double tp_dist = TP1_Pips * PipSize; // Alle Recovery bei TP1 schließen
|
||
|
|
|
||
|
|
int numTrades = (level == 1) ? 2 : 1;
|
||
|
|
double lot = (level == 1) ? Lot_Recovery1 : Lot_Recovery2;
|
||
|
|
|
||
|
|
for(int i = 0; i < numTrades; i++)
|
||
|
|
{
|
||
|
|
if(direction == 1)
|
||
|
|
{
|
||
|
|
double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
|
||
|
|
double sl = NormalizeDouble(ask - sl_dist, _Digits);
|
||
|
|
double tp = NormalizeDouble(ask + tp_dist, _Digits);
|
||
|
|
trade.Buy(lot, _Symbol, ask, sl, tp, "GS_R" + IntegerToString(level));
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
|
||
|
|
double sl = NormalizeDouble(bid + sl_dist, _Digits);
|
||
|
|
double tp = NormalizeDouble(bid - tp_dist, _Digits);
|
||
|
|
trade.Sell(lot, _Symbol, bid, sl, tp, "GS_R" + IntegerToString(level));
|
||
|
|
}
|
||
|
|
Print("✅ Recovery ", level, " Trade ", i+1, " geöffnet | Lot: ", lot);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| PARTIAL PROFIT LOCK |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
void ManagePartialProfitLock()
|
||
|
|
{
|
||
|
|
for(int i = 0; i < 3; i++)
|
||
|
|
{
|
||
|
|
if(EntryTickets[i] == 0) continue;
|
||
|
|
if(!PositionSelectByTicket(EntryTickets[i])) continue;
|
||
|
|
|
||
|
|
double openPrice = PositionGetDouble(POSITION_PRICE_OPEN);
|
||
|
|
double curPrice;
|
||
|
|
ENUM_POSITION_TYPE type = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
|
||
|
|
|
||
|
|
if(type == POSITION_TYPE_BUY)
|
||
|
|
curPrice = SymbolInfoDouble(_Symbol, SYMBOL_BID);
|
||
|
|
else
|
||
|
|
curPrice = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
|
||
|
|
|
||
|
|
double profitPips = (type == POSITION_TYPE_BUY) ?
|
||
|
|
(curPrice - openPrice) / PipSize :
|
||
|
|
(openPrice - curPrice) / PipSize;
|
||
|
|
|
||
|
|
// Erste Teilschließung
|
||
|
|
if(!Partial1Done && profitPips >= Partial1_Pips && i == 2) // Nur auf Trade 3
|
||
|
|
{
|
||
|
|
double vol = PositionGetDouble(POSITION_VOLUME);
|
||
|
|
double partial = NormalizeDouble(vol * Partial1_Percent / 100.0, 2);
|
||
|
|
if(partial >= 0.01)
|
||
|
|
{
|
||
|
|
trade.PositionClosePartial(EntryTickets[i], partial);
|
||
|
|
Print("💰 Partial 1: ", Partial1_Percent, "% bei +", profitPips, " Pips geschlossen");
|
||
|
|
Partial1Done = true;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// Zweite Teilschließung + Break Even auf Rest
|
||
|
|
if(Partial1Done && !Partial2Done && profitPips >= Partial2_Pips && i == 2)
|
||
|
|
{
|
||
|
|
double vol = PositionGetDouble(POSITION_VOLUME);
|
||
|
|
double partial = NormalizeDouble(vol * Partial2_Percent / 100.0, 2);
|
||
|
|
if(partial >= 0.01)
|
||
|
|
{
|
||
|
|
trade.PositionClosePartial(EntryTickets[i], partial);
|
||
|
|
Print("💰 Partial 2: ", Partial2_Percent, "% bei +", profitPips, " Pips geschlossen");
|
||
|
|
Partial2Done = true;
|
||
|
|
|
||
|
|
// Break Even auf alle verbleibenden Trades
|
||
|
|
SetBreakEvenAll();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| BREAK EVEN AUF ALLE TRADES |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
void SetBreakEvenAll()
|
||
|
|
{
|
||
|
|
for(int i = PositionsTotal() - 1; i >= 0; i--)
|
||
|
|
{
|
||
|
|
if(!posInfo.SelectByIndex(i)) continue;
|
||
|
|
if(posInfo.Magic() != 789456) continue;
|
||
|
|
|
||
|
|
double openPrice = posInfo.PriceOpen();
|
||
|
|
double currentSL = posInfo.StopLoss();
|
||
|
|
double spread = (SymbolInfoDouble(_Symbol, SYMBOL_ASK) - SymbolInfoDouble(_Symbol, SYMBOL_BID));
|
||
|
|
|
||
|
|
double newSL;
|
||
|
|
if(posInfo.PositionType() == POSITION_TYPE_BUY)
|
||
|
|
{
|
||
|
|
newSL = NormalizeDouble(openPrice + spread, _Digits);
|
||
|
|
if(newSL > currentSL)
|
||
|
|
{
|
||
|
|
trade.PositionModify(posInfo.Ticket(), newSL, posInfo.TakeProfit());
|
||
|
|
Print("🔒 Break Even gesetzt auf ", newSL);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
newSL = NormalizeDouble(openPrice - spread, _Digits);
|
||
|
|
if(newSL < currentSL || currentSL == 0)
|
||
|
|
{
|
||
|
|
trade.PositionModify(posInfo.Ticket(), newSL, posInfo.TakeProfit());
|
||
|
|
Print("🔒 Break Even gesetzt auf ", newSL);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| TRAILING STOP |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
void ManageTrailingStop()
|
||
|
|
{
|
||
|
|
for(int i = PositionsTotal() - 1; i >= 0; i--)
|
||
|
|
{
|
||
|
|
if(!posInfo.SelectByIndex(i)) continue;
|
||
|
|
if(posInfo.Magic() != 789456) continue;
|
||
|
|
|
||
|
|
double openPrice = posInfo.PriceOpen();
|
||
|
|
double currentSL = posInfo.StopLoss();
|
||
|
|
double currentTP = posInfo.TakeProfit();
|
||
|
|
|
||
|
|
if(posInfo.PositionType() == POSITION_TYPE_BUY)
|
||
|
|
{
|
||
|
|
double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
|
||
|
|
double profitPips = (bid - openPrice) / PipSize;
|
||
|
|
|
||
|
|
if(profitPips >= Trailing_Start)
|
||
|
|
{
|
||
|
|
double newSL = NormalizeDouble(bid - Trailing_Step * PipSize, _Digits);
|
||
|
|
if(newSL > currentSL)
|
||
|
|
{
|
||
|
|
trade.PositionModify(posInfo.Ticket(), newSL, currentTP);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
|
||
|
|
double profitPips = (openPrice - ask) / PipSize;
|
||
|
|
|
||
|
|
if(profitPips >= Trailing_Start)
|
||
|
|
{
|
||
|
|
double newSL = NormalizeDouble(ask + Trailing_Step * PipSize, _Digits);
|
||
|
|
if(newSL < currentSL || currentSL == 0)
|
||
|
|
{
|
||
|
|
trade.PositionModify(posInfo.Ticket(), newSL, currentTP);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| ASIAN RANGE BERECHNEN |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
void UpdateAsianRange()
|
||
|
|
{
|
||
|
|
MqlDateTime dt;
|
||
|
|
TimeToStruct(TimeLocal(), dt);
|
||
|
|
int hour = dt.hour;
|
||
|
|
|
||
|
|
// Am Ende der Asia Session Range festhalten
|
||
|
|
if(hour == Asia_End)
|
||
|
|
{
|
||
|
|
double hi[], lo[];
|
||
|
|
ArraySetAsSeries(hi, true);
|
||
|
|
ArraySetAsSeries(lo, true);
|
||
|
|
|
||
|
|
int bars = Asia_End - Asia_Start;
|
||
|
|
if(bars <= 0) bars = 8;
|
||
|
|
|
||
|
|
if(CopyHigh(_Symbol, PERIOD_H1, 0, bars, hi) >= bars &&
|
||
|
|
CopyLow(_Symbol, PERIOD_H1, 0, bars, lo) >= bars)
|
||
|
|
{
|
||
|
|
AsianHigh = hi[ArrayMaximum(hi, 0, bars)];
|
||
|
|
AsianLow = lo[ArrayMinimum(lo, 0, bars)];
|
||
|
|
AsianRangeSet = true;
|
||
|
|
Print("📊 Asian Range: High=", AsianHigh, " Low=", AsianLow);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// Reset für neuen Tag
|
||
|
|
if(hour == Asia_Start) AsianRangeSet = false;
|
||
|
|
}
|
||
|
|
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| SESSION CLOSE MANAGEMENT |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
void ManageSessionClose()
|
||
|
|
{
|
||
|
|
MqlDateTime dt;
|
||
|
|
TimeToStruct(TimeLocal(), dt);
|
||
|
|
int hour = dt.hour;
|
||
|
|
int dow = dt.day_of_week;
|
||
|
|
|
||
|
|
// Freitag Abend → alle schließen
|
||
|
|
if(No_Friday_Eve && dow == 5 && hour >= Friday_Stop)
|
||
|
|
{
|
||
|
|
if(CountMyTrades() > 0)
|
||
|
|
{
|
||
|
|
Print("📅 Freitag Abend → alle Trades schließen");
|
||
|
|
CloseAllMyTrades();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// Asia Trades vor NY schließen (profitable)
|
||
|
|
if(Close_Before_NY && hour == NY_Start - 1)
|
||
|
|
{
|
||
|
|
CloseProfitableTrades();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| NUR PROFITABLE TRADES SCHLIESSEN |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
void CloseProfitableTrades()
|
||
|
|
{
|
||
|
|
for(int i = PositionsTotal() - 1; i >= 0; i--)
|
||
|
|
{
|
||
|
|
if(!posInfo.SelectByIndex(i)) continue;
|
||
|
|
if(posInfo.Magic() != 789456) continue;
|
||
|
|
if(posInfo.Profit() > 0)
|
||
|
|
{
|
||
|
|
trade.PositionClose(posInfo.Ticket());
|
||
|
|
Print("✅ Profitabler Trade geschlossen vor Session Ende");
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| NOTFALL PARTIAL CLOSE |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
void CheckEmergencyPartial()
|
||
|
|
{
|
||
|
|
if(EmergencyPartial) return;
|
||
|
|
|
||
|
|
double balance = AccountInfoDouble(ACCOUNT_BALANCE);
|
||
|
|
double equity = AccountInfoDouble(ACCOUNT_EQUITY);
|
||
|
|
double lossPerc = ((balance - equity) / balance) * 100.0;
|
||
|
|
|
||
|
|
if(lossPerc >= PartialCloseAt)
|
||
|
|
{
|
||
|
|
Print("⚠️ NOTFALL Partial Close bei ", lossPerc, "% Verlust");
|
||
|
|
for(int i = PositionsTotal() - 1; i >= 0; i--)
|
||
|
|
{
|
||
|
|
if(!posInfo.SelectByIndex(i)) continue;
|
||
|
|
if(posInfo.Magic() != 789456) continue;
|
||
|
|
double halfLot = NormalizeDouble(posInfo.Volume() / 2.0, 2);
|
||
|
|
if(halfLot >= 0.01)
|
||
|
|
trade.PositionClosePartial(posInfo.Ticket(), halfLot);
|
||
|
|
}
|
||
|
|
EmergencyPartial = true;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| TAGESVERLUST PRÜFEN |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
bool CheckDailyLoss()
|
||
|
|
{
|
||
|
|
double equity = AccountInfoDouble(ACCOUNT_EQUITY);
|
||
|
|
double lossPerc = ((DailyStartBalance - equity) / DailyStartBalance) * 100.0;
|
||
|
|
return lossPerc >= DailyLossStop;
|
||
|
|
}
|
||
|
|
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| TÄGLICHEN RESET |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
void CheckDailyReset()
|
||
|
|
{
|
||
|
|
MqlDateTime dt;
|
||
|
|
TimeToStruct(TimeLocal(), dt);
|
||
|
|
|
||
|
|
if(dt.day != LastDay)
|
||
|
|
{
|
||
|
|
LastDay = dt.day;
|
||
|
|
DailyStartBalance = AccountInfoDouble(ACCOUNT_BALANCE);
|
||
|
|
DailyStopReached = false;
|
||
|
|
EmergencyPartial = false;
|
||
|
|
AsianRangeSet = false;
|
||
|
|
Print("📅 Neuer Tag Reset | Balance: $", DailyStartBalance);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| SPREAD PRÜFEN |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
bool IsSpreadOkay()
|
||
|
|
{
|
||
|
|
double spread = (double)(SymbolInfoInteger(_Symbol, SYMBOL_SPREAD)) * _Point;
|
||
|
|
double maxSpread = SpreadMaxPips * PipSize;
|
||
|
|
return spread <= maxSpread;
|
||
|
|
}
|
||
|
|
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| SESSION FILTER |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
bool IsSessionAllowed()
|
||
|
|
{
|
||
|
|
MqlDateTime dt;
|
||
|
|
TimeToStruct(TimeLocal(), dt);
|
||
|
|
int hour = dt.hour;
|
||
|
|
int min = dt.min;
|
||
|
|
int dow = dt.day_of_week;
|
||
|
|
|
||
|
|
if(dow == 0 || dow == 6) return false;
|
||
|
|
if(No_Friday_Eve && dow == 5 && hour >= Friday_Stop) return false;
|
||
|
|
if(hour == News_Block_Start && min < News_Block_Mins) return false;
|
||
|
|
|
||
|
|
// Asia Session
|
||
|
|
if(hour >= Asia_Start && hour < Asia_End) return true;
|
||
|
|
|
||
|
|
// NY Session nach News
|
||
|
|
if(hour >= NY_Start && hour <= NY_End) return true;
|
||
|
|
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| HILFSFUNKTIONEN |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
double GetAverageLossPips()
|
||
|
|
{
|
||
|
|
double totalLoss = 0;
|
||
|
|
int count = 0;
|
||
|
|
|
||
|
|
for(int i = 0; i < 3; i++)
|
||
|
|
{
|
||
|
|
if(EntryTickets[i] == 0) continue;
|
||
|
|
if(!PositionSelectByTicket(EntryTickets[i])) continue;
|
||
|
|
|
||
|
|
double openPrice = PositionGetDouble(POSITION_PRICE_OPEN);
|
||
|
|
ENUM_POSITION_TYPE type = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
|
||
|
|
double curPrice;
|
||
|
|
|
||
|
|
if(type == POSITION_TYPE_BUY)
|
||
|
|
curPrice = SymbolInfoDouble(_Symbol, SYMBOL_BID);
|
||
|
|
else
|
||
|
|
curPrice = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
|
||
|
|
|
||
|
|
double lossPips = (type == POSITION_TYPE_BUY) ?
|
||
|
|
(openPrice - curPrice) / PipSize :
|
||
|
|
(curPrice - openPrice) / PipSize;
|
||
|
|
|
||
|
|
if(lossPips > 0) { totalLoss += lossPips; count++; }
|
||
|
|
}
|
||
|
|
|
||
|
|
return count > 0 ? totalLoss / count : 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
bool HasOpenEntryTrades()
|
||
|
|
{
|
||
|
|
for(int i = 0; i < 3; i++)
|
||
|
|
{
|
||
|
|
if(EntryTickets[i] != 0 && PositionSelectByTicket(EntryTickets[i]))
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
int CountMyTrades()
|
||
|
|
{
|
||
|
|
int count = 0;
|
||
|
|
for(int i = PositionsTotal() - 1; i >= 0; i--)
|
||
|
|
{
|
||
|
|
if(!posInfo.SelectByIndex(i)) continue;
|
||
|
|
if(posInfo.Magic() == 789456) count++;
|
||
|
|
}
|
||
|
|
return count;
|
||
|
|
}
|
||
|
|
|
||
|
|
void CloseAllMyTrades()
|
||
|
|
{
|
||
|
|
for(int i = PositionsTotal() - 1; i >= 0; i--)
|
||
|
|
{
|
||
|
|
if(!posInfo.SelectByIndex(i)) continue;
|
||
|
|
if(posInfo.Magic() != 789456) continue;
|
||
|
|
trade.PositionClose(posInfo.Ticket());
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
void CloseAllTrades()
|
||
|
|
{
|
||
|
|
CloseAllMyTrades();
|
||
|
|
}
|
||
|
|
//+------------------------------------------------------------------+
|