Esempio n. 1
0
        internal static void ReverseUnrealizedPnl(PostingEngineEnvironment env, Transaction openTaxLot, Transaction trade, double unrealizedPnl, double start, double end, double fxrate)
        {
            var accountToFrom = UnRealizedPnlPostingAccounts(openTaxLot, unrealizedPnl);

            new AccountUtils().SaveAccountDetails(env, accountToFrom.From);
            new AccountUtils().SaveAccountDetails(env, accountToFrom.To);

            var fromJournal = new Journal(openTaxLot)
            {
                When       = env.ValueDate,
                Event      = Event.REVERSE_UNREALIZED_PNL,
                FxRate     = fxrate,
                Fund       = env.GetFund(openTaxLot),
                StartPrice = start,
                EndPrice   = end,
                Quantity   = trade.Quantity,

                Account     = accountToFrom.To,
                CreditDebit = env.DebitOrCredit(accountToFrom.To, unrealizedPnl),
                Value       = env.SignedValue(accountToFrom.To, accountToFrom.From, true, unrealizedPnl),
            };

            var toJournal = new Journal(fromJournal)
            {
                Account     = accountToFrom.From,
                CreditDebit = env.DebitOrCredit(accountToFrom.From, unrealizedPnl),
                Value       = env.SignedValue(accountToFrom.To, accountToFrom.From, false, unrealizedPnl),
            };

            env.Journals.AddRange(new[] { fromJournal, toJournal });
        }
Esempio n. 2
0
        /// <summary>
        /// Contra Journal Entries
        /// </summary>
        /// <param name="env"></param>
        /// <param name="element"></param>
        /// <param name="tags"></param>
        /// <param name="from"></param>
        /// <param name="to"></param>
        /// <param name="value"></param>
        internal static void GenerateJournalEntries(PostingEngineEnvironment env, Transaction element, List <Tag> tags, string from, string to, double value)
        {
            var fromAccount = new AccountUtils().CreateAccount(AccountType.Find(from), tags, element);
            var toAccount   = new AccountUtils().CreateAccount(AccountType.Find(to), tags, element);

            new AccountUtils().SaveAccountDetails(env, fromAccount);
            new AccountUtils().SaveAccountDetails(env, toAccount);

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

            var creditJournal = new Journal(debitJournal)
            {
                Account     = toAccount,
                CreditDebit = env.DebitOrCredit(toAccount, value),
                Value       = env.SignedValue(fromAccount, toAccount, false, value),
            };

            env.Journals.AddRange(new[] { debitJournal, creditJournal });
        }
Esempio n. 3
0
        private IEnumerable <Journal> ReverseCredit(PostingEngineEnvironment env, DateTime valueDate, dynamic yearEndResult, string fromAccount, string toAccount, string accountName, double balance)
        {
            var debitAccount  = new AccountUtils().CreateAccount(fromAccount, accountName);
            var creditAccount = new AccountUtils().CreateAccount(toAccount, accountName);

            new AccountUtils().SaveAccountDetails(env, debitAccount);
            new AccountUtils().SaveAccountDetails(env, creditAccount);

            if (yearEndResult.AccountCategory.Equals("Expenses"))
            {
                balance *= -1;
            }

            var debitJournal = new Journal(debitAccount, Event.YEAR_END, valueDate)
            {
                Source   = "year-closeout",
                Fund     = yearEndResult.Fund,
                Quantity = balance,

                FxCurrency = env.BaseCurrency,
                Symbol     = env.BaseCurrency,
                SecurityId = -1,
                FxRate     = 0,
                StartPrice = 0,
                EndPrice   = 0,

                Value       = balance * -1,
                CreditDebit = env.DebitOrCredit(debitAccount, balance),
            };

            var creditJournal = new Journal(creditAccount, Event.YEAR_END, valueDate)
            {
                Source   = "year-closeout",
                Fund     = yearEndResult.Fund,
                Quantity = balance,

                FxCurrency = env.BaseCurrency,
                Symbol     = env.BaseCurrency,
                SecurityId = -1,
                FxRate     = 0,
                StartPrice = 0,
                EndPrice   = 0,

                Value       = balance,
                CreditDebit = env.DebitOrCredit(creditAccount, balance),
            };

            return(new Journal[] { creditJournal, debitJournal });
        }
        private void PostUnrealizedFxGain(PostingEngineEnvironment env, Transaction element, double realizedFxPnl, double start, double end, double fxrate)
        {
            var m2mtranslation = "Mark to Market longs fx translation gain or loss";

            if (element.IsShort())
            {
                m2mtranslation = "Mark to Market shorts fx translation gain or loss";
            }

            var fromTo = new AccountUtils().GetAccounts(env, m2mtranslation, "change in unrealized do to fx translation", new string[] { element.SettleCurrency }.ToList());

            var debit = new Journal(fromTo.From, Event.UNREALIZED_FX_TRANSLATION, env.ValueDate)
            {
                Source     = element.LpOrderId,
                Fund       = env.GetFund(element),
                FxCurrency = element.SettleCurrency,
                Symbol     = element.Symbol,
                SecurityId = element.SecurityId,
                Quantity   = Convert.ToDouble(element.Quantity),

                FxRate     = fxrate,
                StartPrice = start,
                EndPrice   = end,

                Value       = env.SignedValue(fromTo.From, fromTo.To, true, realizedFxPnl * -1),
                CreditDebit = env.DebitOrCredit(fromTo.From, realizedFxPnl),
            };

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

                FxRate     = fxrate,
                StartPrice = start,
                EndPrice   = end,

                Value       = env.SignedValue(fromTo.From, fromTo.To, false, realizedFxPnl * -1),
                CreditDebit = env.DebitOrCredit(fromTo.To, realizedFxPnl),
            };

            env.Journals.AddRange(new List <Journal>(new[] { debit, credit }));
        }
