CompoundPercent For Trader

Author: Copyright 2025
0 Views
0 Downloads
0 Favorites
CompoundPercent For Trader
ÿþ//+------------------------------------------------------------------+

//|                                    AdvancedTradingCalculator.mq5 |

//|                                  Copyright 2025, Trading Systems |

//+------------------------------------------------------------------+

#property copyright "Copyright 2025"

#property version   "2.00"

#property description " 0AH8@5==K9 :0;L:C;OB>@ 4;O B@5945@0 A @8A:-<5=546<5=B><"

#property indicator_chart_window

#property indicator_buffers 1

#property indicator_plots   1



#property indicator_type1   DRAW_LINE

#property indicator_color1  clrBlue

#property indicator_style1  STYLE_SOLID

#property indicator_width1  2



// E>4=K5 ?0@0<5B@K - =25AB8F88

input double InitialCapital = 1000.0;    // 0G0;L=K9 :0?8B0;

input int Years = 10;                    // >;8G5AB2> ;5B

input double MonthlyDeposit = 100.0;     // 65<5AOG=>5 ?>?>;=5=85



// E>4=K5 ?0@0<5B@K - ">@3>2;O

input int TradesPerDay = 3;              // >;8G5AB2> A45;>: 2 45=L

input double WinRate = 55.0;             // 5@>OB=>ABL ?@81K;L=>9 A45;:8 (%)

input double RiskRewardRatio = 1.5;      // B=>H5=85 @8A:0 : ?@81K;8 (1:X)

input double MaxDrawdownLimit = 20.0;     // A8E>;>38G5A:89 10@L5@ ?@>A04:8 (%)

input int RefreshInterval = 1;           // =B5@20; >1=>2;5=8O (2 A5:C=40E)



// ;>10;L=K5 ?5@5<5==K5

double totalAmount[];

double indicatorBuffer[];

string objPrefix = "TradingCalc_";

int windowWidth = 400;

int windowHeight = 480;

int chartWidth, chartHeight;



// !B@C:BC@0 4;O E@0=5=8O B>@3>2KE @0AG5B>2

struct TradingMetrics {

    double maxRiskPerTrade;          // 0:A8<0;L=K9 @8A: =0 A45;:C

    double expectedMonthlyReturn;     // 68405<0O <5AOG=0O 4>E>4=>ABL

    double expectedAnnualReturn;      // 68405<0O 3>4>20O 4>E>4=>ABL

    int monthlyTrades;               // >;8G5AB2> A45;>: 2 <5AOF

    double probabilityOfRuin;        // 5@>OB=>ABL @07>@5=8O

    double expectedMonthlyCapital;   // 68405<K9 :0?8B0; G5@57 <5AOF

    double expectedAnnualCapital;    // 68405<K9 :0?8B0; G5@57 3>4

    double expectedFinalCapital;     // 68405<K9 :0?8B0; 2 :>=F5 A@>:0

};



TradingMetrics metrics;



//+------------------------------------------------------------------+

//| =8F80;870F8O 8=48:0B>@0                                          |

//+------------------------------------------------------------------+

int OnInit()

{

    SetIndexBuffer(0, indicatorBuffer, INDICATOR_DATA);

    ArrayResize(totalAmount, Years * 12);

    

    if(!ValidateInputs()) return INIT_PARAMETERS_INCORRECT;

    

    CreatePanel();

    EventSetTimer(RefreshInterval);

    

    return(INIT_SUCCEEDED);

}



//+------------------------------------------------------------------+

//| @>25@:0 2E>4=KE ?0@0<5B@>2                                       |

//+------------------------------------------------------------------+

bool ValidateInputs()

{

    if(InitialCapital <= 0 || MonthlyDeposit < 0 || Years <= 0)

        return false;

    if(TradesPerDay <= 0 || WinRate <= 0 || WinRate >= 100)

        return false;

    if(RiskRewardRatio <= 0 || MaxDrawdownLimit <= 0 || MaxDrawdownLimit >= 100)

        return false;

        

    return true;

}



