public static ExcelCalcWrapper CreateCancellable <TResult>(Func <CancellationToken, Action <double>, TResult> calculation) { var cancellationTokenSource = new CancellationTokenSource(); Type resultType = typeof(TResult); var calcTaskWrapper = new ExcelCalcWrapper(null, resultType, cancellationTokenSource); void OnProgress(double progress) => UpdateProgress(calcTaskWrapper, progress); calcTaskWrapper.CalcTask = Task.Run(() => (object)calculation(cancellationTokenSource.Token, OnProgress), cancellationTokenSource.Token); calcTaskWrapper.CalcTask.ContinueWith(task => calcTaskWrapper.UpdateStatus(task), cancellationTokenSource.Token); return(calcTaskWrapper); }
Category = AddIn.ExcelFunctionCategory, IsThreadSafe = false, IsVolatile = false, IsExceptionSafe = true)] // TODO turn IsThreadSafe to true and use ConcurrentDictionary? public static object SubscribeResultProperty(string objectHandle, string propertyName, object returnedWhilstWaiting) { return(StorageExcelHelper.ExecuteExcelFunction(() => { const string functionName = nameof(SubscribeResultProperty); return ExcelAsyncUtil.Observe(functionName, new [] { objectHandle, propertyName, returnedWhilstWaiting }, () => { ExcelCalcWrapper wrapper = _calcWrappers[objectHandle]; var excelObservable = new CalcWrapperResultPropertyObservable(wrapper, propertyName, returnedWhilstWaiting); return excelObservable; }); })); }
Category = AddIn.ExcelFunctionCategory, IsThreadSafe = false, IsVolatile = false, IsExceptionSafe = true)] // TODO turn IsThreadSafe to true and use ConcurrentDictionary? public static object SubscribeStatus(string name) { return(StorageExcelHelper.ExecuteExcelFunction(() => { const string functionName = nameof(SubscribeStatus); return ExcelAsyncUtil.Observe(functionName, name, () => { ExcelCalcWrapper wrapper = _calcWrappers[name]; var excelObserver = new CalcWrapperStatusObservable(wrapper); return excelObserver; }); })); }
protected CalcWrapperObservableBase(ExcelCalcWrapper calcWrapper) { _calcWrapper = calcWrapper; _calcWrapper.CalcTask.ContinueWith(task => { if (task.IsFaulted) // TODO what about cancelled { _observer?.OnError(task.Exception.InnerException); } else { _observer?.OnCompleted(); } }); }
public CalcWrapperResultPropertyObservable(ExcelCalcWrapper calcWrapper, string resultPropertyName, object returnedWhilstWaiting) : base(calcWrapper) { PropertyInfo[] properties = calcWrapper.ResultType.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.GetProperty); PropertyInfo propertyInfo = properties.FirstOrDefault(info => info.Name.Equals(resultPropertyName, StringComparison.OrdinalIgnoreCase)); if (propertyInfo == null) { throw new ArgumentException($"Result type {calcWrapper.ResultType.Name} has not public instance property called {resultPropertyName}."); // TODO test and maybe rework } _propertyGetter = propertyInfo.GetMethod; _returnedWhilstWaiting = returnedWhilstWaiting; calcWrapper.CalcTask.ContinueWith(task => { if (task.Status == TaskStatus.RanToCompletion) { PropertyValueUpdate(); } }); }
public CalcWrapperProgressObservable(ExcelCalcWrapper calcWrapper) : base(calcWrapper) => _calcWrapper.OnProgressUpdate += ProgressUpdate;
public CalcWrapperStatusObservable(ExcelCalcWrapper calcWrapper) : base(calcWrapper) => calcWrapper.CalcTask.ContinueWith(task => TaskStatusUpdate(_calcWrapper.Status));
Category = AddIn.ExcelFunctionCategory, IsThreadSafe = false, IsVolatile = false, IsExceptionSafe = true)] // TODO turn IsThreadSafe to true and use ConcurrentDictionary? public static object StorageValueThreeFactor( [ExcelArgument(Name = "Name", Description = "Name of cached object to create.")] string name, [ExcelArgument(Name = ExcelArg.StorageHandle.Name, Description = ExcelArg.StorageHandle.Description)] string storageHandle, [ExcelArgument(Name = ExcelArg.ValDate.Name, Description = ExcelArg.ValDate.Description)] DateTime valuationDate, [ExcelArgument(Name = ExcelArg.Inventory.Name, Description = ExcelArg.Inventory.Description)] double currentInventory, [ExcelArgument(Name = ExcelArg.ForwardCurve.Name, Description = ExcelArg.ForwardCurve.Description)] object forwardCurve, [ExcelArgument(Name = ExcelArg.InterestRateCurve.Name, Description = ExcelArg.InterestRateCurve.Description)] object interestRateCurve, [ExcelArgument(Name = ExcelArg.SpotVol.Name, Description = ExcelArg.SpotVol.Description)] double spotVol, [ExcelArgument(Name = ExcelArg.SpotMeanReversion.Name, Description = ExcelArg.SpotMeanReversion.Description)] double spotMeanReversion, [ExcelArgument(Name = ExcelArg.LongTermVol.Name, Description = ExcelArg.LongTermVol.Description)] double longTermVol, [ExcelArgument(Name = ExcelArg.SeasonalVol.Name, Description = ExcelArg.SeasonalVol.Description)] double seasonalVol, [ExcelArgument(Name = ExcelArg.DiscountDeltas.Name, Description = ExcelArg.DiscountDeltas.Description)] bool discountDeltas, [ExcelArgument(Name = ExcelArg.SettleDates.Name, Description = ExcelArg.SettleDates.Description)] object settleDatesIn, [ExcelArgument(Name = ExcelArg.NumSims.Name, Description = ExcelArg.NumSims.Description)] int numSims, [ExcelArgument(Name = ExcelArg.BasisFunctions.Name, Description = ExcelArg.BasisFunctions.Description)] string basisFunctionsIn, [ExcelArgument(Name = ExcelArg.Seed.Name, Description = ExcelArg.Seed.Description)] object seedIn, [ExcelArgument(Name = ExcelArg.ForwardSimSeed.Name, Description = ExcelArg.ForwardSimSeed.Description)] object fwdSimSeedIn, [ExcelArgument(Name = ExcelArg.NumGridPoints.Name, Description = ExcelArg.NumGridPoints.Description)] object numGlobalGridPointsIn, [ExcelArgument(Name = ExcelArg.NumericalTolerance.Name, Description = ExcelArg.NumericalTolerance.Description)] object numericalTolerance, [ExcelArgument(Name = ExcelArg.ExtraDecisions.Name, Description = ExcelArg.ExtraDecisions.Description)] object extraDecisions) { return(StorageExcelHelper.ExecuteExcelFunction(() => { _calcWrappers[name] = ExcelCalcWrapper.CreateCancellable((cancellationToken, onProgress) => { // TODO provide alternative method for interpolating interest rates Func <Day, double> interpolatedInterestRates = StorageExcelHelper.CreateLinearInterpolatedInterestRateFunc(interestRateCurve, ExcelArg.InterestRateCurve.Name); Func <Day, Day, double> discountFunc = StorageHelper.CreateAct65ContCompDiscounter(interpolatedInterestRates); Day valDate = Day.FromDateTime(valuationDate); Func <Day, Day> settleDateRule = StorageExcelHelper.CreateSettlementRule(settleDatesIn, ExcelArg.SettleDates.Name); CmdtyStorage <Day> storage = _storageObjects[storageHandle]; int numGlobalGridPoints = StorageExcelHelper.DefaultIfExcelEmptyOrMissing(numGlobalGridPointsIn, ExcelArg.NumGridPoints.Default, ExcelArg.NumGridPoints.Name); string basisFunctionsText = basisFunctionsIn.Replace("x_st", "x0").Replace("x_lt", "x1").Replace("x_sw", "x2"); var lsmcParamsBuilder = new LsmcValuationParameters <Day> .Builder { Storage = storage, CurrentPeriod = valDate, Inventory = currentInventory, ForwardCurve = StorageExcelHelper.CreateDoubleTimeSeries <Day>(forwardCurve, ExcelArg.ForwardCurve.Name), DiscountFactors = discountFunc, DiscountDeltas = discountDeltas, BasisFunctions = BasisFunctionsBuilder.Parse(basisFunctionsText), ExtraDecisions = StorageExcelHelper.DefaultIfExcelEmptyOrMissing(extraDecisions, 0, ExcelArg.ExtraDecisions.Name), CancellationToken = cancellationToken, OnProgressUpdate = onProgress, GridCalc = FixedSpacingStateSpaceGridCalc.CreateForFixedNumberOfPointsOnGlobalInventoryRange(storage, numGlobalGridPoints), NumericalTolerance = StorageExcelHelper.DefaultIfExcelEmptyOrMissing(numericalTolerance, LsmcValuationParameters <Day> .Builder.DefaultNumericalTolerance, ExcelArg.NumericalTolerance.Description), SettleDateRule = settleDateRule }; // TODO test that this works with expired storage Day endDate = new[] { valDate, storage.EndPeriod }.Max(); var threeFactorParams = MultiFactorParameters.For3FactorSeasonal(spotMeanReversion, spotVol, longTermVol, seasonalVol, valDate, endDate); // TODO better error messages if seedIn and fwdSimSeedIn cannot be cast int?seed = StorageExcelHelper.IsExcelEmptyOrMissing(seedIn) ? (int?)null : (int)(double)seedIn; int?fwdSimSeed = StorageExcelHelper.IsExcelEmptyOrMissing(fwdSimSeedIn) ? (int?)null : (int)(double)fwdSimSeedIn; lsmcParamsBuilder.SimulateWithMultiFactorModelAndMersenneTwister(threeFactorParams, numSims, seed, fwdSimSeed); return LsmcStorageValuation.WithNoLogger.Calculate(lsmcParamsBuilder.Build()); }); return name; })); }
private static void UpdateProgress(ExcelCalcWrapper calcWrapper, double progress) => calcWrapper.UpdateProgress(progress);