Esempio n. 5
0
        private void AccrualPayment(PostingEngineEnvironment env, Transaction element, Accrual accrual)
        {
            var accountToFrom = GetFromToAccount(element);

            if (accountToFrom.To == null || accountToFrom.From == null)
            {
                env.AddMessage($"Unable to identify From/To accounts for trade {element.OrderSource} :: {element.Side}");
                return;
            }

            new AccountUtils().SaveAccountDetails(env, accountToFrom.From);
            new AccountUtils().SaveAccountDetails(env, accountToFrom.To);

            double fxrate = 1.0;

            if (!element.SettleCurrency.Equals(env.BaseCurrency))
            {
                fxrate = Convert.ToDouble(FxRates.Find(env.ValueDate, element.SettleCurrency).Rate);
            }

            var moneyUSD = element.LocalNetNotional * fxrate;

            var debit = new Journal(element)
            {
                Account     = accountToFrom.From,
                When        = env.ValueDate,
                FxRate      = fxrate,
                CreditDebit = env.DebitOrCredit(accountToFrom.From, moneyUSD),
                Value       = env.SignedValue(accountToFrom.From, accountToFrom.To, true, moneyUSD),
                Event       = "prepaid-expense",
                Fund        = env.GetFund(element),
            };

            var credit = new Journal(element)
            {
                Account     = accountToFrom.To,
                When        = env.ValueDate,
                FxRate      = fxrate,
                CreditDebit = env.DebitOrCredit(accountToFrom.To, moneyUSD),
                Value       = env.SignedValue(accountToFrom.From, accountToFrom.To, false, moneyUSD),
                Event       = "prepaid-expense",
                Fund        = env.GetFund(element),
            };

            env.Journals.Add(debit);
            env.Journals.Add(credit);
        }
Esempio n. 6
0
        internal static void PostRealizedPnl(PostingEngineEnvironment env, Transaction element, double pnL, double start, double end, double fxrate = 1.0)
        {
            var accountToFrom = RealizedPnlPostingAccounts(element, pnL);

            new AccountUtils().SaveAccountDetails(env, accountToFrom.From);
            new AccountUtils().SaveAccountDetails(env, accountToFrom.To);


            if (element.IsDerivative())
            {
                // Need to Credit the From and Debit the to
                pnL *= -1;
            }
            else
            {
                if (element.IsShort() || element.IsCover())
                {
                    pnL *= -1;
                }
            }

            var debitJournal = new Journal(element)
            {
                Account     = accountToFrom.From,
                When        = env.ValueDate,
                StartPrice  = start,
                EndPrice    = end,
                CreditDebit = env.DebitOrCredit(accountToFrom.From, pnL),
                Value       = env.SignedValue(accountToFrom.From, accountToFrom.To, true, pnL),
                FxRate      = fxrate,
                Event       = Event.REALIZED_PNL,
                Fund        = env.GetFund(element),
            };

            var creditJournal = new Journal(element, accountToFrom.To, Event.REALIZED_PNL, env.ValueDate)
            {
                StartPrice  = start,
                EndPrice    = end,
                FxRate      = fxrate,
                CreditDebit = env.DebitOrCredit(accountToFrom.To, pnL * -1),
                Value       = env.SignedValue(accountToFrom.From, accountToFrom.To, false, pnL),
                Fund        = env.GetFund(element),
            };

            env.Journals.AddRange(new[] { debitJournal, creditJournal });
        }
        private void PostRealizedFxGain(PostingEngineEnvironment env, Transaction element, double realizedFxPnl, double start, double end, double fxrate)
        {
            var accountType = (element.IsShort() || element.IsCover()) ? "SHORT POSITIONS AT COST" : "LONG POSITIONS AT COST";
            var fromTo      = new AccountUtils().GetAccounts(env, accountType, "REALIZED GAIN/(LOSS) DUE TO FX", new string[] { element.SettleCurrency }.ToList());

            var debit = new Journal(fromTo.From, "realized-cash-fx", env.ValueDate)
            {
                Source     = element.LpOrderId,
                Fund       = env.GetFund(element),
                FxCurrency = element.SettleCurrency,
                Symbol     = element.Symbol,
                SecurityId = element.SecurityId,
                Quantity   = Convert.ToDouble(element.Quantity),

                FxRate     = fxrate,
                StartPrice = start,
                EndPrice   = end,

                Value       = env.SignedValue(fromTo.From, fromTo.To, true, realizedFxPnl),
                CreditDebit = env.DebitOrCredit(fromTo.From, realizedFxPnl),
            };

            var credit = new Journal(fromTo.To, "realized-cash-fx", env.ValueDate)
            {
                Source     = element.LpOrderId,
                Fund       = env.GetFund(element),
                FxCurrency = element.SettleCurrency,
                Symbol     = element.Symbol,
                SecurityId = element.SecurityId,
                Quantity   = Convert.ToDouble(element.Quantity),

                FxRate     = fxrate,
                StartPrice = start,
                EndPrice   = end,

                Value       = env.SignedValue(fromTo.From, fromTo.To, false, realizedFxPnl),
                CreditDebit = env.DebitOrCredit(fromTo.To, realizedFxPnl),
            };


            env.Journals.AddRange(new List <Journal>(new[] { debit, credit }));
        }
        private void ReversePosting(PostingEngineEnvironment env, string fromAccount, string toAccount, Transaction element, double reversalAmount)
        {
            var fromTo = new AccountUtils().GetAccounts(env, fromAccount, toAccount, new string[] { element.SettleCurrency }.ToList());

            var debit = new Journal(fromTo.From, "reversal-unrealized-cash-fx", env.ValueDate)
            {
                Source     = element.LpOrderId,
                Fund       = env.GetFund(element),
                FxCurrency = element.SettleCurrency,
                Symbol     = element.Symbol,
                SecurityId = element.SecurityId,
                Quantity   = Convert.ToDouble(element.Quantity),
                FxRate     = 0,
                StartPrice = 0,
                EndPrice   = 0,

                Value       = env.SignedValue(fromTo.From, fromTo.To, true, reversalAmount * -1),
                CreditDebit = env.DebitOrCredit(fromTo.From, reversalAmount),
            };

            var credit = new Journal(fromTo.To, "reversal-unrealized-cash-fx", env.ValueDate)
            {
                Source     = element.LpOrderId,
                Fund       = env.GetFund(element),
                FxCurrency = element.SettleCurrency,
                Symbol     = element.Symbol,
                SecurityId = element.SecurityId,
                Quantity   = Convert.ToDouble(element.Quantity),

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

                Value       = env.SignedValue(fromTo.From, fromTo.To, false, reversalAmount * -1),
                CreditDebit = env.DebitOrCredit(fromTo.To, reversalAmount),
            };

            env.Journals.AddRange(new List <Journal>(new[] { debit, credit }));
        }
