protected string GetClearingID(Trade trade, string name)
        {
            // find which allocation number we are
            var allocNo = GetAllocationNo(trade);

            // there are number of entries for each allocation, need to find the one with clearing ID
            int entryNo = 1;
            bool found = true;
            do
            {
                var eventProperty = String.Format("{0}:{1}:{2}", sConfirmRegReportingEvent, allocNo, entryNo);
                var typeProperty = String.Format("{0}:{1}:{2}", sConfirmRegReportingType, allocNo, entryNo);
                if(!trade.Properties.ContainsKey(eventProperty) || !trade.Properties.ContainsKey(typeProperty))
                {
                    found = false;
                }
                else
                {
                    var eventValue = trade.GetProperty(eventProperty);
                    var typeValue = trade.GetProperty(typeProperty);
                    if(eventValue == "2" && typeValue == "0")
                    {
                        // this is it, Event = Clearing, Type = Current
                        var propertyToRetrieve = String.Format("{0}:{1}:{2}", name, allocNo, entryNo);
                        return trade.GetProperty(propertyToRetrieve);
                    }
                }
                entryNo++;
            } while (found);
            return String.Empty;
        }
        internal static string GetGeneratorName(Trade trade)
        {
            var gname = trade.GetProperty(TradeImportHelper.GeneratorProp);
            if (!string.IsNullOrEmpty(gname)) return gname;
            var template = trade.GetProperty(TradeImportHelper.TemplateProp);
            if (template != null)
            {
                var prod = trade.Product;
                string aliasSource = null;
                if (prod is MTMCurrencySwap || prod is CurrencySwap)
                    aliasSource = SwapInfo.AliasSourceCcy;
                else if (prod is FRA)
                    aliasSource = SwapInfo.AliasSourceFra;
                else if (prod is Swap)
                    aliasSource = SwapInfo.AliasSourceIrs;
                else if (prod is Swaption)
                    aliasSource = SwaptionInfo.AliasSourceSwpt;
                if (aliasSource != null)
                {
                    //if (aliasSource.Equals(SwapInfo.AliasSourceIrs) || aliasSource.Equals(SwaptionInfo.AliasSourceSwpt))
                    {
                        // use ot template -> generator mapping
                        var alias =
                            new Alias
                            {
                                AliasType = "Template",
                                EntityId = 0,
                                Source = aliasSource,
                                SourceReference = template
                            };
                        alias = Env.Current.StaticData.GetAlias(alias);
                        if (alias != null)
                        {
                            trade.SetProperty("Generator", alias.Name);
                            return alias.Name;
                        }
                    }
                    /*
                    else
                    {
                        // use generator <- ot template mapping
                        var aliases = Env.Current.StaticData.GetAliasesByName(new Alias
                            {
                                AliasType = "Template",
                                EntityId = 0,
                                Source = aliasSource,
                                Name = template
                            });
                        if (aliases != null && aliases.Count > 0)
                        {
                            var alias = aliases[0];
                            trade.SetProperty("Generator", alias.SourceReference);
                            return alias.SourceReference;

                        }
                    }*/
                }
            }
            return null;
        }
 protected void SetMatchingFlag(Trade otTrade, Trade externalTrade)
 {
     otTrade.SetProperty(ImportRef, externalTrade.GetProperty("ImportRef"));
     otTrade.SetProperty(Reconciled, "true");
     externalTrade.SetProperty(Reconciled, "true");
 }
        public bool Reconcile(Trade otTrade, Trade externalTrade, Market market, bool fullMatch, DateTime reconcileDate,
                              IList<Exception> exceps)
        {
            string unmatchReason = string.Empty;
            var s = otTrade.GetProperty(ImportRef);
            var s2 = externalTrade.GetProperty(ImportRef);
            if (s != null && s2 != null)
            {
                if (s.Equals(s2)) return true;
            }

            s = otTrade.GetProperty(Reconciled);
            if (s != null && s.ToLowerInvariant().Equals("true")) return false;
            s2 = externalTrade.GetProperty(Reconciled);
            if (s2 != null && s2.ToLowerInvariant().Equals("true")) return false;

            if (externalTrade.BookId != otTrade.BookId) return false;
            /*
            if (externalTrade.BookId != 0)
            {
                if (otTrade.BookId != externalTrade.BookId)
                {
                    if (fullMatch) return false;
                    else
                    {
                        var book1 = Env.Current.StaticData.GetPartyById(otTrade.BookId);
                        var book2 = Env.Current.StaticData.GetPartyById(externalTrade.BookId);
                        if (book1 != null && book2 != null)
                        {
                            var port1 = book1.GetProperty(TradeImportHelper.BookProp2);
                            var port2 = book2.GetProperty(TradeImportHelper.BookProp2);
                            if (port1 != null && port2 != null && !port1.Equals(port2))
                            {
                                return false;
                            }
                        }
                        unmatchReason += "Book ";
                    }
                }
            }
            else
            {
                return false;
            }*/
            #region symmetryProduct
            var ifsproduct = externalTrade.Product as SymmetryProduct;
            if (ifsproduct != null)
            {

                if (ifsproduct.SecurityType.ToLowerInvariant() == "currency swaps")
                {
                    if (otTrade.Product is MTMCurrencySwap)
                    {

                        //Check Generator
                        var generator = GetGeneratorName(otTrade);
                        if (generator == null) return false;
                        if (!ifsproduct.Security.StartsWith(generator)) return false;
                        if (!ifsproduct.Generator.Equals(generator.Trim())) return false;
                        if (otTrade.Product.ContractMaturity != ifsproduct.ContractMaturity)
                        {
                            var sd = otTrade.Product.ContractMaturity;
                            var sw = otTrade.Product as MTMCurrencySwap;
                            var paymentP = CalendarHelper.Get(sw.PayLeg.PaymentMarketPlaces);
                            if (!sd.IsBusinessDay(paymentP))
                            {
                                sd = sd.NextBusinessDay(paymentP);
                                if (sd != ifsproduct.ContractMaturity) return false;
                            }
                            else return false;
                        }

                        if (externalTrade.Product.Currency == "USD")
                        {
                            //The Nominal may be in the other currency
                            var swap = otTrade.Product as MTMCurrencySwap;
                            if (swap.PayLeg.NotionalCurrency == "USD")
                            {
                                if (Math.Abs(externalTrade.Quantity - swap.ReceiveLeg.Notional) < Utilities.Epsilon)
                                {
                                    if (fullMatch)
                                        SetMatchingFlag(otTrade, externalTrade);
                                    return true;
                                }
                                unmatchReason += "RecLegNotional ";
                            }
                            else
                            {
                                if (Math.Abs(externalTrade.Quantity - swap.PayLeg.Notional) < Utilities.Epsilon)
                                {
                                    if (fullMatch)
                                        SetMatchingFlag(otTrade, externalTrade);
                                    return true;
                                }
                                unmatchReason += "PayLegNotional ";
                            }
                        }

                        if (externalTrade.Product.Currency == otTrade.SettleCurrency)
                        {
                            if (Math.Abs(externalTrade.Quantity - otTrade.Quantity) > Utilities.Epsilon)
                            {
                                if (fullMatch) return false;
                                else unmatchReason += "Notional ";
                            }

                        }
                        else
                        {
                            if (Math.Abs(externalTrade.Quantity - otTrade.SettleAmount) > Utilities.Epsilon)
                            {
                                if (fullMatch) return false;
                                else unmatchReason += "Notional ";
                            }

                        }

                        if (fullMatch)
                            SetMatchingFlag(otTrade, externalTrade);
                        else
                            otTrade.SetProperty(ReconcileTaskExecutor.UnmatchReason, unmatchReason);
                        return true;
                    }
                    if (otTrade.Product is CurrencySwap)
                    {

                        //Check Generator
                        var generator = GetGeneratorName(otTrade);
                        if (generator == null) return false;
                        if (!ifsproduct.Security.StartsWith(generator)) return false;
                        if (!ifsproduct.Generator.Equals(generator.Trim())) return false;
                        if (otTrade.Product.ContractMaturity != ifsproduct.ContractMaturity)
                        {
                            var sd = otTrade.Product.ContractMaturity;
                            var sw = otTrade.Product as CurrencySwap;
                            var paymentP = CalendarHelper.Get(sw.PayLeg.PaymentMarketPlaces);
                            if (!sd.IsBusinessDay(paymentP))
                            {
                                sd = sd.NextBusinessDay(paymentP);
                                if (sd != ifsproduct.ContractMaturity) return false;
                            }
                            else return false;
                        }


                        //The Nominal may be in the other currency
                        var swap = otTrade.Product as CurrencySwap;

                        if (Math.Abs(externalTrade.Quantity - swap.ReceiveLeg.Notional) < Utilities.Epsilon)
                        {
                            if (fullMatch)
                                SetMatchingFlag(otTrade, externalTrade);
                            return true;
                        }
                        unmatchReason += "RecLegNotional ";

                        if (Math.Abs(externalTrade.Quantity - swap.PayLeg.Notional) < Utilities.Epsilon)
                        {
                            if (fullMatch)
                                SetMatchingFlag(otTrade, externalTrade);
                            return true;
                        }
                        unmatchReason += "PayLegNotional ";

                        if (!fullMatch)
                        {
                            otTrade.SetProperty(ReconcileTaskExecutor.UnmatchReason, unmatchReason);
                            return true;
                        }
                    }
                    return false;
                }


                if (ifsproduct.SecurityType.ToLowerInvariant() == "interest rate swaps")
                {

                    if (otTrade.Product is Swap)
                    {
                        var ccy = otTrade.Product.Currency;
                        if (otTrade.Product is NDS)
                        {
                            ccy = (otTrade.Product as NDS).NonDeliverableCurrency;
                        }
                        if (ccy != ifsproduct.Currency) return false;
                        var generator = GetGeneratorName(otTrade);
                        if (generator == null) return false;
                        var isBasisSwap = generator.ToLower().Contains("basis");
                        if (!ifsproduct.Security.StartsWith(generator)) return false;
                        if (!ifsproduct.Generator.Equals(generator.Trim())) return false;

                        if (otTrade.Product.ContractMaturity != ifsproduct.ContractMaturity)
                        {
                            var sd = otTrade.Product.ContractMaturity;
                            var sw = otTrade.Product as Swap;
                            var paymentP = CalendarHelper.Get(sw.PayLeg.PaymentMarketPlaces);
                            if (!sd.IsBusinessDay(paymentP))
                            {
                                sd = sd.NextBusinessDay(paymentP);
                                if (sd != ifsproduct.ContractMaturity) return false;
                            }
                            else return false;
                        }
                        // for basis swap, we don't have the side infomation, so can only compare the abs value
                        var notionalDiff = isBasisSwap ? Math.Abs(externalTrade.Quantity) - Math.Abs(otTrade.Quantity)
                            : externalTrade.Quantity - otTrade.Quantity;
                        if (Math.Abs(notionalDiff) > Utilities.Epsilon)
                        {
                            if (fullMatch) return false;
                            unmatchReason += "Notional ";
                        }
                       
                        if (fullMatch)
                            SetMatchingFlag(otTrade, externalTrade);
                        else
                            otTrade.SetProperty(ReconcileTaskExecutor.UnmatchReason, unmatchReason);
                        return true;
                    }
                    return false;
                }
                if (ifsproduct.SecurityType.ToLowerInvariant() == "swaptions")
                {

                    if (otTrade.Product is Swaption)
                    {
                        var ccy = otTrade.Product.Currency;
                        var swaption = otTrade.Product as Swaption;
                        if (ccy != ifsproduct.Currency) return false;
                        if (otTrade.Product.ContractMaturity != ifsproduct.ContractMaturity) return false;
                        //Check Generator
                        var generator = GetGeneratorName(otTrade);
                        if (generator == null) return false;
                        if (!ifsproduct.Security.StartsWith(generator)) return false;
                        if (!ifsproduct.Generator.Equals(generator.Trim())) return false;
                        if (Math.Abs(ifsproduct.Strike - swaption.OptionStrike) > Utilities.Epsilon) return false;
                        if (swaption.OptionType == OptionType.Put)
                        { 
                            // PAY
                            if (!ifsproduct.Security.Contains("PAY")) return false;
                        }
                        else if (swaption.OptionType == OptionType.Call)
                        { 
                            //REC
                            if (!ifsproduct.Security.Contains("REC")) return false;
                        }
                        if (Math.Abs(externalTrade.Quantity - otTrade.Quantity) > Utilities.Epsilon)
                        {
                            if (fullMatch) return false;
                            unmatchReason += "Notional ";
                        }
                        if (fullMatch)
                            SetMatchingFlag(otTrade, externalTrade);
                        else otTrade.SetProperty(ReconcileTaskExecutor.UnmatchReason, unmatchReason);
                        return true;
                    }
                    return false;
                }
                if (ifsproduct.SecurityType.ToLowerInvariant() == "fras")
                {

                    if (otTrade.Product is FRA)
                    {
                        var ccy = otTrade.Product.Currency;
                        if (ccy != ifsproduct.Currency) return false;
                        var fra = otTrade.Product as FRA;
                        if (fra.StartDate != ifsproduct.ContractMaturity) return false;
                        //Check Generator
                        var generator = GetGeneratorName(otTrade);
                        if (generator == null) return false;
                        if (!ifsproduct.Security.StartsWith(generator)) return false;
                        if (!ifsproduct.Generator.Equals(generator.Trim())) return false;
                        if (Math.Abs(externalTrade.Quantity - otTrade.Quantity) > Utilities.Epsilon)
                        {
                            if (fullMatch) return false;
                            else unmatchReason += "Notional ";
                        }


                        if (fullMatch)
                            SetMatchingFlag(otTrade, externalTrade);
                        else otTrade.SetProperty(ReconcileTaskExecutor.UnmatchReason, unmatchReason);
                        return true;
                    }
                    return false;
                }
                return false;
            }
            #endregion symemtryProduct
            #region fx
            var fxifs = externalTrade.Product as FX;
            if (fxifs != null)
            {
                if (otTrade.Product is FX)
                {
                    if (otTrade.SettlementDate != externalTrade.SettlementDate) return false;
                    var fx = otTrade.Product as FX;
                    if (!fx.CurrencyPair.Equals(fxifs.CurrencyPair)) return false;

                    if (Math.Abs(fxifs.PrimaryAmount - 0) > Utilities.Epsilon)
                    {
                        if (Math.Abs(fx.PrimaryAmount - fxifs.PrimaryAmount) < 1)
                        {
                            SetMatchingFlag(otTrade, externalTrade);
                            return true;
                        }
                        unmatchReason += "PrimaryAmount ";
                    }
                    else if (Math.Abs(fxifs.QuotingAmount - 0) > Utilities.Epsilon)
                    {
                        if (Math.Abs(fx.QuotingAmount - fxifs.QuotingAmount) < 1)
                        {
                            SetMatchingFlag(otTrade, externalTrade);
                            return true;
                        }
                        unmatchReason += "QuotingAmount ";
                    }
                    else
                    {
                        if (Math.Abs(fxifs.QuotingAmount - 0) < Utilities.Epsilon && Math.Abs(fxifs.PrimaryAmount - 0) < Utilities.Epsilon)
                        {
                            if (Math.Abs(fx.PrimaryAmount - 0) < Utilities.Epsilon || Math.Abs(fx.QuotingAmount - 0) < Utilities.Epsilon)
                            {
                                SetMatchingFlag(otTrade, externalTrade);
                                return true;
                            }
                            unmatchReason += "PrimaryAmount QuotingAmount ";
                        }
                    }
                    if (!fullMatch)
                    {
                        otTrade.SetProperty(ReconcileTaskExecutor.UnmatchReason, unmatchReason);
                        return true;
                    }
                    return false;


                }
                return false;
            }
            #endregion fx
            #region listed
            var fut = externalTrade.Product as Future;
            if (fut != null)
            {
                if (otTrade.Product is Future)
                {
                    var otfut = otTrade.Product as Future;
                    if (otfut.Id != fut.Id) return false;
                    if (Math.Abs(externalTrade.Quantity - otTrade.Quantity) < 1)
                    {
                        SetMatchingFlag(otTrade, externalTrade);
                        return true;
                    }
                    unmatchReason += "Quantity ";
                    if (!fullMatch)
                    {
                        otTrade.SetProperty(ReconcileTaskExecutor.UnmatchReason, unmatchReason);
                        return true;
                    }
                }              
                return false;
            }
            var equ = externalTrade.Product as Equity;
            if (equ != null)
            {
                if (otTrade.Product is Equity)
                {
                    var otfut = otTrade.Product as Equity;
                    if (otfut.Id != equ.Id) return false;
                    if (Math.Abs(externalTrade.Quantity - otTrade.Quantity) < 1)
                    {
                        SetMatchingFlag(otTrade, externalTrade);
                        return true;
                    }
                    unmatchReason += "Quantity ";
                    if (!fullMatch)
                    {
                        otTrade.SetProperty(ReconcileTaskExecutor.UnmatchReason, unmatchReason);
                        return true;
                    }
                }               
                return false;
            }
            var bond = externalTrade.Product as Bond;
            if (bond != null)
            {
                if (otTrade.Product is Mbs)
                {
                    var otfut = otTrade.Product as Mbs;
                    if (otfut.Id != bond.Id) return false;
                    //double dd = otfut.GetPrincipalFactorAsOf(new SimpleDate(reconcileDate),
                    //                                         new SimpleDate(reconcileDate));
                    //if (Math.Abs(externalTrade.Quantity - otTrade.Quantity * dd) < 1)
                    if (Math.Abs(externalTrade.Quantity - otTrade.Quantity) < 0.1)
                    {
                        SetMatchingFlag(otTrade, externalTrade);
                        return true;
                    }
                    unmatchReason += "Quantity ";
                    if (!fullMatch)
                    {
                        otTrade.SetProperty(ReconcileTaskExecutor.UnmatchReason, unmatchReason);
                        return true;
                    }
                    return false;
                }

                if (otTrade.Product is Bond)
                {
                    var otfut = otTrade.Product as Bond;
                    if (otfut.Id != bond.Id) return false;
                    //if (Math.Abs(externalTrade.Quantity - otTrade.Quantity * otTrade.Product.Nominal) < 1)
                    if (Math.Abs(externalTrade.Quantity - otTrade.Quantity) < 0.1)
                    {
                        SetMatchingFlag(otTrade, externalTrade);
                        return true;
                    }
                    unmatchReason += "Quantity ";
                    if (!fullMatch)
                    {
                        otTrade.SetProperty(ReconcileTaskExecutor.UnmatchReason, unmatchReason);
                        return true;
                    }
                }
                return false;
            }
            #endregion listed
            #region fxOption
            var extfxoption = externalTrade.Product as FXOption;
            if (extfxoption != null)
            {

                var fxoption = otTrade.Product as FXOption;
                if (fxoption == null) return false;
                var extDpeDesc = externalTrade.GetProperty(DPEDescription);
                var dpeDesc = otTrade.GetProperty(DPEDescription);
                bool descMatched = false;
                if (extDpeDesc != null && dpeDesc != null && extDpeDesc.Trim().Equals(dpeDesc.Trim()))
                    descMatched = true;
                var oinfo = fxoption.OptionInfo;
                if (fxoption is FxFva)
                {
                    if (!(extfxoption is FxFva)) return false;
                    var fva = fxoption as FxFva;
                    var extFva = extfxoption as FxFva;
                    if (!descMatched)
                    {
                        if (!extfxoption.CurrencyPair.Equals(fxoption.CurrencyPair)) return false;
                        if (extfxoption.IsBuy != fxoption.IsBuy) return false;
                        if (fva.FvaExpiryDate != extFva.FvaExpiryDate) return false;
                    }
                    if (Math.Abs(fva.PrimaryAmount - extFva.PrimaryAmount) > Utilities.Epsilon)
                    {
                        if (fullMatch) return false;
                        unmatchReason += "PrimaryAmount ";
                    }
                }
                else
                {
                    if (descMatched)
                    {
                        if (Math.Abs(extfxoption.PrimaryAmount - fxoption.PrimaryAmount) > Utilities.Epsilon)
                        {
                            if (fullMatch) return false;
                            unmatchReason += "PrimaryAmount ";
                        }
                    }
                    else
                    {
                        if (extfxoption.ExerciseType != fxoption.ExerciseType)
                        {
                            if (fxoption.ExerciseType == OptionExerciseType.Digital && extfxoption.ExerciseType == OptionExerciseType.European)
                            {
                                // tolerate this diff, external is booked as vanilla for digital
                            }
                            else
                                return false;
                        }
                        if (!extfxoption.CurrencyPair.Equals(fxoption.CurrencyPair)) return false;
                        if (extfxoption.IsBuy != fxoption.IsBuy) return false;
                        if (extfxoption.ExpiryDate != fxoption.ExpiryDate) return false;

                        if (fxoption.ExerciseType == OptionExerciseType.Digital ||
                            fxoption.ExerciseType == OptionExerciseType.European || fxoption.ExerciseType == OptionExerciseType.Barrier)
                        {
                            if (extfxoption.OptionType != fxoption.OptionType) return false;


                            if (Math.Abs(extfxoption.PrimaryAmount - fxoption.PrimaryAmount) > Utilities.Epsilon)
                            {
                                if (fullMatch) return false;
                                unmatchReason += "PrimaryAmount ";
                            }
                            //if (Math.Abs(extfxoption.QuotingAmount - fxoption.QuotingAmount) > Utilities.Epsilon)
                            //{
                            //    if (fullMatch) return false;
                            //    unmatchReason += "QuotingAmount ";
                            //}
                            if (Math.Abs(extfxoption.OptionStrike - fxoption.OptionStrike) > Utilities.Epsilon)
                            {
                                if (fullMatch) return false;
                                unmatchReason += "Strike ";
                            }

                            if (fxoption.ExerciseType == OptionExerciseType.Barrier)
                            {
                                var binfo1 = fxoption.OptionInfo as BarrierInfo;
                                var binfo2 = extfxoption.OptionInfo as BarrierInfo;


                                if (Math.Abs(binfo1.BarrierStrike - binfo2.BarrierStrike) > Utilities.Epsilon)
                                {
                                    if (fullMatch) return false;
                                    unmatchReason += "UpperBarrier ";
                                }
                                if (Math.Abs(binfo1.LowerBarrierStrike - binfo2.LowerBarrierStrike) > Utilities.Epsilon)
                                {
                                    if (fullMatch) return false;
                                    unmatchReason += "LowerBarrier ";
                                }

                            }
                        }
                        else if (fxoption.ExerciseType == OptionExerciseType.Touch)
                        {
                            var binfo1 = fxoption.OptionInfo as DigitalInfo;
                            var binfo2 = extfxoption.OptionInfo as DigitalInfo;


                            if (Math.Abs(binfo1.BarrierStrike - binfo2.BarrierStrike) > Utilities.Epsilon)
                            {
                                if (fullMatch) return false;
                                unmatchReason += "UpperBarrier ";
                            }
                            if (Math.Abs(binfo1.LowerBarrierStrike - binfo2.LowerBarrierStrike) > Utilities.Epsilon)
                            {
                                if (fullMatch) return false;
                                unmatchReason += "LowerBarrier ";
                            }
                            if (Math.Abs(extfxoption.PrimaryAmount - fxoption.PrimaryAmount) > Utilities.Epsilon)
                            {
                                if (fullMatch) return false;
                                unmatchReason += "PrimaryAmount ";
                            }

                        }
                    }
                }
                if (fullMatch)
                    SetMatchingFlag(otTrade, externalTrade);
                else
                    otTrade.SetProperty(ReconcileTaskExecutor.UnmatchReason, unmatchReason);
                return true;

            }
            #endregion fxOption
            #region volswap
            var extvolswap = externalTrade.Product as VolSwap;
            if (extvolswap != null)
            {
                var volswap = otTrade.Product as VolSwap;
                if (volswap == null) return false;
                if (volswap.ContractMaturity != extvolswap.ContractMaturity) return false;
                if (volswap.UnderlierId != extvolswap.UnderlierId) return false;
                if (volswap.PaymentCurrency != extvolswap.PaymentCurrency) return false;
                if (Math.Abs(externalTrade.Quantity - otTrade.Quantity) > Utilities.Epsilon)
                {
                    if (fullMatch) return false;
                    unmatchReason += "Notional ";
                }
                if (Math.Abs(volswap.Strike - extvolswap.Strike) > Utilities.Epsilon)
                {
                    if (fullMatch) return false;
                    unmatchReason += "Strike ";
                }
                if (fullMatch)
                    SetMatchingFlag(otTrade, externalTrade);
                else
                    otTrade.SetProperty(ReconcileTaskExecutor.UnmatchReason, unmatchReason);
                return true;
            }
            #endregion volswap
            return false;
        }
        protected string GetAggregateKey(Trade tr)
        {
            if (tr.Product is FX)
            {
                var fx = tr.Product as FX;

                return fx.Primary + "_" + fx.Quoting + "_" + fx.PrimarySettleDate + "_" + tr.BookId;
            }
            if (tr.Product.IsMultiplyTraded)
            {
                return "PR" + tr.Product.Id + "_" + tr.BookId;
            }
            if (tr.Product is FXOption)
            {
                string desc = tr.GetProperty(DPEDescription);
                if (desc == null)
                {
                    var otcOption = tr.Product as FXOption;
                    desc = tr.Product.Description;
                    if (otcOption.ExerciseType == OptionExerciseType.DualDigital)
                    {
                        var optInfo = (DualDigitalInfo)otcOption.OptionInfo;
                        desc = desc + "." + optInfo.SecondStrike + "." + optInfo.SecondUnderlierId;
                    }
                    if (otcOption.ExerciseType == OptionExerciseType.Barrier)
                    {
                        var optInfo = (BarrierInfo)otcOption.OptionInfo;
                        desc = desc + "." + optInfo.BarrierStrike + "." + optInfo.LowerBarrierStrike;
                    }
                }
                return desc + "_" + tr.BookId;
            }
            if (tr.Product is Swap)
            {
                var generator = GetGeneratorName(tr);
                if (generator == null) return "TR" + tr.Id;
                var swap = tr.Product as Swap;
                bool haveStart = false; // ((swap.StartDate - tr.TradingDay) > 5 || (swap.StartDate < tr.TradingDay)) && !(tr.Product is CurrencySwap);
                return generator + "_" + "SWAP" + "_" + (haveStart ? swap.StartDate + "_" : string.Empty) + swap.EndDate + "_" + tr.BookId;
            }
            if (tr.Product is Swaption)
            {
                var generator = GetGeneratorName(tr);
                if (generator == null) return "TR" + tr.Id;
                var swaption = tr.Product as Swaption;
                return generator + "_" + swaption.OptionType + "_" + swaption.OptionStrike + /*"_" + swaption.Swap.StartDate +*/ "_" + swaption.Swap.EndDate + "_" + tr.BookId;
            }
            if (tr.Product is FRA)
            {
                var generator = GetGeneratorName(tr);
                if (generator == null) return "TR" + tr.Id;
                var swaption = tr.Product as FRA;
                return generator + "_" + "FRA" + "_" + /*swaption.StartDate + "_" +*/ tr.SettlementDate + "_" + tr.BookId;
            }
            if (tr.Product is VolSwap)
            {
                return tr.Product.Description + "_" + tr.Product.ContractMaturity + "_" + tr.BookId;
            }
            return "TR" + tr.Id;
        }
        protected string GetRegulatoryID(Trade trade, string name)
        {
            // find which allocation number we are
            var allocNo = GetAllocationNo(trade);

            // some properties have extra :1 at the end. some don't
            var propertyToRetrieve = String.Format("{0}:{1}:1", name, allocNo);
            if(!trade.Properties.ContainsKey(propertyToRetrieve)) // try blank
            {
                propertyToRetrieve = String.Format("{0}:{1}", name, allocNo);
            }
            return trade.GetProperty(propertyToRetrieve);
        }
        protected override string ToStringOptional(ProductEvent pevent, Trade trade, Market market)
        {
            var sb = new StringBuilder();
            // ClearingHouse	Clearinghouse code will be provided
            var ccp = GetCcp(trade);
            if (ccp != null)
                sb.Append(ccp);
            sb.Append(Separator);
            string isSef = string.Empty;
            try
            {
                isSef = GetRegulatoryID(trade, sIsSEFProperty);
            }
            catch(Exception)
            {
                // trade doesn't have regulatory ID - ignore and treat as normal IRS
            }
            if (string.Equals(isSef, "Y", StringComparison.InvariantCultureIgnoreCase))
            {
                // SefFlag
                sb.Append("1").Append(Separator);
                // SefTransID	SEF Transaction ID  required fields when the trade is executed on a SEF platform                
                if (!Utilities.IsNullOrEmpty(trade.PartyReference))
                {
                    int allocNo = GetAllocationNo(trade);
                    var sefTransactionId = String.Format("{0}.{1}", trade.PartyReference, allocNo);
                    sb.Append(sefTransactionId);
                }
                sb.Append(Separator);
                // SefName  required fields when the trade is executed on a SEF platform

                var tradeSefName = trade.GetProperty("SEFName");
                /*var sefNameAlias = Env.Current.StaticData.GetAlias(new Alias
                        {
                            EntityId = 0,
                            AliasType = "SEFName",
                            Source = trade.TradingSystem,
                            SourceReference = tradeSefName
                        });
                if (sefNameAlias == null)
                {
                    throw new Exception(String.Format("Unable to find MLP's SEFName alias for SEFName = {0} on trade {1}", tradeSefName, trade.Id));
                }
                var sefName = sefNameAlias.Name;*/
                sb.Append(tradeSefName); // the importer picks up the alias now
                sb.Append(Separator);

                // USI  required fields when the trade is executed on a SEF platform
                var sefSource = GetRegulatoryID(trade, sSEFSourceProperty);
                var sefId = GetRegulatoryID(trade, sSEFIdProperty);
                if (string.IsNullOrWhiteSpace(sefSource) || string.IsNullOrWhiteSpace(sefId))
                {
                    throw new Exception(String.Format("Unable to find {0} or {1} on trade {2} to construct USI.", sSEFSourceProperty, sSEFIdProperty, trade.Id));
                }

                var regulatoryTradeId = sefSource + sefId;
                sb.Append(regulatoryTradeId);
                sb.Append(Separator);

                // FCM  required fields when the trade is executed on a SEF platform
                var sefFCM = GetRegulatoryID(trade, sSEFClearerProperty);
                if (string.IsNullOrWhiteSpace(sefFCM))
                {
                    throw new Exception(String.Format("Unable to find SEFFCM property on trade {0}.", trade.Id));
                }
                else
                {
                    sb.Append(sefFCM);
                }
                sb.Append(Separator);

                string insertReason = "23 - Affirmation no send";
                sb.Append(insertReason).Append(Separator);
            }
            else
            {
                // non-SEF
                sb.Append(Separator);
                sb.Append(Separator);
                sb.Append(Separator);
                sb.Append(Separator);
                sb.Append(Separator);
                sb.Append(Separator);
            }
            return sb.ToString();
        }
        public override bool Reconcile(Trade otTrade, Trade externalTrade, Market market, bool fullMatch, DateTime reconciliationDate, IList<Exception> exceps)
        {
            var ref1 = otTrade.GetProperty(ReconcileTaskExecutor.Reconciled);
            if (ref1 != null && ref1.ToLowerInvariant().Equals("true")) return false;
            var ref2 = externalTrade.GetProperty(ReconcileTaskExecutor.Reconciled);
            if (ref2 != null && ref2.ToLowerInvariant().Equals("true")) return false;
            if (!(otTrade.Product.GetType() == externalTrade.Product.GetType())) return false;
            
            if (otTrade.PrimeBrokerId != externalTrade.PrimeBrokerId &&
                otTrade.ClearerId != externalTrade.ClearerId) return false;
            if (externalTrade.BookId != otTrade.BookId) return false;
            if (externalTrade.PartyId != otTrade.PartyId) return false;
            if (Math.Abs(otTrade.Price - externalTrade.Price) > Utilities.Epsilon) return false;

            var fut1 = otTrade.Product as Future;
            var fut2 = externalTrade.Product as Future;
            if (fut1 != null && fut2 != null)
            {
                var ticker1 = fut1.Ticker;
                var ticker2 = fut2.Ticker;
                if (!string.IsNullOrEmpty(ticker1) && !string.IsNullOrEmpty(ticker2))
                {
                    if (!ticker1.Equals(ticker2)) return false;
                }
            }
            if ((otTrade.Quantity > 0 && externalTrade.Quantity < 0) ||
                (otTrade.Quantity < 0 && externalTrade.Quantity > 0)) return false;
            
            
            var tradedate1 = new SimpleDate(otTrade.TradeTime);
            var tradedate2 = new SimpleDate(externalTrade.TradeTime);
            if (tradedate1 != tradedate2 && otTrade.TradingDay != tradedate2) return false;
            if (fullMatch)
            {
                if (Math.Abs(otTrade.Quantity - externalTrade.Quantity) > Utilities.Epsilon) return false;
                if (!CompareFees(otTrade, externalTrade)) return false;
            }
            
            
            otTrade.SetProperty(ReconcileTaskExecutor.Reconciled, "true");
            externalTrade.SetProperty(ReconcileTaskExecutor.Reconciled, "true");
            return true;
        }
 public override bool Reconcile(Trade otTrade, Trade externalTrade, Market market, bool fullMatch, DateTime reconciliationDate, IList<Exception> exceps)
 {
     var unmatchReason = string.Empty;
     var ref1 = otTrade.GetProperty(ReconcileTaskExecutor.Reconciled);
     if (ref1 != null && ref1.ToLowerInvariant().Equals("true")) return false;
     var ref2 = externalTrade.GetProperty(ReconcileTaskExecutor.Reconciled);
     if (ref2 != null && ref2.ToLowerInvariant().Equals("true")) return false;
     if (!(otTrade.Product.GetType() == externalTrade.Product.GetType())) return false;
     if (otTrade.BookId != externalTrade.BookId) return false;
     if (otTrade.PrimeBrokerId != externalTrade.PrimeBrokerId &&
         otTrade.ClearerId != externalTrade.ClearerId)
     {
         if (fullMatch) return false;
         unmatchReason += "Account ";
     }
     var prod1 = otTrade.Product;
     var prod2 = externalTrade.Product;
     var fut1 = prod1 as Future;
     var fut2 = prod2 as Future;
     if (fut1 != null && fut2 != null)
     {
         var ticker1 = fut1.Ticker;
         var ticker2 = fut2.Ticker;
         if (!string.IsNullOrEmpty(ticker1) && !string.IsNullOrEmpty(ticker2))
         {
             if (!ticker1.Equals(ticker2)) return false;
         }               
     }
     var fx1 = prod1 as FX;
     var fx2 = prod2 as FX;
     if (fx1 != null && fx2 != null)
     {
         if (!fx1.CurrencyPair.Equals(fx2.CurrencyPair)) return false;
         if (fullMatch)
         {
             if (Math.Abs(fx1.PrimaryAmount - fx2.PrimaryAmount) > Utilities.Epsilon) return false;
             if (Math.Abs(fx1.QuotingAmount - fx2.QuotingAmount) > Utilities.Epsilon) return false;
         }
         return true;
     }
     if (prod1 is Bond || prod1 is Equity)
     {
         if (prod1.Id != prod2.Id) return false;
     }
     if (fullMatch)
     {
         if (Math.Abs(otTrade.Quantity - externalTrade.Quantity) > Utilities.Epsilon) return false;
     }
     return true;
 }
