Exemplo n.º 1
0
        public void AddTransactions(SortedList <DateTime, Transaction> txList, FXMarketHistory fxmh)
        {
            PnLElements = new SortedDictionary <DateTime, PnLElement> {
            };
            DateTime lastDate = new DateTime(2008, 1, 1);

            foreach (var item in txList)
            {
                Transaction tx = item.Value;
                if ((tx.Date.ToOADate() - lastDate.ToOADate()) * 24 * 60 * 60 < 1)
                {
                    lastDate = lastDate.AddSeconds(1);
                }
                else
                {
                    lastDate = tx.Date;
                }
                bool justFees = true;
                if (tx.Received.Ccy == Ccy)
                {
                    justFees = false;
                    switch (tx.Type)
                    {
                    case TransactionType.Deposit:
                        if (Ccy.IsFiat())
                        {
                            PnLElement   pnlD    = GetLastPnLElement();
                            PnLElement   newPnLD = (PnLElement)pnlD.Clone();
                            CurrencyPair cpD     = new CurrencyPair(tx.Received.Ccy, CcyRef);

                            XChangeRate xrD        = fxmh.GetQuote(lastDate, cpD, isArtificial: true).Item2;
                            double      newWeightD = 1 / (1 + pnlD.Position / tx.Received.Amount);
                            newPnLD.AverageCost = (1 - newWeightD) * pnlD.AverageCost + newWeightD * xrD.Rate;
                            newPnLD.Position   += tx.Received.Amount;
                            newPnLD.Deposit    += tx.Received.Amount * xrD.Rate;
                            PnLElements.Add(lastDate, newPnLD);
                        }
                        else
                        {
                            PnLElement pnlDCrypto    = GetLastPnLElement();
                            PnLElement newPnLDCrypto = (PnLElement)pnlDCrypto.Clone();
                            newPnLDCrypto.Position -= tx.Fees.Amount;
                            newPnLDCrypto.Fees     += tx.Fees.Amount;
                            PnLElements.Add(lastDate, newPnLDCrypto);
                        }
                        break;

                    case TransactionType.Trade:
                        PnLElement   pnlT    = GetLastPnLElement();
                        PnLElement   newPnLT = (PnLElement)pnlT.Clone();
                        CurrencyPair cpT     = new CurrencyPair(tx.Received.Ccy, CcyRef);
                        //XChangeRate xrT = fxmh.GetQuote(lastDate, cpT, isArtificial: true).Item2;
                        XChangeRate xrT    = GetAdjustedFXRate(lastDate, tx.XRate, fxmh);
                        double      amount = tx.Received.Amount;
                        if (tx.Fees.Ccy == Ccy)
                        {
                            amount       -= tx.Fees.Amount;
                            newPnLT.Fees += tx.Fees.Amount * xrT.Rate;
                        }
                        double newWeight = 1 / (1 + pnlT.Position / amount);
                        newPnLT.AverageCost = (1 - newWeight) * pnlT.AverageCost + newWeight * xrT.Rate;
                        newPnLT.Position   += amount;
                        PnLElements.Add(lastDate, newPnLT);
                        break;

                    case TransactionType.Transfer:
                        PnLElement pnlTf    = GetLastPnLElement();
                        PnLElement newPnLTf = (PnLElement)pnlTf.Clone();
                        newPnLTf.Position += tx.Received.Amount;
                        double newWeightTf = 1 / (1 + pnlTf.Position / tx.Received.Amount);
                        newPnLT.AverageCost = (1 - newWeightTf) * pnlTf.AverageCost + newWeightTf * 0;
                        PnLElements.Add(lastDate, newPnLTf);
                        break;

                    default:
                        break;
                    }
                }
                if (tx.Paid.Ccy == Ccy)
                {
                    justFees = false;
                    switch (tx.Type)
                    {
                    case TransactionType.Trade:
                        PnLElement pnlTrade    = GetLastPnLElement();
                        PnLElement newPnLTrade = (PnLElement)pnlTrade.Clone();
                        newPnLTrade.Position -= tx.Paid.Amount;
                        Price feesT = tx.Fees;
                        if (tx.Fees.Ccy == Ccy)
                        {
                            CurrencyPair cpFT = new CurrencyPair(feesT.Ccy, CcyRef);
                            XChangeRate  xrFT = fxmh.GetQuote(lastDate, cpFT, isArtificial: true).Item2;
                            newPnLTrade.Fees     += xrFT.ConvertPrice(feesT).Amount;
                            newPnLTrade.Position -= feesT.Amount;
                        }
                        CurrencyPair cpT2 = new CurrencyPair(tx.Paid.Ccy, CcyRef);
                        //XChangeRate xrT2 = fxmh.GetQuote(lastDate, cpT2, isArtificial: true).Item2;
                        XChangeRate xrT2 = GetAdjustedFXRate(lastDate, tx.XRate, fxmh);
                        newPnLTrade.RealizedPnL += tx.Paid.Amount * (xrT2.Rate - newPnLTrade.AverageCost);
                        PnLElements.Add(lastDate, newPnLTrade);
                        break;

                    case TransactionType.WithDrawal:
                        PnLElement   pnl     = GetLastPnLElement();
                        PnLElement   newPnLW = (PnLElement)pnl.Clone();
                        Price        feesW   = tx.Fees;
                        CurrencyPair cpW     = new CurrencyPair(feesW.Ccy, CcyRef);
                        XChangeRate  xW      = fxmh.GetQuote(lastDate, cpW, isArtificial: true).Item2;
                        newPnLW.Fees     += xW.ConvertPrice(feesW).Amount;
                        newPnLW.Position -= feesW.Amount;
                        if (tx.Paid.Ccy.IsFiat())
                        {
                            newPnLW.Position    -= tx.Paid.Amount;
                            newPnLW.Withdrawal  += xW.ConvertPrice(tx.Paid).Amount;
                            newPnLW.RealizedPnL += (tx.Paid.Amount + feesW.Amount) * (xW.Rate - newPnLW.AverageCost);
                        }
                        else
                        {
                            newPnLW.RealizedPnL += feesW.Amount * (xW.Rate - newPnLW.AverageCost);
                        }

                        PnLElements.Add(lastDate, newPnLW);
                        break;

                    default:
                        break;
                    }
                }
                if (tx.Fees.Ccy == Ccy && justFees)
                {
                    throw new Exception("ERROR JUST FEES!");
                }
            }
        }