Esempio n. 9
0
        internal static void PostRealizedPnl(PostingEngineEnvironment env, Transaction element, double realizedPnl, string from, string to)
        {
            var listOfTags = new List <Tag> {
                Tag.Find("SecurityType"),
                Tag.Find("CustodianCode")
            };

            var fromAccount = new AccountUtils().CreateAccount(AccountType.Find(from), listOfTags, element);
            var toAccount   = new AccountUtils().CreateAccount(AccountType.Find(to), listOfTags, element);

            new AccountUtils().SaveAccountDetails(env, fromAccount);
            new AccountUtils().SaveAccountDetails(env, toAccount);

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

            var creditJournal = new Journal(element, toAccount, Event.REALIZED_PNL, env.ValueDate)
            {
                StartPrice  = 0,
                EndPrice    = 0,
                FxRate      = element.TradePrice,
                CreditDebit = env.DebitOrCredit(toAccount, realizedPnl),
                Value       = env.SignedValue(fromAccount, toAccount, false, realizedPnl),
                Fund        = env.GetFund(element),
            };

            env.Journals.AddRange(new[] { debitJournal, creditJournal });
        }
Esempio n. 10
0
        /// <summary>
        /// Single Sided Entry Journal
        /// </summary>
        /// <param name="env"></param>
        /// <param name="element"></param>
        /// <param name="tags"></param>
        /// <param name="accountType"></param>
        /// <param name="value"></param>
        internal static void GenerateJournalEntry(PostingEngineEnvironment env, Transaction element, List <Tag> tags, AccountType accountType, string eventName, double value)
        {
            var account = new AccountUtils().CreateAccount(accountType, tags, element);

            new AccountUtils().SaveAccountDetails(env, account);

            var journal = new Journal(element)
            {
                Account     = account,
                When        = env.ValueDate,
                StartPrice  = 0,
                EndPrice    = 0,
                CreditDebit = env.DebitOrCredit(account, value),
                Value       = value,
                FxRate      = element.TradePrice,
                Event       = eventName,
                Fund        = env.GetFund(element),
            };

            env.Journals.AddRange(new[] { journal });
        }
Esempio n. 11
0
        internal double CreateFxUnsettled(PostingEngineEnvironment env, Transaction element)
        {
            var journals = new List <Journal>();

            // TBD: Needs to be optimized, get all data upfront for a ValueDate and drop into the env
            //env.CallBack?.Invoke($"Create Fx Unsettled {element.SettleCurrency} -- {element.LpOrderId}");

            var unsettledPnls = env.UnsettledPnl.Where(i => i.Source.Equals(element.LpOrderId)).ToList();

            var fxChange = 0.0;

            if (unsettledPnls.Count() == 0)
            {
                return(0.0);
            }

            var prevRate = FxRates.Find(env.PreviousValueDate, unsettledPnls[0].Currency).Rate;
            var eodRate  = FxRates.Find(env.ValueDate, unsettledPnls[0].Currency).Rate;

            unsettledPnls.ForEach(unsettledPnl => {
                var change       = eodRate - prevRate;
                var fxCashCredit = change * (unsettledPnl.Credit / unsettledPnl.FxRate);
                var fxCashDebit  = change * (unsettledPnl.Debit / unsettledPnl.FxRate);
                var fxCash       = fxCashCredit - fxCashDebit;

                var from = "";
                var to   = "";

                if (element.IsDerivative())
                {
                    from = fxCash > 0 ? "Mark to Market Derivatives Contracts due to FX Translation (Assets)" : "Mark to Market Derivatives Contracts due to FX  Translation (Liabilities)";

                    if (from.Contains("(Liabilities)"))
                    {
                        fxCash *= -1;
                    }

                    to = "Change in Unrealized Derivatives Contracts due to FX Translation";
                }
                else
                {
                    var m2mtranslation = "Mark to Market longs fx translation gain or loss";
                    if (element.IsShort() || element.IsCover())
                    {
                        m2mtranslation = "Mark to Market shorts fx translation gain or loss";
                    }

                    from = m2mtranslation;
                    to   = "change in unrealized do to fx translation";
                }

                // Get accounts
                var fromTo = new AccountUtils().GetAccounts(env, from, to, new string[] { unsettledPnl.Currency }.ToList());

                var debit = new Journal(fromTo.From, Event.UNREALIZED_FX_TRANSLATION, env.ValueDate)
                {
                    Source     = unsettledPnl.Source,
                    Fund       = unsettledPnl.Fund,
                    FxCurrency = unsettledPnl.Currency,
                    Symbol     = unsettledPnl.Symbol,
                    SecurityId = unsettledPnl.SecurityId,
                    Quantity   = Convert.ToDouble(unsettledPnl.Quantity),

                    FxRate     = change,
                    StartPrice = prevRate,
                    EndPrice   = eodRate,

                    Value       = env.SignedValue(fromTo.From, fromTo.To, true, fxCash),
                    CreditDebit = env.DebitOrCredit(fromTo.From, fxCash),
                };

                fxChange += debit.Value;

                var credit = new Journal(fromTo.To, Event.UNREALIZED_FX_TRANSLATION, env.ValueDate)
                {
                    Source     = unsettledPnl.Source,
                    Fund       = unsettledPnl.Fund,
                    FxCurrency = unsettledPnl.Currency,
                    Symbol     = unsettledPnl.Symbol,
                    SecurityId = unsettledPnl.SecurityId,
                    Quantity   = Convert.ToDouble(unsettledPnl.Quantity),

                    FxRate     = change,
                    StartPrice = prevRate,
                    EndPrice   = eodRate,

                    Value       = env.SignedValue(fromTo.From, fromTo.To, false, fxCash),
                    CreditDebit = env.DebitOrCredit(fromTo.To, fxCash),
                };

                journals.AddRange(new List <Journal>(new[] { debit, credit }));
            });

            //connection.Close();
            env.Journals.AddRange(journals);

            return(fxChange);
        }
