예제 #1
0
        public static OrderEditView CheckPrice(OrderEditView orderEditView)
        {
            using (IDalSession session = NHSessionFactory.CreateSession())
            {
                ISecurityOrder order = (ISecurityOrder)OrderMapper.GetOrder(session, orderEditView.OrderId);
                ITradeableInstrument tradedInstrument = order.TradedInstrument;
                Price price = new Price(orderEditView.Price, order.TradedInstrument.CurrencyNominal, order.TradedInstrument);

                // Check if the Price is still reliable
                IPriceDetail instrumentPrice = tradedInstrument.CurrentPrice;
                if (instrumentPrice == null || instrumentPrice.Price.IsZero)
                    orderEditView.Warning = string.Format("No price was found for {0} so the validation is not very reliable.", tradedInstrument.DisplayName);
                else
                {
                    // check if the price is within 1% of the last exRate
                    decimal rate = instrumentPrice.Price.Quantity;

                    decimal diff = (price.Quantity - rate) / rate;
                    decimal diffPct = Math.Round(Math.Abs(diff), 4) * 100;
                    if (diffPct > 1)
                        orderEditView.Warning = string.Format("The price you entered is {0}% {1} than the last known price ({2}).", diffPct.ToString("0.##"), (diff < 0 ? "smaller" : "higher"), instrumentPrice.Price.ShortDisplayString);

                    if (instrumentPrice.IsOldDate)
                        orderEditView.Warning += (orderEditView.Warning != string.Empty ? Environment.NewLine : "") + string.Format("The price found for {0} is old ({1}) so the validation is not very reliable.", tradedInstrument.DisplayName, instrumentPrice.Date.ToShortDateString());
                }
                return orderEditView;
            }
        }
예제 #2
0
파일: CommClient.cs 프로젝트: kiquenet/B4F
        /// <summary>
        /// Constructor for creating a test FeeClient object
        /// </summary>
        /// <param name="account"></param>
        /// <param name="instrument"></param>
        /// <param name="side"></param>
        /// <param name="actiontype"></param>
        /// <param name="transactionDate"></param>
        /// <param name="issizebased"></param>
        /// <param name="orderValue"></param>
        /// <param name="amount"></param>
        /// <param name="price"></param>
        /// <param name="ordercurrency"></param>
        /// <param name="isValueInclComm"></param>
        public CommClient(IAccountTypeInternal account,IInstrument instrument, Side side, OrderActionTypes actiontype, 
                         DateTime transactionDate, bool issizebased, InstrumentSize orderValue, Money amount, Price price,
                         ICurrency ordercurrency, bool isValueInclComm)
        {
            if (account == null)
                throw new ApplicationException("It is not possible to calculate the commission when the account is unknown.");

            if (instrument == null)
                throw new ApplicationException("It is not possible to calculate the commission when the instrument value is unknown.");

            this.account = account;
            this.instrument = instrument;
            this.Side = side;
            this.ActionType = actiontype;
            this.TransactionDate = transactionDate;
            this.IsSizeBased = issizebased;
            this.OriginalOrderType = issizebased ? BaseOrderTypes.SizeBased : BaseOrderTypes.AmountBased;
            this.Value = orderValue;
            this.amount = amount;
            this.Price = price;
            this.OrderCurrency = ordercurrency;
            this.IsValueInclComm = isValueInclComm;

            type = CommClientType.Test;
        }
예제 #3
0
 public FundPositionHistorical(IFundPortfolioHistorical parent, InstrumentSize size, Price price, Decimal rate)
 {
     this.Parent = parent;
     this.Size = size;
     this.Price = price;
     this.rate = rate;
 }
예제 #4
0
 public CrumbleTransaction(IOrder order, ICrumbleAccount acctA, IAccount acctB,
         InstrumentSize valueSize, Price price, decimal exRate, DateTime transactionDate,
         DateTime transactionDateTime, Decimal ServiceChargePercentage, Side txSide, ITradingJournalEntry tradingJournalEntry,
         IGLLookupRecords lookups, ListOfTransactionComponents[] components)
     : base(order, acctA, acctB, valueSize, price, exRate, transactionDate, transactionDateTime, ServiceChargePercentage,
         txSide, tradingJournalEntry, lookups, components)
 {
 }
