/// <summary>
        /// Run for each day that the Tax Lot remains open / partially closed
        /// </summary>
        /// <param name="env"></param>
        /// <param name="element">Trade we aee interested in</param>
        public void DailyEvent(PostingEngineEnvironment env, Transaction element)
        {
            double fxrate = 1.0;

            // Lets get fx rate if needed
            if (!element.SettleCurrency.Equals(env.BaseCurrency))
            {
                fxrate = Convert.ToDouble(FxRates.Find(env.ValueDate, element.SettleCurrency).Rate);
            }

            // Calculate the unrealized PNL
            if (env.TaxLotStatus.ContainsKey(element.LpOrderId))
            {
                // Determine if we need to accumulate unrealized PNL
                var taxlot = env.TaxLotStatus[element.LpOrderId];

                // Check to see if the TaxLot is still open and it has a non zero Quantity
                if (!taxlot.Status.ToLowerInvariant().Equals("closed") && Math.Abs(taxlot.Quantity) > 0)
                {
                    var listOfTags = new List <Tag>
                    {
                        Tag.Find("SecurityType"),
                        Tag.Find("CustodianCode")
                    };

                    // We have an open / partially closed tax lot so now need to calculate unrealized Pnl
                    var quantity = taxlot.Quantity;

                    var prevEodPrice = 0.0;
                    var eodPrice     = 0.0;

                    if (env.ValueDate == element.TradeDate)
                    {
                        eodPrice     = MarketPrices.GetPrice(env, env.ValueDate, element).Price;
                        prevEodPrice = element.SettleNetPrice;
                    }
                    else
                    {
                        prevEodPrice = MarketPrices.GetPrice(env, env.PreviousValueDate, element).Price;
                        eodPrice     = MarketPrices.GetPrice(env, env.ValueDate, element).Price;
                    }

                    var unrealizedPnl = CommonRules.CalculateUnrealizedPnl(env, taxlot);

                    AccountToFrom fromToAccounts = null;

                    if (element.IsDerivative())
                    {
                        var originalAccount = AccountUtils.GetDerivativeAccountType(unrealizedPnl);
                        if (originalAccount.Contains("(Liabilities)"))
                        {
                            // This needs to be registered as a Credit to the Libabilities
                            unrealizedPnl *= -1;
                        }
                        fromToAccounts = new AccountUtils().GetAccounts(env, originalAccount, "Change in Unrealized Derivatives Contracts at Fair Value", listOfTags, taxlot.Trade);
                    }
                    else
                    {
                        var originalAccount = taxlot.Side == "SHORT" ? "Mark to Market Shorts" : "Mark to Market Longs";
                        fromToAccounts = new AccountUtils().GetAccounts(env, originalAccount, "CHANGE IN UNREALIZED GAIN/(LOSS)", listOfTags, taxlot.Trade);
                    }

                    var fund = env.GetFund(element);

                    var debit = new Journal(element)
                    {
                        Account     = fromToAccounts.From,
                        When        = env.ValueDate,
                        Symbol      = taxlot.Symbol,
                        Quantity    = quantity,
                        FxRate      = fxrate,
                        Value       = env.SignedValue(fromToAccounts.From, fromToAccounts.To, true, unrealizedPnl),
                        CreditDebit = env.DebitOrCredit(fromToAccounts.From, unrealizedPnl),
                        StartPrice  = prevEodPrice,
                        EndPrice    = eodPrice,
                        Event       = Event.DAILY_UNREALIZED_PNL,
                        Fund        = fund,
                    };

                    var credit = new Journal(element)
                    {
                        Account     = fromToAccounts.To,
                        When        = env.ValueDate,
                        FxRate      = fxrate,
                        Quantity    = quantity,
                        Value       = env.SignedValue(fromToAccounts.From, fromToAccounts.To, false, unrealizedPnl),
                        CreditDebit = env.DebitOrCredit(fromToAccounts.To, env.SignedValue(fromToAccounts.From, fromToAccounts.To, false, unrealizedPnl)),
                        Event       = Event.DAILY_UNREALIZED_PNL,
                        StartPrice  = prevEodPrice,
                        EndPrice    = eodPrice,
                        Fund        = fund,
                    };

                    Logger.Info($"[Journals] ==> From : {debit.CreditDebit}::{debit.Value}::{debit.Account.Type.Category.Name} --> To : {credit.CreditDebit}::{credit.Value}::{credit.Account.Type.Category.Name} ({unrealizedPnl})");

                    env.Journals.AddRange(new[] { debit, credit });

                    // For Derivatives this is un-necessary as we do not have an investment at cost, but we do have Fx on unsettled
                    if (taxlot.Quantity != 0.0)
                    {
                        if (element.TradeDate != env.ValueDate)
                        {
                            new FxPosting().CreateFxUnsettled(env, element);
                        }
                    }
                }
            }
            else
            {
                if (fxrate != 1.0)
                {
                    if (element.TradeDate != env.ValueDate && element.SettleDate >= env.ValueDate)
                    {
                        /*
                         * var fxJournals = FxPosting.CreateFx(
                         *  env,
                         *  "DUE FROM/(TO) PRIME BROKERS ( Unsettled Activity )",
                         *  "fx gain or loss on unsettled balance",
                         *  "daily",
                         *  element.Quantity, null, element);
                         * env.Journals.AddRange(fxJournals);
                         */
                    }
                }
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Run for each day that the Tax Lot remains open / partially closed
        /// </summary>
        /// <param name="env"></param>
        /// <param name="element">Trade we aee interested in</param>
        public void DailyEvent(PostingEngineEnvironment env, Transaction element)
        {
            double fxrate = 1.0;

            // Lets get fx rate if needed
            if (!element.SettleCurrency.Equals(env.BaseCurrency))
            {
                fxrate = Convert.ToDouble(FxRates.Find(env.ValueDate, element.SettleCurrency).Rate);
            }

            // Calculate the unrealized PNL
            if (env.TaxLotStatus.ContainsKey(element.LpOrderId))
            {
                // Determine if we need to accumulate unrealized PNL
                var taxlot = env.TaxLotStatus[element.LpOrderId];

                // Check to see if the TaxLot is still open and it has a non zero Quantity
                if (!taxlot.Status.ToLowerInvariant().Equals("closed") && Math.Abs(taxlot.Quantity) > 0)
                {
                    var listOfTags = new List <Tag>
                    {
                        Tag.Find("SecurityType"),
                        Tag.Find("CustodianCode")
                    };

                    var split        = element.Symbol.Split(new char[] { '/', ' ' });
                    var baseCurrency = split[0];
                    var riskCurrency = split[1];

                    var eodPrice     = MarketPrices.GetPrice(env, env.ValueDate, element).Price;
                    var prevEodPrice = MarketPrices.GetPrice(env, env.PreviousValueDate, element).Price;

                    if (baseCurrency.Equals(env.BaseCurrency))
                    {
                        if (env.ValueDate == element.TradeDate)
                        {
                            prevEodPrice = element.SettleNetPrice;
                        }
                    }
                    else
                    {
                        if (env.ValueDate == element.TradeDate)
                        {
                            prevEodPrice = element.SettleNetPrice;
                        }
                    }

                    // we need to do this when there is no price for the trade from market data
                    if (prevEodPrice == 0.0)
                    {
                        prevEodPrice = element.SettleNetPrice;
                    }

                    if (eodPrice == 0.0)
                    {
                        eodPrice = element.SettleNetPrice;
                    }

                    // We have an open / partially closed tax lot so now need to calculate unrealized Pnl
                    var quantity = taxlot.Quantity;

                    var rateDiff = (eodPrice - prevEodPrice);

                    var unrealizedPnl = (rateDiff * quantity);

                    if (baseCurrency.Equals(env.BaseCurrency))
                    {
                        unrealizedPnl = unrealizedPnl / eodPrice;
                    }

                    var originalAccount = AccountUtils.GetDerivativeAccountType(unrealizedPnl);
                    var fromToAccounts  = new AccountUtils().GetAccounts(env, originalAccount, "Change in Unrealized Derivatives Contracts at Fair Value", listOfTags, taxlot.Trade);

                    var fund = env.GetFund(element);

                    var debit = new Journal(element)
                    {
                        Account     = fromToAccounts.From,
                        When        = env.ValueDate,
                        Symbol      = taxlot.Symbol,
                        Quantity    = quantity,
                        FxRate      = rateDiff,
                        Value       = env.SignedValue(fromToAccounts.From, fromToAccounts.To, false, unrealizedPnl),
                        CreditDebit = env.DebitOrCredit(fromToAccounts.From, unrealizedPnl),
                        StartPrice  = prevEodPrice,
                        EndPrice    = eodPrice,
                        Event       = Event.DAILY_UNREALIZED_PNL,
                        Fund        = fund,
                    };

                    var credit = new Journal(debit)
                    {
                        Account     = fromToAccounts.To,
                        Value       = env.SignedValue(fromToAccounts.From, fromToAccounts.To, true, unrealizedPnl),
                        CreditDebit = env.DebitOrCredit(fromToAccounts.To, unrealizedPnl),
                    };

                    env.Journals.AddRange(new[] { debit, credit });

                    if (element.LpOrderId.Equals("3bbf9793-d01a-4a08-b25c-448fd1777ef1"))
                    {
                    }

                    if (element.TradeDate != env.ValueDate && element.SettleDate >= env.ValueDate)
                    {
                        var fxJournals = FxPosting.CreateFx(
                            env,
                            "daily",
                            quantity, null, element);
                        env.Journals.AddRange(fxJournals);
                    }
                }
            }
            else
            {
                if (fxrate != 1.0)
                {
                    if (element.TradeDate != env.ValueDate && element.SettleDate >= env.ValueDate)
                    {
                        var fxJournals = FxPosting.CreateFx(
                            env,
                            "daily",
                            element.Quantity, null, element);
                        env.Journals.AddRange(fxJournals);
                    }
                }
            }
        }
Esempio n. 3
0
        public void SettlementDateEvent(PostingEngineEnvironment env, Transaction element)
        {
            // On Settlement Date we backout the Tax Lot for FORWARDS
            if (env.TaxLotStatus.ContainsKey(element.LpOrderId))
            {
                var taxlotStatus = env.TaxLotStatus[element.LpOrderId];

                var split        = element.Symbol.Split(new char[] { '/', ' ' });
                var baseCurrency = split[0];
                var riskCurrency = split[1];

                var accountBuy = new AccountUtils().CreateAccount(atSettledCash, new List <string> {
                    element.SecurityType, element.CustodianCode, baseCurrency
                });
                var accountSell = new AccountUtils().CreateAccount(atSettledCash, new List <string> {
                    element.SecurityType, element.CustodianCode, riskCurrency
                });

                new AccountUtils().SaveAccountDetails(env, accountBuy);
                new AccountUtils().SaveAccountDetails(env, accountSell);

                var fxCurrency   = riskCurrency;
                var tradePrice   = taxlotStatus.TradePrice;
                var baseQuantity = element.Quantity;

                var eodPrice = MarketPrices.GetPrice(env, env.ValueDate, element).Price;
                var fxRate   = FxRates.Find(env.ValueDate, fxCurrency).Rate;

                var buyValue  = baseQuantity * tradePrice * fxRate;
                var sellValue = baseQuantity * eodPrice * fxRate;

                if (element.IsBuy()) // BUY
                {
                    var realizedPnl = sellValue - buyValue;

                    var debit = new Journal(accountBuy, Event.SETTLED_CASH, env.ValueDate)
                    {
                        Source     = element.LpOrderId,
                        Fund       = env.GetFund(element),
                        FxCurrency = baseCurrency,
                        Symbol     = element.Symbol,
                        SecurityId = element.SecurityId,
                        Quantity   = Convert.ToDouble(element.Quantity),

                        FxRate     = tradePrice,
                        StartPrice = tradePrice,
                        EndPrice   = eodPrice,

                        Value       = env.SignedValue(accountBuy, accountSell, true, buyValue),
                        CreditDebit = env.DebitOrCredit(accountBuy, buyValue),
                    };

                    var credit = new Journal(accountSell, Event.SETTLED_CASH, env.ValueDate)
                    {
                        Source     = element.LpOrderId,
                        Fund       = env.GetFund(element),
                        FxCurrency = riskCurrency,
                        Symbol     = element.Symbol,
                        SecurityId = element.SecurityId,
                        Quantity   = Convert.ToDouble(element.Quantity),

                        FxRate     = tradePrice,
                        StartPrice = 0,
                        EndPrice   = 0,

                        Value       = env.SignedValue(accountBuy, accountSell, true, sellValue * -1),
                        CreditDebit = env.DebitOrCredit(accountSell, sellValue),
                    };

                    env.Journals.AddRange(new[] { credit, debit });

                    var originalAccount = AccountUtils.GetDerivativeAccountType(realizedPnl);

                    // Realized Pnl to go along with the Settled Cash
                    CommonRules.GenerateJournalEntry(env, element, listOfTags, realizedAccountType, Event.REALIZED_PNL, realizedPnl);

                    CommonRules.GenerateJournalEntries(env, element, listOfTags, originalAccount, "Change in Unrealized Derivatives Contracts at Fair Value", realizedPnl * -1);
                }
                else // SELL
                {
                    var realizedPnl = buyValue - sellValue;

                    var debit = new Journal(accountBuy, Event.SETTLED_CASH, env.ValueDate)
                    {
                        Source     = element.LpOrderId,
                        Fund       = env.GetFund(element),
                        FxCurrency = baseCurrency,
                        Symbol     = element.Symbol,
                        SecurityId = element.SecurityId,
                        Quantity   = Convert.ToDouble(element.Quantity),

                        FxRate     = tradePrice,
                        StartPrice = 0,
                        EndPrice   = 0,

                        Value       = env.SignedValue(accountBuy, accountSell, true, sellValue),
                        CreditDebit = env.DebitOrCredit(accountBuy, element.Quantity),
                    };

                    var credit = new Journal(accountSell, Event.SETTLED_CASH, env.ValueDate)
                    {
                        Source     = element.LpOrderId,
                        Fund       = env.GetFund(element),
                        FxCurrency = riskCurrency,
                        Symbol     = element.Symbol,
                        SecurityId = element.SecurityId,
                        Quantity   = Convert.ToDouble(element.Quantity),

                        FxRate     = tradePrice,
                        StartPrice = 0,
                        EndPrice   = 0,

                        Value       = env.SignedValue(accountBuy, accountSell, true, buyValue * -1),
                        CreditDebit = env.DebitOrCredit(accountSell, element.Quantity),
                    };

                    env.Journals.AddRange(new[] { credit, debit });

                    var originalAccount = AccountUtils.GetDerivativeAccountType(realizedPnl);

                    // Realized Pnl to go along with the Settled Cash
                    CommonRules.GenerateJournalEntry(env, element, listOfTags, realizedAccountType, Event.REALIZED_PNL, realizedPnl);

                    CommonRules.GenerateJournalEntries(env, element, listOfTags, originalAccount, "Change in Unrealized Derivatives Contracts at Fair Value", realizedPnl * -1);
                }

                if (taxlotStatus.Quantity != 0)
                {
                    var buyTrade = env.FindTrade(taxlotStatus.OpenId);
                    var taxlot   = CommonRules.RelieveTaxLot(env, buyTrade, element, taxlotStatus.Quantity * -1, true);
                    taxlotStatus.Quantity = 0;
                    taxlotStatus.Status   = "Closed";
                }
            }
        }
Esempio n. 4
0
        public void TradeDateEvent(PostingEngineEnvironment env, Transaction element)
        {
            double fxrate = 1.0;

            double multiplier = 1.0;

            if (env.SecurityDetails.ContainsKey(element.BloombergCode))
            {
                multiplier = env.SecurityDetails[element.BloombergCode].Multiplier;
            }

            // Lets get fx rate if needed
            if (!element.SettleCurrency.Equals(env.BaseCurrency))
            {
                fxrate = Convert.ToDouble(FxRates.Find(env.ValueDate, element.SettleCurrency).Rate);
            }

            if (element.IsBuy() || element.IsShort())
            {
                var t1 = env.GenerateOpenTaxLot(element, fxrate);

                if (element.Quantity == 0)
                {
                    // TODO: Need to review this as we need to see if there is a parent, and what the parents actuall is
                    return;
                }
            }
            else if (element.IsSell() || element.IsCover())
            {
                // Get Matching Lots
                var openLots = env.Methodology.GetOpenLots(env, element, element.Quantity);

                if (openLots.Count() == 0)
                {
                    var t1 = env.GenerateOpenTaxLot(element, fxrate);
                    // Whats going on here?
                    // We are skipping anything that does not get an OpenLot
                    env.AddMessage($"There should be for a sell {element.Symbol} have at least one open lot, non found");
                }
                else
                {
                    var workingQuantity = element.Quantity;

                    foreach (var lot in openLots)
                    {
                        if (workingQuantity == 0)
                        {
                            break;
                        }

                        if (!env.TaxLotStatus.ContainsKey(lot.Trade.LpOrderId))
                        {
                            // TODO: For this open lot there should be a corresponding open to
                            continue;
                        }

                        var taxlotStatus = env.TaxLotStatus[lot.Trade.LpOrderId];
                        if (taxlotStatus != null && taxlotStatus.Quantity != 0 && !taxlotStatus.Status.ToLowerInvariant().Equals("closed"))
                        {
                            // Does the open Lot fully fullfill the quantity ?
                            if (Math.Abs(taxlotStatus.Quantity) >= Math.Abs(workingQuantity))
                            {
                                var taxlot = CommonRules.RelieveTaxLot(env, lot, element, workingQuantity, true);

                                taxlotStatus.Quantity += workingQuantity;
                                if (taxlotStatus.Quantity == 0)
                                {
                                    taxlotStatus.Status = "Closed";
                                }
                                else
                                {
                                    taxlotStatus.Status = "Partially Closed";
                                }

                                CommonRules.GenerateCloseOutPostings(env, lot, taxlot, element, taxlotStatus, env.GetFund(element));

                                break;
                            }
                            else
                            {
                                var taxlot = CommonRules.RelieveTaxLot(env, lot, element, taxlotStatus.Quantity * -1);

                                workingQuantity -= Math.Abs(taxlotStatus.Quantity);

                                var accountTypes = AccountType.All;

                                var listOfTags = new List <Tag> {
                                    Tag.Find("SecurityType"),
                                    Tag.Find("CustodianCode")
                                };

                                Account fromAccount = null; // Debiting Account
                                Account toAccount   = null; // Crediting Account

                                var realizedPnl = taxlot.RealizedPnl;

                                var originalAccount = AccountUtils.GetDerivativeAccountType(realizedPnl);
                                if (originalAccount.Contains("(Liabilities)"))
                                {
                                    // This needs to be registered as a Credit to the Libabilities
                                    realizedPnl *= -1;
                                }

                                var fromToAccounts = new AccountUtils().GetAccounts(env, originalAccount, "REALIZED GAIN/(LOSS)", listOfTags, taxlot.Trade);
                                fromAccount = fromToAccounts.From;
                                toAccount   = fromToAccounts.To;

                                var debitJournal = new Journal(element)
                                {
                                    Account     = fromAccount,
                                    When        = env.ValueDate,
                                    StartPrice  = taxlot.TradePrice,
                                    EndPrice    = taxlot.CostBasis,
                                    CreditDebit = env.DebitOrCredit(fromAccount, taxlot.RealizedPnl),
                                    Value       = env.SignedValue(fromAccount, toAccount, true, taxlot.RealizedPnl),
                                    FxRate      = fxrate,
                                    Event       = Event.REALIZED_PNL,
                                    Fund        = env.GetFund(element),
                                };

                                var creditJournal = new Journal(debitJournal)
                                {
                                    Account     = toAccount,
                                    CreditDebit = env.DebitOrCredit(toAccount, taxlot.RealizedPnl * -1),
                                    Value       = env.SignedValue(fromAccount, toAccount, false, taxlot.RealizedPnl),
                                };

                                env.Journals.AddRange(new[] { debitJournal, creditJournal });

                                taxlotStatus.Quantity = 0;
                                taxlotStatus.Status   = "Closed";
                            }
                        }
                    }
                }
            }
            else
            {
                // We have a Debit / Credit Dividends
            }
        }
Esempio n. 5
0
        /// <summary>
        /// Run for each day that the Tax Lot remains open / partially closed
        /// </summary>
        /// <param name="env"></param>
        /// <param name="element">Trade we aee interested in</param>
        public void DailyEvent(PostingEngineEnvironment env, Transaction element)
        {
            double fxrate = 1.0;

            // Lets get fx rate if needed
            if (!element.SettleCurrency.Equals(env.BaseCurrency))
            {
                fxrate = Convert.ToDouble(FxRates.Find(env.ValueDate, element.SettleCurrency).Rate);
            }

            // Calculate the unrealized PNL
            if (env.TaxLotStatus.ContainsKey(element.LpOrderId))
            {
                // Determine if we need to accumulate unrealized PNL
                var taxlot = env.TaxLotStatus[element.LpOrderId];

                // Check to see if the TaxLot is still open and it has a non zero Quantity
                if (!taxlot.Status.ToLowerInvariant().Equals("closed") && Math.Abs(taxlot.Quantity) > 0)
                {
                    var prevEodPrice = 0.0;
                    var eodPrice     = 0.0;
                    var fxRate       = 0.0;

                    if (element.TradeCurrency.Equals(env.BaseCurrency))
                    {
                        if (env.ValueDate == element.TradeDate)
                        {
                            prevEodPrice = 1 / element.SettleNetPrice;
                            fxRate       = FxRates.Find(env.ValueDate, element.SettleCurrency).Rate;
                            eodPrice     = fxRate;
                        }
                        else
                        {
                            prevEodPrice = FxRates.Find(env.PreviousValueDate, element.SettleCurrency).Rate;
                            fxRate       = FxRates.Find(env.PreviousValueDate, element.SettleCurrency).Rate;
                            eodPrice     = fxRate;
                        }
                    }
                    else
                    {
                        if (env.ValueDate == element.TradeDate)
                        {
                            prevEodPrice = element.SettleNetPrice;
                            fxRate       = FxRates.Find(env.ValueDate, element.TradeCurrency).Rate;
                            eodPrice     = fxRate;
                        }
                        else
                        {
                            prevEodPrice = FxRates.Find(env.PreviousValueDate, element.TradeCurrency).Rate;
                            fxRate       = FxRates.Find(env.ValueDate, element.TradeCurrency).Rate;
                            eodPrice     = fxRate;
                        }
                    }

                    var unrealizedPnl = 0.0;

                    var quantity = taxlot.Quantity;
                    var rateDiff = (eodPrice - prevEodPrice);

                    if (element.SettleCurrency.Equals(env.BaseCurrency))
                    {
                        unrealizedPnl = (rateDiff * quantity);
                    }
                    else
                    {
                        unrealizedPnl = (rateDiff * quantity) * fxRate;
                    }

                    var originalAccount = AccountUtils.GetDerivativeAccountType(unrealizedPnl);
                    var fromToAccounts  = new AccountUtils().GetAccounts(env, originalAccount, "Change in Unrealized Derivatives Contracts at Fair Value", listOfTags, taxlot.Trade);

                    var fund = env.GetFund(element);

                    var debit = new Journal(element)
                    {
                        Account     = fromToAccounts.From,
                        When        = env.ValueDate,
                        Symbol      = taxlot.Symbol,
                        Quantity    = quantity,
                        FxRate      = rateDiff,
                        Value       = env.SignedValue(fromToAccounts.From, fromToAccounts.To, false, unrealizedPnl),
                        CreditDebit = env.DebitOrCredit(fromToAccounts.From, unrealizedPnl),
                        StartPrice  = prevEodPrice,
                        EndPrice    = eodPrice,
                        Event       = Event.DAILY_UNREALIZED_PNL,
                        Fund        = fund,
                    };

                    var credit = new Journal(debit)
                    {
                        Account     = fromToAccounts.To,
                        Value       = env.SignedValue(fromToAccounts.From, fromToAccounts.To, true, unrealizedPnl),
                        CreditDebit = env.DebitOrCredit(fromToAccounts.To, unrealizedPnl),
                    };

                    env.Journals.AddRange(new[] { debit, credit });

                    if (element.TradeDate != env.ValueDate && element.SettleDate >= env.ValueDate)
                    {
                        var fxJournals = FxPosting.CreateFx(
                            env,
                            "daily",
                            quantity, null, element);
                        env.Journals.AddRange(fxJournals);
                    }
                }
            }
            else
            {
                if (fxrate != 1.0)
                {
                    if (element.TradeDate != env.ValueDate && element.SettleDate >= env.ValueDate)
                    {
                        var fxJournals = FxPosting.CreateFx(
                            env,
                            "daily",
                            element.Quantity, null, element);
                        env.Journals.AddRange(fxJournals);
                    }
                }
            }
        }
Esempio n. 6
0
        public void SettlementDateEvent(PostingEngineEnvironment env, Transaction element)
        {
            if (env.TaxLotStatus.ContainsKey(element.LpOrderId))
            {
                var taxlot = env.TaxLotStatus[element.LpOrderId];

                var tradeCurrency  = element.TradeCurrency;
                var settleCurrency = element.SettleCurrency;
                var allocations    = env.FindTradeAllocations(element);

                var buy  = allocations.Where(i => i.SecurityType.Equals("SPOT") && i.Side.Equals("BUY")).FirstOrDefault();
                var sell = allocations.Where(i => i.SecurityType.Equals("SPOT") && i.Side.Equals("SELL")).FirstOrDefault();

                if (buy == null || sell == null)
                {
                    Logger.Error($"Unable to process {element.SecurityType}::{element.LpOrderId}");
                    return;
                }

                var accountSell = new AccountUtils().CreateAccount(atSettledCash, listOfTradeTags, sell);
                var accountBuy  = new AccountUtils().CreateAccount(atSettledCash, listOfTradeTags, buy);

                new AccountUtils().SaveAccountDetails(env, accountSell);
                new AccountUtils().SaveAccountDetails(env, accountBuy);

                var sellFx = FxRates.Find(env.ValueDate, sell.TradeCurrency);
                var buyFx  = FxRates.Find(env.ValueDate, buy.TradeCurrency);

                var sellValue = sell.Quantity * sellFx.Rate;
                var buyValue  = buy.Quantity * buyFx.Rate;


                if (element.IsBuy())   // BUY
                {
                    var realizedPnl = buyValue + sellValue;

                    var debit = new Journal(accountBuy, Event.SETTLED_CASH, env.ValueDate)
                    {
                        Source     = element.LpOrderId,
                        Fund       = env.GetFund(element),
                        FxCurrency = element.TradeCurrency,
                        Symbol     = element.Symbol,
                        SecurityId = element.SecurityId,
                        Quantity   = Convert.ToDouble(buy.Quantity),

                        FxRate     = buyFx.Rate,
                        StartPrice = 0,
                        EndPrice   = 0,

                        Value       = env.SignedValue(accountBuy, accountSell, true, buyValue),
                        CreditDebit = env.DebitOrCredit(accountBuy, buy.Quantity),
                    };

                    var credit = new Journal(accountSell, Event.SETTLED_CASH, env.ValueDate)
                    {
                        Source     = element.LpOrderId,
                        Fund       = env.GetFund(element),
                        FxCurrency = element.SettleCurrency,
                        Symbol     = element.Symbol,
                        SecurityId = element.SecurityId,
                        Quantity   = Convert.ToDouble(sell.Quantity),

                        FxRate     = sellFx.Rate,
                        StartPrice = 0,
                        EndPrice   = 0,

                        Value       = env.SignedValue(accountBuy, accountSell, true, sellValue),
                        CreditDebit = env.DebitOrCredit(accountSell, sell.Quantity),
                    };

                    env.Journals.AddRange(new[] { credit, debit });

                    var originalAccount = AccountUtils.GetDerivativeAccountType(realizedPnl);

                    // Realized Pnl to go along with the Settled Cash
                    CommonRules.GenerateJournalEntry(env, element, listOfTags, realizedAccountType, Event.REALIZED_PNL, realizedPnl);

                    CommonRules.GenerateJournalEntries(env, element, listOfTags, originalAccount, "Change in Unrealized Derivatives Contracts at Fair Value", realizedPnl * -1);
                }
                else // SELL
                {
                    var realizedPnl = buyValue + sellValue;

                    var debit = new Journal(accountBuy, Event.SETTLED_CASH, env.ValueDate)
                    {
                        Source     = element.LpOrderId,
                        Fund       = env.GetFund(element),
                        FxCurrency = element.TradeCurrency,
                        Symbol     = element.Symbol,
                        SecurityId = element.SecurityId,
                        Quantity   = Convert.ToDouble(buy.Quantity),

                        FxRate     = buyFx.Rate,
                        StartPrice = 0,
                        EndPrice   = 0,

                        Value       = env.SignedValue(accountBuy, accountSell, true, buy.Quantity * buyFx.Rate),
                        CreditDebit = env.DebitOrCredit(accountBuy, buy.Quantity),
                    };

                    var credit = new Journal(accountSell, Event.SETTLED_CASH, env.ValueDate)
                    {
                        Source     = element.LpOrderId,
                        Fund       = env.GetFund(element),
                        FxCurrency = element.SettleCurrency,
                        Symbol     = element.Symbol,
                        SecurityId = element.SecurityId,
                        Quantity   = Convert.ToDouble(sell.Quantity),

                        FxRate     = sellFx.Rate,
                        StartPrice = 0,
                        EndPrice   = 0,

                        Value       = env.SignedValue(accountBuy, accountSell, true, sell.Quantity * sellFx.Rate),
                        CreditDebit = env.DebitOrCredit(accountSell, sell.Quantity),
                    };

                    env.Journals.AddRange(new[] { credit, debit });

                    var originalAccount = AccountUtils.GetDerivativeAccountType(realizedPnl);

                    // Realized Pnl to go along with the Settled Cash
                    CommonRules.GenerateJournalEntry(env, element, listOfTags, realizedAccountType, Event.REALIZED_PNL, realizedPnl);

                    CommonRules.GenerateJournalEntries(env, element, listOfTags, originalAccount, "Change in Unrealized Derivatives Contracts at Fair Value", realizedPnl * -1);
                }

                if (taxlot.Quantity != 0)
                {
                    var buyTrade = env.FindTrade(taxlot.OpenId);
                    CommonRules.RelieveTaxLot(env, buyTrade, element, taxlot.Quantity * -1, true);
                    taxlot.Quantity = 0;
                    taxlot.Status   = "Closed";

                    //Now we have Realized Pnl
                }
            }
        }