Beispiel #1
0
        public static void PlaceOrder(int accountId, int instrumentId, bool isAmountBased, bool isSell, decimal amount, decimal size)
        {
            IDalSession session = NHSessionFactory.CreateSession();

            try
            {
                IAccountTypeInternal bankAccount = (IAccountTypeInternal)AccountMapper.GetAccount(session, accountId);
                IInstrument theInstrument = InstrumentMapper.GetInstrument(session, instrumentId);
                FeeFactory fee = FeeFactory.GetInstance(session);
                Order order;

                if (isAmountBased)
                {
                    Decimal qty = (isSell ? (amount * -1) : amount);
                    Money theMoney = new Money(qty, ((ITradeableInstrument)theInstrument).CurrencyNominal);
                    order = new OrderAmountBased(bankAccount, theMoney, theInstrument, true, fee);
                }
                else
                {
                    Decimal qty = (isSell ? (size * -1) : size);
                    InstrumentSize theSize = new InstrumentSize(qty, theInstrument);
                    order = new OrderSizeBased(bankAccount, theSize, true, fee);
                }

                OrderMapper.Insert(session, order);
            }
            finally
            {
                session.Close();
            }
        }
        public bool Compare(out IList newOrders)
        {
            bool result = false;
            newOrders = null;

            if (parent.Setting.CompareAction == PortfolioCompareAction.Rebalance || parent.Setting.CompareAction == PortfolioCompareAction.BuyModel)
            {
                // Check if allocated ok
                Money diff = TotalActualPositionValue() - TotalModelPositionValue() + TotalReservedCash();
                if (diff.IsNotZero)
                {
                    if (diff.IsWithinTolerance(0.05M))
                        adjustModelPortfolioToActualPortfolio(diff);
                    else
                        throw new ApplicationException(string.Format("For account {0} a rounding error in the rebalance was determined in the compare module", parent.Account.DisplayNumberWithName));
                }

                foreach (PositionComparer pos in this)
                {
                    if (!pos.Instrument.SecCategory.IsCash)
                    {
                        if (pos.InModel)
                        {
                            // Check existing order and its type
                            if (pos.ExistingOrderSize != null && pos.ExistingOrderSize.IsNotZero)
                                throw new ApplicationException(string.Format("It is not possible to place amount base orders whenever there are still active size based orders for {0}", pos.Instrument.Name));

                            // Instrument is in model so adjust the Amount
                            pos.OrderValue = pos.ModelPositionValue - (pos.ActualPositionValue + pos.ExistingOrderAmount + pos.ReservedWithdrawalAmount);
                        }
                        else
                            throw new ApplicationException("It is not possible to do the rebalance whenever there are either still positions or active orders for instruments that are not in the current model. Cancel the existing instruction and create a new one");
                    }
                }

                if (TotalAbsOrderValue() == null || TotalAbsOrderValue().IsZero)
                    return false;

                // Check if allocated ok
                diff = TotalOrderValue() - TotalCash() - TotalOpenOrderAmount() - (ModelContainsCashManagementFund ? null : TotalReservedCash());
                if (diff.IsNotZero)
                {
                    if (diff.IsWithinTolerance(0.01m))
                        adjustOrderValue(diff);
                    else
                        throw new ApplicationException(string.Format("For account {0} a rounding error in the Orders was determined in the compare module", parent.Account.DisplayNumberWithName));
                }

                try
                {
                    // Create the Orders
                    newOrders = new ArrayList();
                    IOrder order = null;

                    foreach (PositionComparer pos in this)
                    {
                        if (!pos.Instrument.SecCategory.IsCash)
                        {
                            if (!pos.IsClosure)
                            {
                                if (pos.OrderValue.IsNotZero)
                                {
                                    // If not use Cash only
                                    // exclude the Cash Management fund unless it is a sell order
                                    // exception -> when the model consists of 100% Cash Management Fund
                                    if (parent.Setting.UseCashOnly
                                        || (!parent.Setting.UseCashOnly && (pos.Instrument.SecCategory.Key != SecCategories.CashManagementFund
                                        || (pos.Instrument.SecCategory.Key == SecCategories.CashManagementFund && pos.Side == Side.Sell)))
                                        || isModelOnlyCashManagementFund())
                                    {
                                        if (IsOrderValueWithinTolerance(pos.OrderValue.GetMoney()))
                                        {
                                            InstructionTypeRebalance instruction = (InstructionTypeRebalance)parent.Setting.Instruction;
                                            order = new OrderAmountBased(parent.Account, pos.OrderValue.GetMoney(), pos.Instrument, (pos.Side == Side.Buy), parent.FeeFactory, instruction.DoNotChargeCommission, parent.Setting.ActionType);
                                            order.Instruction = instruction;
                                            newOrders.Add(order);
                                        }
                                    }
                                }
                            }
                            else
                                throw new ApplicationException(string.Format("During a rebalance all positions should match the model portfolio. Close all mismatched positions first fro account {0}.", parent.Account.DisplayNumberWithName));
                        }
                    }
                    result = true;
                }

                catch (Exception ex)
                {
                    result = false;
                    throw new ApplicationException(string.Format("An error occured in the compare module while rebalancing account {0}.", parent.Account.DisplayNumberWithName), ex);
                }
            }
            return result;
        }