예제 #5
0
        /// <summary>
        /// This method tries to find a commission rule based on the parameters entered
        /// </summary>
        /// <param name="saccount">Account number</param>
        /// <param name="sinstrument">Instrument</param>
        /// <param name="sordervalue">Order value</param>
        /// <param name="samount">Amount</param>
        /// <param name="sprice">Price</param>
        public static string CalculateAccruedInterest(int instrumentId,
            DateTime settlementDate, BaseOrderTypes orderType,
            decimal amountQuantity, decimal sizeQuantity, decimal priceQuantity,
            int exchangeId)
        {
            string result = "";

            try
            {

                using (IDalSession session = NHSessionFactory.CreateSession())
                {
                    InstrumentSize size = null;
                    IBond instrument = (IBond)InstrumentMapper.GetInstrument(session, instrumentId);
                    IExchange exchange = null;
                    if (instrument == null)
                        throw new ApplicationException("select a valid bond");

                    if (exchangeId != 0 && exchangeId != int.MinValue)
                        exchange = ExchangeMapper.GetExchange(session, exchangeId);

                    ICurrency defcurrency = instrument.CurrencyNominal;
                    Price price = null;
                    if (priceQuantity != 0M)
                        price = new Price(priceQuantity, defcurrency, instrument);
                    else if (instrument.CurrentPrice != null)
                        price = instrument.CurrentPrice.Price;

                    if (!(price != null && price.IsNotZero))
                        throw new ApplicationException("There is no price");

                    if (orderType == BaseOrderTypes.AmountBased)
                    {
                        Money amount = new Money(amountQuantity, defcurrency);
                        size = instrument.CalculateSizeBackwards(amount, price, settlementDate);
                    }
                    else
                        size = new InstrumentSize(sizeQuantity, instrument);

                    AccruedInterestDetails accInt = instrument.AccruedInterest(size, settlementDate, exchange);
                    Money calcAmount = size.CalculateAmount(price);

                    if (accInt.IsRelevant)
                        result = accInt.DisplayString + string.Format("<br>Size: {0}<br>Amount: {1}<br>Settlement Date: {2}",
                        size.Quantity, calcAmount.Quantity, settlementDate.ToString("dd-MM-yyyy"));
                    else
                        result = "Accrued interest is not relevant";
                }
            }
            catch (Exception ex)
            {
                result = "Error during accrued interest test: " + ex.Message;
            }
            return result;
        }
예제 #6
0
 public TransactionNTM(IAccountTypeInternal acctA, IAccount acctB,
 InstrumentSize valueSize,
 Price price, decimal exRate, DateTime transactionDate, DateTime transactionDateTime,
 Decimal ServiceChargePercentage, Side txSide,
 ITradingJournalEntry tradingJournalEntry,
 IGLLookupRecords lookups, ListOfTransactionComponents[] components, string description)
     : base(acctA, acctB, valueSize, price, exRate, transactionDate,
             transactionDateTime, ServiceChargePercentage, txSide,
             tradingJournalEntry, lookups, components)
 {
     this.Description = description;
 }
예제 #7
0
 public HistoricalPositionRowView(ICashPositionHistorical position)
 {
     key = position.Key;
     instrumentName = position.PositionInstrument.Name;
     size = position.HistoricalValue.Quantity;
     value = position.HistoricalBaseValue;
     PositionSize = position.HistoricalBaseValue;
     price = new Price(1m, position.PositionInstrument.ToCurrency, position.PositionInstrument);
     priceDate = position.Parent.PositionDate;
     exchangeRate = position.HistoricalValue.XRate;
     //modelAllocation = Math.Round(100m * position.ModelAllocation, 4);
     isin = "Cash";
 }
예제 #8
0
 public BonusDistribution(IAccountTypeInternal acctA, IAccount acctB,
 InstrumentSize valueSize,
 Price price, decimal exRate, DateTime transactionDate, DateTime transactionDateTime,
 Decimal ServiceChargePercentage, Side txSide,
 ICorporateActionBonusDistribution bonusDistributionDetails, ITradingJournalEntry tradingJournalEntry,
 IGLLookupRecords lookups, ListOfTransactionComponents[] components)
     : base(acctA, acctB, valueSize,
          price, exRate, transactionDate, transactionDateTime,
          ServiceChargePercentage, txSide,
          tradingJournalEntry,
          lookups, components)
 {
     this.CorporateActionType = CorporateActionTypes.BonusDistribution;
     this.CorporateActionDetails = bonusDistributionDetails;
 }
예제 #9
0
        public HistoricalPositionRowView(IFundPositionHistorical position)
        {
            key = position.Key;
            instrumentName = position.Size.Underlying.DisplayName;
            PositionSize = position.Size;
            size = position.Size.Quantity;
            value = position.HistoricalBaseValue;
            price = position.Price;
            priceDate = position.Parent.PositionDate;
            exchangeRate = position.HistoricalValue.XRate;
            //modelAllocation = Math.Round(100m * position.ModelAllocation, 4);

            if (position.Size.Underlying.IsTradeable)
            {
                ITradeableInstrument instrument = (ITradeableInstrument)position.Size.Underlying;
                isin = instrument.Isin;
            }
        }
예제 #10
0
        internal StgSizeOrder(IStgAmtOrder childOrder, InstrumentSize value, Price price, IOrderRouteMapper routeMapper)
            : base(childOrder.Account, value, false)
        {
            // Used for TypeConversion

            // Some check
            if (childOrder.ParentOrder != null)
                throw new ApplicationException("This order has a parent order and can no longer be converted.");

            this.IsTypeConverted = true;
            setInitialValues(routeMapper);
            this.price = price;
            this.ChildOrders.Add(childOrder);
            childOrder.Approve();
            //this.CommissionDetails = childOrder.CommissionDetails;
            this.exRate = childOrder.ExRate;
            Validate();
        }
