/** * Create a simulated asset from a real one. * It extract the name of real asset for "fake" one * and the first price (at first date) and simulate * at all dates from dates_simul. * * getPrice(t) with t from dates_simul will then return * a simulated price * getPrice(t) with t before first date from dates_simul * will return real price of asset * getPrice(t) with all others date will throw exception **/ public AssetSimulated(IAsset real, LinkedList<DateTime> dates_simul, RandomNormal rand) { this.real = real; prices = new Dictionary<DateTime, double>(); first_date = dates_simul.First(); r = 0.04; //real.getCurrency().getInterestRate(first_date, TimeSpan.Zero); // TODO //sigma = real.getVolatility(first_date); sigma = 0.2; // debug kevin double St = 75 + 50*rand.NextDouble(); DateTime lastDate = first_date; //double S0 = real.getPrice(first_date); int i = 0; foreach (DateTime date in dates_simul) { double T = (date - lastDate).TotalDays / 365; // time in year double WT = Math.Sqrt(T) * rand.NextNormal(); St = St * Math.Exp((r - sigma * sigma / 2) * T + sigma * WT); prices[date] = St; lastDate = date; i++; } }
public CurrencySimulated(Currencies cur_enum, RandomNormal rand, double r) { this.cur_enum = cur_enum; this.r = r; this.rforeign = 0.01 + 0.05 * rand.NextDouble(); this.sigma = 0.1; this.lastPrice = 1; this.lastDate = DateTime.MinValue; this.rand = rand; this.prices = new Dictionary<DateTime, double>(); }
/** * recalculate everglades price and hedging portfolio on the firstDate -> Today period * with a date every step, with currency management if with_currency is true */ public void simulateBackTestEvolution(bool with_currency, DateTime firstDate, DateTime DateEnd, TimeSpan step, bool recover = false) { firstDate = new DateTime(firstDate.Year, firstDate.Month, firstDate.Day); RandomNormal rand = new RandomNormal(); DateTime current_date; // clean data from firstDate to today current_date = firstDate; if (!recover) { while (current_date <= DateEnd) { try { Access.Clear_Everglades_Price(current_date); } catch (ArgumentException) { } try { Access.Clear_Portfolio_Price(current_date); } catch (ArgumentException) { } current_date = current_date + TimeSpan.FromDays(1); } } // create list of date for calculus current_date = firstDate; LinkedList<DateTime> list_dates = new LinkedList<DateTime>(); while (current_date <= DateEnd) { list_dates.AddLast(current_date); current_date = current_date + step; } LinkedList<DateTime> list_anticipated_dates = everg.getAnticipatedDates(); Portfolio hedge_simul = null; double cash_t = 0; double portvalue; double portsolovalue; double evergvalue; DateTime date_prev = list_dates.First(); // used for anticipated end of everglades bool breakk = false; foreach (DateTime date in list_dates) { double r = everg.getCurrency().getInterestRate(date_prev); if (date == list_dates.First()) { Tuple<double, double[], bool> compute = everg.computePrice(date, with_currency); evergvalue = compute.Item1; hedge_simul = everg.getDeltaPortfolio(date, compute.Item2, with_currency); portsolovalue = hedge_simul.getPrice(date); if (recover) { cash_t = AccessDB.getPortfolioValue(firstDate) / (double)shares_everg - portsolovalue; } else { cash_t = evergvalue - portsolovalue; } portvalue = portsolovalue + cash_t; } else { // here we (virtually) sell old hedging portfolio double t = (date - date_prev).TotalDays / 360; portvalue = hedge_simul.getPrice(date) + hedge_simul.getDividend(date_prev, date) + cash_t * Math.Exp(r * t); cash_t = portvalue; Tuple<double, double[], bool> compute = everg.computePrice(date, with_currency); // test if date is a constatation date if (list_anticipated_dates.Contains(date)) { // if the date is an anticipated constatation date, we check if // we must break now, and if we do we set the price of everglades // with payoff and set breakk to true. if (compute.Item3) { evergvalue = compute.Item1; portsolovalue = hedge_simul.getPrice(date); cash_t -= evergvalue; breakk = true; } else { // if not the last date, we simply price the product and ajust our edge evergvalue = compute.Item1; hedge_simul = everg.getDeltaPortfolio(date, compute.Item2, with_currency); portsolovalue = hedge_simul.getPrice(date); cash_t -= portsolovalue; } } else if (date == everg.getLastDate()) { // if last date, we ge payoff and bam //Tuple<bool, double> payoff = everg_simul.getPayoff(date); evergvalue = compute.Item1; //payoff.Item2; cash_t -= evergvalue; portsolovalue = hedge_simul.getPrice(date); } else { // if not the last date, we simply price the product and ajust our edge evergvalue = compute.Item1; hedge_simul = everg.getDeltaPortfolio(date, compute.Item2, with_currency); portsolovalue = hedge_simul.getPrice(date); cash_t -= hedge_simul.getPrice(date); } } double err = (evergvalue - portvalue) / evergvalue; if (!double.IsInfinity(evergvalue) && !double.IsNaN(evergvalue)) { Write.storeEvergladesPrice(date, evergvalue); } if (!double.IsInfinity(portvalue) && !double.IsNaN(portvalue)) { Write.storePortfolioValue(date, portvalue * shares_everg); } if (breakk) { break; } date_prev = date; } // save last result in BD foreach (IAsset asset in hedge_simul.assetList.Keys) { if (asset is Equity) { int asset_id = Access.GetIdFromName(asset.getName()); double quantity = hedge_simul.assetList[asset]; Write.storePortfolioComposition(DateEnd, asset_id, Math.Round(quantity * shares_everg)); } else if (asset is Currency) { int cur_id = Access.getForexIdFromCurrency(((Currency)asset).getEnum()); ; double quantity = hedge_simul.assetList[asset]; Write.storePortfolioComposition(DateEnd, cur_id, Math.Round(quantity * shares_everg)); } } Write.storeCashValue(DateEnd, cash_t * shares_everg); }
/** * simulate an everglades product and it's underlying portfolio * evolution with the adviced hedging portfolio, and return a list * of Data : * * Data of product price evolution * * Data of hedging portfolio price evolution * * Data of tracking error evolution * * Data of cash spent for hedging portfolio evolution * */ public List<Data> simulateHedgeEvolution(bool with_currency) { RandomNormal rand = new RandomNormal(); LinkedList<DateTime> list_dates = everg.getObservationDates(); LinkedList<DateTime> list_anticipated_dates = everg.getAnticipatedDates(); DateTime first = list_dates.First(); List<IAsset> simulated_list = new List<IAsset>(); List<ICurrency> underlying_list_cur = new List<ICurrency>(); double r = 0.03; foreach (IAsset ass in Assets) { simulated_list.Add(new AssetSimulated(ass, list_dates, rand)); if (with_currency) { Currencies curEnum = ass.getCurrency().getEnum(); if (!underlying_list_cur.Any(x => x.getEnum() == curEnum) && curEnum != Currencies.EUR) { underlying_list_cur.Add(new CurrencySimulated(curEnum, rand, r)); } } } Everglades everg_simul = new Everglades(simulated_list, underlying_list_cur); Portfolio hedge_simul = new Portfolio(simulated_list); Data tracking_error = new Data("simulation-graph-trackingerror"); Data everglades_price = new Data("simulation-graph-prices-everg"); Data hedge_price = new Data("simulation-graph-prices-hedge"); Data portsolo_price = new Data("simulation-graph-soloport"); Data cash_price = new Data("simulation-graph-cash"); Dictionary<String, Data> list_asset_price = new Dictionary<string, Data>(); foreach (IAsset asset in simulated_list) { String nameTemp = asset.getName(); list_asset_price[nameTemp] = new Data(nameTemp); } foreach (IAsset cur in underlying_list_cur) { String nameTemp = cur.getName(); list_asset_price[nameTemp] = new Data(nameTemp); } double cash_t = 0; double portvalue; double portsolovalue; double evergvalue; DateTime date_prev = list_dates.First(); // used for anticipated end of everglades bool breakk = false; foreach (DateTime date in list_dates) { // get prices of assets at these dates in Data foreach (IAsset asset in simulated_list) { String nameTemp = asset.getName(); list_asset_price[nameTemp].add(new DataPoint(date, asset.getPrice(date))); } foreach (IAsset cur in underlying_list_cur) { String nameTemp = cur.getName(); list_asset_price[nameTemp].add(new DataPoint(date, cur.getPrice(date))); } if (date == list_dates.First()) { Tuple<double, double[], bool> compute = everg_simul.computePrice(date, with_currency); evergvalue = compute.Item1; hedge_simul = everg_simul.getDeltaPortfolio(date, compute.Item2, with_currency); portsolovalue = hedge_simul.getPrice(date); cash_t = evergvalue - portsolovalue; portvalue = portsolovalue + cash_t; } else { // here we (virtually) sell old hedging portfolio double t = (date - date_prev).TotalDays / 360; portvalue = hedge_simul.getPrice(date) + hedge_simul.getDividend(date_prev, date) + cash_t * Math.Exp(r * t); cash_t = portvalue; Tuple<double, double[], bool> compute = everg_simul.computePrice(date, with_currency); // test if date is a constatation date if (list_anticipated_dates.Contains(date)) { // if the date is an anticipated constatation date, we check if // we must break now, and if we do we set the price of everglades // with payoff and set breakk to true. if (compute.Item3) { evergvalue = compute.Item1; portsolovalue = hedge_simul.getPrice(date); cash_t -= evergvalue; breakk = true; } else { // if not the last date, we simply price the product and ajust our edge evergvalue = compute.Item1; hedge_simul = everg_simul.getDeltaPortfolio(date, compute.Item2, with_currency); portsolovalue = hedge_simul.getPrice(date); cash_t -= portsolovalue; } } else if (date == everg_simul.getLastDate()) { evergvalue = compute.Item1; cash_t -= evergvalue; portsolovalue = hedge_simul.getPrice(date); } else { // if not the last date, we simply price the product and ajust our edge evergvalue = compute.Item1; hedge_simul = everg_simul.getDeltaPortfolio(date, compute.Item2, with_currency); portsolovalue = hedge_simul.getPrice(date); cash_t -= hedge_simul.getPrice(date); } } double err = (evergvalue - portvalue) / evergvalue; if (!double.IsInfinity(evergvalue) && !double.IsNaN(evergvalue)) { everglades_price.add(new DataPoint(date, evergvalue)); } if (!double.IsInfinity(portvalue) && !double.IsNaN(portvalue)) { hedge_price.add(new DataPoint(date, portvalue)); } if (!double.IsInfinity(portsolovalue) && !double.IsNaN(portsolovalue)) { portsolo_price.add(new DataPoint(date, portsolovalue)); } if (!double.IsInfinity(err) && !double.IsNaN(err)) { tracking_error.add(new DataPoint(date, err)); } if (!double.IsInfinity(cash_t) && !double.IsNaN(cash_t)) { cash_price.add(new DataPoint(date, cash_t)); } if (breakk) { break; } date_prev = date; } List<Data> list = new List<Data>(); list.Add(everglades_price); list.Add(hedge_price); list.Add(tracking_error); list.Add(cash_price); list.Add(portsolo_price); foreach (Data dat in list_asset_price.Values) { list.Add(dat); } return list; }