public List <DateAndStandardDeviations> GetStandardDeviationsForDates(IBasicPredictionCalculationData data, IReadOnlyList <DateAndNumberOfDaysUntil> referencePoints, IReadOnlyList <double> deviations) { const int numberOfPointsBetween = 4; DateAndNumberOfDaysUntil expirationDateForToday = _marketWorkTimeService.GetNumberOfDaysLeftUntilExpiry(_marketWorkTimeService.NowInMarketTimeZone.Date); List <DateAndNumberOfDaysUntil> experies = referencePoints.Union(expirationDateForToday.Yield()).Distinct().OrderBy(t => t.FutureDate).ToList(); List <DateAndNumberOfDaysUntil> dates = new List <DateAndNumberOfDaysUntil>(experies); for (int i = 0; i < experies.Count - 1; i++) { DateAndNumberOfDaysUntil current = experies[i]; DateAndNumberOfDaysUntil next = experies[i + 1]; double range = next.TotalNumberOfDaysUntilExpiry - current.TotalNumberOfDaysUntilExpiry; if (range < 3) { continue; } double step = Math.Round(range / numberOfPointsBetween, 3, MidpointRounding.AwayFromZero); // uniformly inserts points between current date and next date. IEnumerable <int> increments = CollectionExtensions.Range(0, range - step, step).Where(d => (int)d != 0).Select(d => (int)d).Distinct(); foreach (int increment in increments) { DateTime date = current.FutureDate.AddDays(increment); dates.Add(_marketWorkTimeService.GetNumberOfDaysLeftUntilExpiry(date)); } } List <DateAndNumberOfDaysUntil> datesToBuildPredictionFor = dates.OrderBy(e => e.FutureDate).ToList(); Dictionary <DateAndNumberOfDaysUntil, Prediction> predictions = MakePredictionsForDates(data, datesToBuildPredictionFor); List <DateAndStandardDeviations> stdDevs = GetStandardDeviationsForDates(data, predictions, deviations); return(stdDevs); }
public List <BasePortfolioItemGroupViewModel> GetPortfolioData(string customerCode, string accountCode, string tradeAccount) { #region Fetch data OptionPositionsArguments arguments = new OptionPositionsArguments { CustomerCode = customerCode, CustomerAccountCode = accountCode }; EntityResponse <List <OptionPositionInformation> > optionPositions = _portfolioManager.GetOptionPositions(arguments); EntityResponse <List <OptionableStockPositionInformation> > stockPositions = _portfolioManager.GetOptionalStockPositions(customerCode, accountCode, tradeAccount); if (!optionPositions.IsSuccess || !stockPositions.IsSuccess || optionPositions.Entity.Count == 0) { return(new List <BasePortfolioItemGroupViewModel>()); } IEnumerable <PortfolioOption> portfolioOptions = Mapper.Map <List <OptionPositionInformation>, List <PortfolioOption> >(optionPositions.Entity); IEnumerable <PortfolioStock> portfolioStocks = Mapper.Map <List <OptionableStockPositionInformation>, List <PortfolioStock> >(stockPositions.Entity); Dictionary <string, EntityResponse <OptionChain> > optionChains = new Dictionary <string, EntityResponse <OptionChain> >(); #endregion #region Fill additional information foreach (PortfolioOption portfolioItem in portfolioOptions) { EntityResponse <List <OptionBasicInformation> > optionBasicInformation = _marketDataProviderQueryable.GetOptionBasicInformation(optionNumber: portfolioItem.OptionNumber); if (optionBasicInformation.Entity == null || !optionBasicInformation.Entity.Any()) { continue; } OptionBasicInformation basicInfo = optionBasicInformation.Entity.Single(); DateTime expiryDate = basicInfo.ExpireDate; DateAndNumberOfDaysUntil expiry = _marketWorkTimeService.GetNumberOfDaysLeftUntilExpiry(expiryDate); portfolioItem.Expiry = expiry; portfolioItem.UnderlyingCode = basicInfo.OptionUnderlyingCode; portfolioItem.UnderlyingName = basicInfo.OptionUnderlyingName; portfolioItem.StrikePrice = basicInfo.StrikePrice; EntityResponse <OptionChain> optionChain; string underlying = portfolioItem.UnderlyingCode; if (optionChains.ContainsKey(underlying)) { optionChain = optionChains[underlying]; } else { optionChain = _marketDataService.GetOptionChain(underlying); optionChains.Add(underlying, optionChain); } if (optionChain == null) { continue; } Option option = optionChain.Entity[portfolioItem.OptionNumber]; if (option == null) { portfolioItem.UnderlyingCode = null; continue; } Greeks greeks = option.Greeks ?? new Greeks(); portfolioItem.LastPrice = (decimal)option.LatestTradedPrice; //optionChain.Entity.UnderlyingCurrentPrice; portfolioItem.PremiumMultiplier = option.RootPair.PremiumMultiplier; portfolioItem.Greeks = new PortfolioGreeks(portfolioItem.OptionAvailableQuantity, greeks, portfolioItem.OptionSide, portfolioItem.PremiumMultiplier); } portfolioOptions = portfolioOptions.Where(x => x.UnderlyingCode != null); foreach (PortfolioStock portfolioStock in portfolioStocks) { SecurityQuotation quote = _marketDataService.GetSecurityQuotation(portfolioStock.SecurityCode); portfolioStock.LastPrice = quote.LastPrice; portfolioStock.StockMarketValue = quote.LastPrice * portfolioStock.AvailableBalance; portfolioStock.Greeks = new PortfolioGreeks(portfolioStock.AdjustedAvailableQuantity, new Greeks() { Delta = 1 }, portfolioStock.OptionSide, 1); } #endregion IEnumerable <BasePortfolioItemGroup> groupedByStrategies = _strategyService.GetPortfolioItemsGroupedByStrategy(portfolioOptions, portfolioStocks); List <BasePortfolioItemGroupViewModel> result = Mapper.Map <IEnumerable <BasePortfolioItemGroup>, IEnumerable <BasePortfolioItemGroupViewModel> >(groupedByStrategies) .ToList(); return(result); }
public EntityResponse <OptionChain> GetOptionChain(string underlying) { EntityResponse <StockQuoteInfo> stockQuote = GetStockQuote(underlying); if (!stockQuote.IsSuccess) { return(EntityResponse <OptionChain> .Error(stockQuote)); } EntityResponse <List <OptionBasicInformation> > optionBasicInformationResponse = _marketDataProvider.GetOptionBasicInformation(underlying); if (!optionBasicInformationResponse.IsSuccess) { return(EntityResponse <OptionChain> .Error(optionBasicInformationResponse)); } double interestRate = _riskFreeRateProvider.GetRiskFreeRate(); decimal spotPrice = stockQuote.Entity.LastPrice == 0 ? (stockQuote.Entity.PreviousClose ?? 0) : (stockQuote.Entity.LastPrice ?? 0); //filtering OptionBasicInformation and get all not expired DateTime nowInmarketTimeZone = _marketWorkTimeService.NowInMarketTimeZone.Date; List <OptionBasicInformation> optionsBasicInformation = optionBasicInformationResponse.Entity .Where(item => item.ExpireDate.Date >= nowInmarketTimeZone.Date) .ToList(); List <string> optionNumbers = optionsBasicInformation.Select(item => item.OptionNumber).Distinct().ToList(); EntityResponse <List <OptionQuotation> > optionQuotesResponse = GetOptionQuotesByOptionNumbers(optionNumbers); if (!optionQuotesResponse.IsSuccess) { return(EntityResponse <OptionChain> .Error(optionQuotesResponse)); } // To filter the optionBasicInformation Dictionary <string, OptionQuotation> optionQuotesDict = new Dictionary <string, OptionQuotation>(); foreach (OptionQuotation itemOptionQuotation in optionQuotesResponse.Entity) { optionQuotesDict.Add(itemOptionQuotation.OptionNumber, itemOptionQuotation); } if (!MemoryCache.IsOptionChainCacheExpired(underlying)) { // memory cache working. MemoryCache.OptionChainCache[underlying].OptionChains.UpdateQuotation((double)spotPrice, interestRate, optionQuotesResponse.Entity); return(MemoryCache.OptionChainCache[underlying].OptionChains); } // todo: 4 requests here. Big problem with performance SecurityInformationCache securityInfo = _marketDataProvider .GetAllSecuritiesInformation().FirstOrDefault(s => s.SecurityCode == underlying); if (securityInfo == null) { return(ErrorCode.SZKingdomLibraryNoRecords); } HashSet <OptionPair> chains = new HashSet <OptionPair>(); foreach (OptionBasicInformation optionBasicInformation in optionsBasicInformation) { // Filter the option if the quotation of the specified options cannot be found if (!optionQuotesDict.ContainsKey(optionBasicInformation.OptionNumber)) { continue; } DateAndNumberOfDaysUntil expiry = _marketWorkTimeService .GetNumberOfDaysLeftUntilExpiry(optionBasicInformation.ExpireDate); OptionPair pair = new OptionPair { Expiry = expiry, StrikePrice = (double)optionBasicInformation.StrikePrice, PremiumMultiplier = optionBasicInformation.OptionUnit, SecurityCode = optionBasicInformation.OptionUnderlyingCode, SecurityName = optionBasicInformation.OptionUnderlyingName }; if (!chains.Contains(pair)) { chains.Add(pair); } else { pair = chains.Single(c => c.Equals(pair)); } Option op = new Option(pair, optionBasicInformation.OptionNumber, optionBasicInformation.OptionCode) { Name = optionBasicInformation.OptionName, OptionName = optionBasicInformation.OptionName, OpenInterest = optionBasicInformation.UncoveredPositionQuantity, SecurityCode = optionBasicInformation.OptionUnderlyingCode, PreviousClose = (double)optionBasicInformation.PreviousClosingPrice, Greeks = new Greeks() }; if (optionBasicInformation.OptionType == OptionType.Call) { op.LegType = LegType.Call; pair.CallOption = op; } else { op.LegType = LegType.Put; pair.PutOption = op; } } OptionChain chain = new OptionChain(chains, (double)spotPrice, interestRate, optionQuotesResponse.Entity); MemoryCache.AddOrUpdateOptionChainCache(underlying, chain); return(chain); }