/////////////////////////////////////////////////////// // // SaherElm IT Center MQL5 Class // ------------------------------------------------- // Name: XCBaseExpret ... // Description: Base Expert Class ... // // // Maintainer: // ------------ // Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) // ////////////////////////////////////////////////////// // // Global Properties ... #property library #property copyright "Copyright 2023, SaherElm IT Center" #property link "https://saherelm.ir" #property version "1.00" #property description "SaherElm Base Expert Class" #property strict // // Imports ... #include "../Classes/x-saherelm.base.class.mq5" #include "../Classes/x-saherelm.x-alert.class.mq5" #include "../Classes/x-saherelm.x-chart.helper.class.mq5" #include "../Classes/x-saherelm.x-guard.class.mq5" #include "../Classes/x-saherelm.x-position.drawer.class.mq5" #include "../Classes/x-saherelm.x-signaller.class.mq5" #include "../Classes/x-saherelm.x-target.class.mq5" #include "../Classes/x-saherelm.x-trade-manager.class.mq5" #include "../Classes/x-saherelm.x-volume.class.mq5" // // Import Chart Objects ... #include #include #include #include // // Definitions ... // // Implementation ... class XCBaseExpert : public XCBase { // // Public ... public: // // Props ... // // Common ... long eaMagicNumber; // Magic Number int eaSlippage; // Slippgae string eaLogSuffix; // Log Suffix // // Symbol Configurations ... string eaSymbolConfiguration; // Symbol Configurations ... // // Management ... bool eaAllowGuards; // Allow Guards bool eaAllowTrade; // Allow Trade on Signals bool eaAllowLongs; // Allow Long Trades bool eaAllowShorts; // Allow Short Trades double eaMaxAllowedDrawdownFactor; // Max Allowed DrawDown for Trade // // Volume ... ENUM_X_VOLUME_SELECT_TYPE eaVolumeSelect; // Volume Applying Type double eaStaticVoluem; // Static Volume double eaDynamicVolumeStepBalance; // Step of Balance for Increase Volume double eaDynamicVolumeStepVolume; // Step of Volume Increasing double eaConstantRiskBalance; // Constant Risk Balance per Trade double eaConstantPercent; // Constant Percent of Balance Per Trade double eaConstantBalance; // Constant Balance for Calculations // // Alert ... bool eaEnableAlerts; // Enable Alerts bool eaSaveAlerts; // Save Alerts bool eaLogAlerts; // Log Alerts bool eaMailAlerts; // Mail Alerts bool eaPushAlerts; // Push Alerts bool eaTerminalAlerts; // Terminal Alerts // // Reports ... bool eaReportNewMonths; // Report New Month bool eaReportNewWeeks; // Report New Weeks bool eaReportNewDays; // Report New Days bool eaReportNewHours; // Report New Hours bool eaReportTrades; // Report Trades bool eaReportSignals; // Report Signals bool eaReportProtector; // Report Protector Actions bool eaReportRestrictions; // Report Restrictions bool eaReportAfterTradesBalance; // Report Balance after a Trade Finished // // Collector ... bool eaSaveTrades; // Save Trades bool eaSaveSignals; // Save Signals bool eaSaveWins; // Save Winning Conditions bool eaSaveLosts; // Save Lost Conditions bool eaSaveRestrictions; // Save Restriction Reports // // GUI Management Panel ... bool eaShowPanel; // Show Management Panel double eaPanelAllowedTPSLStep; // Value for Change TP/SL in Each Step double eaPanelMinAllowedRiskInPoint; // Min Allowed Risk in Point double eaPanelRiskInPoint; // Risk in Point per Trades double eaPanelRiskToRewardRatio; // Risk To Reward per Trades double eaPanelVolume; // Default volume Per Trade // // Requirements ... // XCAlert *eaAlert; // EA Scope Alert Handler ... XCGuard *eaGuard; // EA Scope Guard Handler ... XCTrade *eaTrader; // EA Scope Trade Handler ... XCVolume *eaVolume; // EA Scope Voluem Handler ... XCTarget *eaTarget; // EA Scope Target Handler ... XTimeTracker eaTimeTracker; // EA Scope Time Tracker ... XCTradeManager *eaTradeManager; // EA Scope Trade Manager Handler ... XCPositionDrawer *eaPositionDrawer; // EA Scope Position Drawer ... // // Specified Event Handlers ... TOnGuarded onGuardedEventHandler; TCanAnalyse canAnalyseEventHandler; TCheckForGuard checkForGuardEventHandler; // // Tools / Actions / Handlers ... // // Expert Advisor Event Handlers ... /** * Handle Initialization of Expert ... * * @return ( bool ) */ bool HandleOnInit() { // bool result = false; // // Validate Inputs ... result = ValidateInputs(); if (!result) { return result; } // int count = 0; bool has = false; // // Initialize Alert Handler ... eaAlert = new XCAlert(); eaAlert.SetPrefix(eaLogSuffix); eaAlert.SetLogAlerts(eaLogAlerts); eaAlert.SetMailAlerts(eaMailAlerts); eaAlert.SetPushAlerts(eaPushAlerts); eaAlert.SetSaveAlerts(eaSaveAlerts); eaAlert.SetEnableAlerts(eaEnableAlerts); eaAlert.SetTerminalAlerts(eaTerminalAlerts); // // Initialize Volume Manager ... eaVolume = new XCVolume(); result = eaVolume.Init( eaVolumeSelect, eaStaticVoluem, eaDynamicVolumeStepBalance, eaDynamicVolumeStepVolume, eaConstantRiskBalance, eaConstantPercent, eaConstantBalance // ); if (!result) { return result; } // // Initialize Trader ... eaTrader = new XCTrade( eaSlippage, eaMagicNumber, 0, 0, eaMaxAllowedDrawdownFactor // ); // // Trade Handler Attachments ... // // Position Modifiy Event Handlers ... count = ArraySize(mOnModifyEventHandlers); has = IsValidSize(count); if (has) { // for (int i = 0; i < count; i++) { eaTrader.AddOnModifyPositionEventHandler(mOnModifyEventHandlers[i]); } } // // Position Stop Loss Event Handlers ... count = ArraySize(mStopLossEventHandlers); has = IsValidSize(count); if (has) { // for (int i = 0; i < count; i++) { eaTrader.AddOnStopLossEventHandler(mStopLossEventHandlers[i]); } } // // Position Take Profit Event Handlers ... count = ArraySize(mTakeProfitEventHandlers); has = IsValidSize(count); if (has) { // for (int i = 0; i < count; i++) { eaTrader.AddOnTakeProfitEventHandler(mTakeProfitEventHandlers[i]); } } // // Position Force Close Event Handlers ... count = ArraySize(mOnForceCloseEventHandlers); has = IsValidSize(count); if (has) { // for (int i = 0; i < count; i++) { eaTrader.AddOnForceClosePositionEventHandler(mOnForceCloseEventHandlers[i]); } } // // Deals Changed Event Handlers ... count = ArraySize(mDealsChangedEventHandlers); has = IsValidSize(count); if (has) { // for (int i = 0; i < count; i++) { eaTrader.AddOnDealsChangedEventHandler(mDealsChangedEventHandlers[i]); } } // // Orders Changed Event Handlers ... count = ArraySize(mOrdersChangedEventHandlers); has = IsValidSize(count); if (has) { // for (int i = 0; i < count; i++) { eaTrader.AddOnOrdersChangedEventHandler(mOrdersChangedEventHandlers[i]); } } // // Positions Changed Event Handlers ... count = ArraySize(mPositionsChangedEventHandlers); has = IsValidSize(count); if (has) { // for (int i = 0; i < count; i++) { eaTrader.AddOnPositionsChangedEventHandler(mPositionsChangedEventHandlers[i]); } } // // Trade Changed Event Handlers ... count = ArraySize(mTradeStateChangedEventHandlers); has = IsValidSize(count); if (has) { // for (int i = 0; i < count; i++) { eaTrader.AddOnTradeStateChangedEventHandler(mTradeStateChangedEventHandlers[i]); } } // // Postion Partially Close Event Handlers ... count = ArraySize(mOnPartialCloseEventHandlers); has = IsValidSize(count); if (has) { // for (int i = 0; i < count; i++) { eaTrader.AddOnPartialClosePositionEventHandler(mOnPartialCloseEventHandlers[i]); } } // // Signal Executed Event Handlers ... count = ArraySize(mOnSignalExecutedEventHandlers); has = IsValidSize(count); if (has) { // for (int i = 0; i < count; i++) { eaTrader.AddOnSignalExecutedEventHandler(mOnSignalExecutedEventHandlers[i]); } } // // Initialize Guard Handler ... eaGuard = new XCGuard( eaAlert, eaTrader // ); // // Attach Event Handler ... eaGuard.onGuardEventListener = onGuardedEventHandler; // // Initialize Target Handler ... eaTarget = new XCTarget(eaTrader, eaAlert); // // Init Position Drawer ... eaPositionDrawer = new XCPositionDrawer(eaTrader); // // Initialize Trae Manager ... eaTradeManager = new XCTradeManager( eaAlert, eaTrader, eaVolume, eaGuard, eaTarget // ); // // Configuring Trade Manager ... // // Attache Check For Guard Event Listener ... eaTradeManager.checkForGuardEventListener = checkForGuardEventHandler; // eaTradeManager.SaveWins(eaSaveWins); eaTradeManager.SaveLosts(eaSaveLosts); eaTradeManager.SaveTrades(eaSaveTrades); eaTradeManager.SaveSignals(eaSaveSignals); eaTradeManager.SaveRestrictions(eaSaveRestrictions); // // Setting Trade Reports ... eaTradeManager .SetTradeReports( eaReportTrades, eaReportSignals, eaReportProtector, eaReportRestrictions, eaReportAfterTradesBalance // ); // // Setting Trade Permissions ... eaTradeManager .SetTradePermissions( eaAllowTrade, eaAllowLongs, eaAllowShorts // ); // // Setting Symbol Configuration ... XSymbolTradeConfig symbolConfigurations[]; eaTradeManager.SetSymbolConfigurations(eaSymbolConfiguration); count = eaTradeManager.FillSymbolConfigurations(symbolConfigurations); has = IsValidSize(count); if (has) { // // Configure Signallers ... for (int i = 0; i < count; i++) { // // Register Signallers ... PrepareSignallers(symbolConfigurations[i]); } } SpecifiedClean(symbolConfigurations); // result = InitPanel(); if (!result) { return result; } // return result; } /** * Handle De Initialization of Expert ... */ void HandleOnDeInit() { // DestroyPanel(); // delete eaTrader; ZeroMemory(eaTrader); // delete eaGuard; ZeroMemory(eaGuard); // delete eaVolume; ZeroMemory(eaVolume); // eaTarget.Destroy(); delete eaTarget; ZeroMemory(eaTarget); // delete eaTradeManager; ZeroMemory(eaTradeManager); // eaPositionDrawer.Destroy(); delete eaPositionDrawer; ZeroMemory(eaPositionDrawer); // eaTimeTracker.Clean(); // SpecifiedClean(eaSignallers); SpecifiedClean(mOnSignalEventHandlers); SpecifiedClean(mOnModifyEventHandlers); SpecifiedClean(mStopLossEventHandlers); SpecifiedClean(mTakeProfitEventHandlers); SpecifiedClean(mOnForceCloseEventHandlers); SpecifiedClean(mDealsChangedEventHandlers); SpecifiedClean(mOrdersChangedEventHandlers); SpecifiedClean(mOnPartialCloseEventHandlers); SpecifiedClean(mPositionsChangedEventHandlers); SpecifiedClean(mTradeStateChangedEventHandlers); // string message = "DeInitialized Successfully ..."; eaAlert.SendAlert(message); // delete eaAlert; ZeroMemory(eaAlert); } /** * Handle Tick ... */ void HandleOnTick() { // // Update GUI Panel ... UpdatePanel(); // // Time Report ... HandleTimeReport(); // // Manage Trades ... eaTradeManager.Manage(); // // Manage Positions Drawings ... eaPositionDrawer.Update(); // int count = ArraySize(eaSignallers); bool has = IsValidSize(count); if (!has) { return; } // // Loop through Signallers ... for (int i = 0; i < count; i++) { // // Calling Process Ticks on Signaller ... eaSignallers[i].OnTick(0); } // HandleOnTickAdditional(); } /** * Handle Trade ... */ void HandleOnTrade() { eaTrader.HandleOnTrade(); } /** * Handle Timer ... */ void virtual HandleOnTimer() { } /** * Handle Chart Event ... * * @param id: int, Event id ... * @param lparam: long, Event Long Parameter ... * @param dparam: double, Event Double Parameter ... * @param sparam: string, Event String Parameter ... */ void virtual HandleOnChartEvent( const int id, const long &lparam, const double &dparam, const string &sparam // ) { } // // Event Triggered Listeners ... /** * Handle New Signal Recieved ... * * @param signal: XSignal, Recieved Signal ... */ void HandleOnSignalTriggered(XSignal &signal) { eaTradeManager.HandleSignal(signal); } /** * Handle Signal Executed Event ... * * @param signal: XSignal, reference to Executed Signal ... */ void HandleOnSignalExecuted(XSignal &signal) { // eaPositionDrawer.AddExecutedSignal(signal); eaTradeManager.target.AddExecutedSignal(signal); } /** * Check For Guard ... * * @param guards: XGuard, reference Collection to holds result ... * @param positions: XPosition, refrence collection to Provides Positions ... * @param barIndex: int, Specified Bar index ... * * @return ( int ) */ int CheckForGuardTriggered( XGuard &guards[], XPosition &positions[], int barIndex = 0 // ) { // int result = 0; // if (!HasChild(eaSignallers)) { return result; } // int count = ArraySize(eaSignallers); for (int i = 0; i < count; i++) { // XGuard iGuards[]; int iGuardsCount = eaSignallers[i].CheckForGuard( iGuards, positions, barIndex // ); if (IsValidSize(iGuardsCount)) { // Copy( iGuards, guards, false // ); } // SpecifiedClean(iGuards); } // result = ArraySize(guards); // return result; } /** * Handle Guard Events ... * * @param action: ENUM_X_GUARD_ACTIONS * @param positions: XPosition[] */ void OnGuardedTriggered( ENUM_X_GUARD_ACTIONS action, XPosition &positions[] // ) { eaTradeManager.HandleGuardEvent(action, positions); } /** * Check Can Analyse Market based on Time ... * * @param symbol: string, Specified Symbol ... * @param period: ENUM_TIMEFRAMES, Specified Period ... * @param time: datetime, Specified Time ... * * @return ( bool ) */ bool HandleCanAnalyseEventTriggered( string symbol, ENUM_TIMEFRAMES period, datetime time // ) { // return eaTradeManager.CanAnalyse( symbol, period, time // ); } // // Trade Event Handlers ... /** * Handle Stop Loss Event Triggered ... * * @param deal: XDeal instance refrence, provides Triggered Deal info ... */ void virtual HandleOnStopLossTriggered(const XDeal &deal) { // eaTradeManager.HandleSL(deal); eaPositionDrawer.HandleStopLossTriggered(deal); UpdatePanelPositionButtons(); } /** * Handle Take Profit Event Triggered ... * * @param deal: XDeal instance refrence, provides Triggered Deal info ... */ void virtual HandleOnTakeProfitTriggered(const XDeal &deal) { // UpdatePanelPositionButtons(); eaTradeManager.HandleTP(deal); eaPositionDrawer.HandleOnTakeProfitTriggered(deal); } /** * Handle Position Force Closed Event ... * * @param ticket: ulong, triggered Positions ticket ... * @param position: XPosition instance refrence, Triggered Position ... * @param comment: string, Comment ... */ void virtual HandleOnPositionForceClosed( const ulong ticket, const XPosition &position, const string comment // ) { // UpdatePanelPositionButtons(); eaTradeManager.HandleForceClose(position); eaPositionDrawer.HandleOnPositionForceClosed( ticket, position, comment // ); } /** * Handle Position Partially Closed Event ... * * @param ticket: ulong, triggered Positions ticket ... * @param profit: double, Position Profit ... * @param comment: string, Comment ... */ void virtual HandleOnPositionPartialClosed( const ulong ticket, const double profit, const string comment // ) { // eaTradeManager.HandlePartiallyClosed( ticket, profit, comment // ); } /** * Handle Deals Changed ... * * @param count: int, number of changes ... * if the count is positive, means new added ... * if the count is negative, means removed ... */ void virtual HandleOnDealsChanged(int count) { } /** * Handle Orders Changed ... * * @param count: int, number of changes ... * if the count is positive, means new added ... * if the count is negative, means removed ... */ void virtual HandleOnOrdersChanged(int count) { } /** * Handle Positions Changed ... * * @param count: int, number of changes ... * if the count is positive, means new added ... * if the count is negative, means removed ... */ void virtual HandleOnPositionsChanged(int count) { UpdatePanelPositionButtons(); } /** * Handle Position Modified Event ... * * @param ticket: ulong, triggered Positions ticket ... * @param profit: double, Position Profit ... * @param comment: string, Comment ... */ void virtual HandleOnPositionModified( const ulong ticket, const double profit, const string comment // ) { // eaPositionDrawer.HandleOnPositionModified( ticket, profit, comment // ); } /** * Handle all Trades States Changed Event ... * * @param state: XOnTradeHandlerState instance refrence, Changed Trade State data ... */ void virtual HandleOnTradeStateChanged(const XOnTradeHandlerState &state) { } // // Validators ... /** * Validate Inputs ... * * @return ( bool ) */ bool virtual ValidateInputs() { // bool result = false; // // TODO: Handle this ... result = true; // return result; } // // Viruals ... /** * Prepare Signallers per Symbol Config ... * * @param symbolConfig: XSymbolTradeConfig, Symbol Trade Configurations ... */ void virtual PrepareSignallers(XSymbolTradeConfig &symbolConfig) { } /** * Additional On Tick Processing if Required ... * * @param barIndex: int, Specified Bar Index ... */ void virtual HandleOnTickAdditional(int barIndex = 0) { } // // Signal Event Handlers ... // void AddOnSignalEventHandler(TOnSignal handler) { // if (handler == NULL) { return; } // Add( handler, mOnSignalEventHandlers // ); } // // Add New Signal Executed Event Handler ... void AddOnSignalExecutedEventHandler(TOnSignal handler) { // if (handler == NULL) { return; } // Add( handler, mOnSignalExecutedEventHandlers // ); } // // Trade Event Handlers ... // void AddOnStopLossEventHandler(TOnStopLoss handler) { // if (handler == NULL) { return; } // Add( handler, mStopLossEventHandlers // ); } // void AddOnTakeProfitEventHandler(TOnTakeProfit handler) { // if (handler == NULL) { return; } // Add( handler, mTakeProfitEventHandlers // ); } // void AddOnDealsChangedEventHandler(TOnDealsChanged handler) { // if (handler == NULL) { return; } // Add( handler, mDealsChangedEventHandlers // ); } // void AddOnOrdersChangedEventHandler(TOnOrdersChanged handler) { // if (handler == NULL) { return; } // Add( handler, mOrdersChangedEventHandlers // ); } // void AddOnModifyPositionEventHandler(TOnModify handler) { // if (handler == NULL) { return; } // Add( handler, mOnModifyEventHandlers // ); } // void AddOnPositionsChangedEventHandler(TOnPositionsChanged handler) { // if (handler == NULL) { return; } // Add( handler, mPositionsChangedEventHandlers // ); } // void AddOnTradeStateChangedEventHandler(TOnTradeStateChanged handler) { // if (handler == NULL) { return; } // Add( handler, mTradeStateChangedEventHandlers // ); } // void AddOnForceClosePositionEventHandler(TOnForceClose handler) { // if (handler == NULL) { return; } // Add( handler, mOnForceCloseEventHandlers // ); } // void AddOnPartialClosePositionEventHandler(TOnPartialClose handler) { // if (handler == NULL) { return; } // Add( handler, mOnPartialCloseEventHandlers // ); } // // Protected ... protected: // // Props ... // // Actions and Tools ... /** * Report Time Changes based on Given Configurations ... */ void HandleTimeReport() { // if (eaAlert == NULL) { return; } // // Monthly Report .... if (eaReportNewMonths && eaTimeTracker.IsNewMonth()) { // string msg = "New Month ..."; // eaAlert.SendAlert(msg); } // // Weekly Report .... if (eaReportNewWeeks && eaTimeTracker.IsNewWeek()) { // string msg = "New Week ..."; // eaAlert.SendAlert(msg); } // // Daily Report .... if (eaReportNewDays && eaTimeTracker.IsNewDay()) { // string msg = "New Day ..."; // eaAlert.SendAlert(msg); } // // Hourly Report .... if (eaReportNewHours && eaTimeTracker.IsNewHour()) { // string msg = "New Hour ..."; // eaAlert.SendAlert(msg); } } /** * Register Signaller ... */ void RegisterSignaller(XCBaseSignaller *signaller) { // // Validate Signaller ... if (signaller == NULL) { return; } // // Attach Signaller OnSignal Event Handlers if Exists ... int count = ArraySize(mOnSignalEventHandlers); bool has = IsValidSize(count); if (has) { // for (int i = 0; i < count; i++) { signaller.AddOnSignalEventHandler(mOnSignalEventHandlers[i]); } } // // Attach Can Analyse Event Handler ... signaller.canAnalyseEventListener = canAnalyseEventHandler; // // Register Signaller ... Add( signaller, eaSignallers // ); } // // Private ... private: // // Props ... // // Specified Event Handlers ... TOnModify mOnModifyEventHandlers[]; TOnSignal mOnSignalEventHandlers[]; TOnStopLoss mStopLossEventHandlers[]; TOnTakeProfit mTakeProfitEventHandlers[]; TOnSignal mOnSignalExecutedEventHandlers[]; TOnForceClose mOnForceCloseEventHandlers[]; TOnDealsChanged mDealsChangedEventHandlers[]; TOnOrdersChanged mOrdersChangedEventHandlers[]; TOnPartialClose mOnPartialCloseEventHandlers[]; TOnPositionsChanged mPositionsChangedEventHandlers[]; TOnTradeStateChanged mTradeStateChangedEventHandlers[]; // XCBaseSignaller *eaSignallers[]; // All Registered Signallers ... // // Panel Support ... // XCChartHelper *eaChartHelper; // Chart Helper Class ... // string objSuffix; // CButton btnBuy; CButton btnSell; CButton btnClose; CButton btnCloseAll; CEdit lblPositionId; // CButton lblTP; CButton lblSL; CButton btnSLPlus; CButton btnTPPlus; CButton btnSLMinus; CButton btnTPMinus; CButton btnSLPlusPlus; CButton btnTPPlusPlus; CButton btnSLMinusMinus; CButton btnTPMinusMinus; // CArrayObj posArray; CButton *btnSelectedPosInfo; CArrayObj selectedPosInfoArr; // ulong selectedPositionID; bool showSelectedPositionInfo; /** * Initial Management GUI Panel ... * * @return ( bool ) */ bool InitPanel() { // bool result = false; // result = !eaShowPanel; if (result) { return result; } // // Check Default Symbol and Period ... // int subWindow = 0; ulong chartId = ChartID(); objSuffix = eaLogSuffix + "_"; // // Initial Chart Class Instance ... eaChartHelper = new XCChartHelper(chartId); // int startX = 5; int startY = 25; // int defaultGap = 5; int defaultWidth = 100; int defaultHeight = 30; // // Buy ... int btnBuyX1 = startX; int btnBuyX2 = startX + defaultWidth; int btnBuyY1 = startY; int btnBuyY2 = startY + defaultHeight; string btnBuyName = objSuffix + "BTN_BUY"; result = btnBuy.Create( chartId, btnBuyName, subWindow, btnBuyX1, btnBuyY1, btnBuyX2, btnBuyY2 // ); if (result) { // // Apply Buy Button Style ... // btnBuy.Text("Buy"); btnBuy.Color(clrYellow); btnBuy.ColorBackground(clrGreen); } // // Sell ... int btnSellX1 = btnBuyX1 + btnBuyX2; int btnSellX2 = btnSellX1 + defaultWidth; int btnSellY1 = btnBuyY1; int btnSellY2 = btnBuyY2; string btnSellName = objSuffix + "BTN_SELL"; result = btnSell.Create( chartId, btnSellName, subWindow, btnSellX1, btnSellY1, btnSellX2, btnSellY2 // ); if (result) { // // Apply Sell Button Style ... // btnSell.Text("Sell"); btnSell.Color(clrYellow); btnSell.ColorBackground(clrDarkRed); } // // LABEL Position ID ... int lblPositionIdX1 = btnBuyX1; int lblPositionIdX2 = lblPositionIdX1 + defaultWidth; int lblPositionIdY1 = btnSellY2 + defaultGap; int lblPositionIdY2 = lblPositionIdY1 + defaultHeight; string lblPositionIdName = objSuffix + "LBL_POS_ID"; result = lblPositionId.Create( chartId, lblPositionIdName, subWindow, lblPositionIdX1, lblPositionIdY1, lblPositionIdX2, lblPositionIdY2 // ); if (result) { // // Apply Label Position ID Style ... lblPositionId.ReadOnly(true); lblPositionId.Text("Pos ID: "); lblPositionId.Color(clrYellow); lblPositionId.ColorBackground(clrDarkGray); } // // Close ... int btnCloseX1 = startX; int btnCloseX2 = btnCloseX1 + defaultWidth; int btnCloseY1 = lblPositionIdY2 + defaultGap; int btnCloseY2 = btnCloseY1 + defaultHeight; string btnCloseName = objSuffix + "BTN_CLOSE"; result = btnClose.Create( chartId, btnCloseName, subWindow, btnCloseX1, btnCloseY1, btnCloseX2, btnCloseY2 // ); if (result) { // // Apply Close Button Style ... // btnClose.Text("Close"); btnClose.Color(clrYellow); btnClose.ColorBackground(clrDarkOrange); } // // Close All ... int btnCloseAllX1 = btnCloseX2 + defaultGap; int btnCloseAllX2 = btnCloseAllX1 + defaultWidth; int btnCloseAllY1 = lblPositionIdY2 + defaultGap; int btnCloseAllY2 = btnCloseAllY1 + defaultHeight; string btnCloseAllName = objSuffix + "BTN_CLOSE_ALL"; result = btnCloseAll.Create( chartId, btnCloseAllName, subWindow, btnCloseAllX1, btnCloseAllY1, btnCloseAllX2, btnCloseAllY2 // ); if (result) { // // Apply Close Button Style ... // btnCloseAll.Text("Close All"); btnCloseAll.Color(clrYellow); btnCloseAll.ColorBackground(clrDarkRed); } // int minusPlusWidth = 20; // // TP Label ... int lblTPX1 = btnCloseX1; int lblTPX2 = lblTPX1 + defaultWidth; int lblTPY1 = btnCloseY2 + defaultGap; int lblTPY2 = lblTPY1 + defaultHeight; string lblTPName = objSuffix + "LBL_TP"; result = lblTP.Create( chartId, lblTPName, subWindow, lblTPX1, lblTPY1, lblTPX2, lblTPY2 // ); if (result) { // // Apply Style ... lblTP.Disable(); lblTP.Text("TP"); lblTP.Color(clrWhite); lblTP.ColorBackground(clrGreen); } // // TP Plus ... int btnTPPlusX1 = lblTPX1; int btnTPPlusX2 = btnTPPlusX1 + minusPlusWidth; int btnTPPlusY1 = lblTPY2 + defaultGap; int btnTPPlusY2 = btnTPPlusY1 + defaultHeight; string btnTPPlusName = objSuffix + "BTN_TP_PLUS"; result = btnTPPlus.Create( chartId, btnTPPlusName, subWindow, btnTPPlusX1, btnTPPlusY1, btnTPPlusX2, btnTPPlusY2 // ); if (result) { // // Apply Style ... btnTPPlus.Text("+"); btnTPPlus.Color(clrYellow); btnTPPlus.ColorBackground(clrGreen); } // // TP Plus Plus ... int btnTPPlusPlusX1 = btnTPPlusX2 + defaultGap; int btnTPPlusPlusX2 = btnTPPlusPlusX1 + minusPlusWidth; int btnTPPlusPlusY1 = lblTPY2 + defaultGap; int btnTPPlusPlusY2 = btnTPPlusPlusY1 + defaultHeight; string btnTPPlusPlusName = objSuffix + "BTN_TP_PLUSPLUS"; result = btnTPPlusPlus.Create( chartId, btnTPPlusPlusName, subWindow, btnTPPlusPlusX1, btnTPPlusPlusY1, btnTPPlusPlusX2, btnTPPlusPlusY2 // ); if (result) { // // Apply Style ... btnTPPlusPlus.Text("++"); btnTPPlusPlus.Color(clrYellow); btnTPPlusPlus.ColorBackground(clrGreen); } // // TP Minus ... int btnTPMinusX1 = lblTPX2 - minusPlusWidth; int btnTPMinusX2 = btnTPMinusX1 + minusPlusWidth; int btnTPMinusY1 = lblTPY2 + defaultGap; int btnTPMinusY2 = btnTPMinusY1 + defaultHeight; string btnTPMinusName = objSuffix + "BTN_TP_MINUS"; result = btnTPMinus.Create( chartId, btnTPMinusName, subWindow, btnTPMinusX1, btnTPMinusY1, btnTPMinusX2, btnTPMinusY2 // ); if (result) { // // Apply Style ... btnTPMinus.Text("-"); btnTPMinus.Color(clrYellow); btnTPMinus.ColorBackground(clrDarkRed); } // // TP Minus Minus ... int btnTPMinusMinusX1 = btnTPMinusX1 - minusPlusWidth - defaultGap; int btnTPMinusMinusX2 = btnTPMinusMinusX1 + minusPlusWidth; int btnTPMinusMinusY1 = lblTPY2 + defaultGap; int btnTPMinusMinusY2 = btnTPMinusY1 + defaultHeight; string btnTPMinusMinusName = objSuffix + "BTN_TP_MINUSMINUS"; result = btnTPMinusMinus.Create( chartId, btnTPMinusMinusName, subWindow, btnTPMinusMinusX1, btnTPMinusMinusY1, btnTPMinusMinusX2, btnTPMinusMinusY2 // ); if (result) { // // Apply Style ... btnTPMinusMinus.Text("--"); btnTPMinusMinus.Color(clrYellow); btnTPMinusMinus.ColorBackground(clrDarkRed); } // // SL Label ... int lblSLX1 = btnCloseAllX1; int lblSLX2 = lblSLX1 + defaultWidth; int lblSLY1 = btnCloseAllY2 + defaultGap; int lblSLY2 = lblTPY1 + defaultHeight; string lblSLName = objSuffix + "LBL_SL"; result = lblSL.Create( chartId, lblSLName, subWindow, lblSLX1, lblSLY1, lblSLX2, lblSLY2 // ); if (result) { // // Apply Style ... lblSL.Disable(); lblSL.Text("SL"); lblSL.Color(clrWhite); lblSL.ColorBackground(clrDarkRed); } // // SL Plus ... int btnSLPlusX1 = lblSLX1; int btnSLPlusX2 = btnSLPlusX1 + minusPlusWidth; int btnSLPlusY1 = lblSLY2 + defaultGap; int btnSLPlusY2 = btnSLPlusY1 + defaultHeight; string btnSLPlusName = objSuffix + "BTN_SL_PLUS"; result = btnSLPlus.Create( chartId, btnSLPlusName, subWindow, btnSLPlusX1, btnSLPlusY1, btnSLPlusX2, btnSLPlusY2 // ); if (result) { // // Apply Style ... btnSLPlus.Text("+"); btnSLPlus.Color(clrYellow); btnSLPlus.ColorBackground(clrGreen); } // // SL Plus Plus ... int btnSLPlusPlusX1 = btnSLPlusX2 + defaultGap; int btnSLPlusPlusX2 = btnSLPlusPlusX1 + minusPlusWidth; int btnSLPlusPlusY1 = lblSLY2 + defaultGap; int btnSLPlusPlusY2 = btnSLPlusPlusY1 + defaultHeight; string btnSLPlusPlusName = objSuffix + "BTN_SL_PLUSPLUS"; result = btnSLPlusPlus.Create( chartId, btnSLPlusPlusName, subWindow, btnSLPlusPlusX1, btnSLPlusPlusY1, btnSLPlusPlusX2, btnSLPlusPlusY2 // ); if (result) { // // Apply Style ... btnSLPlusPlus.Text("++"); btnSLPlusPlus.Color(clrYellow); btnSLPlusPlus.ColorBackground(clrGreen); } // // SL Minus ... int btnSLMinusX1 = lblSLX2 - minusPlusWidth; int btnSLMinusX2 = btnSLMinusX1 + minusPlusWidth; int btnSLMinusY1 = lblSLY2 + defaultGap; int btnSLMinusY2 = btnSLMinusY1 + defaultHeight; string btnSLMinusName = objSuffix + "BTN_SL_MINUS"; result = btnSLMinus.Create( chartId, btnSLMinusName, subWindow, btnSLMinusX1, btnSLMinusY1, btnSLMinusX2, btnSLMinusY2 // ); if (result) { // // Apply Style ... btnSLMinus.Text("-"); btnSLMinus.Color(clrYellow); btnSLMinus.ColorBackground(clrDarkRed); } // // SL Minus Minus ... int btnSLMinusMinusX1 = btnSLMinusX1 - minusPlusWidth - defaultGap; int btnSLMinusMinusX2 = btnSLMinusMinusX1 + minusPlusWidth; int btnSLMinusMinusY1 = lblSLY2 + defaultGap; int btnSLMinusMinusY2 = btnSLMinusY1 + defaultHeight; string btnSLMinusMinusName = objSuffix + "BTN_SL_MINUSMINUS"; result = btnSLMinusMinus.Create( chartId, btnSLMinusMinusName, subWindow, btnSLMinusMinusX1, btnSLMinusMinusY1, btnSLMinusMinusX2, btnSLMinusMinusY2 // ); if (result) { // // Apply Style ... btnSLMinusMinus.Text("--"); btnSLMinusMinus.Color(clrYellow); btnSLMinusMinus.ColorBackground(clrDarkRed); } // UpdatePanelState(); // return result; } /** * Listen For Panel Controls Events and * Update State of GUI Panel ... */ void UpdatePanel() { // if (!eaShowPanel) { return; } // UpdatePanelState(); // // Buy Button Pressed ... if (btnBuy.Pressed()) { // HandleBuyTrade(); btnBuy.Pressed(false); } // // Sell Button Pressed ... if (btnSell.Pressed()) { // HandleSellTrade(); btnSell.Pressed(false); } // // Close Button Pressed ... if (btnClose.Pressed()) { // if (btnClose.IsEnabled()) { // if (selectedPositionID > 0) { HandleCloseTrade(selectedPositionID); } } // btnClose.Pressed(false); } // // Close All Button Pressed ... if (btnCloseAll.Pressed()) { // if (btnCloseAll.IsEnabled()) { HandleCloseTrade(0); } // btnCloseAll.Pressed(false); } // // Check Show Hide Selected Position Info ... if (btnSelectedPosInfo != NULL) { // if (btnSelectedPosInfo.Pressed()) { // // Check Enable ... if (btnSelectedPosInfo.IsEnabled()) { // // Handle Toggle Show/Hide lblSelectedPositionInfo ... CEdit *iLbl = NULL; bool isVisible = showSelectedPositionInfo; int count = selectedPosInfoArr.Total(); if (IsValidSize(count)) { // // Loop Through Labels ... for (int i = 0; i < count; i++) { // iLbl = (CEdit *)selectedPosInfoArr.At(i); isVisible = iLbl.IsVisible(); if (isVisible) { iLbl.Hide(); } else { iLbl.Show(); } } // // Update Button Text ... isVisible = showSelectedPositionInfo; string btnText = isVisible ? "Hide Info" : "Show Info"; btnSelectedPosInfo.Text(btnText); showSelectedPositionInfo = !showSelectedPositionInfo; } // ZeroMemory(iLbl); } // btnSelectedPosInfo.Pressed(false); } } // // TP Managing ... // // TP Plus ... if (btnTPPlus.Pressed()) { // if (btnTPPlus.IsEnabled()) { HandleTPChange(X_DIRECTION_BULLISH); } // btnTPPlus.Pressed(false); } // // TP Plus Plus ... if (btnTPPlusPlus.Pressed()) { // if (btnTPPlusPlus.IsEnabled()) { HandleTPChange(X_DIRECTION_BULLISH, 2); } // btnTPPlusPlus.Pressed(false); } // // TP Minus ... if (btnTPMinus.Pressed()) { // if (btnTPMinus.IsEnabled()) { HandleTPChange(X_DIRECTION_BEARISH); } // btnTPMinus.Pressed(false); } // // TP Minus Minus ... if (btnTPMinusMinus.Pressed()) { // if (btnTPMinusMinus.IsEnabled()) { HandleTPChange(X_DIRECTION_BEARISH, 2); } // btnTPMinusMinus.Pressed(false); } // // SL Managing ... // // SL Plus ... if (btnSLPlus.Pressed()) { // if (btnSLPlus.IsEnabled()) { HandleSLChange(X_DIRECTION_BULLISH); } // btnSLPlus.Pressed(false); } // // SL Plus Plus ... if (btnSLPlusPlus.Pressed()) { // if (btnSLPlusPlus.IsEnabled()) { HandleSLChange(X_DIRECTION_BULLISH, 2); } // btnSLPlusPlus.Pressed(false); } // // SL Minus ... if (btnSLMinus.Pressed()) { // if (btnSLMinus.IsEnabled()) { HandleSLChange(X_DIRECTION_BEARISH); } // btnSLMinus.Pressed(false); } // // SL Minus Minus ... if (btnSLMinusMinus.Pressed()) { // if (btnSLMinusMinus.IsEnabled()) { HandleSLChange(X_DIRECTION_BEARISH, 2); } // btnSLMinusMinus.Pressed(false); } // // Check Positions Buttons ... int posCount = posArray.Total(); bool has = IsValidSize(posCount); if (has) { // for (int i = 0; i < posCount; i++) { // CButton *iBtn = (CButton *)posArray.At(i); // if (iBtn.Pressed()) { // if (iBtn.IsEnabled()) { // ulong posID = ExtractPositionIDFromButtonName(iBtn.Name()); if (posID > 0 && selectedPositionID != posID) { selectedPositionID = posID; UpdatePanelState(); } } // iBtn.Pressed(false); } // ZeroMemory(iBtn); } } } /** * Update GUI Panels Controls States ... */ void UpdatePanelState() { // if (!eaShowPanel) { return; } // // Update States Of Position Select Buttons ... int count = posArray.Total(); bool has = IsValidSize(count) && selectedPositionID > 0; if (has) { // for (int i = 0; i < count; i++) { // CButton *iBtn = (CButton *)posArray.At(i); // ulong posID = ExtractPositionIDFromButtonName(iBtn.Name()); // // Select Position ... XPosition iPos; bool hasPosition = eaTrader.GetPosition( posID, iPos // ); string iTooltip = !hasPosition ? "" : IsLong(iPos.type) ? "Long" : "Short"; // if (posID == selectedPositionID) { // iBtn.Disable(); iBtn.ColorBackground(clrDarkGray); } else { // iBtn.Enable(); // color iBtnBG = IsLong(iPos.type) ? clrGreen : clrDarkRed; // iBtn.ColorBackground(iBtnBG); } // ZeroMemory(iBtn); } } // // Update State of Close All ... if (has && count > 1) { // btnCloseAll.Enable(); btnCloseAll.ColorBackground(clrDarkRed); } else { // btnCloseAll.Disable(); btnCloseAll.ColorBackground(clrDarkGray); } // // Update Selected Position Info Button State ... if (has) { // // Reading Global Chart Info ... int subWindow = 0; int chartWidth = eaChartHelper.Width(); ulong chartId = eaChartHelper.ChartId(); // // Read Selected Position ... XPosition selectedPosition; bool hasPosition = eaTrader.GetPosition( selectedPositionID, selectedPosition // ); // // Read All Positions ... double profits = 0; XPosition positions[]; string positionsInfo = ""; int positionsCount = eaTrader.GetPositions(positions); has = IsValidSize(positionsCount); if (has) { // for (int i = 0; i < positionsCount; i++) { profits += positions[i].profit; } // if (positionsCount > 1) { positionsInfo = "Positions Count: " + ToXString(positionsCount) + ", Profits: " + ToXString(profits); } } // if (hasPosition) { // // Preparing Position Info ... string posTicket = "Ticket: " + ToXString(selectedPosition.ticket); string posType = "Type: " + ToXString(selectedPosition.type); string posSymbolPeriod = "Symbol: " + selectedPosition.symbol + ", " + "Period: " + ToXString(selectedPosition.period); string posProfit = "Profit: " + ToXString(selectedPosition.profit); string posRiskToRewardRatio = "RiskToReward: " + ToXString(selectedPosition.GetRiskRewardRatio()); string accountInfo = "Balance: " + ToXString(eaTrader.mAccount.GetBalance()) + ", " + "Equity: " + ToXString(eaTrader.mAccount.GetEquity()); // string posInfos[]; // // Ticket ... Add( posTicket, posInfos // ); // // Type ... Add( posType, posInfos // ); // // Symbol Period ... Add( posSymbolPeriod, posInfos // ); // // Profit ... Add( posProfit, posInfos // ); // // Risk to Reward Ratio ... Add( posRiskToRewardRatio, posInfos // ); // // Add Positions Info if Exists ... if (IsSpecifiedValid(positionsInfo)) { // Add( positionsInfo, posInfos // ); // // Clear Info Array ... selectedPosInfoArr.Clear(); } // // Adding Account Info ... Add( accountInfo, posInfos // ); // // Create Button If Not Exists ... if (btnSelectedPosInfo == NULL) { // btnSelectedPosInfo = new CButton(); // string name = objSuffix + "BTN_TOOGLE_SPOS_INFO"; // CRect iRect = btnTPPlus.Rect(); // int x1 = iRect.left; int x2 = x1 + 200 + 5; // int y1 = iRect.bottom + 5; int y2 = y1 + iRect.Height(); // bool isCreated = btnSelectedPosInfo.Create( chartId, name, subWindow, x1, y1, x2, y2 // ); if (!isCreated) { // delete btnSelectedPosInfo; ZeroMemory(btnSelectedPosInfo); } else { // // Apply Styles ... btnSelectedPosInfo.Color(clrYellow); btnSelectedPosInfo.ColorBackground(clrDarkBlue); } } // // Check Btn Exists ... has = btnSelectedPosInfo != NULL; if (has) { // int posInfoCount = ArraySize(posInfos); int lblInfoCount = selectedPosInfoArr.Total(); has = IsValidSize(lblInfoCount) && lblInfoCount == posInfoCount; // // Create info Labels ... if (!has) { // selectedPosInfoArr.Clear(); has = IsValidSize(posInfoCount); if (has) { // // Creat Info Control ... // string name = objSuffix + "LBL_SPOS_INFO"; // int lblHeight = 25; int lblWidth = 450; // int startX = chartWidth - lblWidth - 5; int sizeX = startX + lblWidth; // int startY = 5; int sizeY = startY + lblHeight; // // Loop through Position Info's Array to Create Label Controls ... for (int i = 0; i < posInfoCount; i++) { // string iText = posInfos[i]; string iTextMD5 = ToMD5(iText); // string iName = name + "_" + iTextMD5; // int iX1 = startX; int iX2 = sizeX; // int iY1 = startY; int iY2 = startY + lblHeight; // CEdit *iLbl = new CEdit(); bool isCreated = iLbl.Create( chartId, iName, subWindow, iX1, iY1, iX2, iY2 // ); if (isCreated) { // iLbl.Text(iText); iLbl.Color(clrYellow); iLbl.ColorBorder(clrDarkSlateGray); iLbl.ColorBackground(clrDarkSlateGray); // if (showSelectedPositionInfo) { iLbl.Show(); } else { iLbl.Hide(); } // selectedPosInfoArr.Add(iLbl); // startY = iY2; } } } } // // Update Info Labels ... lblInfoCount = selectedPosInfoArr.Total(); has = IsValidSize(lblInfoCount); if (has) { // CEdit *iLbl = NULL; // // Loop Through Infos ... for (int i = 0; i < lblInfoCount; i++) { // iLbl = (CEdit *)selectedPosInfoArr.At(i); // iLbl.Text(posInfos[i]); } // bool isVisible = showSelectedPositionInfo; string btnText = isVisible ? "Hide Info" : "Show Info"; btnSelectedPosInfo.Text(btnText); // ZeroMemory(iLbl); } } // ZeroMemory(posInfos); } // SpecifiedClean(positions); } else { // // Toggle Selected Position Btn ... if (btnSelectedPosInfo != NULL) { // btnSelectedPosInfo.Destroy(); // delete btnSelectedPosInfo; ZeroMemory(btnSelectedPosInfo); } // // Selected Position Lbls ... selectedPosInfoArr.Clear(); } // // Update State of BtnClose and BtnClose All ... if (selectedPositionID == 0) { // btnClose.Disable(); btnClose.ColorBackground(clrDarkGray); // lblTP.Disable(); lblTP.ColorBackground(clrDarkGray); // btnTPPlus.Disable(); btnTPPlus.ColorBackground(clrDarkGray); // btnTPPlusPlus.Disable(); btnTPPlusPlus.ColorBackground(clrDarkGray); // btnTPMinus.Disable(); btnTPMinus.ColorBackground(clrDarkGray); // btnTPMinusMinus.Disable(); btnTPMinusMinus.ColorBackground(clrDarkGray); // lblSL.Disable(); lblSL.ColorBackground(clrDarkGray); // btnSLPlus.Disable(); btnSLPlus.ColorBackground(clrDarkGray); // btnSLPlusPlus.Disable(); btnSLPlusPlus.ColorBackground(clrDarkGray); // btnSLMinus.Disable(); btnSLMinus.ColorBackground(clrDarkGray); // btnSLMinusMinus.Disable(); btnSLMinusMinus.ColorBackground(clrDarkGray); } else { // btnClose.Enable(); btnClose.ColorBackground(clrDarkOrange); // lblTP.Enable(); lblTP.ColorBackground(clrGreen); // btnTPPlus.Enable(); btnTPPlus.ColorBackground(clrGreen); // btnTPPlusPlus.Enable(); btnTPPlusPlus.ColorBackground(clrGreen); // btnTPMinus.Enable(); btnTPMinus.ColorBackground(clrDarkRed); // btnTPMinusMinus.Enable(); btnTPMinusMinus.ColorBackground(clrDarkRed); // lblSL.Enable(); lblSL.ColorBackground(clrDarkRed); // btnSLPlus.Enable(); btnSLPlus.ColorBackground(clrGreen); // btnSLPlusPlus.Enable(); btnSLPlusPlus.ColorBackground(clrGreen); // btnSLMinus.Enable(); btnSLMinus.ColorBackground(clrDarkRed); // btnSLMinusMinus.Enable(); btnSLMinusMinus.ColorBackground(clrDarkRed); } } /** * Update Panel's Position Selector Buttons ... */ void UpdatePanelPositionButtons() { // if (!eaShowPanel) { return; } // // Retrieve Positions ... XPosition positions[]; int count = eaTrader.GetPositions( positions // ); bool has = IsValidSize(count); if (!has) { // posArray.Clear(); selectedPositionID = 0; UpdatePanelState(); return; } // posArray.Clear(); // // Selected Position ID ... bool isSelectdPositionIDExists = false; if (has && selectedPositionID > 0) { // for (int i = 0; i < count; i++) { // if (!isSelectdPositionIDExists && positions[i].ticket == selectedPositionID) { // isSelectdPositionIDExists = true; break; } } } if (!isSelectdPositionIDExists || selectedPositionID == 0) { // XPosition youngest; int youngestIDX = GetXYoungest(youngest, positions); bool hasYoungest = IsValidIndex(youngestIDX) && youngest.IsValid(); if (hasYoungest) { selectedPositionID = youngest.ticket; } // youngest.Clean(); } // int subWindow = 0; ulong chartId = eaChartHelper.ChartId(); // int btnWidth = 25; int btnHeight = 25; // CRect iRect = lblPositionId.Rect(); // int lastX = iRect.left + iRect.Width() + 5; int lastSizeX = lastX + btnWidth; // int lastY = iRect.top; int lastSizeY = lastY + iRect.Height(); // for (int i = 0; i < count; i++) { // XPosition iPos = positions[i]; // string posTypeStr = IsLong(iPos.type) ? "LONG" : "SHORT"; // int iPosBtnX = lastX; int iPosBtnSizeX = iPosBtnX + btnWidth; string iPosBtnName = objSuffix + "_" + posTypeStr + "_POS_SELECT_BTN_" + ToXString(iPos.ticket); // CButton *iPosBtn = new CButton(); has = iPosBtn.Create( chartId, iPosBtnName, subWindow, iPosBtnX, lastY, iPosBtnSizeX, lastSizeY // ); if (has) { // // Apply Styles ... string iPosBtnText = ToXString(iPos.ticket); // iPosBtn.Text(iPosBtnText); iPosBtn.Color(clrWhite); // color iPosBtnBG = IsLong(iPos.type) ? clrGreen : clrDarkRed; iPosBtn.ColorBackground(iPosBtnBG); // lastX = iPosBtnSizeX + 5; // if (selectedPositionID == iPos.ticket) { iPosBtn.Disable(); } // posArray.Add(iPosBtn); } // iPos.Clean(); } // ZeroMemory(positions); UpdatePanelState(); // } /** * Destroy Management GUI Panel ... */ void DestroyPanel() { // delete eaChartHelper; ZeroMemory(eaChartHelper); // delete btnSelectedPosInfo; ZeroMemory(btnSelectedPosInfo); } // void NormalizePanelProps() { // if (eaPanelVolume < 0.01) { eaPanelVolume = 0.01; } // if (eaPanelRiskInPoint < 0) { eaPanelRiskInPoint = 50; } // if (eaPanelAllowedTPSLStep < 5) { eaPanelAllowedTPSLStep = 5; } // if (eaPanelRiskToRewardRatio < 0.5) { eaPanelRiskToRewardRatio = 2; } // if (eaPanelMinAllowedRiskInPoint < 10) { eaPanelMinAllowedRiskInPoint = 10; } } // ulong ExtractPositionIDFromButtonName(string name) { // ulong result = 0; // string nameParts[]; int namePartsCount = SplitContent(nameParts, name, "_"); bool has = IsValidSize(namePartsCount); if (has) { // string lastPart = nameParts[namePartsCount - 1]; StringReplace(lastPart, "_", ""); result = (long)lastPart; } // ZeroMemory(nameParts); // return result; } // // Management Panel Event Handlers ... // void HandleBuyTrade() { HandleTrade(X_DIRECTION_BULLISH); } // void HandleSellTrade() { HandleTrade(X_DIRECTION_BEARISH); } // void HandleTrade(ENUM_X_DIRECTION dir) { // if (!HasDirection(dir)) { return; } // NormalizePanelProps(); // bool isBullish = IsSpecifiedBullish(dir); // double _volume = eaPanelVolume; double r2r = eaPanelRiskToRewardRatio; double _riskInPoints = eaPanelRiskInPoint; double point = GetPoints(eaChartHelper.Symbol()); double entry = GetEntry(eaChartHelper.Symbol(), dir); // double risk = _riskInPoints * point; double reward = risk * r2r; // double sl = isBullish ? entry - risk : entry + risk; double tp = isBullish ? entry + reward : entry - reward; // string comment = eaLogSuffix + "_POS_" + ToXString(dir); // if (isBullish) { // eaTrader.Buy( eaChartHelper.Symbol(), eaChartHelper.Period(), _volume, entry, sl, tp, comment // ); } else { // eaTrader.Sell( eaChartHelper.Symbol(), eaChartHelper.Period(), _volume, entry, sl, tp, comment // ); } } // void HandleCloseTrade(ulong positionID) { // if (positionID == 0) { // XPosition positions[]; int count = eaTrader.GetPositions( positions // ); bool has = IsValidSize(count); if (has) { // int closedCount = eaTrader.Close(positions); has = IsValidSize(closedCount); } } else { // XPosition position; bool has = eaTrader.GetPosition( positionID, position // ); if (has) { // has = eaTrader.Close(positionID); } } } // void HandleTPChange( ENUM_X_DIRECTION dir, int multiplier = 1 // ) { // // Validate ... if (selectedPositionID == 0 || !HasDirection(dir)) { return; } // NormalizePanelProps(); // // Normalize Multiplier ... multiplier = NormalizeInt(multiplier, 1, 2); // // Select Position ... XPosition position; bool has = eaTrader.GetPosition( selectedPositionID, position // ); if (!has) { // position.Clean(); return; } // bool isLong = IsLong(position.type); bool isBullish = IsSpecifiedBullish(dir); // double point = GetPoints(position.symbol); double stepValue = multiplier * (point * eaPanelAllowedTPSLStep); // bool mustIncrease = isBullish ? isLong : !isLong; // double tp = position.tp; tp = mustIncrease ? tp + stepValue : tp - stepValue; bool isModified = eaTrader.Modify( position.ticket, position.sl, tp, objSuffix + "Change TP" // ); if (isModified) { UpdatePanelState(); } // position.Clean(); } // void HandleSLChange( ENUM_X_DIRECTION dir, int multiplier = 1 // ) { // // Validate ... if (selectedPositionID == 0 || !HasDirection(dir)) { return; } // NormalizePanelProps(); // // Normalize Multiplier ... multiplier = NormalizeInt(multiplier, 1, 2); // // Select Position ... XPosition position; bool has = eaTrader.GetPosition( selectedPositionID, position // ); if (!has) { // position.Clean(); return; } // bool isLong = IsLong(position.type); bool isBullish = IsSpecifiedBullish(dir); // double point = GetPoints(position.symbol); double stepValue = multiplier * (point * eaPanelAllowedTPSLStep); // bool mustIncrease = isBullish ? !isLong : isLong; // double risk = position.GetRiskInPoint(); if (risk <= eaPanelMinAllowedRiskInPoint) { // position.Clean(); return; } // double sl = position.sl; sl = mustIncrease ? sl + stepValue : sl - stepValue; bool isModified = eaTrader.Modify( position.ticket, sl, position.tp, objSuffix + "Change SL" // ); if (isModified) { UpdatePanelState(); } // position.Clean(); } // }; //