Beispiel #3
0
        private bool doCashFundOrders(out IList newOrders, out RebalanceResults result)
        {
            //IPortfolio portfolio;
            ICashPortfolio cashPortfolio;
            newOrders = null;
            IInstrument cashFund = null;
            Money totalValue = null;
            bool retVal = false;
            result = RebalanceResults.Success;

            // Get the modelinstruments
            IModelVersion mv = Account.ModelPortfolio.LatestVersion;
            if (mv == null)
                throw new ApplicationException(string.Format("Not possible to place cash fund orders for account {0}: Latest ModelVersion is null", Account.DisplayNumberWithName));

            cashFund = mv.GetCashFundOrAlternative();
            if (cashFund != null)
            {
                if (Setting.UseCashOnly)
                    ((IBuyModelInstruction)Setting.Instruction).GetRoundingDifference(out totalValue);
                else
                {
                    // extra check -> does the account have a positive amount
                    if (this.Account.Portfolio.TotalValue().Sign)
                    {
                        // Get the cash positions
                        cashPortfolio = this.Account.Portfolio.PortfolioCashGL;

                        if (cashPortfolio != null && cashPortfolio.Count > 0)
                        {
                            // Check for foreign currency positions
                            if (cashPortfolio.Any(x => (!x.PositionCurrency.IsBase && x.SettledSize.IsNotZero)))
                                throw new ApplicationException(string.Format("Not possible to place cash fund orders: there are still foreign currency positions for account {0}. Close them first", this.Account.Number.ToString()));

                            // Check for pending Orders
                            IAccountOrderCollection orders = this.Account.OpenOrdersForAccount.Exclude(setting.InstrumentsToExclude);
                            if (orders != null && orders.Count > 0)
                                throw new ApplicationException(string.Format("Not possible to place cash fund orders: there are {0} pending orders for account {1}", orders.Count.ToString(), this.Account.Number.ToString()));

                            // Get the total portfolio value for the Cash Fund Order
                            totalValue = cashPortfolio.SettledCashTotalInBaseValue;
                            // Keep cash free if there is a withdrawal
                            ICashWithdrawalInstruction withdrawal = null;
                            if (Setting.Instruction.InstructionType == InstructionTypes.Rebalance)
                                withdrawal = ((IRebalanceInstruction)Setting.Instruction).CashWithdrawalInstruction;
                            totalValue += Account.ActiveWithdrawalInstructions.TotalKeepCashAmount(withdrawal);

                        }
                    }
                    else
                        result = RebalanceResults.NoCashFundOrdersNegativePortfolioAmount;
                }

                if (totalValue != null && totalValue.IsNotZero && totalValue.Abs().Quantity > 0.01M)
                {
                    IInstructionTypeRebalance instruction = (IInstructionTypeRebalance)Setting.Instruction;
                    OrderAmountBased order = new OrderAmountBased((IAccountTypeInternal)Account, totalValue, cashFund, true, this.FeeFactory, instruction.DoNotChargeCommission, Setting.ActionType);
                    order.Instruction = instruction;
                    newOrders = new ArrayList();
                    newOrders.Add(order);
                    retVal = true;
                }
            }
            return retVal;
        }
        private static bool createMgtFeeTransactionForMP(IJournal journalMgmtFee, IGLLookupRecords lookups, int mgtPeriodId, int year, int quarter, ManagementTypes managementType, FeeFactory feeFactory, DateTime minDate, DateTime maxDate, decimal taxPercentage, bool createCashInitiatedOrders)
        {
            bool retVal = false;
            IDalSession session = NHSessionFactory.CreateSession();
            Hashtable parameterLists = new Hashtable(1);
            Hashtable parameters = new Hashtable(2);

            Util.GetDatesFromQuarter(year, quarter, out minDate, out maxDate);

            parameterLists.Add("periods", Util.GetPeriodsFromQuarter(year, quarter));
            parameters.Add("mgtPeriodId", mgtPeriodId);
            parameters.Add("managementType", managementType);
            IList<IManagementPeriodUnit> unitsUnsorted = session.GetTypedListByNamedQuery<IManagementPeriodUnit>(
                "B4F.TotalGiro.ApplicationLayer.Fee.ManagementPeriodUnitsForMgtFeeTransactionCreation",
                parameters,
                parameterLists);

            if (unitsUnsorted != null && unitsUnsorted.Count > 0)
            {
                var unitsByMP = from a in unitsUnsorted
                          group a by a.ManagementPeriod into g
                          select new { ManagementPeriod = g.Key, Units = g.ToList() };

                if (unitsByMP.Count() != 1)
                    throw new ApplicationException("The number of management periods is not what is expected.");

                IManagementPeriod managementPeriod = unitsByMP.First().ManagementPeriod;
                IList<IManagementPeriodUnit> units = unitsByMP.First().Units;

                DateTime feeStartDate = minDate;
                DateTime feeEndDate = maxDate;

                if (managementPeriod.StartDate > minDate)
                    feeStartDate = managementPeriod.StartDate;
                if (Util.IsNotNullDate(managementPeriod.EndDate) && managementPeriod.EndDate < maxDate)
                    feeEndDate = managementPeriod.EndDate.Value;

                if (feeStartDate.Year != feeEndDate.Year)
                    throw new ApplicationException("The year of the start date and end date for the management fee should equal");

                string mgtFeeDescription;
                decimal mgtFeeThreshold;
                getMgtFeeInfo(managementPeriod, feeEndDate, year, quarter, out mgtFeeDescription, out mgtFeeThreshold);

                if (units != null && units.Count > 0)
                {
                    // check the number of units
                    int expectedUnitCount = Util.DateDiff(DateInterval.Month, feeStartDate, feeEndDate) + 1;
                    if (expectedUnitCount != units.Count)
                        throw new ApplicationException(string.Format("The number of units {0} does not equal the number of expected units {1}.", units.Count, expectedUnitCount));

                    // check if all have the same management period
                    var mps = from a in units
                              group a by a.ManagementPeriod into g
                              select g.Key;
                    if (mps.Count() != 1)
                        throw new ApplicationException("Not all units belong to the same management period.");

                    if (mps.First().Key != managementPeriod.Key)
                        throw new ApplicationException("The management period is not ok.");

                    if (Util.GetPeriodFromDate(managementPeriod.StartDate) == Util.GetPeriodFromDate(feeStartDate) && managementPeriod.StartDate.Day != feeStartDate.Day)
                        throw new ApplicationException(string.Format("The start date of the management period ({0}) does not equal the presented start date ({1}).", managementPeriod.StartDate.ToString("yyyy-MM-dd"), feeStartDate.ToString("yyyy-MM-dd")));

                    if (managementPeriod.EndDate.HasValue)
                    {
                        if (feeEndDate > managementPeriod.EndDate)
                            throw new ApplicationException(string.Format("The end date of the management period ({0}) does not equal the presented end date ({1}).", managementPeriod.EndDate.Value.ToString("yyyy-MM-dd"), feeEndDate.ToString("yyyy-MM-dd")));
                        else if (Util.GetPeriodFromDate(managementPeriod.EndDate.Value) == Util.GetPeriodFromDate(feeEndDate) && managementPeriod.EndDate.Value.Day != feeEndDate.Day)
                            throw new ApplicationException(string.Format("The end date of the management period ({0}) does not equal the presented end date ({1}).", managementPeriod.EndDate.Value.ToString("yyyy-MM-dd"), feeEndDate.ToString("yyyy-MM-dd")));
                    }

                    IAccountTypeCustomer account = (IAccountTypeCustomer)managementPeriod.Account;
                    if (!account.ExitFeePayingAccount.Equals(account))
                        mgtFeeDescription += string.Format(" voor {0}", account.Number);

                    string nextJournalEntryNumber = JournalEntryMapper.GetNextJournalEntryNumber(session, journalMgmtFee);
                    IMemorialBooking memorialBooking = new MemorialBooking(journalMgmtFee, nextJournalEntryNumber);
                    memorialBooking.TransactionDate = feeEndDate.AddDays(1);
                    memorialBooking.Description = mgtFeeDescription;

                    IManagementFee mgtFee = new ManagementFee(account, feeStartDate, feeEndDate, units, memorialBooking, taxPercentage, lookups);
                    if (mgtFee != null && mgtFee.NettAmount != null && mgtFee.NettAmount.IsNotZero)
                    {
                        if (mgtFee.NettAmount.Quantity < mgtFeeThreshold)
                        {
                            ITradeableInstrument instrument;
                            account = account.ExitFeePayingAccount;
                            if (createCashInitiatedOrders && mgtFee.NeedToCreateCashInitiatedOrder(out instrument))
                            {
                                if (instrument != null)
                                {
                                    OrderAmountBased order = new OrderAmountBased(account, mgtFee.Components.TotalAmount, instrument, true, feeFactory, true);
                                    order.OrderInfo = mgtFeeDescription;
                                    mgtFee.CashInitiatedOrder = order;
                                }
                                else
                                {
                                    // Sell from the biggest position
                                    IFundPosition pos = account.Portfolio.PortfolioInstrument.Where(x => x.Size.IsGreaterThanZero).OrderByDescending(x => x.CurrentValue).FirstOrDefault();
                                    if (pos != null && (pos.CurrentBaseValue + mgtFee.NettAmount).IsGreaterThanOrEqualToZero)
                                    {
                                        OrderAmountBased order = new OrderAmountBased(account, mgtFee.Components.TotalAmount, pos.Instrument, true, feeFactory, true);
                                        order.OrderInfo = mgtFeeDescription;
                                        mgtFee.CashInitiatedOrder = order;
                                    }
                                }
                            }

                            if (mgtFee.CashInitiatedOrder == null && (account.Portfolio.TotalValue() + mgtFee.TotalAmount).IsLessThanZero)
                                throw new ApplicationException(string.Format("Could not create a management fee booking for account {0} since the total portfolio value ({1}) is insufficient.", account.DisplayNumberWithName, account.Portfolio.TotalValue().DisplayString));

                            mgtFee.BookLines();
                            GeneralOperationsBookingMapper.Update(session, mgtFee);
                            retVal = true;
                        }
                    }
                }
            }
            session.Close();
            return retVal;
        }
