/////////////////////////////////////////////////////// // // SaherElm IT Center MQL5 Class Library // -------------------------------------- // Name: XCVolume // Description: provides all Requirements for Volume Managing ... // // // Maintainer: // ------------ // Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) // ////////////////////////////////////////////////////// // // Global Properties ... #property library #property copyright "Copyright 2023, SaherElm IT Center" #property link "https://www.saherelm.ir" #property version "1.00" #property strict // // Template Variables of Inputs for Using ... // input group "Volume"; // input ENUM_X_VOLUME_SELECT_TYPE eaVolumeSelect = X_VOLUME_STATIC; // Volume Applying Type // input double eaStaticVoluem = X_MIN_VOLUME; // Static Volume // input double eaDynamicVolumeStepBalance = 0.0; // Step of Balance for Increase Volume // input double eaDynamicVolumeStepVolume = X_MIN_VOLUME; // Step of Volume Increasing // input double eaConstantRiskBalance = 0.0; // Constant Risk Balance per Trade // input double eaConstantPercent = 0.0; // Constant Percent of Balance Per Trade // input double eaConstantBalance = 0.0; // Constant Balance for Calculations // XCVolume *eaVolume; // eaVolume = new XCVolume(); // bool result = eaVolume.Init( // eaVolumeSelect, // eaStaticVoluem, // eaDynamicVolumeStepBalance, // eaDynamicVolumeStepVolume, // eaConstantRiskBalance, // eaConstantPercent, // eaConstantBalance // // ); // if (!result) { // return INIT_FAILED; // } // // Imports ... #include "../Classes/x-saherelm.x-account.class.mq5" #include "../Libraries/x-saherelm.x-trade.lib.mq5" // // Definitions ... #define X_MIN_VOLUME 0.01 // enum ENUM_X_VOLUME_SELECT_TYPE { X_VOLUME_NONE, // None X_VOLUME_STATIC, // Static Volume X_VOLUME_CURRENT, // Current Balance X_VOLUME_EQUITY, // Current Equity X_VOLUME_CONSTANT // Constant Value }; // bool IsValid(ENUM_X_VOLUME_SELECT_TYPE value) { // bool result = false; // result = value != X_VOLUME_NONE; // return result; } // string ToString(ENUM_X_VOLUME_SELECT_TYPE value) { // string result = NULL; // result = EnumToString(value); // return result; } // // Implementation ... class XCVolume : public XCBase { // // Public ... public: // // Props ... XCAccount *account; // // Constructor ... XCVolume() { // account = new XCAccount(); // Default(); } // // Deconstructor ... ~XCVolume() { // ZeroMemory(account); } // bool Init( ENUM_X_VOLUME_SELECT_TYPE _SelectType, double _StaticVolume, double _DynamicVolumeStepBalance, double _DynamicVolumeStepVolume, double _ConstantRiskBalance, double _ConstantPercent, double _ConstantBalance // ) { // bool result = false; // mVolumeType = _SelectType; mStaticVolume = _StaticVolume; mConstantPercent = _ConstantPercent; mConstantBalance = _ConstantBalance; mConstantRiskBalance = _ConstantRiskBalance; mDynamicVolumeStepVolume = _DynamicVolumeStepVolume; mDynamicVolumeStepBalance = _DynamicVolumeStepBalance; // result = // CanUseStaticVolume() || CanUseDynamicVolume() || CanUseConstantRiskBalance() || CanUseConstantBalancePercent() // ; // return result; } // // Prperties ... /** * Get Volume Calculating Method ... * * @return (ENUM_X_VOLUME_SELECT_TYPE) */ ENUM_X_VOLUME_SELECT_TYPE VolumeType() { return mVolumeType; } /** * Set Volume Calculating Method ... * * @param value: ENUM_X_VOLUME_SELECT_TYPE member ... */ void VolumeType(ENUM_X_VOLUME_SELECT_TYPE value) { mVolumeType = value; } /** * Get Static Volume ... * * @return ( double ) */ double StaticVolume() { return mStaticVolume; } /** * Set Static Volume ... * * @param value: double */ void StaticVolume(double value) { // value = NormalizeDouble(value, 0.01, 1); // mStaticVolume = value; } /** * Get Dynamic Volume Step Balance ... * used to Calculate Final Lottage ... * * @return ( double ) */ double DynamicVolumeStepBalance() { return mDynamicVolumeStepBalance; } /** * Set Dynamic Volume Step Balance ... * used to Calculate Final Lottage ... * * @param value: Argument 1 */ void DynamicVolumeStepBalance(double value) { // value = NormalizeDouble(value, 0); // mDynamicVolumeStepBalance = value; } /** * Get Dynamic Volume Step Volume ... * used to Calculate Final Lottage ... * how much increase Final Volume based oBalance Step ... * * @return ( double ) */ double DynamicVolumeStepVolume() { return mDynamicVolumeStepVolume; } /** * Get Dynamic Volume Step Volume ... * used to Calculate Final Lottage ... * how much increase Final Volume based oBalance Step ... * * @param value: double */ void DynamicVolumeStepVolume(double value) { // value = NormalizeDouble(value, 0.01, 0.1); // mDynamicVolumeStepVolume = value; } /** * Get Constant Balance Use for Dyamic Volume Calculation ... * * @return ( double ) */ double ConstantBalance() { return mConstantBalance; } /** * Set Constant Balance Use for Dyamic Volume Calculation ... * * @param value: Argument 1 */ void ConstantBalance(double value) { // value = NormalizeDouble(value, 0); // mConstantBalance = value; } /** * Get Constant Risk Value Based on Account Currency ... * * @return ( double ) */ double ConstantRiskBalance() { return mConstantRiskBalance; } /** * Get Constant Risk Value Based on Account Currency ... * * @param value: double */ void ConstantRiskBalance(double value) { // value = NormalizeDouble(value, 0); // mConstantRiskBalance = value; } /** * Get Constant Percent Based On Selected Balance ... * * @return ( double ) */ double ConstantPercent() { return mConstantPercent; } /** * Set Constant Percent Based On Selected Balance ... * * @param value: double ... */ void ConstantPercent(double value) { // value = NormalizeDouble(value, 0, 100); // mConstantPercent = value; } // // Tools ... /** * Retrieve Balance based on Provided Volume Type ... * * @return ( double ) */ double GetBalance() { // double result = 0; // if (!IsValid(mVolumeType)) { return result; } // if (mConstantBalance > 0 && mVolumeType == X_VOLUME_CONSTANT) { result = mConstantBalance; } else if (mVolumeType == X_VOLUME_CURRENT) { result = account.GetBalance(); } else if (mVolumeType == X_VOLUME_EQUITY) { result = account.GetEquity(); } // return result; } /** * Retrieve Balance based on Provided Volume Type ... * * @return ( double ) */ double GetBalance(ENUM_X_VOLUME_SELECT_TYPE type) { // double result = 0; // if (!IsValid(type)) { return result; } // if (mConstantBalance > 0 && type == X_VOLUME_CONSTANT) { result = mConstantBalance; } else if (type == X_VOLUME_CURRENT) { result = account.GetBalance(); } else if (type == X_VOLUME_EQUITY) { result = account.GetEquity(); } // return result; } /** * Calculate Volume Based On Given Configuration ... * * @param symbol: string, Trading Symbol ... * @param entry: double, Entry Price ... * @param sl: double, Stop Loss Price ... * * @return ( double ) */ double CalculateVolume( string symbol, double entry, double sl // ) { // double result = X_MIN_VOLUME; // bool has = false; // // Validate Args ... has = sl > 0 && entry > 0 && IsValid(symbol); if (!has) { return result; } // // Retrieve Balance Type ... double balance = GetBalance(); double points = GetPoints(symbol); double riskPrice = MathAbs(entry - sl); double riskInPoints = riskPrice / points; // has = CanUseStaticVolume(); if (has) { result = mStaticVolume; } // has = CanUseDynamicVolume(); if (has) { // double multiplier = balance / mDynamicVolumeStepBalance; if (multiplier < 0) { multiplier = 1; } // result = multiplier * mDynamicVolumeStepVolume; } // has = CanUseConstantRiskBalance(); if (has) { // result = account.CalculateVolume( symbol, mConstantRiskBalance, riskInPoints // ); } // has = CanUseConstantBalancePercent(); if (has) { // double riskAmountPerBalance = (mConstantPercent * balance) / 100; // result = account.CalculateVolume( symbol, riskAmountPerBalance, riskInPoints // ); } // if (result < X_MIN_VOLUME) { result = X_MIN_VOLUME; } // // Normalize Volume ... result = NormalizeVolume(result, symbol); // return result; } /** * Calculate Volume Based On Given Configuration ... * * @param signal: XSignal instance reference, provided required Data ... * * @return ( double ) */ double CalculateVolume(XSignal &signal) { // double result = X_MIN_VOLUME; // if (!signal.IsValid()) { return result; } // result = CalculateVolume( signal.symbol, signal.entry, signal.sl // ); // return result; } /** * Calculate Specified Percent of Selected Balance for Volume ... * * @param percent: double, percent of Balance Risking ... * @param symbol: string, Trading Symbol ... * @param entry: double, Entry Price ... * @param sl: double Stop Loss Price ... * * @return ( double ) */ double CalculateVolume( ENUM_X_VOLUME_SELECT_TYPE selectType, double percent, string symbol, double entry, double sl // ) { // double result = X_MIN_VOLUME; // bool has = false; // // Validate Args ... has = sl > 0 && entry > 0 && percent > 0 && IsValid(symbol) && IsValid(selectType) && (selectType == X_VOLUME_EQUITY || selectType == X_VOLUME_CURRENT); if (!has) { return result; } // // Retrieve Balance Type ... double points = GetPoints(symbol); double riskPrice = MathAbs(entry - sl); double balance = GetBalance(selectType); double riskInPoints = riskPrice / points; // double riskAmountPerBalance = (percent * balance) / 100; // result = account.CalculateVolume( symbol, riskAmountPerBalance, riskInPoints // ); // return result; } // // Protected ... protected: // // Tools ... /** * Set Default Props ... */ void Default() { // VolumeType(X_VOLUME_STATIC); StaticVolume(0.01); // ConstantBalance(0); ConstantPercent(0); ConstantRiskBalance(0); // DynamicVolumeStepBalance(0); DynamicVolumeStepVolume(0.01); } /** * Check Configuration is Valid For Static Volume ... * * @return ( bool ) */ bool CanUseStaticVolume() { // bool result = false; // result = IsValid(mVolumeType); if (!result) { return result; } // // Static Volume ... result = // mVolumeType == X_VOLUME_STATIC && mStaticVolume > 0 && // mDynamicVolumeStepBalance == 0 && // mConstantBalance == 0 && mConstantPercent == 0 && mConstantRiskBalance == 0 // ; // return result; } /** * Check Configuration is Valid For Dynamic Volume ... * * @return ( bool ) */ bool CanUseDynamicVolume() { // bool result = false; // result = IsValid(mVolumeType); if (!result) { return result; } // result = // (mVolumeType == X_VOLUME_CURRENT || mVolumeType == X_VOLUME_EQUITY || (mVolumeType == X_VOLUME_CONSTANT && mConstantBalance > 0)) && // mDynamicVolumeStepBalance > 0 && mDynamicVolumeStepVolume > 0 && // mStaticVolume == 0 && mConstantPercent == 0 && mConstantRiskBalance == 0 // ; // return result; } /** * Check Configuration is Valid For Constant Risk Balance ... * * @return ( bool ) */ bool CanUseConstantRiskBalance() { // bool result = false; // result = IsValid(mVolumeType); if (!result) { return result; } // result = // (mVolumeType == X_VOLUME_CURRENT || mVolumeType == X_VOLUME_EQUITY || (mVolumeType == X_VOLUME_CONSTANT && mConstantBalance > 0)) && // mConstantRiskBalance > 0 && // mStaticVolume == 0 && mConstantPercent == 0 && mDynamicVolumeStepBalance == 0 // ; // return result; } /** * Check Configuration is Valid For Constant Risk Percent ... * * @return ( bool ) */ bool CanUseConstantBalancePercent() { // bool result = false; // result = IsValid(mVolumeType); if (!result) { return result; } // result = // (mVolumeType == X_VOLUME_CURRENT || mVolumeType == X_VOLUME_EQUITY || (mVolumeType == X_VOLUME_CONSTANT && mConstantBalance > 0)) && // mConstantPercent > 0 && // mStaticVolume == 0 && mConstantRiskBalance == 0 && mDynamicVolumeStepBalance == 0 // ; // return result; } // // Private ... private: // // Props ... // ENUM_X_VOLUME_SELECT_TYPE mVolumeType; // Balance Type ... // // Static Volume ... double mStaticVolume; // Static Volume ... // double mDynamicVolumeStepBalance; // Step of Balance ... double mDynamicVolumeStepVolume; // Step of Volume ... // double mConstantBalance; // Constant Balance .... double mConstantRiskBalance; // Constant Risk Balance ... double mConstantPercent; // Constant Percent of Balance ... }; //