Esempio n. 12
0
        internal void CreateFxUnsettled(PostingEngineEnvironment env)
        {
            var sql = $@"select credit, debit, symbol, quantity, fx_currency, fund, source, fxrate, security_id, side from vwWorkingJournals 
                         where [event] = 'unrealizedpnl' 
                         and AccountType in ('CHANGE IN UNREALIZED GAIN/(LOSS)', 'Change in Unrealized Derivatives Contracts at Fair Value')
                         and fx_currency != '{env.BaseCurrency}'
                         and [when] < '{env.ValueDate.ToString("MM-dd-yyyy")}'";

            env.CallBack?.Invoke("FX for Mark to Market Calculation Started");

            var connection = new SqlConnection(env.ConnectionString);

            connection.Open();
            var command = new SqlCommand(sql, connection);

            command.Transaction = env.Transaction;
            var reader = command.ExecuteReader(System.Data.CommandBehavior.SingleResult);

            while (reader.Read())
            {
                var unsettledPnl = new
                {
                    Credit     = Convert.ToDouble(reader.GetFieldValue <decimal>(0)),
                    Debit      = Convert.ToDouble(reader.GetFieldValue <decimal>(1)),
                    Symbol     = reader.GetFieldValue <string>(2),
                    Quantity   = Convert.ToDouble(reader.GetFieldValue <decimal>(3)),
                    Currency   = reader.GetFieldValue <string>(4),
                    Fund       = reader.GetFieldValue <string>(5),
                    Source     = reader.GetFieldValue <string>(6),
                    FxRate     = Convert.ToDouble(reader.GetFieldValue <decimal>(7)),
                    SecurityId = reader.GetFieldValue <int>(8),
                    Side       = reader.GetFieldValue <string>(9),
                };

                if (unsettledPnl.Currency.Equals(env.BaseCurrency))
                {
                    continue;
                }

                var prevRate = FxRates.Find(env.PreviousValueDate, unsettledPnl.Currency).Rate;
                var eodRate  = FxRates.Find(env.ValueDate, unsettledPnl.Currency).Rate;

                var change       = eodRate - prevRate;
                var fxCashCredit = change * (unsettledPnl.Credit / unsettledPnl.FxRate);
                var fxCashDebit  = change * (unsettledPnl.Debit / unsettledPnl.FxRate);
                var fxCash       = fxCashCredit - fxCashDebit;

                var m2mtranslation = "Mark to Market longs fx translation gain or loss";

                if (unsettledPnl.Side.ToLowerInvariant().Equals("short") || unsettledPnl.Side.ToLowerInvariant().Equals("cover"))
                {
                    m2mtranslation = "Mark to Market shorts fx translation gain or loss";
                }

                // Get accounts
                var fromTo = new AccountUtils().GetAccounts(env, m2mtranslation, "change in unrealized do to fx translation", new string[] { unsettledPnl.Currency }.ToList());

                var debit = new Journal(fromTo.From, Event.UNREALIZED_FX_TRANSLATION, env.ValueDate)
                {
                    Source     = unsettledPnl.Source,
                    Fund       = unsettledPnl.Fund,
                    FxCurrency = unsettledPnl.Currency,
                    Symbol     = unsettledPnl.Symbol,
                    SecurityId = unsettledPnl.SecurityId,
                    Quantity   = Convert.ToDouble(unsettledPnl.Quantity),

                    FxRate     = change,
                    StartPrice = prevRate,
                    EndPrice   = eodRate,

                    Value       = env.SignedValue(fromTo.From, fromTo.To, true, fxCash),
                    CreditDebit = env.DebitOrCredit(fromTo.From, fxCash),
                };

                var credit = new Journal(fromTo.To, Event.UNREALIZED_FX_TRANSLATION, env.ValueDate)
                {
                    Source     = unsettledPnl.Source,
                    Fund       = unsettledPnl.Fund,
                    FxCurrency = unsettledPnl.Currency,
                    Symbol     = unsettledPnl.Symbol,
                    SecurityId = unsettledPnl.SecurityId,
                    Quantity   = Convert.ToDouble(unsettledPnl.Quantity),

                    FxRate     = change,
                    StartPrice = prevRate,
                    EndPrice   = eodRate,

                    Value       = env.SignedValue(fromTo.From, fromTo.To, false, fxCash),
                    CreditDebit = env.DebitOrCredit(fromTo.To, fxCash),
                };
                env.Journals.AddRange(new List <Journal>(new[] { debit, credit }));
            }

            connection.Close();
        }
        /// <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. 14