Beispiel #5
0
        private bool placeCashFundOrder(ICashWithdrawalInstruction instruction)
        {
            ITradeableInstrument cashFund = null;
            IFundPosition posCashFund = null;
            Money cashAmount = null;
            bool retVal = false;

            // Get the modelinstruments
            IModelVersion mv = instruction.Account.ModelPortfolio.LatestVersion;
            if (mv == null)
                throw new ApplicationException(string.Format("Not possible to place cash fund orders for account {0}: Latest ModelVersion is null", instruction.Account.DisplayNumberWithName));

            cashFund = mv.GetCashFundOrAlternative();
            if (cashFund != null)
                posCashFund = instruction.Account.Portfolio.PortfolioInstrument.GetPosition(cashFund);

            // Deduct the cash on the account
            ICurrency baseCurrency = instruction.Account.AccountOwner.StichtingDetails.BaseCurrency;
            ICashSubPosition cashPos = instruction.Account.Portfolio.PortfolioCashGL.GetSettledBaseSubPosition();
            if (cashPos != null)
                cashAmount = cashPos.Size;

            if (posCashFund != null && posCashFund.Size.IsGreaterThanZero && Money.Add(posCashFund.CurrentBaseValue + cashAmount, instruction.Amount).IsGreaterThanOrEqualToZero)
            {
                OrderAmountBased order = new OrderAmountBased(instruction.Account, instruction.Amount + cashAmount, cashFund, true, getFeeFactory(FeeFactoryInstanceTypes.Commission), instruction.DoNotChargeCommission, OrderActionTypes.Withdrawal);
                order.Instruction = instruction;
                order.OrderInfo = string.Format("Free up cash for cash withdrawal ({0}) on {1}", instruction.Amount.DisplayString, instruction.WithdrawalDate.ToString("dd-MM-yyyy"));
                IList orders = new ArrayList();
                orders.Add(order);
                instruction.UpdateableOrders = orders;
                instruction.Message = string.Format("Cash Fund order generated to free up cash on {0}", DateTime.Now.ToString());
                retVal = true;
            }
            else
                createRebalanceInstruction(instruction);

            return retVal;
        }
