/* Excercise all options at the end of the day */ public static void ExcerciseGasOptions(TradeSet sourcePF) { DateTime marketDate = sourcePF.MarketDate; IEnumerable<Tradelet> tradelets = sourcePF._trades.Values.SelectMany(k => k.tradelets.Values) .Where(k => k.MyTrade.isOption && k.DelStart > marketDate); // > tradeDate removes many possibilities: speed improvement Dictionary<DateTime, DateTime> exDates; double price; Product prod; Trade trade; Trade exercTrade; int signExcerTrade = 0; foreach (Tradelet tlet in tradelets.ToList()) { trade = tlet.MyTrade; prod = trade.MyProduct; exDates = TradingCenter.TCEachTenor(trade.OptionTenorType, tlet.DelStart, tlet.DelEnd).Select(k => new KeyValuePair<DateTime, DateTime>(k, prod.TC.GetGasOptExDate(trade.OptionTenorType, k, trade._instrument.isExchange))).ToDictionary(k => k.Key, k => k.Value); foreach (DateTime day in exDates.Keys) { price = prod.ReturnCurveSeries().GetValue(trade.OptionTenorType, day, marketDate); if (trade.OptionType == OPTION_TYPE.PUT && trade.Strike > price) { trade.isExcercised = true; signExcerTrade = -1; } else if (trade.OptionType == OPTION_TYPE.CALL && trade.Strike < price) { trade.isExcercised = true; signExcerTrade = 1; } else { trade.isExpired = true; } exercTrade = new Trade() { DealID = sourcePF.MyTradeCollection.CreateFakeID(), TradeDate = marketDate, Volume = signExcerTrade * trade.Volume, Price = trade.Strike, UnitName = prod.UnitName, CCY = prod.CCY, ProductName = prod.Name, MyProduct = prod, DelStart = day, DelEnd = TradingCenter.TCTenorSelector(day, trade.OptionTenorType, 1).AddDays(-1), exerciseTrade = trade, OptionID = trade.OptionID}; sourcePF._trades.Add(exercTrade.DealID, exercTrade); } } }
/* No trade-by trade PnL, monthly hedging + DA & BoM for dailies. BoM = average price for rest of month, not a 'real BoM' price */ public static TradeSet PerfectMonthlyHedge(TradeSet sourcePF) { /* original trades are prices, add new hedges and price them [PnL will be zero, but we need position] */ // @@@ A) just add new trades ... slower but who cares :-) // add accumulate exposure and create opposite trade // IEnumerable<IGrouping<DateTime, Tradelet>> monthlyTradeletGroups = sourcePF._trades.Values.SelectMany(k => k.tradelets.Values).GroupBy(k => k.FirstMonth); TradeSet newPF = sourcePF.CloneTradeSet(); // either newPF or alternatively remove replace trades from previous ... but we clone it anyway? here we can look at single optiones as well ... hm :( // now : just add ONE trade into the newPF and think about everything else later DateTime marketDate = sourcePF.MarketDate; DateTime runDate = DateTime.MinValue; Trade newTrade; Product prod; CurveSeries curves; TradingCenter tc; int runTenorType; double deltaExpo; double price; Dictionary<DateTime, object[]> hedgeGran; // @@@ <del start: del start, del end, granularity foreach (string productName in sourcePF.ProductNames) // @@@ replace location with productname, don't mix stuff up { prod = DynamicData.GetProduct(productName); curves = prod.ReturnCurveSeries(); tc = prod.TC; runTenorType = TENOR_TYPE.DAY; foreach (DateTime delDay in TradingCenter.TCEachDay(marketDate.AddDays(1), tc.reqNextBD(marketDate))) // here single trades and below BOM? well yes, that is the liquidity ide ... to improve and generalize { runDate = delDay; price = curves.GetValue(runTenorType, delDay, marketDate); deltaExpo = sourcePF.GetExposure(EXPOSURE_TYPE.DELTA, runTenorType, productName, delDay); newTrade = new Trade() { DealID = sourcePF.MyTradeCollection.CreateFakeID(), TradeDate = marketDate, Volume = prod.UnitSet.ToStandardSize(-1 * deltaExpo, 1), Price = price, UnitName = prod.UnitName, CCY = prod.CCY, ProductName = prod.Name, MyProduct = prod, DelStart = delDay, DelEnd = TradingCenter.TCTenorSelector(delDay, runTenorType, 1).AddDays(-1)}; newTrade.PriceTrade(marketDate); newPF._trades.Add(newTrade.DealID, newTrade); } // loop till next Month >> create a single BoM trade; @@@ ultimatively, create hedge calendar <startDate, endDate, Granularity>: groups which are priced and hedged as once @@@ but finish simple version first! DateTime delStart = runDate.AddDays(1); DateTime delEnd = TradingCenter.TCTenorSelector(runDate, TENOR_TYPE.MONTH, 1).AddDays(-1); runDate = delEnd; if (delEnd >= delStart) { List<DateTime> bomDates = TradingCenter.TCEachDay(delStart, delEnd).ToList(); price = bomDates.Select(k => curves.GetValue(runTenorType, k, marketDate)).Average(); deltaExpo = bomDates.Select(k => sourcePF.GetExposure(EXPOSURE_TYPE.DELTA, runTenorType, productName, k)).Sum(); newTrade = new Trade() { DealID = sourcePF.MyTradeCollection.CreateFakeID(), TradeDate = marketDate, Volume = prod.UnitSet.ToStandardSize(-1 * deltaExpo, 1), Price = price, UnitName = prod.UnitName, CCY = prod.CCY, ProductName = prod.Name, MyProduct = prod, DelStart = delStart, DelEnd = delEnd}; newTrade.PriceTrade(marketDate); newPF._trades.Add(newTrade.DealID, newTrade); } runTenorType = TENOR_TYPE.MONTH; foreach (DateTime delDay in TradingCenter.TCEachTenor(runTenorType, runDate.AddDays(1), sourcePF.GetLastDelDate(productName))) { price = curves.GetValue(runTenorType, delDay, marketDate); deltaExpo = sourcePF.GetExposure(EXPOSURE_TYPE.DELTA, runTenorType, productName, delDay); newTrade = new Trade() { DealID = sourcePF.MyTradeCollection.CreateFakeID(), TradeDate = marketDate, Volume = prod.UnitSet.ToStandardSize(-1 * deltaExpo, TradingCenter.TCTenorSelector(delDay, runTenorType, 1).AddDays(-1).Day), Price = price, UnitName = prod.UnitName, CCY = prod.CCY, ProductName = prod.Name, MyProduct = prod, DelStart = delDay, DelEnd = TradingCenter.TCTenorSelector(delDay, runTenorType, 1).AddDays(-1)}; //@@@ add default portfolio? hm... newTrade.PriceTrade(marketDate); newPF._trades.Add(newTrade.DealID, newTrade); } } return newPF; }
public Tradelet(int tradeletID, Trade myTrade, DateTime delStart, DateTime delEnd) { this.TradeletID = tradeletID; this.MyTrade = myTrade; this.DelStart = delStart; this.DelEnd = delEnd; FirstMonth = TradingCenter.TCTenorSelector(DelStart, TENOR_TYPE.MONTH); }