예제 #11
0
        public PositionRowView(IFundPosition position)
        {
            key = position.Key;
            instrumentName = position.Size.Underlying.DisplayName;
            size = position.Size.Quantity;
            value = position.CurrentBaseValue;
            modelAllocation = Math.Round(100m * position.ModelAllocation, 4);

            if (position.Size.Underlying.IsWithPrice)
            {
                IInstrumentsWithPrices instrument = (IInstrumentsWithPrices)position.Size.Underlying;
                isin = instrument.Isin;
                IsCloseable = instrument.IsTradeable;
                if (instrument.CurrentPrice != null)
                {
                    price = instrument.CurrentPrice.Price;
                    priceDate = instrument.CurrentPrice.Date;
                }
                if (instrument.CurrencyNominal.ExchangeRate != null)
                    exchangeRate = instrument.CurrencyNominal.ExchangeRate.Rate;
                else
                {
                    if (instrument.CurrencyNominal.IsBase)
                        exchangeRate = 1M;
                }
                if (instrument.SecCategory.Key == SecCategories.Bond)
                {
                    IBond bond = (IBond)instrument;
                    if (bond != null && bond.DoesPayInterest)
                    {
                        AccruedInterest = position.
                            Get(v => v.BondCouponPayments).
                            Get(w => w.ActivePayment).
                            Get(x => x.DailyCalculations.
                            Get(y => y.LastCalculation).
                            Get(z => z.CalculatedAccruedInterestUpToDate));

                        ShowAccruedInterest = (AccruedInterest != null && AccruedInterest.IsNotZero);
                    }
                }
            }
        }
예제 #12
0
 internal AggregatedCashValuation(ValuationCollection cashValuations, bool aggregateToBase)
 {
     bool hasInitialized = false;
     if (aggregateToBase)
     {
         foreach (IValuation valuation in cashValuations)
         {
             if (valuation.Instrument.IsCash)
             {
                 if (this.account == null)
                 {
                     this.account = valuation.Account;
                     this.date = valuation.Date;
                     this.key = valuation.Key;
                     this.marketRate = 1M;
                     this.avgOpenExRate = 1M;
                     baseCurrency = ((ICurrency)valuation.Instrument).BaseCurrency;
                     price = new Price(1M, baseCurrency, baseCurrency);
                     this.bookPrice = price;
                     this.costPrice = price;
                     this.marketPrice = price;
                     this.displayInstrumentsCategory = valuation.DisplayInstrumentsCategory;
                     this.AssetClass = valuation.ValuationMutation.AssetClass;
                     this.ValuationMutation = valuation.ValuationMutation;
                 }
                 this.size += valuation.BaseMarketValue;
                 this.bookValue += valuation.BookValue;
                 this.bookChange += valuation.BookChange;
                 this.deposit += valuation.Deposit;
                 this.withDrawal += valuation.WithDrawal;
                 if (!valuation.ValuationMutation.IsSecurityValuationMutation)
                 {
                     this.depositToDate += ((IMonetaryValuationMutation)valuation.ValuationMutation).DepositToDate;
                     this.withDrawalToDate += ((IMonetaryValuationMutation)valuation.ValuationMutation).WithDrawalToDate;
                 }
                 hasInitialized = true;
             }
         }
     }
     if (!hasInitialized)
         throw new ApplicationException("Class AggregatedCashValuation could not be initialized");
 }
예제 #13
0
        public CorporateActionStockDividend(IAccountTypeInternal acctA, IAccount acctB,
        InstrumentSize valueSize, Price price, decimal exRate, DateTime transactionDate,
        IDividendHistory dividendDetails, InstrumentSize previousSize,
        ITradingJournalEntry tradingJournalEntry)
            : base(acctA, acctB, valueSize,
                 price, exRate, transactionDate, transactionDate,
                 0M, valueSize.Sign ? Side.XI : Side.XO,
                 tradingJournalEntry, null, null)
        {
            if (dividendDetails == null)
                throw new ApplicationException("Dividend details are mandatory when creating a stock dividend corporate action");

            if (previousSize == null)
                throw new ApplicationException("The units in possession are mandatory when creating a stock dividend corporate action");
            else if (previousSize.IsZero)
                throw new ApplicationException("The units can not be zero when creating a stock dividend corporate action");

            this.CorporateActionType = CorporateActionTypes.StockDividend;
            this.CorporateActionDetails = dividendDetails;
            this.PreviousSize = previousSize;
        }
