private bool doCloseOrders(out IList newOrders, out RebalanceResults result) { newOrders = null; result = RebalanceResults.Success; bool retVal = false; // Get the portfolio IFundPortfolio portfolio = this.Account.Portfolio.PortfolioInstrument.Exclude(setting.TradeableInstrumentsToExclude); // Get the modelinstruments IModelVersion mv = Account.ModelPortfolio.LatestVersion; if (mv == null) throw new ApplicationException(string.Format("Not possible to compare to model for account {0}: Latest ModelVersion is null", Account.DisplayNumberWithName)); // Instantiate a PortfolioComparer and fill it with Positions & model Instruments PositionComparerCollection pc = new PositionComparerCollection(this); foreach (IFundPosition pos in portfolio.ExcludeNonTradeableInstruments()) { if (pos.Size.IsNotZero) pc.Add(pos); } // check if order does not already exists IAccountOrderCollection orders = this.Account.OpenOrdersForAccount.Exclude(setting.InstrumentsToExclude); if (orders != null && orders.Count > 0) { foreach (IOrder order in orders) { if (!order.IsMonetary) pc.Add((ISecurityOrder)order, setting.CompareAction); } } // Check if Model is correct if (mv.TotalAllocation() != 1m) throw new ApplicationException(string.Format("Not possible to compare to model: {0} does not allocate completely to 100%", mv.ToString())); pc.SetInstrumentsInModel(mv.ModelInstruments); if (pc.CompareForCloseOrders(out newOrders)) retVal = true; return retVal; }
private bool doRebalance(out IList newOrders, out RebalanceResults result) { newOrders = null; result = RebalanceResults.Success; // Get the portfolio IFundPortfolio portfolio = this.Account.Portfolio.PortfolioInstrument.Exclude(setting.TradeableInstrumentsToExclude).ExcludeNonTradeableInstruments(); ICashPortfolio cashPortfolio = this.Account.Portfolio.PortfolioCashGL; // Get the modelinstruments IModelVersion mv = Account.ModelPortfolio.LatestVersion; if (mv == null) throw new ApplicationException(string.Format("Not possible to compare to model for account {0}: Latest ModelVersion is null", Account.DisplayNumberWithName)); // Get the total portfolio value for the model allocation // If there are withdrawals instructions -> Reduce the withdrawal amount // This amount has to be taken out of the rebalance, since it needs to be redrawned from the account Money withdrawalAmount = Account.ActiveWithdrawalInstructions.TotalAmount; Money totalValue = portfolio.TotalValueInBaseCurrency + cashPortfolio.SettledCashTotalInBaseValue + withdrawalAmount; if (totalValue.IsLessThanZero && Account.Portfolio.TotalValue().IsGreaterThanZero && withdrawalAmount != null) throw new ApplicationException(string.Format("The withdrawal amount is larger than the portfolio value for account {0}.", Account.DisplayNumberWithName)); if (isRebalanceNeeded(totalValue, portfolio)) { // Instantiate a PortfolioComparer and fill it with Positions & model Instruments PositionComparerCollection pc = new PositionComparerCollection(this); // add instruments foreach (IFundPosition pos in portfolio.Where(x => x.Size.IsNotZero)) pc.Add(pos); // Add cash foreach (ICashPosition pos in cashPortfolio.Where(x => x.SettledSize.IsNotZero)) pc.Add(pos); // check if order does not already exists IAccountOrderCollection orders = this.Account.OpenOrdersForAccount.Exclude(setting.InstrumentsToExclude); if (orders != null && orders.Count > 0) { foreach (IOrder order in orders) pc.Add(order, setting.CompareAction); } // Check if Model is correct IModelInstrumentCollection modelInstrumentDistribution = mv.ModelInstruments.StrippedCollection(((IRebalanceInstruction)setting.Instruction).ExcludedComponents); if (modelInstrumentDistribution.TotalAllocation != 1m) throw new ApplicationException(string.Format("Not possible to compare to model: {0} does not allocate completely to 100%", mv.ToString())); if (totalValue != null && totalValue.IsNotZero) { foreach (IModelInstrument mi in modelInstrumentDistribution) { pc.Add(mi, totalValue); } // Add the cash from the withrawal instructions pc.AddReservedCash(withdrawalAmount, mv.GetCashManagementFund()); if (pc.Compare(out newOrders)) { doSellForeignCash(newOrders); // When no Orders -> Rebalance was not necessary if (newOrders == null || newOrders.Count == 0) result = RebalanceResults.RebalanceWasNotNeeded; else { //// Set the cash transfers to being processed if (Setting.Instruction.InstructionType == InstructionTypes.Rebalance) { IRebalanceInstruction ri = (IRebalanceInstruction)Setting.Instruction; if (ri.CashTransfers != null && ri.CashTransfers.Where(c => !c.SkipOrders).Count() > 0) { foreach (IJournalEntryLine transfer in ri.CashTransfers.Where(c => !c.SkipOrders)) transfer.SkipOrders = true; } } } } } } else result = RebalanceResults.NoRebalanceNegativePortfolioAmount; return true; }
private bool doBuyModel(out IList newOrders, out RebalanceResults result) { newOrders = null; result = RebalanceResults.Success; IBuyModelInstruction bmi = (IBuyModelInstruction)setting.Instruction; // Get the modelinstruments IModelVersion mv = Account.ModelPortfolio.LatestVersion; if (mv == null) throw new ApplicationException(string.Format("Not possible to compare to model for account {0}: Latest ModelVersion is null", Account.DisplayNumberWithName)); // Get the total portfolio value for the model allocation Money totalValue = bmi.CashTransfers.TotalTransferAmount; if (totalValue != null && totalValue.IsNotZero && totalValue.Sign) { // Instantiate a PortfolioComparer and fill it with Positions & model Instruments PositionComparerCollection pc = new PositionComparerCollection(this); pc.AddCash(totalValue); // Check if Model is correct if (mv.TotalAllocation() != 1m) throw new ApplicationException(string.Format("Not possible to compare to model: {0} does not allocate completely to 100%", mv.ToString())); foreach (IModelInstrument mi in mv.ModelInstruments) { pc.Add(mi, totalValue); } // check if order does not already exists IAccountOrderCollection orders = this.Account.OpenOrdersForAccount; if (orders != null && orders.Count > 0) { if (orders.NewCollection(x => x.Side == Side.Sell).Count() > 0) throw new ApplicationException("It is not possible to process a 'buy orders instruction' whenever there are sell orders."); } if (pc.Compare(out newOrders)) { // When no Orders -> Rebalance was not necessary if (newOrders == null || newOrders.Count == 0) result = RebalanceResults.RebalanceWasNotNeeded; return true; } } else result = RebalanceResults.NoRebalanceNegativePortfolioAmount; return true; }