0
        internal static List <Journal> CreateFx(PostingEngineEnvironment env,
                                                string tradeEvent,
                                                double quantity,
                                                TaxLotStatus taxlotStatus,
                                                Transaction element)
        {
            if (tradeEvent.Equals(Event.TRADE_DATE))
            {
                return(new List <Journal>());
            }

            var riskCurrency = element.SettleCurrency;

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

            // Check to see if the BaseCurrency == SettleCurrency because if it is then no need to do the FX translation
            if (env.BaseCurrency.Equals(riskCurrency))
            {
                return(new List <Journal>());
            }

            var prevEodFxRate = Convert.ToDouble(FxRates.Find(env.PreviousValueDate, riskCurrency).Rate);
            var eodFxRate     = Convert.ToDouble(FxRates.Find(env.ValueDate, riskCurrency).Rate);
            var effectiveRate = eodFxRate - prevEodFxRate;

            var usdEquivalent = element.Quantity * effectiveRate;

            var fromAccount = "Mark to Market Derivatives Contracts due to FX (Liabilities)";
            var toAccount   = "Change in Unrealized Derivatives Contracts due to FX";

            if (usdEquivalent > 0)
            {
                fromAccount = "Mark to Market Derivatives Contracts due to FX (Assets)";
            }

            // Get accounts
            var toFrom = new AccountUtils().GetAccounts(env, fromAccount, toAccount, _TAGS, element);

            var fund = env.GetFund(element);

            var debit = new Journal(element, toFrom.From, $"{tradeEvent}-unrealizedpnl-fx", env.ValueDate)
            {
                Quantity    = quantity,
                FxRate      = effectiveRate,
                StartPrice  = prevEodFxRate,
                FxCurrency  = riskCurrency,
                EndPrice    = eodFxRate,
                Fund        = fund,
                Value       = env.SignedValue(toFrom.From, toFrom.To, true, usdEquivalent),
                CreditDebit = env.DebitOrCredit(toFrom.From, usdEquivalent),
            };

            var credit = new Journal(element, toFrom.To, $"{tradeEvent}-unrealizedpnl-fx", env.ValueDate)
            {
                Quantity   = quantity,
                FxRate     = effectiveRate,
                FxCurrency = riskCurrency,
                StartPrice = prevEodFxRate,
                EndPrice   = eodFxRate,
                Fund       = fund,

                Value       = env.SignedValue(toFrom.From, toFrom.To, false, usdEquivalent),
                CreditDebit = env.DebitOrCredit(toFrom.To, usdEquivalent),
            };


            return(new List <Journal>(new[] { debit, credit }));
        }
Esempio n. 15
0
        public void SettlementDateEvent(PostingEngineEnvironment env, Transaction element)
        {
            var accrual     = env.FindAccruals(element.AccrualId);
            var allocations = env.FindAllocations(element.AccrualId);
            var allocation  = allocations.Where(i => !i.Symbol.Equals(element.Symbol)).FirstOrDefault();

            if (element.Status.Equals("Cancelled"))
            {
                env.AddMessage($"Entry has been cancelled {element.LpOrderId} :: {element.Side}");
                return;
            }

            // If they are the same we need to do nothing
            if (element.TradeDate.Date == element.SettleDate.Date)
            {
                //env.AddMessage($"Journal needs to be checked {element.LpOrderId}, {element.TradeDate}, {element.SettleDate}");
                return;
            }

            var accountToFrom = GetSettlementFromToAccount(element);

            if (accountToFrom.To == null)
            {
                env.AddMessage($"Unable to identify From/To accounts for trade {element.OrderSource} :: {element.Side}");
                return;
            }

            new AccountUtils().SaveAccountDetails(env, accountToFrom.From);
            new AccountUtils().SaveAccountDetails(env, accountToFrom.To);

            double fxrate = 1.0;

            if (!element.SettleCurrency.Equals(env.BaseCurrency))
            {
                fxrate = Convert.ToDouble(FxRates.Find(env.ValueDate, element.SettleCurrency).Rate);
            }

            var moneyUSD = element.LocalNetNotional * fxrate;

            if (element.LocalNetNotional != 0.0)
            {
                var symbol     = allocation != null ? allocation.Symbol : element.ParentSymbol;
                var securityId = allocation != null ? allocation.SecurityId : element.SecurityId;

                if (symbol == null)
                {
                    symbol = element.Symbol;
                }

                var debit = new Journal(accountToFrom.From, "journal", env.ValueDate)
                {
                    Symbol     = symbol,
                    SecurityId = allocation != null ? allocation.SecurityId : element.SecurityId,

                    Source      = element.LpOrderId,
                    Quantity    = element.Quantity,
                    FxCurrency  = element.SettleCurrency,
                    FxRate      = fxrate,
                    CreditDebit = env.DebitOrCredit(accountToFrom.From, moneyUSD),
                    Value       = moneyUSD,
                    Fund        = env.GetFund(element),
                };

                var credit = new Journal(accountToFrom.To, "journal", env.ValueDate)
                {
                    Symbol     = symbol,
                    SecurityId = allocation != null ? allocation.SecurityId : element.SecurityId,

                    Source      = element.LpOrderId,
                    Quantity    = element.Quantity,
                    FxCurrency  = element.SettleCurrency,
                    FxRate      = fxrate,
                    CreditDebit = env.DebitOrCredit(accountToFrom.To, moneyUSD * -1),
                    Value       = moneyUSD * -1,
                    Fund        = env.GetFund(element),
                };

                env.Journals.Add(debit);
                env.Journals.Add(credit);
            }

            return;
        }