예제 #14
0
파일: OrderP4.cs 프로젝트: kiquenet/B4F
        public static void CheckMaximalRoundOffError(bool isSizeBased, InstrumentSize size, Money amount, Price price, Money accruedInterest, Side side)
        {
            if (!isSizeBased)
            {
                InstrumentSize calcAmt = size.CalculateAmount(price) * (decimal)side * -1M;
                //if (accruedInterest != null && accruedInterest.IsNotZero)
                //{
                //    accruedInterest = accruedInterest.Abs() * (decimal)side * -1M;
                //    calcAmt += accruedInterest;
                //}

                InstrumentSize diff = (calcAmt.Abs() - amount.Abs());
                if (diff.IsNotZero && !diff.IsWithinTolerance(0.02m))
                {
                    decimal percLeft = diff.Abs().Quantity / amount.Abs().Quantity;
                    if (percLeft >= 0.05m)
                        throw new ApplicationException(string.Format(
                            "Price times Size ({0}) differs by {1}% from the provided Amount ({2}). Order cannot be filled.",
                            calcAmt.DisplayString, Math.Round(percLeft * 100m, 1), amount.DisplayString));
                }
            }
        }
예제 #15
0
파일: OrderP4.cs 프로젝트: kiquenet/B4F
        /// <summary>
        /// Fills an order by setting the agreed size and price, exchange rate, counter party and transaction date.
        /// </summary>
        /// <param name="trade">The order to be filled</param>
        /// <param name="size">Size of the instrument</param>
        /// <param name="price">Agreed price of the instrument</param>
        /// <param name="amount">Amount of the order (=size * price)</param>
        /// <returns>True if it succeeded</returns>
        protected bool fillOrder(ITransactionOrder trade, InstrumentSize size, Price price, Money amount, Money serviceCharge, Money accruedInterest)
        {
            decimal ratio = 1m;
            Transactions.AddTransactionOrder(trade);
            FilledValue += fillOrderValue(size, amount, serviceCharge, accruedInterest);
            if (this.IsSecurity)
            {
                ((ISecurityOrder)this).ServiceCharge += serviceCharge;
                if (this.IsAmountBased)
                    ((ISecurityOrder)this).AccruedInterest += accruedInterest;
            }

            // If OrderExecution -> set FillRatio
            if (trade.TransactionType == TransactionTypes.Execution)
            {
                if (IsCompleteFilled)
                    // if order is already partly filled -> subtract rest
                    ratio = 1M - Transactions.TotalFillRatio();
                else
                {
                    InstrumentSize diff = PlacedValue.Abs() - fillOrderValue(size, amount, serviceCharge, accruedInterest).Abs();
                    if (diff.IsZero || diff.IsWithinTolerance(0.02M))
                        ratio = 1M;
                    else
                    {
                        ratio = fillOrderValue(size, amount, serviceCharge, accruedInterest).Abs().Quantity / PlacedValue.Abs().Quantity;
                        // If this trade filled the order (OpenSize = 0) -> take the remainder ratio
                        if (OpenValue.IsZero)
                        {
                            decimal var = ratio - (1M - getFillatioTransactions());
                            if (Math.Abs(var) < 0.0001M)
                                ratio = 1M - getFillatioTransactions();
                        }
                    }
                }
            }
            trade.FillRatio = ratio;
            OrderStateMachine.SetNewStatus(this, OrderStateEvents.Fill);

            //// If MoneyOrder on order -> set ExRate
            //if (IsMonetary)
            //{
            //    // Use the size as the amount -> because it is a conversion
            //    processMoneyFill(price, trade);
            //}

            return true;
        }
예제 #16
0
 public override ISecurityOrder Convert(Price price, B4F.TotalGiro.OrderRouteMapper.IOrderRouteMapper routeMapper)
 {
     throw new ApplicationException("Client Orders may not be converted at this time");
 }
