private XChangeRate _GetXChangeRate(CurrencyPair curPair) { if (curPair.IsIdentity) { return(new XChangeRate(1, (CurrencyPair)curPair.Clone())); } else { if (CcyList.Contains(curPair.Ccy1) && CcyList.Contains(curPair.Ccy2)) { XChangeRate xRate = FX.Where(x => x.CcyPair.IsEquivalent(curPair)).FirstOrDefault(); if (xRate == null) { return(null); } if (xRate.CcyPair.Equals(curPair)) { return(xRate); } else { return(xRate.GetInverse()); } } else { return(null); } } }
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 Tuple <double, bool> GetFullData(CurrencyPair cp, DateTime date) { DateTime adjustedDate = FXMinimunFrequency.Adjust(date); try { XChangeRate xr = Data.GetQuote(adjustedDate, cp, isExactDate: true).Item2; return(new Tuple <double, bool> (xr.Rate, false)); } catch { double value = 0; if (UseInternet) { value = GetFXDataFromApi(cp, adjustedDate); } else { XChangeRate xr = Data.GetQuote(Data.LastRealDate, cp, isExactDate: true).Item2; value = xr.Rate; } Data.AddQuote(adjustedDate, new XChangeRate(value, cp)); return(new Tuple <double, bool>(value, true)); } }
public XChangeRate GetQuote(CurrencyPair curPair, bool constructNewQuote = false, bool useConstructedQuote = false) { XChangeRate xr = _GetXChangeRate(curPair); if (xr != null) { return(xr); } else { if (constructNewQuote) { XChangeRate impliedXr = GetImpliedNewQuote(curPair); if (useConstructedQuote) { FX.Add(impliedXr); } return(impliedXr); } else { return(null); } } }
public XChangeRate GetImpliedNewQuote(CurrencyPair curPair) { IEnumerable <Currency> Ccy1List = FX .Where(x => x.CcyPair.Contains(curPair.Ccy1)) .Select(x => (x.CcyPair.Ccy1 == curPair.Ccy1) ? x.CcyPair.Ccy2 : x.CcyPair.Ccy1); IEnumerable <Currency> Ccy2List = FX .Where(x => x.CcyPair.Contains(curPair.Ccy2)) .Select(x => (x.CcyPair.Ccy1 == curPair.Ccy2) ? x.CcyPair.Ccy2 : x.CcyPair.Ccy1); IEnumerable <Currency> ThirdCcies = Ccy1List .Where(x => Ccy2List.Contains(x)); XChangeRate res = new XChangeRate(0.0, curPair); int n = 0; foreach (Currency ccy in ThirdCcies) { try { double rate1 = _GetXChangeRate(curPair.Ccy1, ccy).Rate; double rate2 = _GetXChangeRate(ccy, curPair.Ccy2).Rate; res.Rate += rate1 * rate2; n++; } catch { return(null); } } if (n > 0) { res.Rate /= Convert.ToDouble(n); return(res); } else { return(null); } }
public Transaction(string id, TransactionType type, DateTime date, Price paid, Price received, Price fees = null) { ID = id; Type = type; Date = date; Paid = paid; Received = received; if (fees != null) { Fees = fees; } else { Fees = new Price(0, Currency.None); } switch (type) { case TransactionType.Trade: double ratio = paid.Amount / received.Amount; XRate = new XChangeRate(ratio, received.Ccy, paid.Ccy); break; case TransactionType.WithDrawal: XRate = new XChangeRate(1, paid.Ccy, paid.Ccy); break; default: XRate = new XChangeRate(1, received.Ccy, received.Ccy); break; } }
public void FXMkt_AddQuote() { FXMarket fXMarket = MarketTestTools.CreateMarket(); XChangeRate xrNew = new XChangeRate(909, Currency.XBT, Currency.EUR); fXMarket.AddQuote(xrNew); Assert.IsTrue(xrNew.Equals(fXMarket.GetQuote(xrNew.CcyPair))); }
public void FXMkt_ImpliedRate() { FXMarket fXMarket = MarketTestTools.CreateMarket(); CurrencyPair cp1 = new CurrencyPair(Currency.ETH, Currency.XBT); XChangeRate xrImplied = fXMarket.GetImpliedNewQuote(cp1); Assert.IsTrue(MarketTestTools.EthXbtRefRate.Equals(xrImplied)); }
public void FXMktHist_GetArtificialFXMarket() { FXMarketHistory fxMH = MarketTestTools.CreateMktHistory(); FXMarket fxArt = fxMH.GetArtificialFXMarket(MarketTestTools.dateArt, new CurrencyPair(Currency.EUR, Currency.USD)); XChangeRate xr = fxArt.GetQuote(Currency.EUR, Currency.USD, true); Assert.AreEqual(MarketTestTools.EurUsdArtRate.Rate, xr.Rate, Math.Pow(10, -6)); }
public void XCRate_CryptoFiatPair() { XChangeRate xr = new XChangeRate(0.01, Currency.USD, Currency.BCH); CryptoFiatPair cfp = xr.GetCryptoFiatPair; string xrStr = xr.CcyPair.Ccy2.ToFullName() + xr.CcyPair.Ccy1.ToFullName(); string cfpStr = cfp.Crypto.ToFullName() + cfp.Fiat.ToFullName(); Assert.AreEqual(xrStr, cfpStr); }
public void ConstructQuotes(CurrencyPair cp) { foreach (DateTime date in GetRealDates()) { FXMarket fx = GetRealFXMarket(date, isExactDate: true); XChangeRate xr = fx.GetQuote(cp, constructNewQuote: true, useConstructedQuote: true); } }
public double FXConvert(Price price, Currency curRef) { if (price.IsNull) { return(0); } XChangeRate xcr = GetQuote(price.Ccy, curRef, true); return(price.Amount * xcr.Rate); }
public void FXMkt_GetQuote() { FXMarket fXMarket = MarketTestTools.CreateMarket(); CurrencyPair cp1 = new CurrencyPair(Currency.EUR, Currency.USD); XChangeRate eurUsd = fXMarket.GetQuote(cp1, constructNewQuote: true); bool test1 = MarketTestTools.EurUsdRefRate.Equals(eurUsd) && !fXMarket.FXContains(cp1); XChangeRate eurUsd2 = fXMarket.GetQuote(cp1, constructNewQuote: true, useConstructedQuote: true); bool test2 = MarketTestTools.EurUsdRefRate.Equals(eurUsd) && fXMarket.FXContains(cp1); Assert.IsTrue(test1 && test2); }
private void _AddFXRate(XChangeRate xRate) { if (!CcyList.Contains(xRate.CcyPair.Ccy1)) { CcyList.Add(xRate.CcyPair.Ccy1); } if (!CcyList.Contains(xRate.CcyPair.Ccy2)) { CcyList.Add(xRate.CcyPair.Ccy2); } FX.Add(xRate); }
public FXMarket(DateTime date, XChangeRate quote) { Date = date; FX = new List <XChangeRate> { quote }; CcyList.Add(quote.CcyPair.Ccy1); if (!quote.CcyPair.IsIdentity) { CcyList.Add(quote.CcyPair.Ccy2); } }
public void AddQuote(XChangeRate xRate) { if (xRate.CcyPair.IsIdentity) { return; } XChangeRate foundRate = GetQuote(xRate.CcyPair); if (foundRate == null) { _AddFXRate(xRate); } else { foundRate.Update(xRate); } }
public Price SumPrices(Price p1, Price p2, Currency outCur = Currency.None) { if (outCur == Currency.None) { outCur = p1.Ccy; } if (p2.Amount == 0) { return(p1); } XChangeRate xRate1 = GetQuote(p1.Ccy, outCur, constructNewQuote: true); XChangeRate xRate2 = GetQuote(p2.Ccy, outCur, constructNewQuote: true); if (xRate1 == null || xRate2 == null) { return(null); } return(new Price(p1.Amount * xRate1.Rate + p2.Amount * xRate2.Rate, outCur)); }
public void AddQuote(DateTime date, XChangeRate quote) { if (quote.IsIdentity) { return; } AddCcyPair(quote.CcyPair); DateTime AdjustedDate = Freq.Adjust(date); FXMarket FX = GetRealFXMarketSimple(AdjustedDate); UpdateLastReadDate_NoLive(AdjustedDate); if (FX != null) { FX.AddQuote(quote); } else { RealFXMarkets[AdjustedDate] = new FXMarket(AdjustedDate, quote); } }
public OpenOrder(string refID, OrderInfo orderInfo, FXMarket fxmkt)//, Dictionary<string, PnLElement> pnlInfo) { ID = refID; OrderDescription orderDescr = orderInfo.Descr; string descrPair = orderDescr.Pair; var infos = orderDescr.Order.Split(' '); IsBuyOrder = orderDescr.Type == "buy"; Volume = Convert.ToDouble(infos[1]); int cryptoLen = descrPair.Length - 3; Currency ccy1 = CurrencyPorperties.FromNameToCurrency(descrPair.Substring(0, cryptoLen)); Currency ccy2 = CurrencyPorperties.FromNameToCurrency(descrPair.Substring(cryptoLen, 3)); CurrencyPair cp = new CurrencyPair(ccy1, ccy2); Rate = new XChangeRate((double)orderInfo.Descr.Price, cp); CurrentRate = fxmkt.GetQuote(cp); Return = Rate.Rate / CurrentRate.Rate - 1; PreviouslyExecutedVolume = 0.0; TotalPnL = 0; }
internal Tuple <string, PnLElement> ToArray(XChangeRate xChangeRate, DateTime date) { var dateList = PnLElements.Keys.Where(x => x <= date); if (dateList.Count() == 0) { PnLElement res = new PnLElement(0, 0, 0, 0, 0); res.Weight = 0; res.xChangeRate = xChangeRate.Rate; return(new Tuple <string, PnLElement>(Ccy.ToFullName(), res)); } else { DateTime dateToUse = dateList.Last(); PnLElement pnl = PnLElements[dateToUse]; int round = Ccy.IsFiat() ? 2 : 8; PnLElement res = (PnLElement)pnl.Clone(); res.xChangeRate = xChangeRate.Rate; res.OnGoingPnL = pnl.Position * (xChangeRate.Rate - pnl.AverageCost); return(new Tuple <string, PnLElement>(Ccy.ToFullName(), 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 XCRate_GetInverse() { XChangeRate xr = new XChangeRate(0.01, Currency.USD, Currency.BCH); Assert.AreEqual(100, xr.GetInverse().Rate); }
public bool FXContains(CurrencyPair cp) { XChangeRate xcr = _GetXChangeRate(cp); return(xcr != null); }
internal Tuple <string, PnLElement> ToArray(XChangeRate xChangeRate) { return(ToArray(xChangeRate, PnLElements.Keys.Last())); }
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!"); } } }
private FXMarket _CreateArtificialFXMarket(DateTime date, List <CurrencyPair> cpList) { if (date != Freq.Adjust(date)) { throw new Exception($"Your date is not Freq adjusted {date} != {Freq.Adjust(date)}"); } if (cpList.Count == 0) { cpList = CpList; } FXMarket res = GetRealFXMarket(date, isExactDate: true); if (res == null) { res = GetArtificialFXMarketSimple(date); } if (!res.FXContains(cpList)) { foreach (CurrencyPair cp in cpList) { if (res.FXContains(cp)) { continue; } FXMarket beforeFX = RealFXMarkets .Where(x => x.Key <= date && x.Value.FXContains(cp)) .LastOrDefault().Value; FXMarket afterFX = RealFXMarkets .Where(x => x.Key >= date && x.Value.FXContains(cp)) .FirstOrDefault().Value; double beforeRate = 0, afterRate = 0, rate = 0, w = 0.5; bool useBefore = beforeFX != null; bool useAfter = afterFX != null; if (useBefore) { beforeRate = beforeFX.GetQuote(cp).Rate; } if (useAfter) { afterRate = afterFX.GetQuote(cp).Rate; } if (!(useBefore || useAfter)) { continue; } if (useAfter && useBefore) { if (afterFX.Date.AddSeconds(1) > beforeFX.Date) { w = (date - beforeFX.Date).TotalSeconds / (double)(afterFX.Date - beforeFX.Date).TotalSeconds; } else { throw new Exception($"The afterFX Market {afterFX.Date} comes before the beforeFX Market {beforeFX.Date}"); } } else { if (useBefore) { w = 0; } else { w = 1; } } rate = (1 - w) * beforeRate + w * afterRate; XChangeRate xRateCp = new XChangeRate(rate, cp); res.AddQuote(xRateCp); res.DefineAsArtificial(); } } if (res.FXContains(cpList)) { ArtificialFXMarkets[date] = res; } else { res = _CreateArtificialFXMarket(date, new List <CurrencyPair> { }); } return(res); }