Esempio n. 16
0
        public void TradeDateEvent(PostingEngineEnvironment env, Transaction element)
        {
            var accrual     = env.FindAccruals(element.AccrualId);
            var allocations = env.FindAllocations(element.AccrualId);
            var allocation  = allocations.Where(i => !i.Symbol.Equals(element.Symbol)).FirstOrDefault();

            //Console.WriteLine(element.Symbol);

            if (element.Symbol.Equals("ZZ_INVESTOR_CONTRIBUTIONS"))
            {
            }

            if (element.Status.Equals("Cancelled"))
            {
                env.AddMessage($"Entry has been cancelled {element.LpOrderId} :: {element.Side}");
                return;
            }

            // Need to consider both
            if (element.TradeDate.Date != element.SettleDate.Date)
            {
                env.AddMessage($"Journal needs to be checked {element.LpOrderId}, {element.TradeDate}, {element.SettleDate}");
                return;
            }

            var accountToFrom = GetFromToAccount(element);

            if (accountToFrom.To == null)
            {
                env.AddMessage($"Unable to identify From/To accounts for trade {element.OrderSource} :: {element.Side}");
                return;
            }

            new AccountUtils().SaveAccountDetails(env, accountToFrom.From);
            new AccountUtils().SaveAccountDetails(env, accountToFrom.To);

            double fxrate = 1.0;

            if (!element.SettleCurrency.Equals(env.BaseCurrency))
            {
                fxrate = Convert.ToDouble(FxRates.Find(env.ValueDate, element.SettleCurrency).Rate);
            }

            var moneyUSD = element.LocalNetNotional * fxrate;

            if (element.LocalNetNotional != 0.0)
            {
                var symbol     = allocation != null ? allocation.Symbol : element.ParentSymbol;
                var securityId = allocation != null ? allocation.SecurityId : element.SecurityId;

                if (symbol == null)
                {
                    symbol = element.Symbol;
                }

                var debit = new Journal(element)
                {
                    Symbol     = symbol,
                    SecurityId = securityId,

                    Account     = accountToFrom.From,
                    When        = env.ValueDate,
                    FxRate      = fxrate,
                    CreditDebit = env.DebitOrCredit(accountToFrom.From, moneyUSD),
                    Value       = moneyUSD,
                    Event       = Event.JOURNAL,
                    Fund        = env.GetFund(element),
                };

                var credit = new Journal(element)
                {
                    Symbol     = symbol,
                    SecurityId = securityId,

                    Account     = accountToFrom.To,
                    When        = env.ValueDate,
                    FxRate      = fxrate,
                    CreditDebit = env.DebitOrCredit(accountToFrom.To, moneyUSD),
                    Value       = moneyUSD,
                    Event       = Event.JOURNAL,
                    Fund        = env.GetFund(element),
                };

                env.Journals.Add(debit);
                env.Journals.Add(credit);
            }

            return;
        }
        private void GenerateDailyUnrealized(PostingEngineEnvironment env, TaxLotStatus taxLotStatus, Transaction element, double quantity, double fxRate)
        {
            var prevEodPrice = 0.0;
            var eodPrice     = 0.0;

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

            var endPrice = element.SettleNetPrice;

            if (taxLotStatus.Quantity == 0.0)
            {
                eodPrice = endPrice;
            }

            var unrealizedPnl = CommonRules.CalculateUnrealizedPnl(env, taxLotStatus, quantity, eodPrice);

            var originalAccount = taxLotStatus.Side == "SHORT" ? "Mark to Market Shorts" : "Mark to Market Longs";
            var fromToAccounts  = new AccountUtils().GetAccounts(env, originalAccount, "CHANGE IN UNREALIZED GAIN/(LOSS)", listOfTags, taxLotStatus.Trade);

            if (taxLotStatus.Side == "SHORT")
            {
                unrealizedPnl *= -1;
            }

            var fund = env.GetFund(taxLotStatus.Trade);

            var debit = new Journal(taxLotStatus.Trade)
            {
                Account     = fromToAccounts.From,
                When        = env.ValueDate,
                Symbol      = taxLotStatus.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(debit)
            {
                Account     = fromToAccounts.To,
                Value       = env.SignedValue(fromToAccounts.From, fromToAccounts.To, false, unrealizedPnl),
                CreditDebit = env.DebitOrCredit(fromToAccounts.To, unrealizedPnl),
            };

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

            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",
                        quantity, null, element);
                    env.Journals.AddRange(fxJournals);
                }

                if (taxLotStatus.Quantity != 0.0)
                {
                    if (env.ValueDate.Equals(new DateTime(2019, 12, 17)))
                    {
                    }

                    if (element.TradeDate != env.ValueDate)
                    {
                        // Has to happen for every day
                        var fxJournalsForInvestmentAtCost = FxPosting.CreateFx(
                            env,
                            CommonRules.GetFXMarkToMarketAccountType(element, "FX MARKET TO MARKET ON STOCK COST"),
                            "Change in unrealized due to fx on original Cost",
                            "daily", quantity, taxLotStatus, element);
                        env.Journals.AddRange(fxJournalsForInvestmentAtCost);

                        new FxPosting().CreateFxUnsettled(env, element);
                    }
                }
            }
        }
Esempio n. 18
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. 19
0
        internal static void GenerateTradeDateJournals(PostingEngineEnvironment env, Transaction element)
        {
            double multiplier = 1.0;

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

            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);
            }

            var tradeAllocations = env.Allocations.Where(i => i.LpOrderId == element.LpOrderId).ToList();

            // Retrieve Allocation Objects for this trade
            if (tradeAllocations.Count() > 2)
            {
                env.AddMessage($"#of allocations > 2 please investigate {element.LpOrderId}");
                return;
            }

            if (tradeAllocations.Count() == 2)
            {
                var debitEntry = tradeAllocations[0].Side == element.Side ? tradeAllocations[0] : tradeAllocations[1];
                if (debitEntry.Symbol.Equals("@CASHUSD"))
                {
                    env.AddMessage($"Unexpected Cash allocation please investigate {element.LpOrderId}");
                    return;
                }
            }

            var accountToFrom = GetFromToAccount(env, element);

            if (accountToFrom.To == null || accountToFrom.From == null)
            {
                env.AddMessage($"Unable to identify From/To accounts for trade {element.OrderSource} :: {element.Side}");
                return;
            }

            if (element.NetMoney != 0.0)
            {
                var moneyUSD = Math.Abs(element.NetMoney) * fxrate;

                // BUY -- Debit
                // SELL -- Credit

                if (element.IsSell() || element.IsCover())
                {
                    moneyUSD = moneyUSD * -1;
                }

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

                var fromJournal = new Journal(element, accountToFrom.From, Event.TRADE_DATE, env.ValueDate)
                {
                    CreditDebit = env.DebitOrCredit(accountToFrom.From, moneyUSD),
                    Value       = env.SignedValue(accountToFrom.From, accountToFrom.To, true, moneyUSD),
                    FxRate      = fxrate,
                    StartPrice  = element.SettleNetPrice,
                    EndPrice    = eodPrice,
                    Fund        = env.GetFund(element),
                };

                var toJournal = new Journal(element, accountToFrom.To, Event.TRADE_DATE, env.ValueDate)
                {
                    FxRate      = fxrate,
                    CreditDebit = env.DebitOrCredit(accountToFrom.To, moneyUSD * -1),
                    Value       = env.SignedValue(accountToFrom.From, accountToFrom.To, false, moneyUSD),
                    StartPrice  = element.SettleNetPrice,
                    EndPrice    = eodPrice,
                    Fund        = env.GetFund(element),
                };

                env.Journals.AddRange(new[] { fromJournal, toJournal });
            }
        }
