예제 #1
0
        public void TestPackUnpack()
        {
            // подготовить липу
            var lstEq     = new List <EquityOnTime>();
            var timeStart = DateTime.Now.Date.AddDays(-190);
            var timeEnd   = DateTime.Now.Date;

            var i = 0;

            for (var date = timeStart; date < timeEnd; date = date.AddDays(1))
            {
                var y = 1.5 + Math.Sin(i++ / 20.0);
                lstEq.Add(new EquityOnTime((float)y, date));
            }

            // упаковать
            var chartMini = MiniChartPacker.PackChartInArray(lstEq);

            Assert.Greater(chartMini.Length, 0, "Chart is not empty");
            var min = chartMini.Min();
            var max = chartMini.Max();

            Assert.Greater(max - min, 250, "Chart range is close to 255");

            // распаковать
            var points = MiniChartPacker.MakePolygon(chartMini, 60, 30, 2, 2);

            Assert.AreEqual(chartMini.Length + 2, points.Length, "unpacked has the same size");
        }
예제 #2
0
        public bool Calculate(AccountEfficiency ef)
        {
            if (ef == null)
            {
                throw new ArgumentException("EfficiencyCalculator.Calculate - input ptr is NULL");
            }
            if (ef.Statistics.Account == 0)
            {
                throw new ArgumentException("EfficiencyCalculator.Calculate - input_ptr.AccountId is 0");
            }

            // получить сделки
            var deals = DealStorage.Instance.GetDeals(ef.Statistics.Account);

            ef.openedDeals = new List <MarketOrder>();
            ef.closedDeals = new List <MarketOrder>();

            foreach (var deal in deals)
            {
                if (deal.IsOpened)
                {
                    ef.openedDeals.Add(deal);
                }
                else
                {
                    ef.closedDeals.Add(deal);
                }
            }

            if (deals.Count == 0)
            {
                Logger.Info("AccountEfficiency.Calculate - нет сделок");
                return(false);
            }

            ef.Statistics.DealsCount = deals.Count;
            ef.DealsStillOpened      = ef.openedDeals.Count;

            // транзакции
            ef.listTransaction = BalanceStorage.Instance.GetBalanceChanges(ef.Statistics.Account);
            if (ef.listTransaction == null || ef.listTransaction.Count == 0)
            {
                Logger.Info("AccountEfficiency.Calculate - нет транзакций");
                return(false);
            }

            Logger.Info("AccountEfficiency.Calculate(" + ef.Statistics.Account + ")");

            // время отсчета - время первого заведения средств
            var startDate = ef.listTransaction.Min(t => t.ValueDate);

            // получить список используемых котировок
            var symbolsUsed = ef.closedDeals.Select(d => d.Symbol).Union(ef.openedDeals.Select(o => o.Symbol)).Distinct().ToList();
            // ... в т.ч., котировок для перевода базовой валюты в валюту депо (плечо)
            // и перевода контрвалюты в валюту депо (профит)
            var symbolsMore = new List <string>();

            foreach (var smb in symbolsUsed)
            {
                bool inverse, eq;
                var  smbBase = DalSpot.Instance.FindSymbol(smb, true, ef.Statistics.DepoCurrency, out inverse, out eq);
                if (!string.IsNullOrEmpty(smbBase))
                {
                    symbolsMore.Add(smbBase);
                }
                var smbCounter = DalSpot.Instance.FindSymbol(smb, false, ef.Statistics.DepoCurrency, out inverse, out eq);
                if (!string.IsNullOrEmpty(smbCounter))
                {
                    symbolsMore.Add(smbCounter);
                }
            }
            symbolsUsed.AddRange(symbolsMore);
            symbolsUsed = symbolsUsed.Distinct().ToList();

            // котировки
            var dicQuote = new Dictionary <string, List <QuoteData> >();

            foreach (var smb in symbolsUsed)
            {
                dicQuote.Add(smb,
                             dailyQuoteStorage.GetQuotes(smb).Select(q => new QuoteData(q.b, q.b, q.a)).ToList());
            }
            //TickerStorage.Instance.GetQuotes(symbolsUsed.ToDictionary(s => s, s => (DateTime?)null));
            if (dicQuote == null || dicQuote.Count == 0)
            {
                Logger.Info("AccountEfficiency.Calculate - нет котировок");
                return(false);
            }

            if (ef.openedDeals.Count > 0)
            {
                foreach (var t in ef.openedDeals)
                {
                    List <QuoteData> dicQuoteValue;
                    if (!dicQuote.TryGetValue(t.Symbol, out dicQuoteValue))
                    {
                        Logger.Error(String.Format("Symbol {0} was not found in dicQuote", t.Symbol));
                    }
                    else
                    if (dicQuoteValue.Count == 0)
                    {
                        Logger.Error(String.Format("No quote data for symbol {0}", t.Symbol));
                    }
                    else
                    {
                        t.PriceExit = dicQuoteValue.Last().GetPrice(t.Side == 1
                                ? QuoteType.Bid : QuoteType.Ask);
                    }
                }
            }

            var quoteArc = new QuoteArchive(dicQuote);
            AccountPerformanceRaw performance;

            try
            {
                performance = equityCurveCalculator.CalculateEquityCurve(deals, ef.Statistics.DepoCurrency, quoteArc, ef.listTransaction);
            }
            catch (Exception ex)
            {
                Logger.Error("Ошибка в EfficiencyCalculator.CalculateEquityCurve()", ex);
                return(false);
            }

            ef.Statistics.TotalTradedInDepoCurrency = performance.totalTradedVolume;
            var lstEquity = performance.equity;

            if (lstEquity == null)
            {
                return(false);
            }
            ef.listLeverage = performance.leverage;

            // исключить пустые значения с начала отсчета
            ef.listEquity = new List <EquityOnTime>();
            var startCopy = false;

            foreach (var eq in lstEquity)
            {
                if (eq.equity > 0)
                {
                    startCopy = true;
                }
                if (startCopy)
                {
                    ef.listEquity.Add(eq);
                }
            }

            if (ef.listEquity.Count == 0)
            {
                return(false);
            }
            ef.StartDate      = startDate;
            ef.InitialBalance = ef.listEquity[0].equity;

            // рассчитать коэффициенты доходности
            CalculateProfitCoeffs(ef);
            CalculateRiskCoeffs(ef);

            // актуальные котировки
            ef.currentQuotes = quoteArc.GetCurrentQuotes();

            ef.Statistics.Chart = ef.listProfit1000 == null ||
                                  ef.listProfit1000.Count == 0
                                             ? new byte[MiniChartPacker.profitChartPointCount]
                                             : MiniChartPacker.PackChartInArray(ef.listProfit1000);

            // дней торгует
            var startDayOpen = DateTime.Now;

            if (ef.openedDeals.Count > 0)
            {
                startDayOpen = ef.openedDeals.Max(d => d.TimeEnter);
            }
            if (ef.closedDeals.Count > 0)
            {
                var dateClosed = ef.closedDeals.Min(d => d.TimeEnter);
                if (dateClosed < startDayOpen)
                {
                    startDayOpen = dateClosed;
                }
            }
            ef.Statistics.DaysTraded = (int)Math.Round((DateTime.Now - startDayOpen).TotalDays);

            // сумма профитных сделок (результат) к сумме убыточных сделок
            var sumProf = ef.closedDeals.Sum(d => d.ResultDepo > 0 ? d.ResultDepo : 0) +
                          ef.openedDeals.Sum(d => d.ResultDepo > 0 ? d.ResultDepo : 0);
            var sumLoss = ef.closedDeals.Sum(d => d.ResultDepo > 0 ? d.ResultDepo : 0) +
                          ef.openedDeals.Sum(d => d.ResultDepo > 0 ? d.ResultDepo : 0);

            ef.Statistics.AvgWeightedDealProfitToLoss = sumLoss == 0 && sumProf == 0
                                                           ? 0
                                                           : 100 * sumProf / (sumProf + sumLoss);
            var dateFirst = DateTime.Now.Date.AddMonths(-3);

            ef.Statistics.WithdrawalLastMonths = (float)ef.listTransaction.Sum(t =>
                                                                               (t.ChangeType ==
                                                                                BalanceChangeType.Withdrawal &&
                                                                                t.ValueDate >= dateFirst)
                                                                                   ? t.AmountDepo : 0);
            // профит в ПП
            ef.Statistics.SumProfitPoints = ef.closedDeals.Sum(d => d.ResultPoints);

            return(true);
        }