Пример #10
0
        internal static String WriteTrade(Trade trade, SimpleDate date, DateTime effectiveTime, char separator)
        {
            var sb = new StringBuilder();

            var swap = trade.Product as Swap;
            var future = trade.Product as Future;
            var bond = trade.Product as Bond;
            var otcOption = trade.Product as OtcOption;
            var iOption = trade.Product as IOption;
            var ndf = trade.Product as NDF;
            var repo = trade.Product as Repo;

            sb.Append(trade.Status).Append(separator);
            var bookParty = Env.Current.StaticData.GetPartyById(trade.BookId);
            var p = bookParty.RoleList.Contains("Book") ? bookParty.GetProperty("Portfolio") : String.Empty;
            var s = bookParty.RoleList.Contains("Book") ? bookParty.GetProperty("Strategy") : String.Empty;
            sb.Append(p).Append(separator).Append(s).Append(separator);
            sb.Append(trade.Id).Append(separator);
            sb.Append(trade.BuySell).Append(separator);
            sb.Append(iOption == null ? null : (OptionType?)iOption.OptionType).Append(separator);
            sb.Append(SymTradeHelper.GetPayerReceiver(trade)).Append(separator);
            sb.Append(trade.Product.Typology(OrchestradeCommon.Products.ProductTypology.Pricing)).Append(separator); //product type
            sb.Append(trade.Product.Typology(OrchestradeCommon.Products.ProductTypology.Processing)).Append(separator); //processing type
            sb.Append(trade.GetProperty("TemplateName")).Append(separator);
            sb.Append(SymTradeHelper.GetNominal(trade)).Append(separator);
            sb.Append(trade.Status != null && trade.Status.Equals("Terminated") ? 0.0 : SymTradeHelper.GetCurrentNominal(trade, date, effectiveTime)).Append(separator);
            sb.Append(SymTradeHelper.GetPrimaryAmount(trade)).Append(separator);
            sb.Append(SymTradeHelper.GetQuotingAmount(trade)).Append(separator);
            sb.Append(swap == null ? null : (double?)swap.PayLeg.CurrentLegNominal).Append(separator);
            sb.Append(swap == null ? null : (double?)swap.ReceiveLeg.CurrentLegNominal).Append(separator);
            sb.Append(trade.Product.Currency).Append(separator);
            sb.Append(trade.Product.GetProperty("DefaultTicker")).Append(separator);
            sb.Append(trade.Product.Cusip).Append(separator);
            sb.Append(trade.Product.Description).Append(separator);
            sb.Append(swap == null ? null : swap.PayLeg).Append(separator);
            sb.Append(swap == null ? null : (double?)swap.PayLeg.Spread).Append(separator);
            sb.Append(swap == null ? null : "\"" + swap.PayLeg.PayReceiveDescription + "\"").Append(separator);
            sb.Append(swap == null ? null : swap.PayLeg.RateIndexTenor).Append(separator);
            sb.Append(swap == null ? null : (Daycount?)swap.PayLeg.Daycount).Append(separator);
            sb.Append(swap == null ? null : (StubType?)swap.PayLeg.StubType).Append(separator);
            sb.Append(swap == null ? null : (SimpleDate?)swap.PayLeg.StubDate).Append(separator);
            sb.Append(swap == null ? null : swap.PayLeg.StubIndexTenor).Append(separator);
            sb.Append(swap == null ? null : swap.PayLeg.StubInterpTenor).Append(separator);
            sb.Append(swap == null ? null : swap.ReceiveLeg).Append(separator);
            sb.Append(swap == null ? null : (double?)swap.ReceiveLeg.Spread).Append(separator);
            sb.Append(swap == null ? null : "\"" + swap.ReceiveLeg.PayReceiveDescription + "\"").Append(separator);
            sb.Append(swap == null ? null : swap.ReceiveLeg.RateIndexTenor).Append(separator);
            sb.Append(swap == null ? null : (Daycount?)swap.ReceiveLeg.Daycount).Append(separator);
            sb.Append(swap == null ? null : (StubType?)swap.ReceiveLeg.StubType).Append(separator);
            sb.Append(swap == null ? null : (SimpleDate?)swap.ReceiveLeg.StubDate).Append(separator);
            sb.Append(swap == null ? null : swap.ReceiveLeg.StubIndexTenor).Append(separator);
            sb.Append(swap == null ? null : swap.ReceiveLeg.StubInterpTenor).Append(separator);
            sb.Append(iOption == null ? null : (double?)iOption.OptionStrike).Append(separator);
            sb.Append(trade.Product.UnderlierInfo).Append(separator);
            sb.Append(trade.Price).Append(separator);
            sb.Append(trade.Product.FixedRate).Append(separator);
            sb.Append(String.Format("{0:dd/MM/yyyy}",new SimpleDate(trade.TradeTime).ToDateTime())).Append(separator);
            sb.Append(String.Format("{0:dd/MM/yyyy}", trade.SettlementDate.ToDateTime())).Append(separator);
            sb.Append(String.Format("{0:dd/MM/yyyy}",trade.Product.ContractMaturity.ToDateTime())).Append(separator);
            sb.Append(iOption == null ? null : (int?)iOption.OptionExerciseTime).Append(separator);
            sb.Append(iOption == null ? null : iOption.OptionExerciseTimeZone).Append(separator);
            sb.Append(otcOption == null ? null : otcOption.SettlementMarketPlaces).Append(separator);
            sb.Append(ndf == null ? null : (SimpleDate?)ndf.FXFixingDate).Append(separator);
            sb.Append(repo == null || repo.Collaterals[0] == null ? null : (double?)repo.Collaterals[0].HairCut).Append(separator);
            sb.Append(iOption == null ? null : (OptionExerciseType?)iOption.ExerciseType).Append(separator);
            sb.Append(otcOption == null ? null : (ExerciseSettlement?)otcOption.ExerciseSettlement).Append(separator);
            sb.Append(SymTradeHelper.GetSettlementAmount(trade)).Append(separator);
            sb.Append(Env.Current.StaticData.GetPartyById(trade.InitialPartyId)).Append(separator);
            sb.Append(Env.Current.StaticData.GetPartyById(trade.PartyId)).Append(separator);
            sb.Append(Env.Current.StaticData.GetPartyById(trade.PrimeBrokerId)).Append(separator);
            sb.Append(Env.Current.StaticData.GetPartyById(trade.ClearerId)).Append(separator);
            sb.Append(Env.Current.StaticData.GetPartyById(trade.StepOutPartyId)).Append(separator);
            sb.Append(Env.Current.StaticData.GetPartyById(trade.CcpId)).Append(separator);
            var upfrontFee = trade.Fees == null ? null :
                trade.Fees.Where(f => f.FeeType.Equals(FeeType.Upfront)).OrderBy(f => f.Date).FirstOrDefault();
            sb.Append(upfrontFee == null ? null : ((Double?)upfrontFee.Amount * (upfrontFee.PayReceive == PayReceive.Pay ? -1 : 1))).Append(separator);
            sb.Append(otcOption == null ? null : (double?)otcOption.InitialPremiumAmount).Append(separator);
            sb.Append(otcOption == null ? null : (SimpleDate?)otcOption.InitialPremiumDate).Append(separator);
            sb.Append(otcOption == null ? null : otcOption.InitialPremiumCurrency).Append(separator);
            sb.Append(otcOption == null ? null : (PayReceive?)otcOption.InitialPremiumPayReceive);

            return sb.ToString();
        }
