예제 #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 void DataBind(List <PerformerStatEx> performerStats, ChatControlBackEnd chat)
        {
            var images = imgListChartMini.Images.Cast <Image>().ToList();

            imgListChartMini.Images.Clear();
            foreach (var img in images)
            {
                img.Dispose();
            }
            var data = new List <PerformerStatEx>();

            // UserScore вычисляется на сервере
            // RecalcUserScore(performerStats);

            var userInfoExSource = new UserInfoExCache(TradeSharpAccountStatistics.Instance.proxy);
            var usersInfoEx      = userInfoExSource.GetUsersInfo(performerStats.Select(p => p.UserId).Distinct().ToList());

            var rowColors    = new[] { Color.Red, Color.ForestGreen, Color.Black };
            var stringFormat = new StringFormat
            {
                Alignment     = StringAlignment.Near,
                LineAlignment = StringAlignment.Center
            };

            using (var font = new Font(Font.FontFamily, 7))
                foreach (var performerStat in performerStats)
                {
                    // создать картинку с графиком
                    var bmp = new Bitmap(imgListChartMini.ImageSize.Width, imgListChartMini.ImageSize.Height);
                    if (performerStat.Chart != null)
                    {
                        using (var gr = Graphics.FromImage(bmp))
                        {
                            var leftValue = performerStat.AvgYearProfit;
                            var leftText  = string.Format("{0:f2}%", leftValue);

                            var leftTextWidth = gr.MeasureString(leftText, font).ToSize().Width;
                            var rightValue    = performerStat.ProfitLastMonthsAbs;
                            var rightText     = rightValue.ToStringUniformMoneyFormat(false);
                            var textWidth     = leftTextWidth + gr.MeasureString(rightText, font).ToSize().Width;
                            if (!ShowLabelsInMiniChart)
                            {
                                textWidth = 0;
                            }
                            PointF[] points;
                            if (ChartBrush != null)
                            {
                                points = MiniChartPacker.MakePolygon(performerStat.Chart,
                                                                     imgListChartMini.ImageSize.Width - textWidth,
                                                                     imgListChartMini.ImageSize.Height, 1, 1);
                            }
                            else
                            {
                                points = MiniChartPacker.MakePolyline(performerStat.Chart,
                                                                      imgListChartMini.ImageSize.Width - textWidth,
                                                                      imgListChartMini.ImageSize.Height, 1, 1);
                            }
                            gr.SmoothingMode     = SmoothingMode.AntiAlias;
                            gr.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;
                            if (ShowLabelsInMiniChart)
                            {
                                for (var i = 0; i < points.Length; i++)
                                {
                                    points[i] = new PointF(points[i].X + leftTextWidth, points[i].Y);
                                }
                                gr.DrawString(leftText, font,
                                              new SolidBrush(leftValue >= 0 ? rowColors[1] : rowColors[0]), 0,
                                              imgListChartMini.ImageSize.Height / 2, stringFormat);
                                gr.DrawString(rightText, font,
                                              new SolidBrush(rightValue >= 0 ? rowColors[1] : rowColors[0]),
                                              imgListChartMini.ImageSize.Width - textWidth + leftTextWidth,
                                              imgListChartMini.ImageSize.Height / 2, stringFormat);
                            }

                            if (ChartBrush != null)
                            {
                                gr.FillPolygon(ChartBrush, points);
                            }
                            else
                            {
                                gr.DrawLines(ChartPen ?? new Pen(leftValue >= 0 ? rowColors[1] : rowColors[0], 2), points);
                            }
                        }
                    }
                    var item = new PerformerStatEx(performerStat)
                    {
                        ChartIndex = imgListChartMini.Images.Count
                    };
                    imgListChartMini.Images.Add(bmp);
                    imgListChartMini.Images.SetKeyName(item.ChartIndex, item.ChartIndex.ToString());

                    // создать фотку
                    UserInfoEx userInfoEx = null;
                    if (usersInfoEx != null)
                    {
                        userInfoEx = usersInfoEx.Find(ui => ui != null && ui.Id == performerStat.UserId);
                    }
                    if (userInfoEx != null && userInfoEx.AvatarSmall != null)
                    {
                        item.AvatarSmallIndex = imgListAvatar.Images.Count;
                        imgListAvatar.Images.Add(userInfoEx.AvatarSmall);
                        imgListAvatar.Images.SetKeyName(item.AvatarSmallIndex, item.AvatarSmallIndex.ToString());
                    }
                    else
                    {
                        item.AvatarSmallIndex = -1;
                    }

                    data.Add(item);
                }

            grid.DataBind(data);
            grid.Invalidate();

            if (this.chat != null)
            {
                this.chat.RoomsReceived -= RoomsReceived;
            }
            this.chat = chat;

            if (chat == null)
            {
                return;
            }

            chat.RoomsReceived += RoomsReceived;
            chat.GetRooms();
        }
예제 #3
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);
        }