Forex_Strategy_Builder.Backtester.CalculateAdditionalStats C# (CSharp) Метод

CalculateAdditionalStats() статический приватный Метод

Calculates the values of the stats parameters.
static private CalculateAdditionalStats ( ) : void
Результат void
        static void CalculateAdditionalStats()
        {
            longBalance       = new double[Bars];
            shortBalance      = new double[Bars];
            longMoneyBalance  = new double[Bars];
            shortMoneyBalance = new double[Bars];

            maxLongMoneyBalance  = Configs.InitialAccount;
            minLongMoneyBalance  = Configs.InitialAccount;
            maxShortMoneyBalance = Configs.InitialAccount;
            minShortMoneyBalance = Configs.InitialAccount;
            maxLongBalance  = 0;
            minLongBalance  = 0;
            maxShortBalance = 0;
            minShortBalance = 0;

            maxLongBalanceDate        = Time[0];
            minLongBalanceDate        = Time[0];
            maxShortBalanceDate       = Time[0];
            minShortBalanceDate       = Time[0];
            maxLongMoneyBalanceDate   = Time[0];
            minLongMoneyBalanceDate   = Time[0];
            maxShortMoneyBalanceDate  = Time[0];
            minShortMoneyBalanceDate  = Time[0];
            maxLongDrawdownDate       = Time[0];
            maxShortDrawdownDate      = Time[0];
            maxLongMoneyDrawdownDate  = Time[0];
            maxShortMoneyDrawdownDate = Time[0];

            grossLongProfit       = 0;
            grossLongLoss         = 0;
            grossShortProfit      = 0;
            grossShortLoss        = 0;
            grossLongMoneyProfit  = 0;
            grossLongMoneyLoss    = 0;
            grossShortMoneyProfit = 0;
            grossShortMoneyLoss   = 0;

            maxLongDrawdown       = 0;
            maxShortDrawdown      = 0;
            maxLongMoneyDrawdown  = 0;
            maxShortMoneyDrawdown = 0;
            maxShortDrawdown      = 0;
            maxLongMoneyDrawdown  = 0;
            maxShortMoneyDrawdown = 0;
            maxLongMoneyDrawdownPercent  = 0;
            maxShortMoneyDrawdownPercent = 0;

            barsWithPos        = 0;
            barsWithLongPos    = 0;
            barsWithShortPos   = 0;

            winningLongTrades  = 0;
            winningShortTrades = 0;
            losingLongTrades   = 0;
            losingShortTrades  = 0;

            totalLongTrades   = 0;
            totalShortTrades  = 0;

            maxLongWin        = 0;
            maxShortWin       = 0;
            maxLongMoneyWin   = 0;
            maxShortMoneyWin  = 0;
            maxLongLoss       = 0;
            maxShortLoss      = 0;
            maxLongMoneyLoss  = 0;
            maxShortMoneyLoss = 0;

            for (int bar = 0; bar < FirstBar; bar++)
            {
                longBalance[bar]  = 0;
                shortBalance[bar] = 0;
                longMoneyBalance[bar]  = Configs.InitialAccount;
                shortMoneyBalance[bar] = Configs.InitialAccount;
            }

            for (int bar = Data.FirstBar; bar < Bars; bar++)
            {
                double accountExchangeRate = AccountExchangeRate(Close[bar]);
                double pipsToMoney = InstrProperties.Point * InstrProperties.LotSize / accountExchangeRate;

                longBalance[bar]  = longBalance[bar - 1];
                shortBalance[bar] = shortBalance[bar - 1];
                longMoneyBalance[bar]  = longMoneyBalance[bar - 1];
                shortMoneyBalance[bar] = shortMoneyBalance[bar - 1];

                bool isLong  = false;
                bool isShort = false;
                for (int pos = 0; pos < Positions(bar); pos++)
                {
                    if (PosDir(bar, pos) == PosDirection.Long)
                        isLong = true;

                    if (PosDir(bar, pos) == PosDirection.Short)
                        isShort = true;

                    double positionProfitLoss      = PosProfitLoss(bar, pos);
                    double positionMoneyProfitLoss = PosMoneyProfitLoss(bar, pos);

                    if (PosTransaction(bar, pos) == Transaction.Close  ||
                        PosTransaction(bar, pos) == Transaction.Reduce ||
                        PosTransaction(bar, pos) == Transaction.Reverse)
                    {
                        if (OrdFromNumb(PosOrdNumb(bar, pos)).OrdDir == OrderDirection.Sell)
                        {   // Closing long position
                            longBalance[bar]      += positionProfitLoss;
                            longMoneyBalance[bar] += positionMoneyProfitLoss;

                            if (positionProfitLoss > 0)
                            {
                                grossLongProfit      += positionProfitLoss;
                                grossLongMoneyProfit += positionMoneyProfitLoss;
                                winningLongTrades++;
                                if (positionProfitLoss > maxLongWin)
                                    maxLongWin = positionProfitLoss;
                                if (positionMoneyProfitLoss > maxLongMoneyWin)
                                    maxLongMoneyWin = positionMoneyProfitLoss;
                            }
                            if (positionProfitLoss < 0)
                            {
                                grossLongLoss      += positionProfitLoss;
                                grossLongMoneyLoss += positionMoneyProfitLoss;
                                losingLongTrades++;
                                if (positionProfitLoss < maxLongLoss)
                                    maxLongLoss = positionProfitLoss;
                                if (positionMoneyProfitLoss < maxLongMoneyLoss)
                                    maxLongMoneyLoss = positionMoneyProfitLoss;
                            }

                            totalLongTrades++;
                        }
                        if (OrdFromNumb(PosOrdNumb(bar, pos)).OrdDir == OrderDirection.Buy)
                        {   // Closing short position
                            shortBalance[bar]      += positionProfitLoss;
                            shortMoneyBalance[bar] += positionMoneyProfitLoss;

                            if (positionProfitLoss > 0)
                            {
                                grossShortProfit      += positionProfitLoss;
                                grossShortMoneyProfit += positionMoneyProfitLoss;
                                winningShortTrades++;
                                if (positionProfitLoss > maxShortWin)
                                    maxShortWin = positionProfitLoss;
                                if (positionMoneyProfitLoss > maxShortMoneyWin)
                                    maxShortMoneyWin = positionMoneyProfitLoss;
                            }
                            if (positionProfitLoss < 0)
                            {
                                grossShortLoss      += positionProfitLoss;
                                grossShortMoneyLoss += positionMoneyProfitLoss;
                                losingShortTrades++;
                                if (positionProfitLoss < maxShortLoss)
                                    maxShortLoss = positionProfitLoss;
                                if (positionMoneyProfitLoss < maxShortMoneyLoss)
                                    maxShortMoneyLoss = positionMoneyProfitLoss;
                            }

                            totalShortTrades++;
                        }
                    }
                }

                barsWithPos      += (isLong || isShort) ? 1 : 0;
                barsWithLongPos  += isLong  ? 1 : 0;
                barsWithShortPos += isShort ? 1 : 0;

                if (maxLongBalance < longBalance[bar])
                {
                    maxLongBalance = longBalance[bar];
                    maxLongBalanceDate = Time[bar];
                }
                if (minLongBalance > longBalance[bar])
                {
                    minLongBalance = longBalance[bar];
                    minLongBalanceDate = Time[bar];
                }
                if (maxShortBalance < shortBalance[bar])
                {
                    maxShortBalance = shortBalance[bar];
                    maxShortBalanceDate = Time[bar];
                }
                if (minShortBalance > shortBalance[bar])
                {
                    minShortBalance = shortBalance[bar];
                    minShortBalanceDate = Time[bar];
                }
                if (maxLongMoneyBalance < longMoneyBalance[bar])
                {
                    maxLongMoneyBalance = longMoneyBalance[bar];
                    maxLongMoneyBalanceDate = Time[bar];
                }
                if (minLongMoneyBalance > longMoneyBalance[bar])
                {
                    minLongMoneyBalance = longMoneyBalance[bar];
                    minLongMoneyBalanceDate = Time[bar];
                }
                if (maxShortMoneyBalance < shortMoneyBalance[bar])
                {
                    maxShortMoneyBalance = shortMoneyBalance[bar];
                    maxShortMoneyBalanceDate = Time[bar];
                }
                if (minShortMoneyBalance > shortMoneyBalance[bar])
                {
                    minShortMoneyBalance = shortMoneyBalance[bar];
                    minShortMoneyBalanceDate = Time[bar];
                }

                // Maximum Drawdown
                if (maxLongBalance - longBalance[bar] > maxLongDrawdown)
                {
                    maxLongDrawdown = maxLongBalance - longBalance[bar];
                    maxLongDrawdownDate = Time[bar];
                }

                if (maxLongMoneyBalance - longMoneyBalance[bar] > maxLongMoneyDrawdown)
                {
                    maxLongMoneyDrawdown = maxLongMoneyBalance - longMoneyBalance[bar];
                    maxLongMoneyDrawdownPercent = 100 * maxLongMoneyDrawdown / maxLongMoneyBalance;
                    maxLongMoneyDrawdownDate   = Time[bar];
                }

                if (maxShortBalance - shortBalance[bar] > maxShortDrawdown)
                {
                    maxShortDrawdown = maxShortBalance - shortBalance[bar];
                    maxShortDrawdownDate = Time[bar];
                }

                if (maxShortMoneyBalance - shortMoneyBalance[bar] > maxShortMoneyDrawdown)
                {
                    maxShortMoneyDrawdown = maxShortMoneyBalance - shortMoneyBalance[bar];
                    maxShortMoneyDrawdownPercent = 100 * maxShortMoneyDrawdown / maxShortMoneyBalance;
                    maxShortMoneyDrawdownDate = Time[bar];
                }
            }

            // Holding period returns
            AHPR      = 0;
            AHPRLong  = 0;
            AHPRShort = 0;

            double[] HPR      = new double[totalTrades];
            double[] HPRLong  = new double[totalLongTrades];
            double[] HPRShort = new double[totalShortTrades];

            double totalHPR      = 0;
            double totalHPRLong  = 0;
            double totalHPRShort = 0;

            double startBalance      = Configs.InitialAccount;
            double startBalanceLong  = Configs.InitialAccount;
            double startBalanceShort = Configs.InitialAccount;

            int count  = 0;
            int countL = 0;
            int countS = 0;

            for (int pos = 0; pos < PositionsTotal; pos++)
            {   // Charged fees
                Position position = Backtester.PosFromNumb(pos);
                // Winning losing trades.
                if (position.Transaction == Transaction.Close  ||
                    position.Transaction == Transaction.Reduce ||
                    position.Transaction == Transaction.Reverse)
                {
                    if (OrdFromNumb(position.FormOrdNumb).OrdDir == OrderDirection.Sell)
                    {  // Closing long position
                        HPRLong[countL] = 1 + position.MoneyProfitLoss / startBalanceLong;
                        totalHPRLong += HPRLong[countL];
                        countL++;
                        startBalanceLong += position.MoneyProfitLoss;
                    }
                    if (OrdFromNumb(position.FormOrdNumb).OrdDir == OrderDirection.Buy)
                    {  // Closing short position
                        HPRShort[countS] = 1 + position.MoneyProfitLoss / startBalanceShort;
                        totalHPRShort += HPRShort[countS];
                        countS++;
                        startBalanceShort += position.MoneyProfitLoss;
                    }
                    HPR[count] = 1 + position.MoneyProfitLoss / startBalance;
                    totalHPR += HPR[count];
                    count++;
                    startBalance += position.MoneyProfitLoss;
                }
            }

            double averageHPR      = totalHPR      / totalTrades;
            double averageHPRLong  = totalHPRLong  / totalLongTrades;
            double averageHPRShort = totalHPRShort / totalShortTrades;

            AHPR      = 100 * (averageHPR      - 1);
            AHPRLong  = 100 * (averageHPRLong  - 1);
            AHPRShort = 100 * (averageHPRShort - 1);

            GHPR      = 100 * (Math.Pow((NetMoneyBalance      / Configs.InitialAccount), (1f / totalTrades))      - 1);
            GHPRLong  = 100 * (Math.Pow((NetLongMoneyBalance  / Configs.InitialAccount), (1f / totalLongTrades))  - 1);
            GHPRShort = 100 * (Math.Pow((NetShortMoneyBalance / Configs.InitialAccount), (1f / totalShortTrades)) - 1);

            // Sharpe Ratio
            sharpeRatio      = 0;
            sharpeRatioLong  = 0;
            sharpeRatioShort = 0;

            double sumPow      = 0;
            double sumPowLong  = 0;
            double sumPowShort = 0;

            for (int i = 0; i < totalTrades; i++)
                sumPow += Math.Pow((HPR[i] - averageHPR), 2);
            for (int i = 0; i < totalLongTrades; i++)
                sumPowLong += Math.Pow((HPRLong[i] - averageHPRLong), 2);
            for (int i = 0; i < totalShortTrades; i++)
                sumPowShort += Math.Pow((HPRShort[i] - averageHPRShort), 2);

            double stDev      = Math.Sqrt(sumPow      / (totalTrades      - 1));
            double stDevLong  = Math.Sqrt(sumPowLong  / (totalLongTrades  - 1));
            double stDevShort = Math.Sqrt(sumPowShort / (totalShortTrades - 1));

            sharpeRatio      = (averageHPR      - 1) / stDev;
            sharpeRatioLong  = (averageHPRLong  - 1) / stDevLong;
            sharpeRatioShort = (averageHPRShort - 1) / stDevShort;
        }