Beispiel #6
0
 private static void executeBooking(ICashDividend booking, IFeeFactory feeFactory)
 {
     ITradeableInstrument instrument;
     if (booking.NeedToCreateCashInitiatedOrder(out instrument))
     {
         Money divAmount = booking.Components.TotalAmount;
         if (instrument != null)
         {
             OrderAmountBased order = new OrderAmountBased(booking.Account, divAmount, instrument, true, feeFactory, true);
             order.OrderInfo = booking.Description;
             booking.CashInitiatedOrder = order;
         }
         else
         {
             // Sell from the biggest position
             IFundPosition pos = booking.Account.Portfolio.PortfolioInstrument.Where(x => x.Size.IsGreaterThanZero).OrderByDescending(x => x.CurrentValue).FirstOrDefault();
             if (pos != null && (pos.CurrentBaseValue + divAmount).IsGreaterThanOrEqualToZero)
             {
                 OrderAmountBased order = new OrderAmountBased(booking.Account, divAmount, pos.Instrument, true, feeFactory, true);
                 order.OrderInfo = booking.Description;
                 booking.CashInitiatedOrder = order;
             }
         }
     }
     booking.Execute();
 }
Beispiel #7
0
        public static OrderValidationResult PlaceOrder(
                                                int accountId, 
                                                int instrumentId, 
                                                Side side,
                                                bool isAmountBased, 
                                                decimal size,
                                                decimal amount,
                                                int currencyId,
                                                bool isValueInclComm,
                                                bool ignoreWarnings,
                                                bool bypassValidation)
        {
            OrderValidationResult validationResult = new OrderValidationResult(OrderValidationSubType.Invalid_NotValidated, "This order has not been validated.");
            IDalSession session = NHSessionFactory.CreateSession();

            try
            {
                IAccountTypeInternal account = (IAccountTypeInternal)AccountMapper.GetAccount(session, accountId);
                IInstrument instrument = InstrumentMapper.GetInstrument(session, instrumentId);
                //FeeFactory fee = FeeFactory.GetInstance(session);
                Order order;
                decimal sign = (side == Side.Sell ? -1 : 1);

                if (!isAmountBased)
                {
                    InstrumentSize value = new InstrumentSize(sign * size, instrument);
                    order = new OrderSizeBased(account, value, false, null, true);
                }
                else
                {
                    ICurrency currency = InstrumentMapper.GetCurrency(session, currencyId);
                    if (currency == null)
                        currency = ((ITradeableInstrument)instrument).CurrencyNominal;
                    Money value = new Money(sign * amount, currency);
                    order = new OrderAmountBased(account, value, instrument, isValueInclComm, null, true);
                }

                // Do Validation
                if (bypassValidation)
                    validationResult = new OrderValidationResult(OrderValidationSubType.Success, "");
                else
                    validationResult = order.Validate();

                if (validationResult.MainType == OrderValidationType.Success ||
                   (validationResult.MainType == OrderValidationType.Warning && ignoreWarnings))
                {
                    OrderMapper.Insert(session, order);
                    validationResult = new OrderValidationResult(OrderValidationSubType.Success, "");
                }
            }
            finally
            {
                session.Close();
            }

            return validationResult;
        }