//+------------------------------------------------------------------+

//|  0AG5B B>@3>2KE <5B@8:                                            |

//+------------------------------------------------------------------+

void CalculateTradingMetrics()

{

    //  0AG5B :>;8G5AB20 A45;>:

    metrics.monthlyTrades = TradesPerDay * 22; // ?@8<5@=> 22 B>@3>2KE 4=O 2 <5AOF

    

    //  0AG5B <0:A8<0;L=>3> @8A:0 =0 A45;:C

    double maxRiskAmount = (InitialCapital * MaxDrawdownLimit / 100) / sqrt(metrics.monthlyTrades);

    metrics.maxRiskPerTrade = NormalizeDouble(maxRiskAmount / InitialCapital * 100, 2);

    

    //  0AG5B >68405<>9 4>E>4=>AB8

    double winProb = WinRate / 100;

    double loseProb = 1 - winProb;

    double expectedValuePerTrade = (winProb * RiskRewardRatio) - loseProb;

    

    metrics.expectedMonthlyReturn = expectedValuePerTrade * metrics.monthlyTrades * metrics.maxRiskPerTrade;

    metrics.expectedAnnualReturn = metrics.expectedMonthlyReturn * 12;

    

    //  0AG5B 25@>OB=>AB8 @07>@5=8O (D>@<C;0 5;;8)

    double kellyPercentage = (winProb * RiskRewardRatio - loseProb) / RiskRewardRatio;

    metrics.probabilityOfRuin = exp(-2 * pow(InitialCapital / maxRiskAmount, 2) * pow(kellyPercentage, 2));

    

    //  0AG5B >68405<>3> :0?8B0;0

    CalculateExpectedCapital();

}



//+------------------------------------------------------------------+

//|  0AG5B >68405<>3> :0?8B0;0                                        |

//+------------------------------------------------------------------+

void CalculateExpectedCapital()

{

    // '5@57 <5AOF

    metrics.expectedMonthlyCapital = InitialCapital * (1 + metrics.expectedMonthlyReturn/100) + MonthlyDeposit;

    

    // '5@57 3>4 (A CG5B>< 565<5AOG=KE ?>?>;=5=89)

    metrics.expectedAnnualCapital = InitialCapital;

    for(int i = 0; i < 12; i++) {

        metrics.expectedAnnualCapital = metrics.expectedAnnualCapital * (1 + metrics.expectedMonthlyReturn/100) + MonthlyDeposit;

    }

    

    //  :>=F5 A@>:0

    metrics.expectedFinalCapital = InitialCapital;

    for(int i = 0; i < Years * 12; i++) {

        metrics.expectedFinalCapital = metrics.expectedFinalCapital * (1 + metrics.expectedMonthlyReturn/100) + MonthlyDeposit;

        totalAmount[i] = metrics.expectedFinalCapital;

    }

}



//+------------------------------------------------------------------+

//| !>740=85 8=D>@<0F8>==>9 ?0=5;8                                    |

//+------------------------------------------------------------------+

void CreatePanel()

{

    chartWidth = (int)ChartGetInteger(0, CHART_WIDTH_IN_PIXELS);

    chartHeight = (int)ChartGetInteger(0, CHART_HEIGHT_IN_PIXELS);

    

    // !>7405< D>= ?0=5;8

    ObjectCreate(0, objPrefix + "Background", OBJ_RECTANGLE_LABEL, 0, 0, 0);

    ObjectSetInteger(0, objPrefix + "Background", OBJPROP_XDISTANCE, chartWidth - windowWidth - 10);

    ObjectSetInteger(0, objPrefix + "Background", OBJPROP_YDISTANCE, 10);

    ObjectSetInteger(0, objPrefix + "Background", OBJPROP_XSIZE, windowWidth);

    ObjectSetInteger(0, objPrefix + "Background", OBJPROP_YSIZE, windowHeight);

    ObjectSetInteger(0, objPrefix + "Background", OBJPROP_BGCOLOR, clrWhiteSmoke);

    ObjectSetInteger(0, objPrefix + "Background", OBJPROP_BORDER_TYPE, BORDER_FLAT);

    ObjectSetInteger(0, objPrefix + "Background", OBJPROP_COLOR, clrBlack);

    

    CreateLabel("Title", " 0AH8@5==K9 :0;L:C;OB>@ A;>6=>3> ?@>F5=B0 4;O B@5945@0", 10, 15, clrBlack, true);

}



