public void WriteFXHistory(CurrencyPairTimeSeries cpts) { string pathLib = GetFXLibraryPath(cpts); this.PublishInfo($"Saving FX: {cpts.CurPair.ToString()}"); StringBuilder sb = new StringBuilder(); sb.AppendLine("Time,Close"); IEnumerable <DateTime> DateList = Data.GetAllDates(); //DateList = cpts.Freq.GetSchedule(DateList.First(), DateList.Last(), true); foreach (DateTime date in DateList) { double close = Data.GetQuote(date, cpts.CurPair).Item2.Rate; Int64 dateUnix = StaticLibrary.DateTimeToUnixTimeStamp(date); //if (StaticLibrary.UnixTimeStampToDateTime(dateUnix + FXMinimunFrequency.GetFrequency(true)) < DateTime.UtcNow) if (StaticLibrary.UnixTimeStampToDateTime(dateUnix) < DateTime.UtcNow) { sb.AppendLine($"{dateUnix},{close}"); } else { this.PublishInfo($"Stopped at line: {StaticLibrary.UnixTimeStampToDateTime(dateUnix)}"); } } File.WriteAllText(pathLib, sb.ToString()); }
public Dictionary <string, PnLElement> ToTable(FXMarketHistory fxmh, DateTime date) { int n = PnLs.Count + 1; Dictionary <string, PnLElement> res = new Dictionary <string, PnLElement> { }; PnLElement total = new PnLElement(); foreach (Currency ccy in PnLs.Keys) { CurrencyPair cpCcy = new CurrencyPair(ccy, CcyRef); XChangeRate xrCcy = fxmh.GetQuote(date, cpCcy, isArtificial: true).Item2; Tuple <string, PnLElement> item = PnLs[ccy].ToArray(xrCcy, date); res.Add(item.Item1, item.Item2); total.Position += item.Item2.Position * item.Item2.xChangeRate.Value; total.OnGoingPnL += item.Item2.OnGoingPnL; total.Fees += item.Item2.Fees; total.RealizedPnL += item.Item2.RealizedPnL; total.Deposit += item.Item2.Deposit; total.Withdrawal += item.Item2.Withdrawal; } total.Weight = 1.0; res.Add("Total", total); foreach (Currency key in PnLs.Keys) { PnLElement item = res[key.ToFullName()]; item.Weight = item.Position * item.xChangeRate / total.Position; res[key.ToFullName()] = item; } return(res); }
public XChangeRate GetAdjustedFXRate(DateTime date, XChangeRate tx_xr, FXMarketHistory fxmh) { if (CpRef.IsFiatPair) { return(fxmh.GetQuote(date, CpRef, isArtificial: true).Item2); } CryptoFiatPair cfp = tx_xr.CcyPair.GetCryptoFiatPair; if (cfp.IsNone) { return(fxmh.GetQuote(date, tx_xr.CcyPair, isArtificial: true).Item2); } CurrencyPair cp = new CurrencyPair(cfp.Fiat, CcyRef); XChangeRate mkt_rate = fxmh.GetQuote(date, cp, isArtificial: true).Item2; double alpha = 1; if (Ccy != tx_xr.CcyPair.Ccy1) { alpha = -1; } return(new XChangeRate(mkt_rate.Rate * Math.Pow(tx_xr.Rate, alpha), cfp.Crypto, cfp.Fiat)); }
public void FXMktHistory_GetQuote() { FXMarketHistory fxMH = MarketTestTools.CreateMktHistory(); CurrencyPair cp = new CurrencyPair(Currency.XBT, Currency.USD); Tuple <DateTime, XChangeRate> xr1 = fxMH.GetQuote(MarketTestTools.dateArt, cp, isArtificial: true); Tuple <DateTime, XChangeRate> xr2 = fxMH.GetQuote(MarketTestTools.dateArt, cp, isArtificial: false, isExactDate: false); Tuple <DateTime, XChangeRate> xr3 = fxMH.GetQuote(MarketTestTools.dateArt, cp, isArtificial: false, isExactDate: true); bool test1 = xr1.Item1 == MarketTestTools.dateArt && xr1.Item2.Equals(MarketTestTools.XbtUsdArtRate); bool test2 = xr2.Item1 == MarketTestTools.date1 && xr2.Item2.Equals(fxMH.GetRealFXMarket(MarketTestTools.date1).GetQuote(cp)); bool test3 = xr3.Item1 == MarketTestTools.dateArt && xr3.Item2 == null; Assert.IsTrue(test1 && test2 && test3); }
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!"); } } }