Beispiel #8
0
        public static OrderValidationResult PlaceOrder(
                                                int accountId, 
                                                int instrumentId, 
                                                Side side,
                                                bool isAmountBased, 
                                                decimal size,
                                                decimal amount,
                                                int currencyId,
                                                bool isValueInclComm,
                                                bool noCharges,
                                                bool ignoreWarnings,
                                                bool bypassValidation)
        {
            OrderValidationResult validationResult = new OrderValidationResult(OrderValidationSubType.Invalid_NotValidated, "This order has not been validated.");
            IDalSession session = NHSessionFactory.CreateSession();

            try
            {
                IAccountTypeCustomer account = (IAccountTypeCustomer)AccountMapper.GetAccount(session, accountId);
                IInstrument instrument = InstrumentMapper.GetInstrument(session, instrumentId);
                FeeFactory fee = FeeFactory.GetInstance(session);
                Order order;
                decimal sign = (side == Side.Sell ? -1 : 1);

                if (!isAmountBased)
                {
                    InstrumentSize value = new InstrumentSize(sign * size, instrument);
                    order = new OrderSizeBased(account, value, false, fee, noCharges);
                }
                else
                {
                    ICurrency currency = InstrumentMapper.GetCurrency(session, currencyId);
                    if (currency == null)
                        currency = ((ITradeableInstrument)instrument).CurrencyNominal;
                    if (!getCurrencies(account, instrument).Contains(currency))
                        throw new ArgumentException(
                            string.Format("Invalid currency ({0}). Currency should be either the base currency or the instrument currency.",
                                          currency.Symbol));
                    Money value = new Money(sign * amount, currency);
                    order = new OrderAmountBased(account, value, instrument, isValueInclComm, fee, noCharges);
                }

                // Do Validation
                if (bypassValidation)
                    validationResult = new OrderValidationResult(OrderValidationSubType.Success, "");
                else
                    validationResult = order.Validate();

                if (validationResult.MainType == OrderValidationType.Success ||
                   (validationResult.MainType == OrderValidationType.Warning && ignoreWarnings))
                {
                    OrderMapper.Insert(session, order);
                    validationResult = new OrderValidationResult(OrderValidationSubType.Success, "");
                }
            }
            finally
            {
                session.Close();
            }

            return validationResult;
        }