/// <summary> /// Function: Calculates the NAV of the Strategies in the Tree. /// </summary> /// <param name="day">reference day</param> public double NAVCalculation(DateTime day) { foreach (Strategy strat in _strategyDB.Values.ToList()) { if (strat.InitialDate <= day && strat.FinalDate >= day && (strat.Portfolio != null || (strat.Portfolio == null && strat.FundingType != FundingType.TotalReturn))) { strat.Tree.NAVCalculation(day); } } if (!_strategyExecutionDB.ContainsKey(day)) { _strategyExecutionDB.TryAdd(day, new ConcurrentDictionary <int, double>()); } BusinessDay date_local = Calendar.FindCalendar("All").GetBusinessDay(day); //BusinessDay date_local = _parentStrategy.Calendar.GetBusinessDay(day); if (date_local != null) { ConcurrentDictionary <int, double> dict = _strategyExecutionDB[date_local.DateTime]; DateTime t1 = DateTime.Now; double v = _parentStrategy.NAVCalculation(date_local); tt12 += (DateTime.Now - t1); if (!dict.ContainsKey(_parentStrategy.ID)) { dict.TryAdd(_parentStrategy.ID, v); } return(v); } return(0.0); }
/// <summary> /// Function: Calculates the NAV of the Strategies in the Tree. /// </summary> /// <param name="day">reference day</param> public double NAVCalculation(DateTime day) { lock (objLock) { foreach (Strategy strat in _strategyDB.Values.ToList()) { if (strat.InitialDate <= day && strat.FinalDate >= day) { strat.Tree.NAVCalculation(day); } } if (!_strategyExecutionDB.ContainsKey(day)) { _strategyExecutionDB.Add(day, new Dictionary <int, double>()); } BusinessDay date_local = _parentStrategy.Calendar.GetBusinessDay(day); if (date_local != null) { if (!_strategyExecutionDB[date_local.DateTime].ContainsKey(_parentStrategy.ID)) { _strategyExecutionDB[date_local.DateTime].Add(_parentStrategy.ID, _parentStrategy.NAVCalculation(date_local)); } return(_strategyExecutionDB[date_local.DateTime][_parentStrategy.ID]); } return(0.0); } }
/// <summary> /// Function: Clear the portfolio's new orders of the entire tree below this for a specific date. /// </summary> /// <param name="date">DateTime value date /// </param> /// <param name="clearMemory">True if clear AUM memory also.</param> public void ClearOrders(DateTime orderDate, bool clearMemory) { foreach (Strategy strat in _strategyDB.Values.ToList()) { strat.Tree.ClearOrders(orderDate, clearMemory); } BusinessDay date_local = _parentStrategy.Calendar.GetBusinessDay(orderDate); if (date_local != null) { if (_parentStrategy.Initialized) { if (clearMemory) { _parentStrategy.ClearNextAUMMemory(orderDate); } if (_parentStrategy.Portfolio != null) { _parentStrategy.Portfolio.ClearOrders(orderDate); } } } }
/// <summary> /// Function: Calculate the NAV strategies without portfolios prior to the ones with portfolios. /// Used for index calculation for example. /// </summary> /// <param name="day">reference day</param> public double PreNAVCalculation(DateTime day) { foreach (Strategy strat in _strategyDB.Values.ToList()) { if (strat.InitialDate <= day && strat.FinalDate >= day && (strat.Portfolio != null || (strat.Portfolio == null && strat.FundingType != FundingType.TotalReturn))) { strat.Tree.PreNAVCalculation(day); } } //BusinessDay date_local = _parentStrategy.Calendar.GetBusinessDay(day); BusinessDay date_local = Calendar.FindCalendar("All").GetBusinessDay(day); if (date_local != null) { if (!_strategyExecutionDB.ContainsKey(date_local.DateTime)) { _strategyExecutionDB.TryAdd(date_local.DateTime, new ConcurrentDictionary <int, double>()); } if (_parentStrategy.Portfolio == null && !_strategyExecutionDB[date_local.DateTime].ContainsKey(_parentStrategy.ID)) { _strategyExecutionDB[date_local.DateTime].TryAdd(_parentStrategy.ID, _parentStrategy.NAVCalculation(date_local)); } } return(0); }
/// <summary> /// Function: Return the business day closest to a given date. /// </summary> /// <param name="date">Reference date. /// </param> /// <param name="type">Type of search. /// </param> public BusinessDay GetClosestBusinessDay(DateTime date, TimeSeries.DateSearchType type) { BusinessDay res = GetBusinessDay(date); if (res != null) { BusinessDay ret = new BusinessDay(res.DateTime, res.DayMonth, res.DayYear, res.DayIndex, res.CalendarID); return(ret); } if (type == TimeSeries.DateSearchType.Previous) { DateTime firstDate = _dateTimes[0]; DateTime lastDate = _dateTimes[_dateTimes.Count - 1]; if (date >= lastDate) { BusinessDay temp = GetBusinessDay(lastDate); BusinessDay bday = new BusinessDay(temp.DateTime, temp.DayMonth, temp.DayYear, temp.DayIndex, temp.CalendarID); res.SetTime(date.TimeOfDay); return(res); } for (DateTime d = date; d >= firstDate; d = d.AddDays(-1)) { res = GetBusinessDay(d); if (res != null) { BusinessDay bday = new BusinessDay(res.DateTime, res.DayMonth, res.DayYear, res.DayIndex, res.CalendarID); bday.SetTime(date.TimeOfDay); return(bday); } } } else { DateTime lastDate = _dateTimes[_dateTimes.Count - 1]; for (DateTime d = date; d <= lastDate; d = d.AddDays(1)) { res = GetBusinessDay(d); if (res != null) { BusinessDay bday = new BusinessDay(res.DateTime, res.DayMonth, res.DayYear, res.DayIndex, res.CalendarID); bday.SetTime(date.TimeOfDay); return(bday); } } } return(null); }
/// <summary> /// Function: Calculate the NAV which is taken as the previous value in order to keep constant. /// </summary> public override double NAVCalculation(BusinessDay date) { BusinessDay previousDate = date.AddMilliseconds(-1); double val = this[previousDate.DateTime, TimeSeriesType.Last, TimeSeriesRollType.Last]; CommitNAVCalculation(date, val, TimeSeriesType.Last); return(val); }
/// <summary> /// Function: Create a Strategy and run startup procedures /// </summary> /// <param name="name">name</param> /// <param name="ccy">base currency</param> /// <param name="initialDate">starting date</param> /// <param name="initialValue">starting NAV</param> /// <param name="simulated">false if persistent</param> new public static ConstantStrategy CreateStrategy(string name, Currency ccy, BusinessDay initialDate, double initialValue, bool simulated) { Instrument instrument = Instrument.CreateInstrument(name, InstrumentType.Strategy, name + "ConstantStrategy", ccy, FundingType.TotalReturn, simulated); ConstantStrategy strategy = ConstantStrategy.CreateStrategy(instrument, initialDate, 1); strategy.SetConstantCarryCost(0.0 / (double)10000.0, 0.0 / (double)10000.0, DayCountConvention.Act360, 360); strategy.TimeSeriesRoll = TimeSeriesRollType.Last; strategy.Initialize(); return(strategy); }
/// <summary> /// Function: Return the business day with a given index. /// </summary> /// <param name="idx">Index of the business date to be retrieved. /// </param> public BusinessDay GetBusinessDay(int idx) { if (_dateIndexDictionary.ContainsKey(idx)) { BusinessDay bday = _dateIndexDictionary[idx]; return(new BusinessDay(bday.DateTime, bday.DayMonth, bday.DayYear, bday.DayIndex, bday.CalendarID)); } else { return(null); } }
/// <summary> /// Function: Executed the logic for each strategy and its sub-nodes /// </summary> /// <param name="orderDate">reference day</param> public void ExecuteLogic(DateTime orderDate, bool force = false) { ExecuteLogic_internal(orderDate, true, force); if (Strategy.Portfolio != null && Strategy.Portfolio.Residual != null) { BusinessDay orderDate_local = Calendar.FindCalendar("All").GetBusinessDay(orderDate); if (orderDate_local != null) { Strategy residual = Strategy.Portfolio.Residual; residual.ExecuteLogic(residual.ExecutionContext(orderDate_local), force); } } }
/// <summary> /// Function: Startup function called once during the creation of the strategy. /// </summary> /// <remarks>called during the cloning process</remarks> private void Startup(BusinessDay initialDate, Dictionary <int, double> initial_values) { foreach (Strategy strat in _strategyDB.Values.ToList()) { strat.Tree.Startup(initialDate, initial_values); } _parentStrategy.Startup(initialDate, Math.Abs(initial_values[_parentStrategy.ID]), _parentStrategy.Portfolio); if (initial_values[_parentStrategy.ID] < 0) { _parentStrategy.UpdateAUMOrder(initialDate.DateTime, initial_values[_parentStrategy.ID]); } }
/// <summary> /// Function: Create a Strategy and run startup procedures /// </summary> /// <param name="instrument">base instrument</param> /// <param name="initialDate">starting date</param> /// <param name="initialValue">starting NAV</param> public static ConstantStrategy CreateStrategy(Instrument instrument, BusinessDay initialDate, double initialValue) { if (instrument.InstrumentType == InstrumentType.Strategy) { ConstantStrategy Strategy = new ConstantStrategy(instrument); Strategy.Startup(initialDate, initialValue, null); return(Strategy); } else { throw new Exception("Instrument not an Strategy"); } }
/// <summary> /// Function: Initialisation process for the Tree. /// </summary> /// <param name="orderDate">reference day</param> /// <param name="preNavCalculaiton">true if pre-nav calculation is to be performed</param> private void InitializeProcess(DateTime date, Boolean preNavCalculaiton) { BusinessDay date_local = _parentStrategy.Calendar.GetBusinessDay(date); if (preNavCalculaiton) { PreNAVCalculation(date_local.DateTime); } if (_parentStrategy.Portfolio != null) { _parentStrategy.Portfolio.SubmitOrders(date_local.DateTime); } }
/// <summary> /// Function: Add business day to the calendar. /// </summary> /// <param name="date">Reference date. /// </param> /// <param name="businessDayMonth">Index of the date in the date's calendar month. /// </param> /// <param name="businessDayYear">Index of the date in the date's calendar year. /// </param> /// <param name="businessDayIndex">Index of the date's in the entire calendar. /// </param> public void AddBusinessDay(DateTime date, int businessDayMonth, int businessDayYear, int businessDayIndex) { if (GetBusinessDay(date) != null) { throw new Exception("Date Already Exists"); } BusinessDay bday = new BusinessDay(date, businessDayMonth, businessDayYear, businessDayIndex, this.ID); _dateIndexDictionary.Add(bday.DayIndex, bday); _dateTimeDictionary.Add(bday.DateTime, bday); Factory.AddBusinessDay(bday); }
/// <summary> /// Function: Add or remove strategy as a node in the Tree. /// </summary> /// <param name="day">reference day</param> public void AddRemoveSubStrategies(DateTime day) { foreach (Strategy strat in _strategyDB.Values.ToList()) { if (strat.InitialDate <= day && strat.FinalDate >= day && strat.Portfolio != null) { strat.Tree.AddRemoveSubStrategies(day); } } BusinessDay date_local = _parentStrategy.Calendar.GetBusinessDay(day); if (date_local != null) { _parentStrategy.AddRemoveSubStrategies(date_local); } }
/// <summary> /// Function: Return the business day representing a given DateTime. /// </summary> /// <param name="date">Date to be translated to a business day. /// </param> public BusinessDay GetBusinessDay(DateTime date) { if (_dateTimeDictionary.ContainsKey(date.Date)) { BusinessDay temp = _dateTimeDictionary[date.Date]; BusinessDay bday = new BusinessDay(temp.DateTime, temp.DayMonth, temp.DayYear, temp.DayIndex, temp.CalendarID); //bday.SetTime(date.Hour, date.Minute, date.Second, date.Millisecond); bday.SetTime(date.TimeOfDay); return(bday);// _dateTimeDictionary[date.Date].SetTime(date.Hour, date.Minute, date.Second, date.Millisecond); } else { return(null); } }
/// <summary> /// Function: Calls PostExecuteLogic for each strategy and its sub-nodes /// </summary> /// <param name="orderDate">reference day</param> public void PostExecuteLogic(DateTime day) { foreach (Strategy strat in _strategyDB.Values.ToList()) { if (strat.InitialDate <= day && strat.FinalDate >= day) { strat.Tree.PostExecuteLogic(day); } } BusinessDay date_local = _parentStrategy.Calendar.GetBusinessDay(day); if (date_local != null) { _parentStrategy.PostExecuteLogic(date_local); } }
/// <summary> /// Function: Receive execution levels for a given portfolio. This function is usually used for historical simulations. /// </summary> /// <param name="executionDate">reference date for the executed orders</param> /// <param name="portfolio">reference portfolio</param> public static void ReceiveExecutionLevels(DateTime executionDate, Portfolio portfolio) { Dictionary <int, Dictionary <string, Order> > orders = portfolio.OpenOrders(executionDate, true); if (orders != null) { foreach (Dictionary <string, Order> os in orders.Values) { foreach (Order order in os.Values) { if (order.Status == OrderStatus.Submitted) { Instrument instrument = order.Instrument; BusinessDay date = Calendar.FindCalendar("WE").GetBusinessDay(executionDate); if (date != null) { double executionLevel = instrument[executionDate, TimeSeriesType.Last, instrument.InstrumentType == InstrumentType.Strategy ? TimeSeriesRollType.Last : TimeSeriesRollType.Last]; if (instrument.InstrumentType == InstrumentType.Future) { executionLevel *= (instrument as Future).PointSize; } if (!double.IsNaN(executionLevel)) { if (order.Unit != 0.0) { if (true) { if (instrument.InstrumentType == InstrumentType.Future) { double n_contracts = order.Unit; double exec_fee = 0.0; Dictionary <int, Dictionary <int, Instruction> > instructions = Factory.Instructions(); if (instructions.ContainsKey(portfolio.ID)) { if (instructions[portfolio.ID].ContainsKey(instrument.ID)) { exec_fee = instructions[portfolio.ID][instrument.ID].ExecutionFee; } else if (instructions[portfolio.ID].ContainsKey((instrument as Future).UnderlyingID)) { exec_fee = instructions[portfolio.ID][(instrument as Future).UnderlyingID].ExecutionFee; } else if (instructions[portfolio.ID].ContainsKey(0)) { exec_fee = instructions[portfolio.ID][0].ExecutionFee; } } if (instructions.ContainsKey(0)) { if (instructions[0].ContainsKey(instrument.ID)) { exec_fee = instructions[0][instrument.ID].ExecutionFee; } else if (instructions[0].ContainsKey(0)) { exec_fee = instructions[0][0].ExecutionFee; } } if (order.Unit > 0) { executionLevel += exec_fee; } else if (order.Unit < 0) { executionLevel -= exec_fee; } Instrument underlying = (instrument as Future).Underlying; double value = underlying.ExecutionCost; if (value < 0) { value = -value; if (order.Unit > 0) { executionLevel += value * executionLevel; } else { executionLevel -= value * executionLevel; } } else { value *= (instrument as Future).PointSize; if (order.Unit > 0) { executionLevel += value; } else { executionLevel -= value; } } } } } portfolio.UpdateOrderTree(order, OrderStatus.Executed, double.NaN, executionLevel, executionDate); } else { portfolio.UpdateOrderTree(order, OrderStatus.NotExecuted, double.NaN, executionLevel, executionDate); } } } } } } }
/// <summary> /// Function: Return the index of a given business day. /// </summary> /// <param name="date">Business day to retreive the index of. /// </param> public int GetBusinessDay(BusinessDay date) { return(GetBusinessDay(date.DateTime).DayIndex); }
/// <summary> /// Function: Internal function to executed the logic for each strategy and its sub-nodes /// </summary> /// <param name="orderDate">reference day</param> /// /// <param name="recursive">true if recursive</param> private void ExecuteLogic(DateTime orderDate, bool recursive) { if (_parentStrategy.Portfolio != null) { DateTime executionDate = orderDate.AddDays(1); List <Strategy> recalcs = new List <Strategy>(); Parallel.ForEach(_strategyDB.Values, strat => { if (strat.InitialDate <= orderDate && strat.FinalDate >= executionDate && strat.Portfolio != null) { double oldAUM = strat.GetNextAUM(orderDate, TimeSeriesType.Last); if (double.IsNaN(oldAUM) || oldAUM == 0.0) { recalcs.Add(strat); } else { strat.Tree.ExecuteLogic(orderDate, false); } } }); BusinessDay orderDate_local = _parentStrategy.Calendar.GetBusinessDay(orderDate); if (_parentStrategy.Initialized && orderDate_local != null) { _parentStrategy.ExecuteLogic(_parentStrategy.ExecutionContext(orderDate_local)); if (!recursive) { return; } double newAUM = _parentStrategy.GetNextAUM(orderDate, TimeSeriesType.Last); if (!double.IsNaN(newAUM)) { Boolean recalc = false; Parallel.ForEach(recalcs, strat => { if (strat.InitialDate <= orderDate_local.DateTime && strat.FinalDate >= orderDate_local.AddBusinessDays(1).DateTime) { double oldAUM = strat.GetNextAUM(orderDate, TimeSeriesType.Last); if (!double.IsNaN(oldAUM)) { recalc = true; } } }); if (recalc) { _parentStrategy.ClearMemory(orderDate_local.DateTime); _parentStrategy.Tree.ClearOrders(orderDate_local.DateTime, true); _parentStrategy.Tree.ExecuteLogic(orderDate_local.DateTime, false); } } } } }
/// <summary> /// Function: List of instruments that are linked to this calendar. /// </summary> public BusinessDay NextTradingBusinessDate(DateTime date) { BusinessDay orderDate_local = GetClosestBusinessDay(date, TimeSeries.DateSearchType.Next); return(orderDate_local.AddMilliseconds(1)); }
/// <summary> /// Function: Internal function to executed the logic for each strategy and its sub-nodes /// </summary> /// <param name="orderDate">reference day</param> /// /// <param name="recursive">true if recursive</param> private void ExecuteLogic_internal(DateTime orderDate, bool recursive, bool force) { if (_parentStrategy.Portfolio != null) { DateTime executionDate = orderDate.AddDays(1); ConcurrentQueue <Strategy> recalcs = new ConcurrentQueue <Strategy>(); Parallel.ForEach(_strategyDB.Values, strat => //foreach(var strat in _strategyDB.Values) { if (strat.InitialDate <= orderDate && strat.FinalDate >= executionDate && strat.Portfolio != null && !strat.IsResidual) { //double oldAUM = strat.GetSODAUM(orderDate, TimeSeriesType.Last); double oldAUM = strat.GetAUM(orderDate, TimeSeriesType.Last); if (double.IsNaN(oldAUM) || oldAUM == 0.0) { double old_strat_aum = strat.GetAUM(orderDate, TimeSeriesType.Last); double old_port_aum = strat.Portfolio[orderDate, TimeSeriesType.Last, TimeSeriesRollType.Last]; Console.WriteLine("ENQUEUE: " + strat + " " + oldAUM + " " + old_strat_aum + " " + old_port_aum); recalcs.Enqueue(strat); } //else // strat.Tree.ExecuteLogic(orderDate, false); //if strat.Tree.ExecuteLogic_internal(orderDate, false, force); } }); //BusinessDay orderDate_local = _parentStrategy.Calendar.GetBusinessDay(orderDate); BusinessDay orderDate_local = Calendar.FindCalendar("All").GetBusinessDay(orderDate); // if (_parentStrategy.Initialized && orderDate_local != null && !_parentStrategy.IsResidual) { _parentStrategy.ExecuteLogic(_parentStrategy.ExecutionContext(orderDate_local), force); if (!recursive) { return; } double newAUM = _parentStrategy.GetSODAUM(orderDate, TimeSeriesType.Last); if (!double.IsNaN(newAUM)) { Boolean recalc = false; Parallel.ForEach(recalcs, strat => { if (strat.InitialDate <= orderDate_local.DateTime && strat.FinalDate >= orderDate_local.AddBusinessDays(1).DateTime&& !strat.IsResidual) { //double oldAUM = strat.GetNextAUM(orderDate, TimeSeriesType.Last); double oldAUM = strat.GetSODAUM(orderDate, TimeSeriesType.Last); if (!double.IsNaN(oldAUM)) { recalc = true; } } }); if (recalc) { _parentStrategy.ClearMemory(orderDate_local.DateTime); _parentStrategy.Tree.ClearOrders(orderDate_local.DateTime, true); _parentStrategy.Tree.ExecuteLogic_internal(orderDate_local.DateTime, false, force); } } } } }