private void BuildEquityChartUnsafe(AccountStatistics stat)
        {
            chartProfit.Graphs[0].Series[0].Clear();
            //chartProfit.Graphs[0].Series[1].Clear();
            chartProfit1000.Graphs[0].Series[0].Clear();
            if (stat.listEquity == null || stat.listEquity.Count == 0)
            {
                return;
            }

            if (stat.listEquity != null)
            {
                foreach (var pt in stat.listEquity)
                {
                    chartProfit.Graphs[0].Series[0].Add(new BalanceByDate(pt.time, pt.equity));
                }
            }

            chartProfit.Initialize();

            // доход на 1000
            foreach (var pt in stat.listProfit1000)
            {
                chartProfit1000.Graphs[0].Series[0].Add(new BalanceByDate(pt.time, pt.equity));
            }
            chartProfit1000.Initialize();
        }
Beispiel #2
0
        private StringBuilder GetProfitStatistic(List <EquityOnTime> accountStatistics, decimal accountBalance, decimal accountEquity)
        {
            var result                    = new StringBuilder();
            var balanceChangesText        = "- ";
            var balanceChangesPercentText = "- ";
            var currentDrawDownText       = "- ";
            var maxDrawDownText           = "- ";

            try
            {
                if (accountStatistics.Count > 1)
                {
                    var equtyByDay = accountStatistics.Skip(Math.Max(0, accountStatistics.Count - 7)).Select(x => x.equity).ToList();
                    var profitWeek = 0F;
                    for (int i = 0; i < equtyByDay.Count - 1; i++)
                    {
                        profitWeek += (equtyByDay[i + 1] - equtyByDay[i]);
                    }
                    var profitWeekPercent
                        = (equtyByDay.Last() - equtyByDay.First()) / equtyByDay.Last();
                    var profitToday =
                        equtyByDay[equtyByDay.Count - 1] - equtyByDay[equtyByDay.Count - 2];
                    var profitTodayPercent =
                        (equtyByDay[equtyByDay.Count - 1] - equtyByDay[equtyByDay.Count - 2]) / equtyByDay[equtyByDay.Count - 1];

                    balanceChangesText        = $"{profitToday:F3} / {profitWeek:F3}";
                    balanceChangesPercentText = $"{profitTodayPercent * 100:F3} % / {profitWeekPercent * 100:F3} %";

                    var stat        = new AccountStatistics();
                    var maxDrawDown = stat.CalculateMaxDrawdown(accountStatistics);
                    maxDrawDownText = $"{maxDrawDown:F3} %";

                    var currentDrawDown = accountEquity < accountBalance
                        ? 100 * (accountEquity - accountBalance) / accountBalance
                        : 0;
                    currentDrawDownText = $"{currentDrawDown} %";
                }
            }
            catch (Exception ex)
            {
                Logger.Error("Ошибка скрипта AccountInfoCommentScript", ex);
            }

            result.AppendLine($"[b] Баланс {accountBalance}");
            result.AppendLine($"[b] Прирост за сутки / неделю: {balanceChangesText}");
            result.AppendLine($"[b] Прирост за сутки / неделю (%/%): {balanceChangesPercentText}");
            result.AppendLine($"[b] Текущее draw down (%): {currentDrawDownText}");
            result.AppendLine($"[b] Max draw down (%): {maxDrawDownText}");

            return(result);
        }
        public void JsonIsReadProperly()
        {
            string            json = ReadDataFile("AccountStatistics.json");
            AccountStatistics stat = new AccountStatistics(json, false);

            Assert.Equal(1, stat.Memory);
            Assert.Equal(2, stat.Storage);
            Assert.Equal(3, stat.Streams);
            Assert.Equal(4, stat.Consumers);

            stat = new AccountStatistics("{}", false);
            Assert.Equal(0, stat.Memory);
            Assert.Equal(0, stat.Storage);
            Assert.Equal(0, stat.Streams);
            Assert.Equal(0, stat.Consumers);
        }
