protected void RampUp(DateTime date, MarkitSurface marketData) { // Count number of active positions int openPositions = _activePositions.Count(); // Check to see if ramp-up is over. if (openPositions == _simulationParameters.maxNumberInstruments()) { isRampUpPeriod = false; Console.WriteLine("Ramp-up period completed on : {0}", date); return; } // Check if slot is available for new investment if (openPositions < _simulationParameters.maxNumberInstruments()) { // Display Console.WriteLine("Number of positions available for investment: {0}", _simulationParameters.maxNumberInstruments() - openPositions); // Always invest only once in ramp-up period Console.WriteLine("Investing..."); Invest(date, Weight(date), marketData); } // This case should never be reached... means we're above max nb of positions else { throw new ArgumentException("RampUpException", "Ramp up failure."); } }
// ************************************************************ // INVESTMENT // ************************************************************ #region Investment after ramp-up public virtual void Update(DateTime date, MarkitSurface marketData) { Console.WriteLine(" Updating a portfolio of {0} autocalls.", _activePositions.Count()); // Update the cash interest rate _bankAccount.UpdateRate(date, marketData.ShortRate()); // 1. Regarder si on arrive à maturité sur un instrument. // Si oui, se demander si on restrike et dans quelles conditions foreach (KeyValuePair <Guid, AutocallPosition> deriv in _activePositions) { // Case 1 : At Maturity if (deriv.Value.isRedemption(date)) { Event_Maturity(date, deriv, marketData.impliedSpot); } // Case 2 : Not Maturity, but on a coupon date else if (deriv.Value.isRecallDate(date)) { Event_Recall(date, deriv, marketData); } // Case 3 : MtM valuations of existing products else { // Valuation is handle as a single block later // NoEvent(date, deriv, marketData); } } // 2. Clean up the active positions CleanUp(); // 3. Value all remaining products ComputeNPV(date, marketData); // 4. Réinvestir (aux dates de rebalancement) if (_rebalCalendar.Contains(date)) { // Display Console.WriteLine(" >> Rebalancing date detected: {0}.", date); // During ramp-up if (isRampUpPeriod) { Console.WriteLine(" >> Ramp-up period found on {0}.", date); RampUp(date, marketData); } // After ramp-up else { Allocate(date, marketData); } } }
protected void ComputeNPV(DateTime date, MarkitSurface marketData) { Console.WriteLine(" >> Performing valuation for {0} autocalls.", _activePositions.Count()); foreach (KeyValuePair <Guid, AutocallPosition> kvp in _activePositions) { kvp.Value.NPV(date, marketData); } }
// ************************************************************ // METHODS // ************************************************************ // Set current date and data protected void SetLocalData(DateTime pricingDate, MarkitSurface marketData) { if (pricingDate != marketData.informationDate) { Console.WriteLine("Warning : Market data provided does not match pricing date."); } _pricingDate = pricingDate; _currentMarketData = marketData; }
public double Parallel_NPV(DateTime pricingDate, MarkitSurface marketData, IPricingEngine engine) { _instrument.setPricingEngine(engine); double npv = _instrument.NPV(); Console.WriteLine("NPV {0}", npv.ToString("P", System.Globalization.CultureInfo.InvariantCulture)); _NPV[pricingDate] = npv; return(npv); }
// Instrument public myAutocall Instrument(DateTime d, double notional, MarkitSurface marketData) { // Display Console.WriteLine("Creation of a new instrument requested on {0}", d); // Set current date and market data locally SetLocalData(d, marketData); Console.WriteLine("Local data set with information date {0}", marketData.informationDate); // return private method return(GetAutocall(notional: notional)); }
public double NPV(DateTime pricingDate, MarkitSurface marketData) { IPricingEngine engine = helper().Engine(pricingDate, marketData); _instrument.setPricingEngine(engine); double npv = _instrument.NPV(); Console.WriteLine(" >> NPV : {0}", npv); //Console.WriteLine(" >> NPV : {0}", npv.ToString("P", System.Globalization.CultureInfo.InvariantCulture)); _NPV[pricingDate] = npv; return(npv); }
protected void Invest(DateTime date, double notional, MarkitSurface marketData) { // Get a new product for investment on date myAutocall newProduct = _instrumentHelper.Instrument(date, notional, marketData); Console.WriteLine("New autocall product constructed."); // Withdrawing from bank account to fund investment _bankAccount.Transaction(date, -1 * notional); // Add new investment to active positions Guid id = Guid.NewGuid(); _activePositions[id] = new AutocallPosition(newProduct, _instrumentHelper, id); Console.WriteLine("New autocall product added to the active positions under GUID: {0}", id); }
public IPricingEngine Engine(DateTime d, MarkitSurface marketData) { // Get stochastic process var stochasticProcess = GetStochasticProcess(d, marketData); // Set properties IPricingEngine monteCarloEngine = new MakeMCEuropeanAutocallEngine <PseudoRandom>(stochasticProcess) .withSteps(timeSteps()) .withAntitheticVariate(antithetic()) .withBrownianBridge(brownianBridge()) .withSamples(samples()) .withSeed(seed()) .value(); // Apply engine to instrument return(monteCarloEngine); }
protected GeneralizedBlackScholesProcess GetStochasticProcess(DateTime d, MarkitSurface marketData) { // Spot level Handle <Quote> spotLevel = new Handle <Quote>(new SimpleQuote(marketData.impliedSpot)); // Risk free rate (term structure) Handle <YieldTermStructure> riskFreeTS = marketData.riskFree_FwdCrv(); // Dividend yield (term structure) Handle <YieldTermStructure> dividendTS = marketData.dividend_FwdCrv(); // Volatility ATM Forward (term structure) BlackVarianceCurve atmf_vol_curve = marketData.ATMF_Vol_TS(d); Handle <BlackVolTermStructure> volatilityTS = new Handle <BlackVolTermStructure>(atmf_vol_curve); // Return return(new GeneralizedBlackScholesProcess(spotLevel, dividendTS, riskFreeTS, volatilityTS)); }
protected void Allocate(DateTime date, MarkitSurface markitSurface) { // Count number of active positions int openPositions = _activePositions.Count(); // Compute the weight double weight = Weight(date); // Check if slot is available for new investment if (openPositions < _simulationParameters.maxNumberInstruments()) { // Count the number of slots available int newInvestments = _simulationParameters.maxNumberInstruments() - openPositions; for (int k = 0; k < newInvestments; k++) { Invest(date, weight, markitSurface); } } }
protected void Parallel_ComputeNPV(DateTime date, MarkitSurface marketData) { int k = 1; Console.WriteLine("Parallel Update of the NPV called:"); List <AutocallPosition> positions = _activePositions.Values.ToList(); Console.WriteLine(" >> Found {0} positions in portfolio.", _activePositions.Count()); if (_activePositions.Count() > 0) { Parallel.ForEach(positions, (pos) => // foreach (KeyValuePair<Guid, AutocallPosition> kvp in _activePositions) { Console.WriteLine(" >> Computing NPV for position: {0}", k); IPricingEngine engine = _instrumentHelper.Engine(date, marketData); pos.Parallel_NPV(date, marketData, engine); }); } }
// ************************************************************ // CORE SIMULATION // ************************************************************ #region Core simulation methods public void Run() { int totalObs = observations(); _strategy.Initialize(_parameters.startDate()); for (int i = 0; i <= totalObs; i++) { // Determine current date Date currentDate = _parameters.calendar().adjust(_parameters.startDate().AddDays(i), _parameters.businessDayConvention()); DateTime currentDateTime = new DateTime(currentDate.year(), currentDate.month(), currentDate.Day); DisplayNewSimulationDate(currentDate); MarkitSurface markitSurface = _database[currentDateTime]; Console.WriteLine("Market data found. Starting update..."); _strategy.Update(currentDate, markitSurface); } Console.WriteLine("Simualtion completed."); }
protected void Event_Recall(DateTime date, KeyValuePair <Guid, AutocallPosition> kvp, MarkitSurface marketData) { double spot = marketData.impliedSpot; // No recall on this recall (observation) date if (!kvp.Value.isRecall(spot, date)) { NoEvent(date, kvp, marketData); } // At this point the instrument is being recalled double pmt = 0.0; pmt = kvp.Value.RecallPayment(spot, date); // Adding the cash to the bank account _bankAccount.Transaction(date, pmt); // Close position kvp.Value.Close(date, pmt, true, true); // Add to the list of positions to be terminated _positionsToBeClosed.Add(kvp.Key); }
// ************************************************************ // EVENTS HANDLING // ************************************************************ #region Events handling (coupons, maturity, etc.) protected void NoEvent(DateTime date, KeyValuePair <Guid, AutocallPosition> kvp, MarkitSurface marketData) { kvp.Value.NPV(date, marketData); }