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; } }
/// <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; }
public FundPositionHistorical(IFundPortfolioHistorical parent, InstrumentSize size, Price price, Decimal rate) { this.Parent = parent; this.Size = size; this.Price = price; this.rate = rate; }
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) { }
/// <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; }
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; }
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"; }
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; }
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; } }
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(); }
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); } } } }
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"); }
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; }
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)); } } }
/// <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; }
public override ISecurityOrder Convert(Price price, B4F.TotalGiro.OrderRouteMapper.IOrderRouteMapper routeMapper) { throw new ApplicationException("Client Orders may not be converted at this time"); }
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); }
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(); }
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(); }
public new virtual ISecurityOrder Convert(Price price, IOrderRouteMapper routeMapper) { InstrumentSize value = Amount.CalculateSize(price); return new StgSizeOrder(this, value, price, routeMapper); }
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; }
public new virtual ISecurityOrder Convert(Price price, IOrderRouteMapper routeMapper) { Money value = this.Value.CalculateAmount(price); return new StgAmtOrder(this, value); }
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"); } } } }
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; } } }
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(); // } //} }
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); }
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); }
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; }
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(); } }
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; }