///+------------------------------------------------------------------+

//| $>@<0B8@>20=85 G8A;0 A @07@O40<8                                  |

//+------------------------------------------------------------------+

string FormatMoney(double value)

{

    string result = DoubleToString(value, 2);

    int pos = StringFind(result, ".");

    if(pos == -1) pos = StringLen(result);

    

    while(pos > 3)

    {

        pos -= 3;

        result = StringSubstr(result, 0, pos) + " " + StringSubstr(result, pos);

    }

    return result;

}



//+------------------------------------------------------------------+

//| !:;>=5=85 A;>20 "3>4" 2 7028A8<>AB8 >B G8A;0                      |

//+------------------------------------------------------------------+

string YearDeclension(int years)

{

    string result;

    int remainder100 = years % 100;

    int remainder10 = years % 10;

    

    if(remainder100 >= 11 && remainder100 <= 19)

        result = ";5B";

    else if(remainder10 == 1)

        result = "3>4";

    else if(remainder10 >= 2 && remainder10 <= 4)

        result = "3>40";

    else

        result = ";5B";

        

    return result;

}



//+------------------------------------------------------------------+

//| 1=>2;5=85 ?0=5;8                                                 |

//+------------------------------------------------------------------+

void UpdatePanel()

{

    CalculateTradingMetrics();

    

    int y = 40;

    

    // !5:F8O :0?8B0;0

    CreateLabel("Section1", "== 0@0<5B@K :0?8B0;0 ==", 10, y, clrNavy, true); y += 25;

    CreateLabel("InitialCapital", "0G0;L=K9 :0?8B0;: $" + FormatMoney(InitialCapital), 10, y, clrBlack); y += 20;

    CreateLabel("MonthlyDeposit", "65<5AOG=>5 ?>?>;=5=85: $" + FormatMoney(MonthlyDeposit), 10, y, clrBlack); y += 20;

    

    // !5:F8O B>@3>2KE ?0@0<5B@>2

    y += 10;

    CreateLabel("Section2", "== ">@3>2K5 ?0@0<5B@K ==", 10, y, clrNavy, true); y += 25;

    CreateLabel("TradesInfo", "!45;>: 2 45=L: " + IntegerToString(TradesPerDay) + " (" + IntegerToString(metrics.monthlyTrades) + " 2 <5AOF)", 10, y, clrBlack); y += 20;

    CreateLabel("WinRate", "5@>OB=>ABL CA?5E0: " + DoubleToString(WinRate, 1) + "%", 10, y, clrBlack); y += 20;

    CreateLabel("RRR", " 8A:/@81K;L: 1:" + DoubleToString(RiskRewardRatio, 1), 10, y, clrBlack); y += 20;

    

    // !5:F8O @8A:-<5=546<5=B0

    y += 10;

    CreateLabel("Section3", "==  8A:-<5=546<5=B ==", 10, y, clrNavy, true); y += 25;

    CreateLabel("MaxRiskTrade", "0:A8<0;L=K9 @8A: =0 A45;:C: " + DoubleToString(metrics.maxRiskPerTrade, 2) + "%", 10, y, clrBlack); y += 20;

    CreateLabel("MaxDrawdown", "8<8B ?@>A04:8: " + DoubleToString(MaxDrawdownLimit, 1) + "%", 10, y, clrBlack); y += 20;

    CreateLabel("ProbRuin", "5@>OB=>ABL @07>@5=8O: " + DoubleToString(metrics.probabilityOfRuin * 100, 4) + "%", 10, y, clrBlack); y += 20;

    

    // !5:F8O >68405<>9 4>E>4=>AB8

    y += 10;

    CreateLabel("Section4", "== 68405<0O 4>E>4=>ABL ==", 10, y, clrNavy, true); y += 25;

    CreateLabel("MonthlyReturn", "5AOG=0O 4>E>4=>ABL: " + DoubleToString(metrics.expectedMonthlyReturn, 2) + "%", 10, y, clrGreen); y += 20;

    CreateLabel("AnnualReturn", ">4>20O 4>E>4=>ABL: " + DoubleToString(metrics.expectedAnnualReturn, 2) + "%", 10, y, clrGreen); y += 20;

    

    // !5:F8O ?@>3=>70 :0?8B0;0

    y += 10;

    CreateLabel("Section5", "== @>3=>7 :0?8B0;0 ==", 10, y, clrNavy, true); y += 25;

    CreateLabel("MonthCapital", "'5@57 <5AOF: $" + FormatMoney(metrics.expectedMonthlyCapital), 10, y, clrGreen); y += 20;

    CreateLabel("YearCapital", "'5@57 3>4: $" + FormatMoney(metrics.expectedAnnualCapital), 10, y, clrGreen); y += 20;

    CreateLabel("FinalCapital", "'5@57 " + IntegerToString(Years) + " " + YearDeclension(Years) + ": $" + FormatMoney(metrics.expectedFinalCapital), 10, y, clrGreen); y += 40;

    

    UpdateChart();

}



//+------------------------------------------------------------------+

//| 07>2K5 DC=:F88                                                   |

//+------------------------------------------------------------------+

void OnDeinit(const int reason)

{

    ObjectsDeleteAll(0, objPrefix);

    EventKillTimer();

}



void OnTimer()

{

    UpdatePanel();

}



void CreateLabel(string name, string text, int x, int y, color clr, bool isBold = false)

{

    ObjectCreate(0, objPrefix + name, OBJ_LABEL, 0, 0, 0);

    ObjectSetInteger(0, objPrefix + name, OBJPROP_XDISTANCE, chartWidth - windowWidth - 10 + x);

    ObjectSetInteger(0, objPrefix + name, OBJPROP_YDISTANCE, y);

    ObjectSetString(0, objPrefix + name, OBJPROP_TEXT, text);

    ObjectSetInteger(0, objPrefix + name, OBJPROP_COLOR, clr);

    ObjectSetString(0, objPrefix + name, OBJPROP_FONT, isBold ? "Arial Bold" : "Arial");

    ObjectSetInteger(0, objPrefix + name, OBJPROP_FONTSIZE, isBold ? 10 : 9);

}



void UpdateChart()

{

    ObjectDelete(0, objPrefix + "Graph");

    

    ObjectCreate(0, objPrefix + "Graph", OBJ_TREND, 0, 0, totalAmount[0], Years * 12, totalAmount[Years * 12 - 1]);

    ObjectSetInteger(0, objPrefix + "Graph", OBJPROP_COLOR, clrBlue);

    ObjectSetInteger(0, objPrefix + "Graph", OBJPROP_WIDTH, 2);

    ObjectSetInteger(0, objPrefix + "Graph", OBJPROP_RAY_RIGHT, false);

    

    ChartRedraw();

}



int OnCalculate(const int rates_total,

                const int prev_calculated,

                const datetime &time[],

                const double &open[],

                const double &high[],

                const double &low[],

                const double &close[],

                const long &tick_volume[],

                const long &volume[],

                const int &spread[])

{

    for(int i = 0; i < rates_total && i < ArraySize(totalAmount); i++)

    {

        indicatorBuffer[i] = totalAmount[i];

    }

    

    return(rates_total);

}

Comments

Markdown supported. Formatting help

Markdown Formatting Guide

Element Markdown Syntax
Heading # H1
## H2
### H3
Bold **bold text**
Italic *italicized text*
Link [title](https://www.example.com)
Image ![alt text](image.jpg)
Code `code`
Code Block ```
code block
```
Quote > blockquote
Unordered List - Item 1
- Item 2
Ordered List 1. First item
2. Second item
Horizontal Rule ---