Esempio n. 20
0
        internal static void GenerateCloseOutPostings(PostingEngineEnvironment env, TaxLotDetail lot, TaxLot taxlot, Transaction element, TaxLotStatus taxlotStatus, string fund)
        {
            double multiplier = 1.0;

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

            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);
            }

            var prevPrice     = MarketPrices.GetPrice(env, env.PreviousValueDate, lot.Trade).Price;
            var unrealizedPnl = Math.Abs(taxlotStatus.Quantity) * (element.SettleNetPrice - prevPrice) * multiplier;

            unrealizedPnl = Math.Abs(unrealizedPnl) * CommonRules.DetermineSign(taxlotStatus.Trade);

            var buyTrade = env.FindTrade(lot.Trade.LpOrderId);

            ReverseUnrealizedPnl(
                env,
                buyTrade,
                element,
                unrealizedPnl,
                MarketPrices.GetPrice(env, env.PreviousValueDate, lot.Trade).Price,
                element.SettleNetPrice, fxrate);

            var PnL = taxlot.RealizedPnl;

            PostRealizedPnl(
                env,
                buyTrade,
                PnL,
                taxlot.TradePrice,
                taxlot.CostBasis, fxrate);

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

            Account fromAccount = null;
            Account toAccount   = null;

            if (element.IsDerivative())
            {
                return;
            }
            else
            {
                var accountType         = (buyTrade.IsShort() || buyTrade.IsCover()) ? "SHORT POSITIONS AT COST" : "LONG POSITIONS AT COST";
                var markToMarketAccount = (buyTrade.IsShort() || buyTrade.IsCover()) ? "Mark to Market Shorts" : "Mark to Market Longs";

                fromAccount = new AccountUtils().CreateAccount(AccountType.Find(accountType), listOfFromTags, element);
                toAccount   = new AccountUtils().CreateAccount(AccountType.Find(markToMarketAccount), listOfFromTags, element);
            }

            new AccountUtils().SaveAccountDetails(env, fromAccount);
            new AccountUtils().SaveAccountDetails(env, toAccount);

            // Now Generate Entries
            var fromJournal = new Journal(element)
            {
                Account     = fromAccount,
                CreditDebit = env.DebitOrCredit(fromAccount, PnL),
                When        = env.ValueDate,
                StartPrice  = taxlot.TradePrice,
                EndPrice    = taxlot.CostBasis,
                Value       = PnL,
                FxRate      = 1,
                Event       = Event.REALIZED_PNL,
                Fund        = env.GetFund(element),
            };

            var toJournal = new Journal(fromJournal)
            {
                Account     = toAccount,
                CreditDebit = env.DebitOrCredit(toAccount, PnL * -1),
                Value       = PnL * -1,
            };

            env.Journals.AddRange(new[] { fromJournal, toJournal });
        }
Esempio n. 21
0
        internal static void GenerateSettlementDateJournals(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);
            }

            var accountToFrom = new AccountingRules().GetFromToAccountOnSettlement(env, element);

            if (accountToFrom.To == null || accountToFrom.From == null)
            {
                env.AddMessage($"Unable to identify From/To accounts for trade {element.OrderSource} :: {element.Side}");
                return;
            }

            // This is the fully loaded value to tbe posting

            if (element.NetMoney != 0.0)
            {
                var moneyUSD = Math.Abs(element.NetMoney) * fxrate;

                // BUY -- Debit
                // SELL -- Credit

                if (element.IsShort() || element.IsSell())
                {
                    moneyUSD = moneyUSD * -1;
                }

                var debit = new Journal
                {
                    Source      = element.LpOrderId,
                    Account     = accountToFrom.From,
                    When        = env.ValueDate,
                    FxCurrency  = element.SettleCurrency,
                    Symbol      = element.Symbol,
                    SecurityId  = element.SecurityId,
                    Quantity    = element.Quantity,
                    FxRate      = fxrate,
                    CreditDebit = env.DebitOrCredit(accountToFrom.From, moneyUSD),
                    Value       = env.SignedValue(accountToFrom.From, accountToFrom.To, true, moneyUSD),
                    Event       = Event.SETTLEMENT,
                    Fund        = env.GetFund(element)
                };

                var credit = new Journal
                {
                    Source     = element.LpOrderId,
                    FxCurrency = element.SettleCurrency,
                    Symbol     = element.Symbol,
                    SecurityId = element.SecurityId,
                    Quantity   = element.Quantity,

                    FxRate  = fxrate,
                    When    = env.ValueDate,
                    Account = accountToFrom.To,

                    CreditDebit = env.DebitOrCredit(accountToFrom.To, moneyUSD * -1),
                    Value       = env.SignedValue(accountToFrom.From, accountToFrom.To, false, moneyUSD),
                    Event       = Event.SETTLEMENT,
                    Fund        = env.GetFund(element)
                };

                env.Journals.AddRange(new[] { debit, credit });
            }
        }
Esempio n. 22
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
                }
            }
        }
