/// <summary> /// Constructor /// </summary> /// <param name="parent">Parent order</param> /// <param name="feeFactory">Fee factory to use for calculating transaction costs</param> internal MonetaryOrder(IOrderAmountBased parent, IFeeFactory feeFactory) : base(parent.Account, (parent.Amount - parent.Commission)) { if (parent.TradedInstrument != null && parent.TradedInstrument.IsTradeable) { ITradeableInstrument instrument = (ITradeableInstrument)parent.TradedInstrument; this.requestedCurrency = instrument.CurrencyNominal; checkInitialValues(); setCommission(feeFactory); this.moneyParent = parent; } else throw new ApplicationException("Can not insert a monetary order without a requested currency"); }
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 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; }
/// <summary> /// Constructor, initializes amount-based order class /// </summary> /// <param name="account">User account</param> /// <param name="childOrder">Amount-based child order</param> public AggregateAmtOrder(IAccountTypeInternal account, IOrderAmountBased childOrder) : base(account, new Money(0M, (ICurrency)childOrder.Value.Underlying), childOrder.TradedInstrument, childOrder.IsValueInclComm, null, true) { base.Side = childOrder.Side; }
public bool FixUp(IOrderAmountBased order) { bool success = false; Money diff = Diff; if (diff.IsNotZero && diff.IsWithinTolerance(0.09M)) { // Only adjust for saved orders (at trade fill) -> otherwise adjust the commission if (order.Key != 0 && (order.Amount.Abs() - Amount - ServiceCharge).IsWithinTolerance(0.03M)) { Amount = order.Amount.Abs() - ServiceCharge; Commission = order.Commission.Abs(); } else Commission -= diff; success = true; } return success; }