Beispiel #4
0
        public string RenderReport(Account account, AccountStatistics stat,
                                   List <MarketOrder> openedOrders, List <MarketOrder> closedOrders,

                                   bool renderClosedDeals)
        {
            this.account           = account;
            this.stat              = stat;
            this.openedOrders      = openedOrders;
            this.closedOrders      = closedOrders;
            this.renderClosedDeals = renderClosedDeals;

            var sb = new StringBuilder();

            RenderDocumentHead(sb);
            RenderBody(sb);
            RenderDocumentCloseTag(sb);
            return(sb.ToString());
        }
        private void ShowStatistics(AccountStatistics stat)
        {
            var depoCurx = AccountStatus.Instance.AccountData.Currency;
            var statList = new List <StatItem>
            {
                new StatItem(Localizer.GetString("TitleAccountNumber"),
                             AccountStatus.Instance.AccountData.ID.ToString()),
                new StatItem(Localizer.GetString("TitleDate"), string.Format("{0:dd.MM.yyyy}", DateTime.Now)),
                new StatItem(Localizer.GetString("TitleInitialDate"), string.Format("{0:dd.MM.yyyy}",
                                                                                    stat.listEquity.Count > 0
                                                                                            ? stat.listEquity[0].time
                                                                                            : cbStartFrom.Checked
                                                                                                  ? dpStart.Value
                                                                                                  : DateTime.Now)),
                new StatItem(Localizer.GetString("TitleInitialDeposit"),
                             stat.InitialBalance.ToStringUniformMoneyFormat(false) + " " + depoCurx),
                new StatItem(Localizer.GetString("TitleCurrentDeposit"),
                             stat.Statistics.Equity.ToStringUniformMoneyFormat(false) + " " + depoCurx),
                new StatItem(Localizer.GetString("TitleDealsTotal"), stat.Statistics.DealsCount.ToString()),
                new StatItem(Localizer.GetString("TitleOpenedDeals"), stat.DealsStillOpened.ToString()),
                new StatItem(Localizer.GetString("TitleSummaryResult"),
                             (stat.sumClosedResult + stat.sumOpenResult).ToStringUniformMoneyFormat() + " " +
                             depoCurx),
                new StatItem(Localizer.GetString("TitleSummaryResultInClosedDeals"),
                             stat.sumClosedResult.ToStringUniformMoneyFormat() + " " + depoCurx),
                new StatItem(Localizer.GetString("TitleSummaryResultInOpenedDeals"),
                             stat.sumOpenResult.ToStringUniformMoneyFormat() + " " + depoCurx),
                new StatItem(Localizer.GetString("TitleSummaryDepositsAndWithdraws"),
                             stat.sumDeltaBalance.ToStringUniformMoneyFormat() + " " + depoCurx),
                new StatItem(Localizer.GetString("TitleMaximumRelativeDrawdown"),
                             stat.Statistics.MaxRelDrawDown.ToString("f1") + "%"),
                new StatItem(Localizer.GetString("TitleGADailyProfit"),
                             (100 * stat.ProfitGeomDay).ToStringUniformMoneyFormat() + "%"),
                new StatItem(Localizer.GetString("TitleGAMonthlyProfit"),
                             (100 * stat.ProfitGeomMonth).ToStringUniformMoneyFormat() + "%"),
                new StatItem(Localizer.GetString("TitleGAAnnualProfit"),
                             (100 * stat.ProfitGeomYear).ToStringUniformMoneyFormat() + "%")
            };

            dgStat.DataBind(statList, typeof(StatItem));
        }
        private AccountStatistics BuildEquityCurve(
            List <MarketOrder> orders,
            List <MarketOrder> openOrders,
            List <BalanceChange> balanceChanges)
        {
            var stat = new AccountStatistics
            {
                Statistics = new PerformerStat
                {
                    DealsCount = orders.Count + openOrders.Count,
                },
                DealsStillOpened = openOrders.Count,
                listEquity       = new List <EquityOnTime>()
            };

            if (worker.CancellationPending)
            {
                return(stat);
            }
            SetProgressValueSafe(40, Localizer.GetString("MessageActualizingQuoteHistory") + "...");

            if (balanceChanges.Count == 0)
            {
                MessageBox.Show(Localizer.GetString("MessageNoTransfersData"));
                return(stat);
            }
            var curxDepo = AccountStatus.Instance.AccountData.Currency;
            // запросить котировки, если стоит соотв. флаг
            var quotesDic = UpdateQuotesForStats(orders, openOrders, curxDepo);

            // построить кривую эквити
            // отсчет от первого движения на счете либо от стартовой даты
            balanceChanges = balanceChanges.OrderBy(bc => bc.ValueDate).ToList();
            var startDate = cbStartFrom.Checked ? dpStart.Value : balanceChanges[0].ValueDate;

            // начальный баланс
            var initialBalance = !cbStartFrom.Checked ? balanceChanges[0].SignedAmountDepo
                : balanceChanges.Where(bc => bc.ValueDate <= startDate).Sum(bc => bc.SignedAmountDepo);

            // движения от начального баланса с заданным интервалом дискретизации
            var dueBalances = balanceChanges.Where(bc => bc.ValueDate > startDate).ToList();
            var dueDeals    = orders.Union(openOrders).OrderBy(o => o.TimeEnter).ToList();

            var endDate = DateTime.Now;
            var balance = initialBalance;

            var cursor = new BacktestTickerCursor();
            var path   = ExecutablePath.ExecPath + TerminalEnvironment.QuoteCacheFolder;

            if (!cursor.SetupCursor(path, quotesDic.Keys.ToList(), quotesDic.Min(t => t.Value)))
            {
                MessageBox.Show(Localizer.GetString("MessageErrorGettingQuotesFromFiles"));
                return(stat);
            }
            var currentQuotes    = new Dictionary <string, QuoteData>();
            var timeframeMinutes = Timeframe;

            SetProgressValueSafe(60, Localizer.GetString("MessageCalculationInProcess") + "...");
            try
            {
                for (var time = startDate; time < endDate; time = time.AddMinutes(timeframeMinutes))
                {
                    if (worker.CancellationPending)
                    {
                        return(stat);
                    }
                    // получить баланс на дату
                    for (var i = 0; i < dueBalances.Count; i++)
                    {
                        if (dueBalances[i].ValueDate > time)
                        {
                            break;
                        }
                        balance += dueBalances[i].SignedAmountDepo;
                        dueBalances.RemoveAt(i);
                        i--;
                    }
                    var equity = balance;

                    // получить текущие котировки
                    var candles = cursor.MoveToTime(time);
                    foreach (var candle in candles)
                    {
                        var quote = new QuoteData(candle.Value.open,
                                                  DalSpot.Instance.GetAskPriceWithDefaultSpread(candle.Key,
                                                                                                candle.Value.open),
                                                  candle.Value.timeOpen);

                        if (currentQuotes.ContainsKey(candle.Key))
                        {
                            currentQuotes[candle.Key] = quote;
                        }
                        else
                        {
                            currentQuotes.Add(candle.Key, quote);
                        }
                    }

                    // уточнить результат по открытым позициям
                    for (var i = 0; i < dueDeals.Count; i++)
                    {
                        if (worker.CancellationPending)
                        {
                            return(stat);
                        }
                        if (dueDeals[i].TimeExit.HasValue)
                        {
                            if (dueDeals[i].TimeExit.Value <= time)
                            {
                                dueDeals.RemoveAt(i);
                                i--;
                                continue;
                            }
                        }
                        var deal = dueDeals[i];
                        if (deal.TimeEnter <= time)
                        {
                            // посчитать текущий результат сделки
                            // в контрвалюте
                            if (!currentQuotes.ContainsKey(deal.Symbol))
                            {
                                continue;
                            }
                            var dealTickerQuote = currentQuotes[deal.Symbol];
                            var dealTickerPrice = deal.Side > 0 ? dealTickerQuote.bid : dealTickerQuote.ask;
                            var dealResult      = deal.Volume * deal.Side * (dealTickerPrice - deal.PriceEnter);

                            // перевод прибыли в валюту депо
                            bool inverse, areSame;
                            var  dealTransferSymbol = DalSpot.Instance.FindSymbol(deal.Symbol,
                                                                                  false, curxDepo, out inverse,
                                                                                  out areSame);
                            float?baseDepoRate = null;
                            if (areSame)
                            {
                                baseDepoRate = 1f;
                            }
                            else
                            {
                                if (!string.IsNullOrEmpty(dealTransferSymbol))
                                {
                                    if (currentQuotes.ContainsKey(dealTransferSymbol))
                                    {
                                        var quote = currentQuotes[dealTransferSymbol];
                                        if (quote.time >= time)
                                        {
                                            baseDepoRate = !inverse
                                                               ? (deal.Side > 0 ? quote.bid : quote.ask)
                                                               : (deal.Side > 0 ? 1 / quote.ask : 1 / quote.bid);
                                        }
                                    }
                                }
                            }
                            if (!baseDepoRate.HasValue)
                            {
                                continue;
                            }
                            dealResult *= baseDepoRate.Value;
                            equity     += (decimal)dealResult;
                        }
                    } // for (deal ...
                    // сохранить отметку - время/доходность
                    stat.listEquity.Add(new EquityOnTime((float)equity, time));
                } // for (time ... += Timeframe
            }
            finally
            {
                cursor.Close();
            }
            // если история начинается с пустого депо - изъять эти строки из истории
            var firstNotEmpty = stat.listEquity.FindIndex(e => e.equity > 0);

            if (firstNotEmpty == stat.listEquity.Count - 1)
            {
                stat.listEquity.Clear();
            }
            else
            if (firstNotEmpty > 0)
            {
                stat.listEquity.RemoveRange(0, firstNotEmpty);
            }

            SetProgressValueSafe(70,
                                 Localizer.GetString("MessageBuildingEquityChart") + "...");
            stat.Calculate(balanceChanges, openOrders, startDate);
            return(stat);
        }
 private void BuildEquityChartSafe(AccountStatistics stat)
 {
     Invoke(new Action <AccountStatistics>(BuildEquityChartUnsafe),
            stat);
 }
 private void UpdateTablesAndCharts(AccountStatistics stat)
 {
     ShowStatistics(stat);
     BuildEquityChartSafe(stat);
 }
        private void MakeCalculation(object obj, DoWorkEventArgs args)
        {
            if (AccountStatus.Instance.AccountData == null ||
                MainForm.serverProxyTrade.proxy == null)
            {
                MessageBox.Show(Localizer.GetString("MessageNoConnectionServer"));
                return;
            }
            var accountId = AccountStatus.Instance.AccountData.ID;

            // получить сделки за указанный период и эквити на начало периода
            // и все пополнения - снятия
            SetProgressValueSafe(10, Localizer.GetString("MessageGettingOrderHistory") + "...");
            if (worker.CancellationPending)
            {
                return;
            }
            List <MarketOrder> orders;
            var status = TradeSharpAccount.Instance.GetHistoryOrdersUncompressed(accountId,
                                                                                 cbStartFrom.Checked ? dpStart.Value : (DateTime?)null, out orders);

            if (status != RequestStatus.OK || orders == null)
            {
                MessageBox.Show(string.Format(
                                    Localizer.GetString("MessageUnableToGetOrderHistory") + ": {0}",
                                    EnumFriendlyName <RequestStatus> .GetString(status)));
                return;
            }
            // получить изменения баланса
            if (worker.CancellationPending)
            {
                return;
            }
            SetProgressValueSafe(20, Localizer.GetString("MessageGettingTransfersHistory") + "...");
            List <BalanceChange> balanceChanges;

            status = TradeSharpAccount.Instance.proxy.GetBalanceChanges(accountId, null, out balanceChanges);
            if (status != RequestStatus.OK || balanceChanges == null)
            {
                MessageBox.Show(string.Format(Localizer.GetString("MessageUnableToGetTransfersHistory") + ": {0}",
                                              EnumFriendlyName <RequestStatus> .GetString(status)));
                return;
            }
            // получить открытые ордера
            if (worker.CancellationPending)
            {
                return;
            }
            SetProgressValueSafe(30, Localizer.GetString("MessageGettingOpenPosHistory") + "...");
            List <MarketOrder> openOrders;

            status = TradeSharpAccount.Instance.proxy.GetMarketOrders(accountId, out openOrders);
            if (status != RequestStatus.OK || openOrders == null)
            {
                MessageBox.Show(string.Format(Localizer.GetString("MessageUnableToGetOpenPosHistory") + ": {0}",
                                              EnumFriendlyName <RequestStatus> .GetString(status)));
                return;
            }
            // построить кривую equity и посчитать характеристики торговли по счету
            var stat = BuildEquityCurve(orders, openOrders, balanceChanges);

            statistics = stat;

            // сохранить доходность в словаре
            if (statByAccount.ContainsKey(accountId))
            {
                statByAccount[accountId] = stat;
            }
            else
            {
                statByAccount.Add(accountId, stat);
            }

            if (worker.CancellationPending)
            {
                return;
            }
            // построить график и вывести показатели доходности
            SetProgressValueSafe(90, Localizer.GetString("MessageMakingReport") + "...");

            SetProgressValueSafe(100, Localizer.GetString("MessageCalculationCompleted") + "...");

            Invoke(new Action(() =>
            {
                UpdateTablesAndCharts(stat);
                MessageBox.Show(this,
                                Localizer.GetString("MessageCalculationCompleted"),
                                Localizer.GetString("TitleNotice"), MessageBoxButtons.OK,
                                MessageBoxIcon.Information);
            }));

            SetProgressValueSafe(0, string.Empty);
        }