public async void ExternalDataIsSupplementedWithLocalDataWhenObservationsAreMissing() { DateTime startDate = new DateTime(2000, 1, 1); DateTime endDate = new DateTime(2000, 1, 3); var inst = new Instrument { ID = 1, Symbol = "SPY", AssetCategory = AssetClass.Stock, QDMSInstrumentID = 2 }; var data = new List <OHLCBar> { new OHLCBar { Open = 1, High = 2, Low = 0, Close = 1, DT = new DateTime(2000, 1, 1) }, new OHLCBar { Open = 1, High = 2, Low = 0, Close = 1, DT = new DateTime(2000, 1, 2) }, }; var ppSetStub = new DbSetStub <PriorPosition>(); _contextMock.Setup(x => x.PriorPositions).Returns(ppSetStub); _externalSourceMock.Setup( x => x.GetData(It.IsAny <Instrument>(), It.IsAny <DateTime>(), It.IsAny <DateTime>(), It.IsAny <BarSize>())) .ReturnsAsync(data); await _datasourcer.GetData(inst, startDate, endDate).ConfigureAwait(true); _contextMock.Verify(x => x.PriorPositions); }
public async Task ExternalDataIsSupplementedWithLocalDataWhenObservationsAreMissing() { DateTime startDate = new DateTime(2000, 1, 1); DateTime endDate = new DateTime(2000, 1, 3); var inst = new Instrument { ID = 1, Symbol = "SPY", AssetCategory = AssetClass.Stock, QDMSInstrumentID = 2 }; var data = new List <OHLCBar> { new OHLCBar { Open = 1, High = 2, Low = 0, Close = 1, DT = new DateTime(2000, 1, 1) }, new OHLCBar { Open = 1, High = 2, Low = 0, Close = 1, DT = new DateTime(2000, 1, 2) }, }; _dbContext.PriorPositions.Add(new PriorPosition() { Instrument = inst, InstrumentID = inst.ID, Date = endDate, Price = 5 }); _dbContext.SaveChanges(); _externalSourceMock.Setup( x => x.GetData(It.IsAny <Instrument>(), It.IsAny <DateTime>(), It.IsAny <DateTime>(), It.IsAny <BarSize>())) .ReturnsAsync(data); var resultData = await _datasourcer.GetData(inst, startDate, endDate); Assert.That(resultData.Count == 3); }
public async Task CashInstrumentLocalRequestsUseFxRates() { DateTime startDate = new DateTime(2000, 1, 1); DateTime endDate = new DateTime(2000, 1, 3); var inst = new Instrument { ID = 1, Symbol = "EUR.USD", AssetCategory = AssetClass.Cash, QDMSInstrumentID = 2 }; var eur = new Currency { ID = 2, Name = "EUR" }; _data.Currencies.Add(eur); _data.FXRates.Add(new FXRate() { FromCurrencyID = 2, FromCurrency = eur, Rate = 1.5m, Date = endDate }); _externalSourceMock.Setup( x => x.GetData(It.IsAny <Instrument>(), It.IsAny <DateTime>(), It.IsAny <DateTime>(), It.IsAny <BarSize>())) .ReturnsAsync(new List <OHLCBar>()); var resultData = await _datasourcer.GetData(inst, startDate, endDate); Assert.That(resultData.Any(x => x.Date.ToDateTime() == endDate)); }
public async Task IfExternalSourceHasNoDataLocalBackupIsUsedInstead() { DateTime startDate = new DateTime(2000, 1, 1); DateTime endDate = new DateTime(2000, 2, 1); var inst = new Instrument { ID = 2, Symbol = "SPY", AssetCategory = AssetClass.Stock, QDMSInstrumentID = 2 }; _dbContext.PriorPositions.Add(new PriorPosition() { Instrument = inst, InstrumentID = inst.ID, Date = endDate, Price = 5 }); _dbContext.SaveChanges(); _externalSourceMock.Setup( x => x.GetData(It.IsAny <Instrument>(), It.IsAny <DateTime>(), It.IsAny <DateTime>(), It.IsAny <BarSize>())) .ReturnsAsync(new List <OHLCBar>()); var resultData = await _datasourcer.GetData(inst, startDate, endDate); _externalSourceMock.Verify(x => x.GetData( It.IsAny <Instrument>(), It.IsAny <DateTime>(), It.IsAny <DateTime>(), It.IsAny <BarSize>())); Assert.That(resultData.Any(x => x.Date.ToDateTime() == endDate)); }
public void DataIsCachedBetweenRequests() { DateTime startDate = new DateTime(2000, 1, 1); DateTime endDate = new DateTime(2000, 1, 2); var inst = new Instrument { ID = 1, Symbol = "SPY", AssetCategory = AssetClass.Stock, QDMSInstrumentID = 2 }; var data = new List<OHLCBar> { new OHLCBar { Open = 1, High = 2, Low = 0, Close = 1, DT = new DateTime(2000,1,1)}, new OHLCBar { Open = 1, High = 2, Low = 0, Close = 1, DT = new DateTime(2000,1,2)}, }; var ppSetStub = new DbSetStub<PriorPosition>(); _contextMock.Setup(x => x.PriorPositions).Returns(ppSetStub); _externalSourceMock.Setup( x => x.GetData(It.IsAny<Instrument>(), It.IsAny<DateTime>(), It.IsAny<DateTime>(), It.IsAny<BarSize>())) .Returns(data); _datasourcer.GetData(inst, startDate, endDate); //request a second time: should use cache instead of external source _datasourcer.GetData(inst, startDate, endDate); _externalSourceMock.Verify(x => x.GetData( It.IsAny<Instrument>(), It.IsAny<DateTime>(), It.IsAny<DateTime>(), It.IsAny<BarSize>()), Times.Once); }
public async void FxDataIsInvertedWhenNecessary() { var inst = new Instrument { Symbol = "USD.CAD", ID = 1, AssetCategory = AssetClass.Cash }; var startDate = new DateTime(2000, 1, 1); var endDate = new DateTime(2000, 1, 1); var fxrSetStub = new DbSetStub <FXRate>(); fxrSetStub.Add(new FXRate { FromCurrencyID = 2, ToCurrencyID = 1, Date = startDate, Rate = 1.1m }); var currencySetStub = new DbSetStub <Currency>(); currencySetStub.Add(new Currency { ID = 2, Name = "CAD" }); _contextMock.Setup(x => x.Currencies).Returns(currencySetStub); _contextMock.Setup(x => x.FXRates).Returns(fxrSetStub); var data = await _datasourcer.GetData(inst, startDate, endDate).ConfigureAwait(true); Assert.AreEqual(1m / 1.1m, data[0].Close); }
public async void CashInstrumentLocalRequestsUseFxRates() { DateTime startDate = new DateTime(2000, 1, 1); DateTime endDate = new DateTime(2000, 1, 3); var inst = new Instrument { ID = 1, Symbol = "EUR.USD", AssetCategory = AssetClass.Cash, QDMSInstrumentID = 2 }; var fxrSetStub = new DbSetStub <FXRate>(); var currencySetStub = new DbSetStub <Currency>(); currencySetStub.Add(new Currency { ID = 2, Name = "EUR" }); _contextMock.Setup(x => x.Currencies).Returns(currencySetStub); _contextMock.Setup(x => x.FXRates).Returns(fxrSetStub); _externalSourceMock.Setup( x => x.GetData(It.IsAny <Instrument>(), It.IsAny <DateTime>(), It.IsAny <DateTime>(), It.IsAny <BarSize>())) .ReturnsAsync(new List <OHLCBar>()); await _datasourcer.GetData(inst, startDate, endDate).ConfigureAwait(true); _contextMock.Verify(x => x.FXRates); }
public async void IfExternalSourceHasNoDataLocalBackupIsUsedInstead() { DateTime startDate = new DateTime(2000, 1, 1); DateTime endDate = new DateTime(2000, 2, 1); var inst = new Instrument { ID = 1, Symbol = "SPY", AssetCategory = AssetClass.Stock, QDMSInstrumentID = 2 }; var ppSetStub = new DbSetStub <PriorPosition>(); _contextMock.Setup(x => x.PriorPositions).Returns(ppSetStub); _externalSourceMock.Setup( x => x.GetData(It.IsAny <Instrument>(), It.IsAny <DateTime>(), It.IsAny <DateTime>(), It.IsAny <BarSize>())) .ReturnsAsync(new List <OHLCBar>()); await _datasourcer.GetData(inst, startDate, endDate).ConfigureAwait(true); _externalSourceMock.Verify(x => x.GetData( It.IsAny <Instrument>(), It.IsAny <DateTime>(), It.IsAny <DateTime>(), It.IsAny <BarSize>())); _contextMock.Verify(x => x.PriorPositions); }
public void SetUp() { _inst = new Instrument {ID = 1, Multiplier = 1, AssetCategory = AssetClass.Stock}; _t = new Trade { Orders = new List<Order>(), CashTransactions = new List<CashTransaction>(), FXTransactions = new List<FXTransaction>() }; _dsMock = new Mock<IDataSourcer>(); _dsMock.Setup(x => x.GetData(It.IsAny<Instrument>(), It.IsAny<DateTime>(), It.IsAny<DateTime>(), It.IsAny<QDMS.BarSize>())) .Returns<Instrument, DateTime, DateTime, QDMS.BarSize>((a, b, c, d) => GenerateData(b, c)); _contextMock = new Mock<IDBContext>(); _dbSetStub = new DbSetStub<EquitySummary>(); var equitySummaries = new List<EquitySummary> { new EquitySummary { Date = new DateTime(2000,1,1), Total = 10000 } }; _dbSetStub.AddRange(equitySummaries); _contextMock.SetupGet(x => x.EquitySummaries).Returns(_dbSetStub); _repository = new TradesRepository(_contextMock.Object, _dsMock.Object, 0.1m); }
public void LastPriceFxDataIsInvertedWhenNecessary() { var inst = new Instrument { Symbol = "USD.CAD", ID = 1, AssetCategory = AssetClass.Cash }; var startDate = new DateTime(2000, 1, 1); var fxrSetStub = new DbSetStub <FXRate>(); fxrSetStub.Add(new FXRate { FromCurrencyID = 2, ToCurrencyID = 1, Date = startDate, Rate = 1.1m }); var currencySetStub = new DbSetStub <Currency>(); currencySetStub.Add(new Currency { ID = 2, Name = "CAD" }); _contextMock.Setup(x => x.Currencies).Returns(currencySetStub); _contextMock.Setup(x => x.FXRates).Returns(fxrSetStub); decimal fxRate; var price = _datasourcer.GetLastPrice(inst, out fxRate); Assert.AreEqual(1m / 1.1m, price); }
public void ExternalDataIsSupplementedWithLocalDataWhenObservationsAreMissing() { DateTime startDate = new DateTime(2000, 1, 1); DateTime endDate = new DateTime(2000, 1, 3); var inst = new Instrument { ID = 1, Symbol = "SPY", AssetCategory = AssetClass.Stock, QDMSInstrumentID = 2 }; var data = new List<OHLCBar> { new OHLCBar { Open = 1, High = 2, Low = 0, Close = 1, DT = new DateTime(2000,1,1)}, new OHLCBar { Open = 1, High = 2, Low = 0, Close = 1, DT = new DateTime(2000,1,2)}, }; var ppSetStub = new DbSetStub<PriorPosition>(); _contextMock.Setup(x => x.PriorPositions).Returns(ppSetStub); _externalSourceMock.Setup( x => x.GetData(It.IsAny<Instrument>(), It.IsAny<DateTime>(), It.IsAny<DateTime>(), It.IsAny<BarSize>())) .Returns(data); _datasourcer.GetData(inst, startDate, endDate); _contextMock.Verify(x => x.PriorPositions); }
private List <OHLCBar> GetPriorPositionsData(Instrument instrument, DateTime fromDate, DateTime toDate) { var prices = Context .PriorPositions .Where(x => x.InstrumentID == instrument.ID && x.Date >= fromDate && x.Date <= toDate) .OrderBy(x => x.Date) .Select(p => new { p.Date, p.Price }) .ToList(); _logger.Log(LogLevel.Info, string.Format("Retrieved {0} data points for instrument {1} from prior positions.", prices.Count, instrument)); return(prices .Select( p => new OHLCBar { Open = p.Price, High = p.Price, Low = p.Price, Close = p.Price, AdjOpen = p.Price, AdjHigh = p.Price, AdjLow = p.Price, AdjClose = p.Price, DT = p.Date }) .ToList()); }
public decimal?GetLastPrice(Instrument inst, out decimal fxRate, string currency = "USD") { _logger.Log(LogLevel.Info, string.Format("Last price request for {0} and currency {1}", inst, currency)); DateTime lastLocalDate; decimal? lastLocalPrice = GetLocalLastPrice(inst, out fxRate, out lastLocalDate); if (!_useExternalDataSource || !ExternalDataSource.Connected) { return(lastLocalPrice); } else { DateTime lastExternalDate; decimal? lastExternalPrice = ExternalDataSource.GetLastPrice(inst, out lastExternalDate); if (lastExternalPrice.HasValue && lastExternalDate >= lastLocalDate) { fxRate = GetLastFXRate(currency); return(lastExternalPrice.Value); } else { return(lastLocalPrice); } } }
/// <summary> /// Used for the instrument chart. /// </summary> public List <OHLCBar> GetAllExternalData(Instrument inst) { if (!_useExternalDataSource) { _logger.Log(LogLevel.Info, string.Format("Request for all external data on instrument {0} not fulfilled, external data not allowed.", inst)); return(new List <OHLCBar>()); } _logger.Log(LogLevel.Info, string.Format("Request for all external data on instrument {0}", inst)); return(ExternalDataSource.GetAllData(inst)); }
private decimal?GetLocalLastPrice(Instrument instrument, out decimal fxRate, out DateTime date) { if (instrument.AssetCategory == AssetClass.Cash) { return(GetLocalLastFxRatePrice(instrument, out fxRate, out date)); } else { return(GetLocalLastPriorPositionPrice(instrument, out fxRate, out date)); } }
private List <OHLCBar> GetInstrumentFxRatesData(Instrument instrument, DateTime fromDate, DateTime toDate) { if (instrument.AssetCategory != AssetClass.Cash) { throw new Exception("Wrong asset class."); } string[] splitSymbol = instrument.Symbol.Split(".".ToCharArray()); string fxCurrencyName = splitSymbol[0] == "USD" ? splitSymbol[1] : splitSymbol[0]; var currency = Context.Currencies.FirstOrDefault(x => x.Name == fxCurrencyName); if (currency == null) { throw new Exception(string.Format("Currency {0} not found.", fxCurrencyName)); } //Some currencies are in the format X.USD, others in format USD.X //The latter need to be inverted because all fx rates are given in X.USD bool invert = splitSymbol[0] == "USD"; var prices = Context .FXRates .Where(x => x.FromCurrencyID == currency.ID && x.Date >= fromDate && x.Date <= toDate) .OrderBy(x => x.Date) .Select(p => new { p.Date, Price = invert ? 1m / p.Rate : p.Rate }) .ToList(); _logger.Log(LogLevel.Info, string.Format("Retrieved {0} data points for instrument {1} from fx rates.", prices.Count, instrument)); return(prices .Select( p => new OHLCBar { Open = p.Price, High = p.Price, Low = p.Price, Close = p.Price, AdjOpen = p.Price, AdjHigh = p.Price, AdjLow = p.Price, AdjClose = p.Price, DT = p.Date }) .ToList()); }
private decimal?GetLocalLastPriorPositionPrice(Instrument inst, out decimal fxRate, out DateTime date) { var pos = Context.PriorPositions.Where(x => x.InstrumentID == inst.ID).OrderByDescending(x => x.Date).FirstOrDefault(); if (pos == null) { _logger.Log(LogLevel.Error, "Could not find any local data on instrument " + inst.ToString()); fxRate = 1; date = DateTime.Now; return(null); } fxRate = pos.FXRateToBase; date = pos.Date; return(pos.Price); }
public async Task <List <OHLCBar> > GetData(Instrument inst, DateTime startTime, DateTime endTime, BarSize frequency = BarSize.OneDay) { _logger.Log(LogLevel.Info, string.Format("Data request for {0} from {1} to {2} @ {3}", inst, startTime, endTime, frequency)); //Check the cache lock (_dataCacheLock) { if (_dataCache.ContainsKey(inst.ID) && _dataCache[inst.ID].First().DT.Date <= startTime.Date && _dataCache[inst.ID].Last().DT.Date >= endTime.Date) { _logger.Log(LogLevel.Info, "Found data in cache"); return(_dataCache[inst.ID].Where(x => x.DT >= startTime && x.DT <= endTime).ToList()); } } //if external data is not allowed, just grab the prior positions data if (!_useExternalDataSource) { _logger.Info("Using local data, external datasource disallowed."); return(GetLocalData(inst, startTime, endTime)); } //If the cache is not enough, go to the external datasource var data = await ExternalDataSource.GetData(inst, startTime, endTime); //External datasource didn't have anything, get data from prior positions if (data == null || data.Count == 0) { _logger.Log(LogLevel.Info, "Data was not available externally, getting it form prior positions."); return(GetLocalData(inst, startTime, endTime)); } //QDMS data does NOT cover the entire period requested. //Try to supplement the data with the prices from prior positions if (frequency == BarSize.OneDay && (data.First().DT.Date > startTime.Date || data.Last().DT.Date < endTime)) { _logger.Log(LogLevel.Info, "External data did not cover full period, supplementing with prior positions."); SupplementWithLocalData(inst, startTime, endTime, ref data); } AddToCache(data, inst.ID); return(data); }
/// <summary> /// Use prior positions data to fill missing data from external source /// </summary> private void SupplementWithLocalData(Instrument inst, DateTime startTime, DateTime endTime, ref List <OHLCBar> data) { //lacks data before if (data.First().DT.Date > startTime.Date) { var localData = GetLocalData(inst, startTime, data.First().DT.AddDays(-1).Date); data.AddRange(localData); } //lacks data after if (data.Last().DT.Date < endTime.Date) { var localData = GetLocalData(inst, data.Last().DT.AddDays(1).Date, endTime); data.AddRange(localData); } data = data.Distinct((x, y) => x.DT.Date == y.DT.Date).OrderBy(x => x.DT).ToList(); }
public List<OHLCBar> GetData(Instrument inst, DateTime startTime, DateTime endTime, BarSize frequency = BarSize.OneDay) { _logger.Log(LogLevel.Info, string.Format("Data request for {0} from {1} to {2} @ {3}", inst, startTime, endTime, frequency)); //Check the cache lock (_dataCacheLock) { if (_dataCache.ContainsKey(inst.ID) && _dataCache[inst.ID].First().DT <= startTime && _dataCache[inst.ID].Last().DT >= endTime) { _logger.Log(LogLevel.Info, "Found data in cache"); return _dataCache[inst.ID].Where(x => x.DT >= startTime && x.DT <= endTime).ToList(); } } //if external data is not allowed, just grab the prior positions data if (!_useExternalDataSource) { return GetLocalData(inst, startTime, endTime); } //If the cache is not enough, go to the external datasource var data = ExternalDataSource.GetData(inst, startTime, endTime); //External datasource didn't have anything, get data from prior positions if (data == null || data.Count == 0) { _logger.Log(LogLevel.Info, "Data was not available externally, getting it form prior positions"); return GetLocalData(inst, startTime, endTime); } //QDMS data does NOT cover the entire period requested. //Try to supplement the data with the prices from prior positions if(frequency == BarSize.OneDay && (data.First().DT.Date > startTime.Date || data.Last().DT.Date < endTime)) { SupplementWithLocalData(inst, startTime, endTime, ref data); } AddToCache(data, inst.ID); return data; }
private List <OHLCBar> GetLocalData(Instrument instrument, DateTime fromDate, DateTime toDate) { try { if (instrument.AssetCategory == AssetClass.Cash) { return(GetInstrumentFxRatesData(instrument, fromDate, toDate)); } else { return(GetPriorPositionsData(instrument, fromDate, toDate)); } } catch (Exception ex) { _logger.Error(string.Format("Exception on requesting data for instrument {0}", instrument), ex); return(new List <OHLCBar>()); } }
public void LastPriceFxDataIsInvertedWhenNecessary() { var inst = new Instrument { Symbol = "USD.CAD", ID = 1, AssetCategory = AssetClass.Cash }; var startDate = new DateTime(2000, 1, 1); _data.FXRates.Add(new FXRate { FromCurrencyID = 2, ToCurrencyID = 1, Date = startDate, Rate = 1.1m }); _data.Currencies.Add(new Currency { ID = 2, Name = "CAD" }); decimal fxRate; var price = _datasourcer.GetLastPrice(inst, out fxRate); Assert.AreEqual(1m / 1.1m, price); }
public async Task FxDataIsInvertedWhenNecessary() { var inst = new Instrument { Symbol = "USD.CAD", ID = 1, AssetCategory = AssetClass.Cash }; var startDate = new DateTime(2000, 1, 1); var endDate = new DateTime(2000, 1, 1); _data.FXRates.Add(new FXRate { FromCurrencyID = 2, ToCurrencyID = 1, Date = startDate, Rate = 1.1m }); _data.Currencies.Add(new Currency { ID = 2, Name = "CAD" }); var data = await _datasourcer.GetData(inst, startDate, endDate); Assert.AreEqual(1m / 1.1m, data[0].Close); }
public async void DataIsCachedBetweenRequests() { DateTime startDate = new DateTime(2000, 1, 1); DateTime endDate = new DateTime(2000, 1, 2); var inst = new Instrument { ID = 1, Symbol = "SPY", AssetCategory = AssetClass.Stock, QDMSInstrumentID = 2 }; var data = new List <OHLCBar> { new OHLCBar { Open = 1, High = 2, Low = 0, Close = 1, DT = new DateTime(2000, 1, 1) }, new OHLCBar { Open = 1, High = 2, Low = 0, Close = 1, DT = new DateTime(2000, 1, 2) }, }; var ppSetStub = new DbSetStub <PriorPosition>(); _contextMock.Setup(x => x.PriorPositions).Returns(ppSetStub); _externalSourceMock.Setup( x => x.GetData(It.IsAny <Instrument>(), It.IsAny <DateTime>(), It.IsAny <DateTime>(), It.IsAny <BarSize>())) .ReturnsAsync(data); await _datasourcer.GetData(inst, startDate, endDate).ConfigureAwait(true); //request a second time: should use cache instead of external source await _datasourcer.GetData(inst, startDate, endDate).ConfigureAwait(true); _externalSourceMock.Verify(x => x.GetData( It.IsAny <Instrument>(), It.IsAny <DateTime>(), It.IsAny <DateTime>(), It.IsAny <BarSize>()), Times.Once); }
private decimal?GetLocalLastFxRatePrice(Instrument instrument, out decimal fxRate, out DateTime date) { if (instrument.AssetCategory != AssetClass.Cash) { throw new Exception("Wrong asset class."); } fxRate = 1; string[] splitSymbol = instrument.Symbol.Split(".".ToCharArray()); string fxCurrencyName = splitSymbol[0] == "USD" ? splitSymbol[1] : splitSymbol[0]; var currency = Context.Currencies.FirstOrDefault(x => x.Name == fxCurrencyName); if (currency == null) { throw new Exception(string.Format("Currency {0} not found.", fxCurrencyName)); } //Some currencies are in the format X.USD, others in format USD.X //The latter need to be inverted because all fx rates are given in X.USD bool invert = splitSymbol[0] == "USD"; var price = Context .FXRates .Where(x => x.FromCurrencyID == currency.ID) .OrderByDescending(x => x.Date) .FirstOrDefault(); if (price == null) { _logger.Log(LogLevel.Error, "Could not find any local data on instrument " + instrument.ToString()); date = DateTime.Now; return(null); } date = price.Date; return(invert ? 1m / price.Rate : price.Rate); }
public Position(Instrument instrument, decimal optionsCapitalUsageMultiplier = 1) { Instrument = instrument; Orders = new List<Order>(); _openPositions = new List<Tuple<decimal, int>>(); Capital = new AllocatedCapital(); PnLLong = 0; PnLShort = 0; RealizedPnLLong = 0; RealizedPnLShort = 0; _unrecognizedPnLLong = 0; _unrecognizedPnLShort = 0; _priorPeriodQuantity = 0; _deferredPnL = 0; ROAC = 1; _optionsCapitalUsageMultiplier = optionsCapitalUsageMultiplier; }
private List<OHLCBar> GetPriorPositionsData(Instrument instrument, DateTime fromDate, DateTime toDate) { var prices = Context .PriorPositions .Where(x => x.InstrumentID == instrument.ID && x.Date >= fromDate && x.Date <= toDate) .OrderBy(x => x.Date) .Select(p => new { p.Date, p.Price }) .ToList(); _logger.Log(LogLevel.Info, string.Format("Retrieved {0} data points for instrument {1} from prior positions.", prices.Count, instrument)); return prices .Select( p => new OHLCBar { Open = p.Price, High = p.Price, Low = p.Price, Close = p.Price, AdjOpen = p.Price, AdjHigh = p.Price, AdjLow = p.Price, AdjClose = p.Price, DT = p.Date }) .ToList(); }
public void SetUp() { _inst = new Instrument { ID = 1, Multiplier = 1, AssetCategory = AssetClass.Stock }; }
public decimal? GetLastPrice(Instrument inst, out decimal fxRate, string currency = "USD") { _logger.Log(LogLevel.Info, string.Format("Last price request for {0} and currency {1}", inst, currency)); DateTime lastLocalDate; decimal? lastLocalPrice = GetLocalLastPrice(inst, out fxRate, out lastLocalDate); if (!_useExternalDataSource || !ExternalDataSource.Connected) { return lastLocalPrice; } else { DateTime lastExternalDate; decimal? lastExternalPrice = ExternalDataSource.GetLastPrice(inst, out lastExternalDate); if (lastExternalPrice.HasValue && lastExternalDate >= lastLocalDate) { fxRate = GetLastFXRate(currency); return lastExternalPrice.Value; } else { return lastLocalPrice; } } }
private decimal? GetLocalLastPrice(Instrument instrument, out decimal fxRate, out DateTime date) { if (instrument.AssetCategory == AssetClass.Cash) { return GetLocalLastFxRatePrice(instrument, out fxRate, out date); } else { return GetLocalLastPriorPositionPrice(instrument, out fxRate, out date); } }
public void LastPriceFxDataIsInvertedWhenNecessary() { var inst = new Instrument { Symbol = "USD.CAD", ID = 1, AssetCategory = AssetClass.Cash }; var startDate = new DateTime(2000, 1, 1); var fxrSetStub = new DbSetStub<FXRate>(); fxrSetStub.Add(new FXRate { FromCurrencyID = 2, ToCurrencyID = 1, Date = startDate, Rate = 1.1m }); var currencySetStub = new DbSetStub<Currency>(); currencySetStub.Add(new Currency { ID = 2, Name = "CAD" }); _contextMock.Setup(x => x.Currencies).Returns(currencySetStub); _contextMock.Setup(x => x.FXRates).Returns(fxrSetStub); decimal fxRate; var price = _datasourcer.GetLastPrice(inst, out fxRate); Assert.AreEqual(1m / 1.1m, price); }
/// <summary> /// Used for the instrument chart. /// </summary> public List<OHLCBar> GetAllExternalData(Instrument inst) { if (!_useExternalDataSource) { _logger.Log(LogLevel.Info, string.Format("Request for all external data on instrument {0} not fulfilled, external data not allowed.", inst)); return new List<OHLCBar>(); } _logger.Log(LogLevel.Info, string.Format("Request for all external data on instrument {0}", inst)); return ExternalDataSource.GetAllData(inst); }
/// <summary> /// Use prior positions data to fill missing data from external source /// </summary> private void SupplementWithLocalData(Instrument inst, DateTime startTime, DateTime endTime, ref List<OHLCBar> data) { //lacks data before if(data.First().DT.Date > startTime.Date) { var localData = GetLocalData(inst, startTime, data.First().DT.AddDays(-1).Date); data.AddRange(localData); } //lacks data after if(data.Last().DT.Date < endTime.Date) { var localData = GetLocalData(inst, data.Last().DT.AddDays(1).Date, endTime); data.AddRange(localData); } data = data.Distinct((x,y) => x.DT.Date == y.DT.Date).OrderBy(x => x.DT).ToList(); }
public void CapitalUsageIsAverageOfPositions() { _t.Orders.Add(new Order { Quantity = 10, Instrument = _inst, Price = 100, FXRateToBase = 1, BuySell = "BUY", TradeDate = new DateTime(2000, 1, 1), Currency = new Currency { Name = "USD" } }); var inst2 = new Instrument { ID = 2, Multiplier = 1, AssetCategory = AssetClass.Stock }; _t.Orders.Add(new Order { Quantity = 20, Instrument = inst2, Price = 100, FXRateToBase = 1, BuySell = "BUY", TradeDate = new DateTime(2000, 1, 1), Currency = new Currency { Name = "USD" } }); _repository.UpdateStats(_t, true); Assert.AreEqual(10 * 100 + 20 * 100, _t.CapitalTotal); }
private static Instrument TryAddAndGetCurrencyInstrument(Order order, IDBContext context) { var instrument = context .Instruments .FirstOrDefault(x => x.AssetCategory == AssetClass.Cash && x.Symbol == order.SymbolString); if (instrument != null) return instrument; //it's already in the DB, no need to add it //otherwise construct a new instrument, add it, and return it. instrument = new Instrument { Symbol = order.SymbolString, UnderlyingSymbol = order.SymbolString, Description = order.SymbolString, ConID = order.ConID, AssetCategory = AssetClass.Cash, Multiplier = 1 }; context.Instruments.Add(instrument); context.SaveChanges(); return instrument; }
public void CapitalUsageCorrectlyTracked() { var inst2 = new Instrument { ID = 2, Multiplier = 1, AssetCategory = AssetClass.Stock }; var order1 = new Order { Instrument = _inst, InstrumentID = _inst.ID, Multiplier = 1, FXRateToBase = 1, Price = 10, Quantity = 100, CurrencyID = 1, BuySell = "BUY", IsReal = true, TradeDate = new DateTime(2000, 1, 2) }; var order2 = new Order { Instrument = inst2, InstrumentID = inst2.ID, Multiplier = 1, FXRateToBase = 1, Price = 20, Quantity = -100, CurrencyID = 1, BuySell = "SELL", IsReal = true, TradeDate = new DateTime(2000, 1, 3, 12, 0, 0) }; var order3 = new Order { Instrument = inst2, InstrumentID = inst2.ID, Multiplier = 1, FXRateToBase = 1, Price = 19, Quantity = 100, CurrencyID = 1, BuySell = "BUY", IsReal = true, TradeDate = new DateTime(2000, 1, 3, 13, 0, 0) }; var trade = new Trade { Orders = new List<Order> { order1, order2, order3 } }; var trades = new List<Trade> { trade }; _data = new Dictionary<int, TimeSeries> { { 1, TimeSeriesGenerator.GenerateData(new DateTime(2000,1,1), new DateTime(2000,2,1), 11) }, { 2, TimeSeriesGenerator.GenerateData(new DateTime(2000,1,1), new DateTime(2000,2,1), 20) } }; var tracker = new PortfolioTracker(_data, _fxData, trades, "test", new DateTime(2000, 1, 1), 1); var date = new DateTime(2000, 1, 1); foreach (TimeSeries ts in _data.Values) { ts.ProgressTo(date); } tracker.ProcessItemsAt(date); tracker.OnDayClose(date, 10000); Assert.AreEqual(0, tracker.Capital.Gross.Last()); date = date.AddDays(1); foreach (TimeSeries ts in _data.Values) { ts.ProgressTo(date); } tracker.ProcessItemsAt(date); tracker.OnDayClose(date, 10000); Assert.AreEqual(10 * 100, tracker.Capital.Gross.Last()); Assert.AreEqual(10 * 100, tracker.Capital.Long.Last()); date = date.AddDays(1); foreach (TimeSeries ts in _data.Values) { ts.ProgressTo(date); } tracker.ProcessItemsAt(date); tracker.OnDayClose(date, 10000); Assert.AreEqual(11 * 100 + 20 * 100, tracker.Capital.Gross.Last()); Assert.AreEqual(11 * 100, tracker.Capital.Long.Last()); Assert.AreEqual(20 * 100, tracker.Capital.Short.Last()); }
public void CashInstrumentLocalRequestsUseFxRates() { DateTime startDate = new DateTime(2000, 1, 1); DateTime endDate = new DateTime(2000, 1, 3); var inst = new Instrument { ID = 1, Symbol = "EUR.USD", AssetCategory = AssetClass.Cash, QDMSInstrumentID = 2 }; var fxrSetStub = new DbSetStub<FXRate>(); var currencySetStub = new DbSetStub<Currency>(); currencySetStub.Add(new Currency { ID = 2, Name = "EUR" }); _contextMock.Setup(x => x.Currencies).Returns(currencySetStub); _contextMock.Setup(x => x.FXRates).Returns(fxrSetStub); _externalSourceMock.Setup( x => x.GetData(It.IsAny<Instrument>(), It.IsAny<DateTime>(), It.IsAny<DateTime>(), It.IsAny<BarSize>())) .Returns(new List<OHLCBar>()); _datasourcer.GetData(inst, startDate, endDate); _contextMock.Verify(x => x.FXRates); }
private List<OHLCBar> GetInstrumentFxRatesData(Instrument instrument, DateTime fromDate, DateTime toDate) { if(instrument.AssetCategory != AssetClass.Cash) throw new Exception("Wrong asset class."); string[] splitSymbol = instrument.Symbol.Split(".".ToCharArray()); string fxCurrencyName = splitSymbol[0] == "USD" ? splitSymbol[1] : splitSymbol[0]; var currency = Context.Currencies.FirstOrDefault(x => x.Name == fxCurrencyName); if (currency == null) throw new Exception(string.Format("Currency {0} not found.", fxCurrencyName)); //Some currencies are in the format X.USD, others in format USD.X //The latter need to be inverted because all fx rates are given in X.USD bool invert = splitSymbol[0] == "USD"; var prices = Context .FXRates .Where(x => x.FromCurrencyID == currency.ID && x.Date >= fromDate && x.Date <= toDate) .OrderBy(x => x.Date) .Select(p => new {p.Date, Price = invert ? 1m / p.Rate : p.Rate}) .ToList(); _logger.Log(LogLevel.Info, string.Format("Retrieved {0} data points for instrument {1} from fx rates.", prices.Count, instrument)); return prices .Select( p => new OHLCBar { Open = p.Price, High = p.Price, Low = p.Price, Close = p.Price, AdjOpen = p.Price, AdjHigh = p.Price, AdjLow = p.Price, AdjClose = p.Price, DT = p.Date }) .ToList(); }
private decimal? GetLocalLastPriorPositionPrice(Instrument inst, out decimal fxRate, out DateTime date) { var pos = Context.PriorPositions.Where(x => x.InstrumentID == inst.ID).OrderByDescending(x => x.Date).FirstOrDefault(); if (pos == null) { _logger.Log(LogLevel.Error, "Could not find any local data on instrument " + inst.ToString()); fxRate = 1; date = DateTime.Now; return null; } fxRate = pos.FXRateToBase; date = pos.Date; return pos.Price; }
private List<OHLCBar> GetLocalData(Instrument instrument, DateTime fromDate, DateTime toDate) { try { if (instrument.AssetCategory == AssetClass.Cash) { return GetInstrumentFxRatesData(instrument, fromDate, toDate); } else { return GetPriorPositionsData(instrument, fromDate, toDate); } } catch(Exception ex) { _logger.Error(ex, string.Format("Exception on requesting data for instrument {0}", instrument)); return new List<OHLCBar>(); } }
private decimal? GetLocalLastFxRatePrice(Instrument instrument, out decimal fxRate, out DateTime date) { if (instrument.AssetCategory != AssetClass.Cash) throw new Exception("Wrong asset class."); fxRate = 1; string[] splitSymbol = instrument.Symbol.Split(".".ToCharArray()); string fxCurrencyName = splitSymbol[0] == "USD" ? splitSymbol[1] : splitSymbol[0]; var currency = Context.Currencies.FirstOrDefault(x => x.Name == fxCurrencyName); if (currency == null) throw new Exception(string.Format("Currency {0} not found.", fxCurrencyName)); //Some currencies are in the format X.USD, others in format USD.X //The latter need to be inverted because all fx rates are given in X.USD bool invert = splitSymbol[0] == "USD"; var price = Context .FXRates .Where(x => x.FromCurrencyID == currency.ID) .OrderByDescending(x => x.Date) .FirstOrDefault(); if (price == null) { _logger.Log(LogLevel.Error, "Could not find any local data on instrument " + instrument.ToString()); date = DateTime.Now; return null; } date = price.Date; return invert ? 1m / price.Rate : price.Rate; }
public void SetUp() { _data = new Dictionary<int, TimeSeries>(); _fxData = new Dictionary<int, TimeSeries>(); _inst = new Instrument { ID = 1, Multiplier = 1, AssetCategory = AssetClass.Stock }; }
public void IfExternalSourceHasNoDataLocalBackupIsUsedInstead() { DateTime startDate = new DateTime(2000, 1, 1); DateTime endDate = new DateTime(2000, 2, 1); var inst = new Instrument { ID = 1, Symbol = "SPY", AssetCategory = AssetClass.Stock, QDMSInstrumentID = 2}; var ppSetStub = new DbSetStub<PriorPosition>(); _contextMock.Setup(x => x.PriorPositions).Returns(ppSetStub); _externalSourceMock.Setup( x => x.GetData(It.IsAny<Instrument>(), It.IsAny<DateTime>(), It.IsAny<DateTime>(), It.IsAny<BarSize>())) .Returns(new List<OHLCBar>()); _datasourcer.GetData(inst, startDate, endDate); _externalSourceMock.Verify(x => x.GetData( It.IsAny<Instrument>(), It.IsAny<DateTime>(), It.IsAny<DateTime>(), It.IsAny<BarSize>())); _contextMock.Verify(x => x.PriorPositions); }