예제 #17
0
        protected virtual TransactionFillDetails getTransactionFillDetailsAmountBasedOrderByGoalSeek(
            Money grossAmount, Side side, bool isCommissionRelevant, bool isValueInclComm,
            DateTime settlementDate, Price price, IExchange exchange,
            ICommRule rule, ICommClient client, decimal servChargePerc, int precision)
        {
            decimal realAmount;
            decimal guess = grossAmount.Abs().CalculateSize(price).Quantity;
            FinancialMath.MaxCycles = 200;

            // Check -> use Commission
            bool useComm = true;
            bool useAddComm = false;
            if (!isCommissionRelevant || rule == null)
                useComm = false;

            if (useComm)
                useAddComm = (rule.AdditionalCalculation != null);

            realAmount = FinancialMath.GoalSeek(x =>
                new InstrumentSize(x, this).CalculateAmount(price).Quantity +
                (useComm ? rule.CommCalculation.Calculate(client.GetNewInstance(new InstrumentSize(x, this), price, (useAddComm ? rule.AdditionalCalculation.Calculate(client.GetNewInstance(new InstrumentSize(x, this), price)) : null))).Quantity : 0M) +
                (useAddComm ? rule.AdditionalCalculation.Calculate(client.GetNewInstance(new InstrumentSize(x, this), price)).Quantity : 0M) +
                (new InstrumentSize(x, this).CalculateAmount(price).Abs().Quantity * servChargePerc),
                grossAmount.Abs().Quantity, guess, precision);

            InstrumentSize size = new InstrumentSize(realAmount, this);
            Money amount = size.CalculateAmount(price);
            InstrumentSize cleanSize = amount.CalculateSize(price);

            Money servCh = (amount.Abs() * servChargePerc);
            Money comm = amount.ZeroedAmount();
            Money addComm = amount.ZeroedAmount();
            if (useComm)
            {
                if (rule.AdditionalCalculation != null)
                    addComm = rule.AdditionalCalculation.Calculate(client.GetNewInstance(cleanSize, price));
                comm = rule.CommCalculation.Calculate(client.GetNewInstance(cleanSize, price, addComm));

                // if sell -> comm is already in the amount
                if (side == Side.Sell && (comm + addComm) != null && (comm + addComm).IsNotZero)
                {
                    amount += (comm + addComm);
                    cleanSize = amount.CalculateSize(price);
                    if (!isValueInclComm)
                    {
                        if (rule.AdditionalCalculation != null)
                            addComm = rule.AdditionalCalculation.Calculate(client.GetNewInstance(cleanSize, price));
                        comm = rule.CommCalculation.Calculate(client.GetNewInstance(cleanSize, price, addComm));
                    }
                }
            }
            return new TransactionFillDetails(cleanSize, amount, null, servCh, servChargePerc, comm + addComm, grossAmount.Abs(), side);
        }
예제 #18
0
 protected virtual TransactionFillDetails getTransactionFillDetailsAmountBasedOrderByGoalSeek(
     IOrderAmountBased order, DateTime settlementDate, Price price, IExchange exchange,
     ICommRule rule, ICommClient client, decimal servChargePerc, int precision)
 {
     try
     {
         TransactionFillDetails details = getTransactionFillDetailsAmountBasedOrderByGoalSeek(
             order.GrossAmount, order.Side, order.IsCommissionRelevant, order.IsValueInclComm,
             settlementDate, price, exchange, rule, client, servChargePerc, precision);
         if (details.IsOK)
         {
             Money diff = details.Diff;
             if (diff != null && diff.IsNotZero && diff.IsWithinTolerance(0.09M))
             {
                 details.FixUp(order);
                 details.Size = details.Amount.CalculateSize(price);
                 details.Info = string.Format("F{0}", precision);
             }
         }
         return details;
     }
     catch
     {
     }
     return new TransactionFillDetails();
 }
예제 #19
0
        public static void UpdateHistoricalPrice(DateTime date, decimal PriceQuantity, string isin)
        {
            IDalSession session = NHSessionFactory.CreateSession();

            IInstrumentsWithPrices instrument = (IInstrumentsWithPrices)InstrumentMapper.GetInstrumentswithPricesByIsin(session, isin)[0];
            Price price = new Price(PriceQuantity, instrument.CurrencyNominal, instrument);

            IList<IHistoricalPrice> historicalPrices = HistoricalPriceMapper.GetHistoricalPrices(session, instrument, date);
            IHistoricalPrice historicalPrice = null;

            if (historicalPrices.Count == 0)
            {
                instrument.HistoricalPrices.AddHistoricalPrice(new HistoricalPrice(price, date));
                InstrumentMapper.Update(session, instrument);
            }
            else
            {
                historicalPrice = (IHistoricalPrice)historicalPrices[0];
                historicalPrice.Price = price;
                HistoricalPriceMapper.Update(session, historicalPrice);
            }

            //Hashtable parameters = new Hashtable();
            //parameters.Add("InstrumentID", instrument.Key);
            //session.ExecuteStoredProcedure("EXEC dbo.TG_FillHistPricesWeekendsHolidays @p_intInstrumentID = :InstrumentID", parameters);

            session.Close();
        }
예제 #20
0
파일: StgAmtOrder.cs 프로젝트: kiquenet/B4F
 public new virtual ISecurityOrder Convert(Price price, IOrderRouteMapper routeMapper)
 {
     InstrumentSize value = Amount.CalculateSize(price);
     return new StgSizeOrder(this, value, price, routeMapper);
 }