Пример #11
0
        public override bool Reconcile(Trade otTrade, Trade externalTrade, Market market, bool fullMatch, DateTime reconciliationDate, IList<Exception> exceps)
        {
            var date = new SimpleDate(reconciliationDate);
            var time = reconciliationDate;
            if (externalTrade.Status.Equals(MurexInfo.StateDead)) return false;

            string unmatchReason = string.Empty;
            bool sameRef = false;

            var otTid = otTrade.GetProperty(TradeImportHelper.MurexTradeId);
            var extTid = externalTrade.GetProperty(TradeImportHelper.MurexTradeId);
            externalTrade.SetProperty(ReconcileTaskExecutor.ImportRef, extTid);
            if (otTid != null && extTid != null)
            {
                if (!otTid.Equals(extTid, StringComparison.Ordinal)) return false;
                else sameRef = !fullMatch;  // if not in fullMatch mode, turn on sameRef flag
            }            
            if (otTrade.BookId != externalTrade.BookId)
            {
                if (fullMatch) return false;
                else
                {
                    var book1 = Env.Current.StaticData.GetPartyById(otTrade.BookId);
                    var book2 = Env.Current.StaticData.GetPartyById(externalTrade.BookId);
                    if (book1 != null && book2 != null)
                    {
                        var port1 = book1.GetProperty(TradeImportHelper.BookProp2);
                        var port2 = book2.GetProperty(TradeImportHelper.BookProp2);
                        if (port1 != null && port2 != null && !port1.Equals(port2))
                        {
                            return false;
                        }
                    }
                    unmatchReason += "Book ";
                }
            }

            if (externalTrade.Product is MurexProduct)
            {
                var murex = externalTrade.Product as MurexProduct;
                var ot = otTrade.Product;
                var generator = SymmetryPositionReconciler.GetGeneratorName(otTrade);

                if (!CompareParties(otTrade, externalTrade, fullMatch, ref unmatchReason) && fullMatch) return false;
                if (!ot.ProcessingType.Equals(murex.ProductProcessingType))
                {
                    if ((ot.ProcessingType.Equals("Swap") && murex.ProductProcessingType.Equals("NDS")) ||
                        (ot.ProcessingType.Equals("NDS") && murex.ProductProcessingType.Equals("Swap")))
                    {
                        if (fullMatch) return false;
                        else unmatchReason += "Swap/NDS ";
                    }
                    else return false;
                }
                if (otTrade.TradingDay != externalTrade.TradingDay)
                {
                    if (!sameRef) return false;
                    else unmatchReason += "TradeDate ";
                }
                if (generator == null || murex.Generator == null || !generator.Equals(murex.Generator))
                {
                    if (!sameRef) return false;
                    else if (!unmatchReason.Contains("Swap/NDS")) unmatchReason += "Template ";
                }
                #region swap
                if (ot is Swap)
                {
                    // can be irs, currency swap or mtm currency swap
                    var swap = ot as Swap;
                    var payLeg = swap.PayLeg;
                    var recLeg = swap.ReceiveLeg;
                    Leg leg1, leg2; // 1 and 2 in import file
                    if ((payLeg.IsFixedRate && !recLeg.IsFixedRate) ||
                        (!payLeg.IsFixedRate && recLeg.IsFixedRate))
                    {
                        // fixed-float: leg1 is fixed, leg2 is float
                        if (payLeg.IsFixedRate)
                        {
                            if (!externalTrade.BuySell.Equals(BuySell.Sell.ToString()))
                            {
                                if (!sameRef) return false;
                                else unmatchReason += "Direction ";
                            }
                            leg1 = payLeg;
                            leg2 = recLeg;
                        }
                        else
                        {
                            if (externalTrade.BuySell.Equals(BuySell.Sell.ToString()))
                            {
                                if (!sameRef) return false;
                                else unmatchReason += "Direction ";
                            }
                            leg1 = recLeg;
                            leg2 = payLeg;
                        }
                        if (!CompareLegs(leg1, leg2, murex, false, fullMatch, sameRef, ref unmatchReason, reconciliationDate) && fullMatch) return false;
                    }
                    else if (!payLeg.IsFixedRate && !recLeg.IsFixedRate)
                    {
                        // float-float: buy/sell = rec/pay is on leg1
                        if (externalTrade.Quantity > 0)
                        {
                            leg1 = recLeg;
                            leg2 = payLeg;
                        }
                        else
                        {
                            leg1 = payLeg;
                            leg2 = recLeg;
                        }
                        if (!CompareLegs(leg1, leg2, murex, true, fullMatch, sameRef, ref unmatchReason, reconciliationDate) && fullMatch) return false;
                    }
                    if (!CompareFees(otTrade, murex))
                    {
                        if (fullMatch) return false;
                        else unmatchReason += "UpfrontFee ";
                    }
                }
                #endregion swap
                #region fra
                else if (ot is FRA)
                {
                    var fra = ot as FRA;
                    if (otTrade.BuySell != externalTrade.BuySell)
                    {
                        if (!sameRef) return false;
                        else unmatchReason += "BuySell ";
                    }
                    if (fra.StartDate != murex.EffectiveDate)
                    {
                        if (!sameRef) return false;
                        else unmatchReason += "StartDate ";
                    }
                    if (fra.EndDate != murex.EndDate)
                    {
                        if (!sameRef) return false;
                        else unmatchReason += "EndDate ";
                    }
                    if (Math.Abs(fra.FixedRate - murex.FixedRate) > _rateTolerance)
                    {
                        if (fullMatch) return false;
                        else unmatchReason += "FixedRate ";
                    }
                    if (Math.Abs(fra.CurrentNominal(date, time, false) - murex.Nominal1) > _qtyTolerance)
                    {
                        if (fullMatch) return false;
                        else unmatchReason += "Nominal ";
                    }
                    if (!CompareFees(otTrade, murex))
                    {
                        if (fullMatch) return false;
                        else unmatchReason += "UpfrontFee ";
                    }
                }
                #endregion fra
                #region swaption
                else if (ot is Swaption)
                {
                    var spt = ot as Swaption;
                    if (otTrade.SettlementDate != murex.EffectiveDate)
                    {
                        if (!sameRef) return false;
                        else unmatchReason += "SettleDate ";
                    }
                    if (spt.ExpiryDate != murex.EndDate)
                    {
                        if (!sameRef) return false;
                        else unmatchReason += "ExpiryDate ";
                    }
                    if (murex.ExerciseSettlement != ExerciseSettlement.None
                        && spt.ExerciseSettlement != murex.ExerciseSettlement)
                    {
                        if (!sameRef) return false;
                        else unmatchReason += "SettlementType ";
                    }
                    if (spt.ExerciseType != murex.ExerciseType)
                    {
                        if (!sameRef) return false;
                        else unmatchReason += "ExerciseType ";
                    }
                    if (!otTrade.BuySell.Equals(externalTrade.BuySell))
                    {
                        if (!sameRef) return false;
                        else unmatchReason += "BuySell ";
                    }
                    {
                        var premiumMatch = true;
                        if (Math.Abs(spt.InitialPremiumAmount - Math.Abs(murex.UpFrontAmount)) > _qtyTolerance) premiumMatch = false;
                        if ((spt.InitialPremiumCurrency != null && murex.UpFrontCcy == null) || (spt.InitialPremiumCurrency == null && murex.UpFrontCcy != null) ||
                            (spt.InitialPremiumCurrency != null && murex.UpFrontCcy != null && spt.InitialPremiumCurrency != murex.UpFrontCcy))
                            premiumMatch = false;
                        if (spt.InitialPremiumDate != murex.UpFrontDate)
                            premiumMatch = false;
                        if (!premiumMatch)
                        {
                            if (fullMatch) return false;
                            else unmatchReason += "Premium ";
                        }
                    }
                    // call= payleg is fixed, put = recleg is fixed
                    var payLeg = spt.Swap.PayLeg;
                    var recLeg = spt.Swap.ReceiveLeg;
                    double fixedRate;
                    if (murex.CallPut == OptionType.Call)
                    {
                        if (!payLeg.IsFixedRate)
                        {
                            if (!sameRef) return false;
                            else unmatchReason += "PutCall ";
                        }
                        fixedRate = payLeg.FixedRate;
                    }
                    else if (murex.CallPut == OptionType.Put)
                    {
                        if (!recLeg.IsFixedRate)
                        {
                            if (!sameRef) return false;
                            else unmatchReason += "PutCall ";
                        }
                        fixedRate = recLeg.FixedRate;
                    }
                    else return false;

                    if (Math.Abs(payLeg.CurrentNominal(date, time, false) - murex.Nominal1) > _qtyTolerance)
                    {
                        if (fullMatch) return false;
                        else unmatchReason += "Nominal ";
                    }
                    if (Math.Abs(fixedRate - murex.FixedRate) > _rateTolerance)
                    {
                        if (fullMatch) return false;
                        else unmatchReason += "FixedRate ";
                    }
                    if (payLeg.NotionalCurrency != murex.Currency1)
                    {
                        if (!sameRef) return false;
                        else unmatchReason += "Currency ";
                    }
                    if (payLeg.StartDate != murex.SwapStartDate
                        && payLeg.FirstCalculationPeriodStart != murex.SwapStartDate)
                    {
                        if (!sameRef) return false;
                        else unmatchReason += "SwapStartDate ";
                    }
                    if (payLeg.EndDate != murex.SwapEndDate)
                    {
                        if (!sameRef) return false;
                        else unmatchReason += "SwapEndDate ";
                    }

                }
                #endregion swaption
                else
                {
                    // do not support other type
                    return false;
                }
                otTrade.SetProperty(ReconcileTaskExecutor.ImportRef, extTid);
                if (!fullMatch && unmatchReason.Length > 0)
                    otTrade.SetProperty(ReconcileTaskExecutor.UnmatchReason, unmatchReason);
                return true;
            }
            else if (externalTrade.Product is GenericProduct)
            {
                // no product found in ot
                return false;
            }
            else
            {               
                if (externalTrade.Product.GetType() != otTrade.Product.GetType())
                {
                    if (IsLumpFxNdf() && otTrade.Product is FX && externalTrade.Product is FX)
                    {
                        // lump them together
                    }
                    else return false;
                } 
                #region listed
                if (externalTrade.Product.IsMultiplyTraded)
                {
                    if (otTrade.Product.Id != externalTrade.Product.Id) return false;

                    {
                        if (Math.Abs(otTrade.Quantity - externalTrade.Quantity) > _qtyTolerance)
                        {
                            if (fullMatch) return false;
                            else unmatchReason += "Quantity ";
                        }
                        if (!ComparePrice(otTrade, externalTrade))
                        {
                            if (fullMatch) return false;
                            else unmatchReason += "Price ";
                        }
                    }
                }
                #endregion listed
                #region fx
                else if (otTrade.Product is FX)
                {
                    var fx1 = otTrade.Product as FX;
                    var fx2 = externalTrade.Product as FX;
                    if (!otTrade.BuySell.Equals(externalTrade.BuySell)) return false;
                    if (!fx1.Primary.Equals(fx2.Primary)) return false;
                    if (!fx1.Quoting.Equals(fx2.Quoting)) return false;

                    {
                        if (Math.Abs(fx1.PrimaryAmount - fx2.PrimaryAmount) > _amountTolerance)
                        {
                            if (fullMatch) return false;
                            else unmatchReason += "PrimaryAmount ";
                        }
                        if (Math.Abs(fx1.QuotingAmount - fx2.QuotingAmount) > _amountTolerance)
                        {
                            if (fullMatch) return false;
                            else unmatchReason += "QuotingAmount ";
                        }
                    }
                    if (!IsLumpFxNdf())
                    {
                        if (otTrade.Product is NDF)
                        {
                            var ndf1 = fx1 as NDF;
                            var ndf2 = fx2 as NDF;
                            if (ndf1.FXFixingName != null && ndf1.FXFixingName != ndf2.FXFixingName) return false;
                            if (ndf1.NonDeliverableCurrency != null && ndf1.NonDeliverableCurrency != ndf2.NonDeliverableCurrency) return false;
                            if (!ndf1.FXFixingDate.IsNull && !ndf2.FXFixingDate.IsNull && ndf1.FXFixingDate != ndf2.FXFixingDate) return false;
                            if (ndf1.FixingValue != 0 && ndf2.FixingValue != 0 && Math.Abs(ndf1.FixingValue - ndf2.FixingValue) > _priceTolerance)
                            {
                                if (fullMatch) return false;
                                else unmatchReason += "FixingValue ";
                            }
                        }
                    }
                }
                #endregion fx
                #region fxoption
                else if (otTrade.Product is FXOption)
                {
                    if (!CompareParties(otTrade, externalTrade, fullMatch, ref unmatchReason) && fullMatch) return false;
                    var fxo1 = otTrade.Product as FXOption;
                    var fxo2 = externalTrade.Product as FXOption;
                    if (fxo1.IsBuy != fxo2.IsBuy)
                    {
                        if (!sameRef) return false;
                        else unmatchReason += "BuySell ";
                    }
                    if (fxo1.Primary != fxo2.Primary)
                    {
                        if (!sameRef) return false;
                        else unmatchReason += "PrimaryCcy ";
                    }
                    if (fxo1.Quoting != fxo2.Quoting)
                    {
                        if (!sameRef) return false;
                        else unmatchReason += "QuotingCcy ";
                    }
                    if (otTrade.TradingDay != externalTrade.TradingDay)
                    {
                        if (!sameRef) return false;
                        else unmatchReason += "TradeDate ";
                    }
                    if (fxo1.OptionType != fxo2.OptionType)
                    {
                        if (!sameRef) return false;
                        else unmatchReason += "PutCall ";
                    }
                    if (fxo1.ExerciseSettlement != fxo2.ExerciseSettlement)
                    {
                        if (!sameRef) return false;
                        else unmatchReason += "SettlementType ";
                    }
                    if (fxo1.ExerciseType != fxo2.ExerciseType)
                    {
                        if (!sameRef) return false;
                        else unmatchReason += "ExerciseType ";
                    }
                    if (fxo1.ExerciseSettlement == ExerciseSettlement.Cash && fxo1.SettleCurrency != fxo2.SettleCurrency)
                    {
                        if (!sameRef) return false;
                        else unmatchReason += "SettleCurrency ";
                    }
                    if (fxo1.ExpiryDate != fxo2.ExpiryDate)
                    {
                        if (!sameRef) return false;
                        else unmatchReason += "ExpiryDate ";
                    }
                    if (Math.Abs(fxo1.PrimaryAmount - fxo2.PrimaryAmount) > _amountTolerance)
                    {
                        if (fullMatch) return false;
                        else unmatchReason += "PrimaryAmount ";
                    }
                    if (Math.Abs(fxo1.QuotingAmount - fxo2.QuotingAmount) > _amountTolerance)
                    {
                        if (fullMatch) return false;
                        else unmatchReason += "QuotingAmount ";
                    }
                    if (Math.Abs(fxo1.OptionStrike - fxo2.OptionStrike) > _priceTolerance)
                    {
                        if (fullMatch) return false;
                        else unmatchReason += "Strike ";
                    }

                    var premiumMatch = true;
                    if (Math.Abs(fxo1.InitialPremiumAmount - fxo2.InitialPremiumAmount) > _amountTolerance) premiumMatch = false;
                    if (fxo1.InitialPremiumCurrency != null && fxo2.InitialPremiumCurrency == null) premiumMatch = false;
                    if (fxo1.InitialPremiumCurrency == null && fxo2.InitialPremiumCurrency != null) premiumMatch = false;
                    if (fxo1.InitialPremiumCurrency != null && fxo2.InitialPremiumCurrency != null
                        && fxo1.InitialPremiumCurrency != fxo2.InitialPremiumCurrency) premiumMatch = false;
                    if (fxo1.InitialPremiumDate != fxo1.InitialPremiumDate) premiumMatch = false;
                    if (!premiumMatch)
                    {
                        if (fullMatch) return false;
                        else unmatchReason += "Premium ";
                    }
                }
                #endregion fxoption
                otTrade.SetProperty(ReconcileTaskExecutor.ImportRef, extTid);
                if (!fullMatch && unmatchReason.Length > 0)
                    otTrade.SetProperty(ReconcileTaskExecutor.UnmatchReason, unmatchReason);
                return true;
            }
        }
Пример #12
0
        protected string GetAccount(Trade tr)
        {
            var accountpb = tr.GetProperty(MurexInfo.AccountProp);
            if (accountpb != null)
            {
                return accountpb;
            }
            var partyId = tr.PrimeBrokerId > 0 ? tr.PrimeBrokerId : tr.ClearerId;
            if (partyId > 0)
            {

                var account = Alias.PartyToAlias(0, "Murex", partyId);
                return account;
            }

            return null;
        }