Esempio n. 23
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. 24
0
        /// <summary>
        /// Create the entries for Unsettled Fx gain / loss
        /// </summary>
        /// <param name="env">Environment</param>
        /// <param name="taxlotStatus"></param>
        /// <param name="tradeEvent"></param>
        /// <param name="element">Transaction</param>
        /// <returns>a list of the created journal entries</returns>
        internal static List <Journal> CreateFx(PostingEngineEnvironment env,
                                                string fromAccount,
                                                string toAccount,
                                                string tradeEvent,
                                                double quantity,
                                                TaxLotStatus taxlotStatus,
                                                Transaction element)
        {
            if (tradeEvent.Equals(Event.TRADE_DATE))
            {
                return(new List <Journal>());
            }

            // TBD: THIS IS FOR BOBBY
            if (element.SecurityType.Equals("FORWARD"))
            {
                return(new List <Journal>());
            }

            // Check to see if the BaseCurrency == SettleCurrency because if it is then no need to do the FX translation
            if (env.BaseCurrency.Equals(element.SettleCurrency))
            {
                return(new List <Journal>());
            }

            var currency = element.SettleCurrency;

            var prevEodFxRate = Convert.ToDouble(FxRates.Find(env.PreviousValueDate, currency).Rate);
            var eodFxRate     = Convert.ToDouble(FxRates.Find(env.ValueDate, currency).Rate);
            var effectiveRate = eodFxRate - prevEodFxRate;

            var usdEquivalent = element.NetMoney * effectiveRate;

            if (element.IsBuy())
            {
                usdEquivalent *= -1;
            }
            else if (element.IsShort())
            {
            }

            // Get accounts
            var toFrom = new AccountUtils().GetAccounts(env, fromAccount, toAccount, _TAGS, element);

            var debit = new Journal(element, toFrom.From, $"{tradeEvent}-unrealizedpnl-fx", env.ValueDate)
            {
                Quantity   = quantity,
                FxRate     = effectiveRate,
                StartPrice = prevEodFxRate,
                EndPrice   = eodFxRate,
                Fund       = env.GetFund(element),

                Value       = env.SignedValue(toFrom.From, toFrom.To, true, usdEquivalent),
                CreditDebit = env.DebitOrCredit(toFrom.From, usdEquivalent),
            };

            var credit = new Journal(element, toFrom.To, $"{tradeEvent}-unrealizedpnl-fx", env.ValueDate)
            {
                Quantity   = quantity,
                FxRate     = effectiveRate,
                StartPrice = prevEodFxRate,
                EndPrice   = eodFxRate,
                Fund       = env.GetFund(element),

                Value       = env.SignedValue(toFrom.From, toFrom.To, false, usdEquivalent),
                CreditDebit = env.DebitOrCredit(toFrom.To, usdEquivalent),
            };


            return(new List <Journal>(new[] { debit, credit }));
        }
Esempio n. 25
0
        public bool Run(PostingEngineEnvironment env)
        {
            var dates = "select minDate = min([when]), maxDate = max([when]) from vwJournal";

            env.CallBack?.Invoke("ExpencesAndRevenues Calculation Started");

            var table = new DataTable();

            // read the table structure from the database
            using (var adapter = new SqlDataAdapter(dates, new SqlConnection(env.ConnectionString)))
            {
                adapter.Fill(table);
                adapter.Dispose();
            };

            var valueDate = Convert.ToDateTime(table.Rows[0]["minDate"]);
            var endDate   = Convert.ToDateTime(table.Rows[0]["maxDate"]);

            using (var cc = new SqlConnection(env.ConnectionString))
            {
                cc.Open();

                SetupEnvironment.Setup(cc);

                cc.Close();
            }

            var journals = new List <Journal>();

            var connection = new SqlConnection(env.ConnectionString);

            connection.Open();
            var transaction = connection.BeginTransaction();

            var sqlHelper = new SqlHelper(env.ConnectionString);

            var rowsCompleted = 1;
            var numberOfDays  = (endDate - valueDate).Days;

            while (valueDate <= endDate)
            {
                if (!valueDate.IsBusinessDate())
                {
                    valueDate = valueDate.AddDays(1);
                    rowsCompleted++;
                    continue;
                }

                try
                {
                    var sqlParams = new SqlParameter[]
                    {
                        new SqlParameter("@startDate", new DateTime(valueDate.Year, 1, 1)),
                        new SqlParameter("@businessDate", valueDate),
                        new SqlParameter("@prevbusinessDate", valueDate.PrevBusinessDate()),
                    };

                    var dataTable = sqlHelper.GetDataTables("DayOverDayIncome", CommandType.StoredProcedure, sqlParams.ToArray());

                    foreach (DataRow row in dataTable[0].Rows)
                    {
                        int offset = 0;
                        var expencesAndRevenues = new
                        {
                            Fund    = Convert.ToString(row[offset++]),
                            Credit  = Convert.ToDecimal(row[offset++]),
                            Debit   = Convert.ToDecimal(row[offset++]),
                            Balance = Convert.ToDecimal(row[offset++]),
                        };

                        var accountType = $"Net Income Current Year";

                        if (AccountType.Find(AccountCategory.AC_EQUITY, accountType, false) == null)
                        {
                            // Need to create the Account Type
                            var createdAccountType = AccountType.FindOrCreate(AccountCategory.AC_EQUITY, accountType);
                            new AccountUtils().Save(env, createdAccountType);
                        }

                        var balance = Convert.ToDouble(expencesAndRevenues.Balance);

                        var account = new AccountUtils().GetAccount(env, accountType, new string[] { env.BaseCurrency }.ToList());

                        var debit = new Journal(account, "expences-revenues", valueDate)
                        {
                            Source   = "calculated-data",
                            Fund     = expencesAndRevenues.Fund,
                            Quantity = balance,

                            FxCurrency = env.BaseCurrency,
                            Symbol     = env.BaseCurrency,
                            SecurityId = -1,
                            FxRate     = 0,
                            StartPrice = 0,
                            EndPrice   = 0,

                            // If this number is +ve then its actually a Debit and this is going into a Equity account which needs to be -ve and not +ve
                            Value       = balance * -1,
                            CreditDebit = env.DebitOrCredit(account, balance * -1),
                        };

                        journals.AddRange(new List <Journal>(new[] { debit }));
                    }
                }
                catch (Exception ex)
                {
                    env.CallBack?.Invoke($"Exception on {valueDate.ToString("MM-dd-yyyy")}, {ex.Message}");
                }

                env.CallBack?.Invoke($"Completed ExpencesAndRevenues for {valueDate.ToString("MM-dd-yyyy")}", numberOfDays, rowsCompleted++);
                valueDate = valueDate.AddDays(1);
            }

            if (journals.Count() > 0)
            {
                env.CollectData(journals);
                journals.Clear();
            }

            transaction.Commit();
            connection.Close();

            return(true);
        }
Esempio n. 26
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. 27
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);
                    }
                }
            }
        }