예제 #21
0
파일: OrderP4.cs 프로젝트: kiquenet/B4F
        public IOrderExecution Fill(InstrumentSize size, Price price, Money amount, decimal exRate,
            IAccount counterParty, DateTime transactionDate, DateTime transactionDateTime, IExchange exchange,
            bool isCompleteFill, Money serviceCharge, decimal serviceChargePercentage, Money accruedInterest,
            ITradingJournalEntry tradingJournalEntry, IGLLookupRecords lookups)
        {
            IOrderExecution returnValue = null;

            if (size == null || price == null || amount == null)
                throw new Exception("Size, Price and Amount are mandatory when filling the order.");

            if (IsFillable != OrderFillability.True)
                throw new ApplicationException("This Order is not fillable.");

            setSignServiceCharge(ref serviceCharge, ref serviceChargePercentage);
            if (accruedInterest != null && accruedInterest.IsNotZero)
                accruedInterest = accruedInterest.Abs() * (decimal)this.Side * -1M;
            CheckMaximalRoundOffError(IsSizeBased, size, amount, price, accruedInterest, this.Side);

            if (isCompleteFill)
            {
                // Check whether the order has not been filled before
                if (Transactions.Count > 0)
                    throw new ApplicationException("The order has already been filled and so it can not be a complete fill.");

                if (this.OpenValue.IsZero)
                    throw new ApplicationException("The open value of this order is zero.");

                InstrumentSize diff = getTradeDifferenceOpenValue(size, amount, serviceCharge, accruedInterest);
                if (diff.IsNotZero)
                {
                    const decimal maxAllowed = 0.05m;
                    // TickSize && NominalValue
                    decimal tickSize = 0M;
                    if (this.OrderType == OrderTypes.SizeBased)
                    {
                        IInstrumentExchange ie = getInstrumentExchange(exchange);
                        if (ie != null)
                            tickSize = ie.TickSize;
                    }
                    if (this.RequestedInstrument.SecCategory.Key == SecCategories.Bond)
                        tickSize = ((IBond)this.RequestedInstrument).NominalValue.Quantity;

                    if (!(tickSize > 0M && Math.Abs(diff.Quantity / tickSize) < 1M))
                    {
                        decimal fillRatio = diff.Abs().Quantity / this.OpenValue.Abs().Quantity;
                        if (fillRatio > maxAllowed)
                            throw new ApplicationException(
                                string.Format("The size of this transaction is different from the order size by more than {0:0.##}%.", maxAllowed * 100));
                    }
                }
                amount.XRate = exRate;
            }
            else
            {
                orderInitialCheck(ref amount, size, exRate, serviceCharge, accruedInterest);
            }

            this.IsCompleteFilled = isCompleteFill;
            orderCheckSide(this.Side, ref amount, ref size);
            checkServiceChargePercentage(serviceCharge, serviceChargePercentage, amount);

            ListOfTransactionComponents[] components = packageComponents(amount, serviceCharge, accruedInterest);

            returnValue = new OrderExecution(this, counterParty, size, price, exRate, transactionDate, transactionDateTime, serviceChargePercentage, tradingJournalEntry, lookups, components);
            fillOrder(returnValue, size, price, amount, serviceCharge, accruedInterest);
            return returnValue;
        }
예제 #22
0
 public new virtual ISecurityOrder Convert(Price price, IOrderRouteMapper routeMapper)
 {
     Money value = this.Value.CalculateAmount(price);
     return new StgAmtOrder(this, value);
 }
예제 #23
0
파일: Price.cs 프로젝트: kiquenet/B4F
 private static Price MathOperation(Price lhs, Price rhs, MathOperator op)
 {
     if (((Object)rhs == null) && ((Object)lhs == null))
     {
         //throw new ApplicationException("Both Prices may not be Null!");
         return null;
     }
     else if (((Object)rhs == null) || ((Object)lhs == null))
     {
         if ((Object)rhs == null)
         {
             return (Price)lhs.MemberwiseClone();
         }
         else
         {
             switch (op)
             {
                 case MathOperator.Add:
                     return (Price)rhs.MemberwiseClone();
                 case MathOperator.Subtract:
                     return (rhs * -1);
                 default:
                     throw new ApplicationException("You did not select a valid math operation");
             }
         }
     }
     else
     {
         // Use Eq because it is not possible to do operator overloading on an interface
         if (!(lhs.Underlying.Equals(rhs.Underlying)))
         {
             throw new ApplicationException("Cannot add Two different currencies!");
         }
         else if (!(lhs.Instrument.Equals(rhs.Instrument)))
         {
             throw new ApplicationException("Cannot add Two different instruments!");
         }
         else
         {
             switch (op)
             {
                 case MathOperator.Add:
                     return lhs.Clone(lhs.Quantity + rhs.Quantity);
                 case MathOperator.Subtract:
                     return lhs.Clone(lhs.Quantity - rhs.Quantity);
                 default:
                     throw new ApplicationException("You did not select a valid math operation");
             }
         }
     }
 }
