Capital management is the most crucial and often underestimated component of any trading system. Proper capital management can enhance—and sometimes significantly improve—the performance of your trading algorithm.
This application automatically calculates the optimal fraction and trade volume using the algorithm proposed by Ralph Vince in his book "The Mathematics of Money Management" to achieve maximum geometric growth of the account balance. This point exists and is unique for any trading system, which is why it is essential to know it. In your trading systems, you must never use a trade size exceeding the optimal value!
Capital management algorithms are NOT designed for mathematically losing systems based on averaging, martingale, or similar strategies. Such systems will be filtered out by the application before any calculations, as the optimal fraction and trade volume for these systems are always equal to zero. Capital management algorithms can improve results ONLY for mathematically profitable trading systems (those with a positive mathematical expectation). Therefore, this service is recommended ONLY for professionals who understand what they are doing.
Additionally, the algorithm does not account for correlation (dependencies) between simultaneously operating systems. For the algorithm to work effectively, a well-diversified set of trading systems is necessary.
Before the first launch, each trading system must be tested in the strategy tester for the period up to the present moment. It is recommended to select a timeframe that includes at least 100 trades. Then, using the Test Trade Saver Script and following the instructions, extract the result files from the testing files (*.tst) in the required format.
If the trading system has already been used in the terminal and there are positions in the history with the specified MAGIC, you must set a different CUSTOM_MAGIC_NUMBER parameter in the script!
Next, to ensure that the data files are regularly updated and remain current, you need to run the Trade Saver Service following the provided instructions.
Thus, after the initial data export from tests using the Trade Saver Script, the Trade Saver Service continuously updates the files with new data as it becomes available, while the Optimal F Service regularly calculates and writes new values to the results file
#include "OptimalFResultsLoader.mqh"
// create loader COptimalFResultsLoader* optimalFResultsLoader = new COptimalFResultsLoader("/SRProject/results.csv"); // print all fields for magic = '1111' Print(optimalFResultsLoader.getOptimalFFor(1111), " ", optimalFResultsLoader.getBiggestLossFor(1111), " ", optimalFResultsLoader.getOptimalLotsFor(1111)); // delete loader from memory delete(optimalFResultsLoader);
//+------------------------------------------------------------------+ //| OptimalFResultsLoader.mqh | //| Semyon Racheev | //| | //+------------------------------------------------------------------+ #property copyright "Semyon Racheev" #property link "" #property version "1.00" #include <Files\FileTxt.mqh> class COptimalFResultsLoader { private: const string name_; const uchar delimiter_; const ushort separator_; const string srcFilePath_; bool checkStringForOptimalFResultsDeserializing(string &inputStr[]) const; ushort calculateCharCode(const uchar separator) const; public: COptimalFResultsLoader(const string srcFilePath, uchar separator); ~COptimalFResultsLoader(); double getOptimalLotsFor(const ulong magicNumber) const; double getOptimalFFor(const ulong magicNumber) const; double getBiggestLossFor(const ulong magicNumber) const; }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ COptimalFResultsLoader::COptimalFResultsLoader(const string srcFilePath = "/SRProject/results.csv", uchar separator = ','):name_("OptimalFResultsLoader"), srcFilePath_(srcFilePath), delimiter_(separator), separator_(calculateCharCode(separator)) { } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ COptimalFResultsLoader::~COptimalFResultsLoader() { } //+------------------public------------------------------------------+ //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ double COptimalFResultsLoader::getOptimalLotsFor(const ulong inputMagicNumber) const { double rsl = 0.0; CFileTxt* file = new CFileTxt(); int fileHandle = file.Open(srcFilePath_,FILE_READ|FILE_UNICODE|FILE_CSV); while (!FileIsEnding(fileHandle)) { string readString = file.ReadString(); string str[]; StringSplit(readString, separator_, str); if (checkStringForOptimalFResultsDeserializing(str)) { if (inputMagicNumber == (ulong)StringToInteger(str[0])) { rsl = StringToDouble(str[3]); } } } file.Close(); delete(file); return(rsl); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ double COptimalFResultsLoader::getOptimalFFor(const ulong inputMagicNumber) const { double rsl = 0.0; CFileTxt* file = new CFileTxt(); int fileHandle = file.Open(srcFilePath_,FILE_READ|FILE_UNICODE|FILE_CSV); while (!FileIsEnding(fileHandle)) { string readString = file.ReadString(); string str[]; StringSplit(readString, separator_, str); if (checkStringForOptimalFResultsDeserializing(str)) { if (inputMagicNumber == (ulong)StringToInteger(str[0])) { rsl = StringToDouble(str[2]); } } } file.Close(); delete(file); return(rsl); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ double COptimalFResultsLoader::getBiggestLossFor(const ulong inputMagicNumber) const { double rsl = 0.0; CFileTxt* file = new CFileTxt(); int fileHandle = file.Open(srcFilePath_,FILE_READ|FILE_UNICODE|FILE_CSV); while (!FileIsEnding(fileHandle)) { string readString = file.ReadString(); string str[]; StringSplit(readString, separator_, str); if (checkStringForOptimalFResultsDeserializing(str)) { if (inputMagicNumber == (ulong)StringToInteger(str[0])) { rsl = StringToDouble(str[1]); } } } file.Close(); delete(file); return(rsl); } //+---------------------private--------------------------------------+ //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ bool COptimalFResultsLoader::checkStringForOptimalFResultsDeserializing(string &inputStr[]) const { if (ArraySize(inputStr) < 4) { return(false); } return(true); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ ushort COptimalFResultsLoader::calculateCharCode(const uchar separator) const { string str = CharToString(separator); return(StringGetCharacter(str,0)); } //+------------------------------------------------------------------+
If for any reason you do not like the purchased program, you can request a refund within 30 days from the date of purchase. You can also make an exchange for any other product at an equal cost or by paying the difference.
Simply send a request for refund or exchange with your order number by email: [email protected].
Refund requests received more than 30 days after purchase will be rejected.