` // // an Structure for Holds an Specified Symbols // Positions Info ... struct XTradeSymbolInfo { // // Properties ... // string symbol; // Trading Symbol // int longs; // All Long Trades int shorts; // All Short Trades // int trades; // All Trades // int losses; // All Loosing Trades int profits; // All Winning Trades // datetime managedStart; // Managed Start Time // int managedSLs; // Managed SL(s) int managedTPs; // Managed TP(s) int managedTrades; // Managed Trades // double managedBalance; // Managed Start Balance double managedProfits; // Managed Profit(s) // // Constructor ... XTradeSymbolInfo() { Clean(); } // // Tools ... // // Cleanup ... void Clean() { // symbol = NULL; // longs = 0; shorts = 0; // trades = 0; // losses = 0; profits = 0; // managedStart = NULL; // managedSLs = 0; managedTPs = 0; managedTrades = 0; // managedBalance = 0; managedProfits = 0; // ZeroMemory(this); } // // Validate ... bool IsValid() { // bool result = false; // result = IsSpecifiedValid(symbol); // return result; } // bool IsSameAs(XTradeSymbolInfo &item) { // bool result = false; // result = IsValid() && item.IsValid() && symbol == item.symbol; // return result; } // string GetRestrictionDescription( ENUM_XTRADE_RESTRICTION_PERIOD period // ) { // string result = NULL; // if (!IsValid() || !HasRestrictions(period)) { return result; } // result += "-------------------" + "\n" + "Restrictions: " + "\n" + "-------------------" + "\n" + "Symbol: " + ToXString(symbol) + "\n" + "Period: " + ToXString(period) + "\n" + "Start: " + ToFormatString(managedStart) + "\n" + "Balance: " + ToXString(managedBalance) + "\n" + "-------------------" + "\n" + "Trades: " + ToXString(managedTrades) + "\n" + "SL: " + ToXString(managedSLs) + "\n" + "TP: " + ToXString(managedTPs) + "\n" + "Profit: " + ToXString(managedProfits) + "\n" + ""; // return result; } }; // void SetForceCloseTradesAt( string _forceCloseAt // ) { forceCloseAt = _forceCloseAt; } // void SetTradeSession( string symbol, string start, string end, string name = NULL // ) { // // Validate Args ... bool has = IsValid(end) && IsValid(start) && IsValid(symbol); if (!has) { return; } // // Create Session ... // XTradeSession session; // session.end = end; session.name = name; session.start = start; // int sessionIDX = -1; has = FindSymbolSession( sessionIDX, symbol // ); // if (!has) { // // Add New Symbol Session ... // XSymbolSessions iSymbolSession; iSymbolSession.symbol = symbol; // AddTradingSession( session, iSymbolSession // ); // AddRef( iSymbolSession, sessions // ); // iSymbolSession.Clean(); } else { // // Update Trading Sessions of Exists Symbol Session ... AddTradingSession( session, sessions[sessionIDX] // ); } // // Cleanup Resources ... session.Clean(); } // void SetTradeRestrictions( ENUM_XTRADE_RESTRICTION_PERIOD _period, int _maxAllowedTPs, int _maxAllowedSLs, int _maxAllowedTrades // ) { // // Normalizing Args ... _maxAllowedTPs = NormalizeInt(_maxAllowedTPs, 0); _maxAllowedSLs = NormalizeInt(_maxAllowedSLs, 0); _maxAllowedTrades = NormalizeInt(_maxAllowedTrades, 0); // restrictionsPeriod = _period; maxAllowedTPs = _maxAllowedTPs; maxAllowedSLs = _maxAllowedSLs; maxAllowedTrades = _maxAllowedTrades; } // // Symbol Info ... // bool FindSymbolIndex( int &index, XTradeSymbolInfo &item // ) { // bool result = false; // index = -1; // result = item.IsValid(); if (!result) { return result; } // result = HasChild(symbols); if (!result) { return result; } // index = FindIndex( item, symbols // ); // result = IsValidIndex(index); // return result; } // bool FindSymbolIndex( int &index, string symbol // ) { // bool result = false; // index = -1; // result = IsValid(symbol) && HasChild(symbols); if (!result) { return result; } // int count = ArraySize(symbols); for (int i = 0; i < count; i++) { // result = symbols[i].symbol == symbol; if (result) { // index = i; break; } } // result = IsValidIndex(index); // return result; } // void AddOrUpdateSymbolInfo(XTradeSymbolInfo &item) { // bool has = item.IsValid(); if (!has) { return; } // int index = -1; bool isExists = FindSymbolIndex( index, item // ); if (!isExists) { // AddRef( item, symbols // ); } else { // symbols[index].longs += item.longs; symbols[index].shorts += item.shorts; symbols[index].trades += item.trades; symbols[index].losses += item.losses; symbols[index].profits += item.profits; symbols[index].managedSLs += item.managedSLs; symbols[index].managedTPs += item.managedTPs; symbols[index].managedTrades += item.managedTrades; symbols[index].managedProfits += item.managedProfits; // // Handle Remove on Managed SL based On Managed TP ... if (item.managedTPs > 0) { // symbols[index].managedSLs -= item.managedTPs; if (symbols[index].managedSLs < 0) { symbols[index].managedSLs = 0; } } // // Handle Remove on Managed TP based On Managed SL ... if (item.managedSLs > 0) { // symbols[index].managedTPs -= item.managedSLs; if (symbols[index].managedTPs < 0) { symbols[index].managedTPs = 0; } } } } // void ResetSymbolsRestrictions() { // bool has = HasChild(symbols); if (has) { // string prefix = "Protector: "; // datetime start = TimeCurrent(); double balance = trader.mAccount.GetBalance(); bool hasRestrictions = HasRestrictions(restrictionsPeriod); if (!hasRestrictions) { // balance = 0; start = NULL; } // int count = ArraySize(symbols); for (int i = 0; i < count; i++) { // XTradeSymbolInfo iInfo = symbols[i]; if (reportRestrictions) { // string message = iInfo.GetRestrictionDescription(restrictionsPeriod); alert.SendAlert(message); } SaveRestrictions(iInfo); // symbols[i].managedSLs = 0; symbols[i].managedTPs = 0; symbols[i].managedTrades = 0; symbols[i].managedProfits = 0; symbols[i].managedStart = start; symbols[i].managedBalance = balance; // iInfo.Clean(); } // string message = prefix + "Reset Symbols Restrictions"; HandleReportProtector(message); } } // void HandleRestrictions() { // bool isNewDay = timeTracker.IsNewDay(); bool isNewHour = timeTracker.IsNewHour(); bool isNewWeek = timeTracker.IsNewWeek(); bool isNewMonth = timeTracker.IsNewMonth(); // // Reset Force Closed Flag on new Day Starts ... if (isNewDay) { isForceCloseAtTime = false; } // bool canResetRestrictions = ( // // Hourly ... (isNewHour && restrictionsPeriod == XTRADE_RESTRICATION_HOURLY) // || // // Daily ... (isNewDay && restrictionsPeriod == XTRADE_RESTRICATION_DAILY) // || // // Weekly ... (isNewWeek && restrictionsPeriod == XTRADE_RESTRICATION_WEEKLY) // || // // Monthly ... (isNewMonth && restrictionsPeriod == XTRADE_RESTRICATION_MONTHLY) // ) // ; if (canResetRestrictions) { ResetSymbolsRestrictions(); } } // bool SaveRestrictions(XTradeSymbolInfo &info) { // bool result = false; // if (!mSaveRestrictions) { return result; } // result = info.IsValid(); if (!result) { return result; } // string filePath = GetRestrictionsFilePath(info.symbol); result = IsValid(filePath); if (!result) { return result; } // string content = info.GetRestrictionDescription(restrictionsPeriod); // result = collector.Append( filePath, content // ); // return result; } // // Symbol Session ... // bool FindSymbolSession( int &index, string symbol // ) { // bool result = false; // index = -1; // result = IsValid(symbol) && HasChild(sessions); if (!result) { return result; } // int count = ArraySize(sessions); for (int i = 0; i < count; i++) { // result = sessions[i].symbol == symbol; if (result) { // index = i; break; } } // result = IsValidIndex(index); // return result; } // void AddTradingSession( XTradeSession &session, XSymbolSessions &symbolSession // ) { // bool has = session.IsValid() && symbolSession.IsValid(); if (!has) { return; } // // Check Session Exists in Symbol Session ... bool isExists = false; if (HasChild(symbolSession.sessions)) { // int count = ArraySize(symbolSession.sessions); for (int i = 0; i < count; i++) { // isExists = symbolSession.sessions[i].end == session.end && symbolSession.sessions[i].start == session.start; if (isExists) { break; } } } // if (!isExists) { // AddRef( session, symbolSession.sessions // ); } } /** * Check Signal Execution Conditions ... * * @param signal: XSignal instance reference ... * @param executionResult: ENUM_X_SIGNAL_EXECUTION_RESULT member reference ... * * @return ( bool ) */ bool CheckSignal( XSignal &signal, ENUM_X_SIGNAL_EXECUTION_RESULT &executionResult // ) { // bool result = false; // // Cleanup ... executionResult = X_SIGNAL_EXECUTION_UNKNOWN; // // Validate Signal ... result = signal.IsValid(); if (!result) { return result; } // // Reporting Signal ... if (reportSignals) { // string message = signal.GetMessage("Provided"); alert.SendAlert(message); } // SaveSignal(signal); // // Check Trade Permission ... if (!allowTrade) { // result = false; executionResult = X_SIGNAL_EXECUTION_FAILED_NOT_ALLOWED; // return result; } // bool isLong = IsLong(signal.type); bool isShort = IsShort(signal.type); // bool isLongAndAllowed = isLong && allowLongs; // bool isShortAndAllowed = isShort && allowShorts; // result = isLongAndAllowed || isShortAndAllowed; if (!result) { // executionResult = X_SIGNAL_EXECUTION_FAILED_NOT_ALLOWED; // return result; } // // Check Symbol Info Exists or not ... int symbolInfoIDX = -1; bool isSymbolInfoExists = FindSymbolIndex( symbolInfoIDX, signal.symbol // ); // // Check Symbol Session Exists or not ... int symbolSessionIDX = -1; bool isSymbolSessionExists = FindSymbolSession( symbolSessionIDX, signal.symbol // ); // // Chack Trade Session Validating ... if (isSymbolSessionExists) { // result = sessions[symbolSessionIDX].CanTrade(); if (!result) { // executionResult = X_SIGNAL_EXECUTION_FAILED_DELAY_NOT_PASSED; // return result; } } // // Check Trade Permissions Based on SL(s) Count ... bool hasRestrictions = restrictionsPeriod != XTRADE_RESTRICATION_NONE; if (hasRestrictions) { // // Only Can Check Restrictions when // Symbol Info Exists ... if (isSymbolInfoExists) { // bool isTPAllowed = maxAllowedTPs == 0 ? true : symbols[symbolInfoIDX].managedTPs < maxAllowedTPs; bool isSLAllowed = maxAllowedSLs == 0 ? true : symbols[symbolInfoIDX].managedSLs < maxAllowedSLs; bool isTradeAllowed = maxAllowedTrades == 0 ? true : symbols[symbolInfoIDX].managedTrades < maxAllowedTrades; // result = isTPAllowed && isSLAllowed && isTradeAllowed; } // // Report Error ... if (!result) { // executionResult = X_SIGNAL_EXECUTION_FAILED_MAX_REACHED; // return result; } } // return result; } /** * Execute Specified Signal ... * * @param signal: XSignal instance reference ... * @param conditions: XCATBEAStrategyConditions instance reference ... * * @return ( bool ) */ bool Execute(XSignal &signal) { // bool result = false; // result = signal.IsValid(); if (!result) { return result; } // int idx = -1; bool isExists = HasTrade( idx, signal // ); result = !isExists; if (!result) { return result; } // ENUM_X_SIGNAL_EXECUTION_RESULT executionResult; // // Checking Signal For Execution ... result = CheckSignal( signal, executionResult // ); if (result) { // result = trader.ExecuteSignal( signal, executionResult // ); } // // Alert Signal Execution ... if (reportTrades) { // string executionMessage = ToString(executionResult); // string message = NULL; if (result) { message = signal.GetMessage("Executed"); } else { message = signal.GetMessage("Failed due (" + executionMessage + ")"); } // alert.SendAlert(message); } // if (result) { // // Create Symbol Info Struct ... XTradeSymbolInfo iSymbolInfo; // iSymbolInfo.trades = 1; iSymbolInfo.managedTrades = 1; iSymbolInfo.symbol = signal.symbol; // bool isLong = IsLong(signal.type); if (isLong) { iSymbolInfo.longs = 1; } else { iSymbolInfo.shorts = 1; } // // Fill Balance for Restrications ... bool hasRestrictions = HasRestrictions(restrictionsPeriod); if (hasRestrictions) { // // Read Balance ... double balance = trader.mAccount.GetBalance(); iSymbolInfo.managedBalance = balance; iSymbolInfo.managedStart = TimeCurrent(); } // AddOrUpdateSymbolInfo(iSymbolInfo); // // Create Trade Struct ... XTradeInfo iTrade; // ulong positionID = trader.GetLastOpenPositionTicket(); double commission = trader.GetPositionCommission(positionID); // iTrade.signal = signal; iTrade.positionID = positionID; iTrade.commission = commission; iTrade.signaledAt = signal.time; iTrade.executedAt = TimeCurrent(); iTrade.conditions = signal.conditions; // AddRef( iTrade, trades // ); } // return result; } /** * Check Specified Symbol is Active for * Analysing or Open Trades ... */ bool IsActiveSession(string symbol) { // bool result = false; // // Validate Args ... result = IsValid(symbol); if (!result) { return result; } // // TODO: Complete this ... // // // // Check Symbol Session Exists or not ... // int symbolSessionIDX = -1; // bool isSymbolSessionExists = FindSymbolSession( // symbolSessionIDX, // symbol // // ); // // // // Chack Trade Session Validating ... // if (isSymbolSessionExists) // { // result = sessions[symbolSessionIDX].CanTrade(); // } // return result; } // string forceCloseAt; bool isForceCloseAtTime; // int maxAllowedTPs; int maxAllowedSLs; int maxAllowedTrades; ENUM_XTRADE_RESTRICTION_PERIOD restrictionsPeriod; XTradeSymbolInfo symbols[]; XSymbolSessions sessions[]; // forceCloseAt = NULL; isForceCloseAtTime = false; // maxAllowedTPs = 0; maxAllowedSLs = 0; maxAllowedTrades = 0; restrictionsPeriod = XTRADE_RESTRICATION_NONE;