예제 #24
0
파일: Price.cs 프로젝트: kiquenet/B4F
        private static bool CompareOperation(Price lhs, Price rhs, CompareOperator cp)
        {
            bool result;

            if (((Object)rhs == null) || ((Object)lhs == null))
            {
                throw new ApplicationException("One or both Prices can not be Null!");
            }
            else
            {
                // Use Eq because it is not possible to do operator overloading on an interface
                if (!(lhs.Underlying.Equals(rhs.Underlying)))
                {
                    throw new ApplicationException("Cannot compare prices with different currencies");
                }
                else if (!(lhs.Instrument.Equals(rhs.Instrument)))
                {
                    throw new ApplicationException("Cannot compare prices with different instruments");
                }
                else
                {
                    switch (cp)
                    {
                        case CompareOperator.Greater:
                            result = (lhs.Quantity > rhs.Quantity);
                            break;
                        case CompareOperator.GreaterOrEqual:
                            result = (lhs.Quantity >= rhs.Quantity);
                            break;
                        case CompareOperator.Smaller:
                            result = (lhs.Quantity < rhs.Quantity);
                            break;
                        case CompareOperator.SmallerOrEqual:
                            result = (lhs.Quantity <= rhs.Quantity);
                            break;
                        default:
                            throw new ApplicationException("You did not select a valid comparison option");
                    }
                    return result;
                }
            }
        }
예제 #25
0
파일: OrderP4.cs 프로젝트: kiquenet/B4F
        private void processMoneyFill(Price price, ITransactionOrder newTrade)
        {
            //// If MoneyOrder on order -> set ExRate
            //if (IsMonetary)
            //{
            //    IStgMonetaryOrder mo = null;
            //    if (IsStgOrder && IsMonetary)
            //        mo = this as IStgMonetaryOrder;

            //    if (mo != null && mo.MoneyParent != null)
            //    {
            //        // First check if already exist
            //        if (mo.MoneyParent.ParentOrder != null)
            //            throw new ApplicationException("Monetary orders can only be filled once.");

            //        decimal exRate = Math.Round(1 / price.Quantity, 6);
            //        Money amount = mo.MoneyParent.Amount.Convert(exRate, (ICurrency)price.Instrument);
            //        StgAmtOrder newParent = new StgAmtOrder((IStgAmtOrder)mo.MoneyParent, amount, exRate);
            //        mo.MoneyParent.SetParentOrder(newParent);
            //        newTrade.ConvertedOrder = newParent;
            //        ((IOrder)mo.MoneyParent).SetExRate(exRate);

            //        //newParent.Approve();
            //    }
            //}
        }
예제 #26
0
 public virtual TransactionFillDetails GetTransactionFillDetails(
     IOrder order, Price price, DateTime settlementDate, IFeeFactory feeFactory,
     decimal fillRatio, IExchange exchange)
 {
     if (order.IsSizeBased)
         return GetTransactionFillDetails((IOrderSizeBased)order, price, settlementDate, feeFactory, fillRatio, exchange);
     else
         return GetTransactionFillDetails((IOrderAmountBased)order, price, settlementDate, feeFactory, fillRatio, exchange);
 }
예제 #27
0
파일: StgAmtOrder.cs 프로젝트: kiquenet/B4F
        public virtual IStgSizeOrder ConvertBondOrder(Price price, DateTime settlementDate, IOrderRouteMapper routeMapper)
        {
            if (TradedInstrument.SecCategory.Key != SecCategories.Bond)
                throw new ApplicationException("This is not a bond order.");

            IBond bond = (IBond)TradedInstrument;
            if (bond.DoesPayInterest)
            {
                // Calculate backwards the number of bonds
                InstrumentSize value = bond.CalculateSizeBackwards(Amount, price, settlementDate);
                StgSizeOrder convertedOrder = new StgSizeOrder(this, value, price, routeMapper);
                AccruedInterestDetails calc = bond.AccruedInterest(value, settlementDate, null);
                if (calc.IsRelevant)
                    convertedOrder.AccruedInterest = calc.AccruedInterest;
                return convertedOrder;
            }
            else
                return (IStgSizeOrder)this.Convert(price, routeMapper);
        }
예제 #28
0
        public virtual TransactionFillDetails GetTransactionFillDetails(
            IOrderSizeBased order, Price price, DateTime settlementDate, IFeeFactory feeFactory,
            decimal fillRatio, IExchange exchange)
        {
            Money serviceCharge = null;
            Money commission = null;
            decimal serviceChargePercentageforOrder = getServiceChargePercentage(order, exchange);

            // Use the Value of the child order -> difference will go to Crumble account
            InstrumentSize size = order.Value * fillRatio;
            Money amount = size.CalculateAmount(price);

            if (serviceChargePercentageforOrder != 0M)
                serviceCharge = (amount * serviceChargePercentageforOrder).Abs().Negate();

            TransactionFillDetails details = new TransactionFillDetails(size, amount, null, serviceCharge, serviceChargePercentageforOrder, commission, order.GrossAmount, order.Side);
            details.SetSign(order.Side);
            return details;
        }
예제 #29
0
        public static void UpdateOrderFill(OrderFillView orderFillView)
        {
            IDalSession session = NHSessionFactory.CreateSession();

            try
            {
                ICurrency orderCurrency;
                ITransaction transaction;
                IExchange exchange = null;
                Money serviceCharge = null;
                decimal serviceChargePercentage = 0m;

                ISecurityOrder order = (ISecurityOrder)OrderMapper.GetOrder(session, orderFillView.OrderId);

                IAccount counterpartyAccount = AccountMapper.GetAccountByNumber(session, FUND_SETTLE);
                if (counterpartyAccount == null)
                    throw new ApplicationException(string.Format("The counterparty account {0} can not be found in the database.", FUND_SETTLE));

                if (orderFillView.ExchangeId != 0 && orderFillView.ExchangeId != int.MinValue)
                    exchange = ExchangeMapper.GetExchange(session, orderFillView.ExchangeId);
                if (exchange == null)
                    throw new ApplicationException("Select an exchange when filling the order");

                if (order.Value.Underlying.IsCash)
                    orderCurrency = (ICurrency)order.Value.Underlying;
                else
                    orderCurrency = ((ITradeableInstrument)order.Value.Underlying).CurrencyNominal;

                Price price = new Price(orderFillView.Price, orderCurrency, ((ISecurityOrder)(order)).TradedInstrument);

                InstrumentSize size = new InstrumentSize(orderFillView.Size, order.TradedInstrument);

                ICurrency txCurrency = null;
                if (order.TradedInstrument.IsCash)
                    txCurrency = (ICurrency)order.TradedInstrument;
                else
                    txCurrency = (ICurrency)order.TradedInstrument.CurrencyNominal;

                decimal exRate = order.TradedInstrument.CurrencyNominal.ExchangeRate.Rate;
                if (orderFillView.ServiceChargeAmount != 0)
                {
                    serviceCharge = new Money(orderFillView.ServiceChargeAmount, txCurrency);
                    serviceChargePercentage = orderFillView.ServiceChargePercentage;
                }

                //if (orderFillView.IsCompleteFill)
                //{
                Money amount = new Money(orderFillView.Amount, txCurrency);
                //transaction = order.Fill(size, price, amount, exRate, counterpartyAccount,
                //    orderFillView.TransactionDate, orderFillView.TransactionTime, exchange,
                //    orderFillView.IsCompleteFill, serviceCharge, serviceChargePercentage);
                //}
                //else
                //    transaction = order.Fill(size, price, exRate, counterpartyAccount, orderFillView.TransactionDate, serviceCharge, serviceChargePercentage);

                //if (Util.IsNotNullDate(orderFillView.SettlementDate))
                //    transaction.ContractualSettlementDate = orderFillView.SettlementDate;
                //transaction.Approve();

                //TransactionMapper.Insert(session, transaction);

                //if (transaction.Approved)
                //{
                //    IFeeFactory fees = FeeFactory.GetInstance(session);
                //    //order.Allocate(transaction, fees);

                //    OrderMapper.Update(session, order);
                //}
            }
            finally
            {
                session.Close();
            }
        }
예제 #30
0
        public TransactionFillDetails GetTransactionFillDetails(
            IOrderAmountBased order, Price price, DateTime settlementDate, IFeeFactory feeFactory,
            decimal fillRatio, IExchange exchange)
        {
            decimal serviceChargePercentageforOrder = getServiceChargePercentage(order, exchange);
            TransactionFillDetails details = null;

            if (IsCommissionLinear)
            {
                Money amount = order.Amount * fillRatio;
                Money serviceCharge = null;

                if (serviceChargePercentageforOrder != 0M)
                {
                    Money newAmount = amount * (decimal)(1M / (1M + serviceChargePercentageforOrder));
                    serviceCharge = (amount.Abs() - newAmount.Abs());
                    amount = newAmount;
                }

                // Calculate Commission
                Money commission = null;
                // if the trade fills the Order completely -> take the Commission from the Order
                if (fillRatio == 1M)
                    commission = order.Commission;

                // Convert amount when necessary
                if (!amount.Underlying.Equals(price.Underlying) && !price.Underlying.IsObsoleteCurrency)
                    amount = amount.Convert(order.ExRate, price.Underlying);

                InstrumentSize size = amount.CalculateSize(price);

                details = new TransactionFillDetails(size, amount, null, serviceCharge, serviceChargePercentageforOrder, commission, order.GrossAmount, order.Side);
            }
            else
            {
                // Do the goalseek
                ICommClient client;
                ICommRule rule = feeFactory.GetRelevantCommRule(order.Account, this, order.Side,
                    order.ActionType, settlementDate, true, out client);

                for (int i = 4; i > 0; i--)
                {
                    details = getTransactionFillDetailsAmountBasedOrderByGoalSeek(
                        order, settlementDate, price, exchange,
                        rule, client, serviceChargePercentageforOrder, i);

                    if (details.IsOK && !details.IsDiff)
                        break;
                }
                if (!details.IsOK || details.IsDiff)
                    throw new ApplicationException("Not possible to calculate the trade amounts, probably a commission rule applied with a minimum amount.");
            }
            if (details != null)
                details.SetSign(order.Side);
            return details;
        }