public bool Run(PostingEngineEnvironment env)
        {
            env.CallBack?.Invoke("Pull From BookMon Calculation Started");

            using (var connection = new SqlConnection(env.ConnectionString))
            {
                connection.Open();
                var sql     = @"
                        declare @minDate as Date
                        declare @maxDate as Date

                        select @minDate = min(busDate), @maxDate = max(busDate) from PositionMaster..IntraDayPositionSplit

                        exec FundAccounting..PullDailyActivity @minDate, @maxDate
                        exec FundAccounting..PullDailyMarketPrices @minDate, @maxDate
                        exec FundAccounting..PullDailyFxPrices @minDate, @maxDate
                        ";
                var command = new SqlCommand(sql, connection);
                command.CommandTimeout = 60; // 1 Mins, shoudl not take this long.

                command.ExecuteNonQuery();
                connection.Close();
            }

            return(true);
        }
示例#2
0
 public static void Save(this Journal[] entries, PostingEngineEnvironment env)
 {
     foreach (var i in entries)
     {
         i.Save(env.Connection, env.Transaction);
     }
 }
示例#3
0
        /// <summary>
        /// Relieves the passed Taxlot
        /// </summary>
        /// <param name="env">Environment</param>
        /// <param name="lot">The Tax Lot to relieve</param>
        /// <param name="trade">The current trade</param>
        /// <param name="quantity">Quantity to relieve</param>
        /// <param name="fxrate">Appropriate fxrate</param>
        internal static TaxLot RelieveTaxLot(PostingEngineEnvironment env, TaxLotDetail lot, Transaction trade, double quantity, bool reverse = false)
        {
            var prevFxRate = FxRates.Find(lot.Trade.TradeDate, lot.Trade.SettleCurrency).Rate;

            var investmentAtCost = quantity * lot.Trade.SettleNetPrice * prevFxRate;

            if (reverse)
            {
                investmentAtCost = investmentAtCost * -1;
            }

            var tl = new TaxLot
            {
                Trade            = trade,
                TradeDate        = trade.TradeDate,
                InvestmentAtCost = investmentAtCost, // Needs to be the Investment Cost that we are relieving from the Tax
                BusinessDate     = env.ValueDate,
                OpeningLotId     = lot.Trade.LpOrderId,
                ClosingLotId     = trade.LpOrderId,
                TradePrice       = lot.Trade.SettleNetPrice,
                CostBasis        = trade.SettleNetPrice,
                Quantity         = quantity
            };

            CalculateRealizedPnl(env, tl);

            tl.Save(env.Connection, env.Transaction);

            return(tl);
        }
示例#4
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 });
        }
示例#5
0
 public new void TradeDateEvent(PostingEngineEnvironment env, Transaction element)
 {
     if (element.Symbol.StartsWith("COST"))
     {
     }
     base.TradeDateEvent(env, element);
 }
示例#6
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 });
        }
        /// <summary>
        /// Calculate the Unrealized Pnl for the passed TaxLotStatus
        /// </summary>
        /// <param name="env"></param>
        /// <param name="i"></param>
        /// <param name="trade"></param>
        /// <returns></returns>
        private double CalculateUnrealizedPnl(PostingEngineEnvironment env, TaxLotDetail i, Transaction trade, double workingQuantity)
        {
            var fxrate = FxRates.Find(env.ValueDate, i.Trade.SettleCurrency).Rate;

            double multiplier = 1.0;

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


            if (env.TaxLotStatus.ContainsKey(i.Trade.LpOrderId))
            {
                var lot = i.TaxLotStatus;

                var quantity = lot.Quantity;

                var unrealizedPnl = (trade.SettleNetPrice - i.Trade.SettleNetPrice) * quantity * fxrate * multiplier;

                return(unrealizedPnl);
            }

            return(0);
        }
示例#8
0
        public List <TaxLotDetail> GetOpenLots(PostingEngineEnvironment env, Transaction element, double workingQuantity)
        {
            Logger.Info($"Getting Open Tax Lots for {element.Symbol}::{element.Side}::{workingQuantity}::{element.TradeDate.ToString("MM-dd-yyyy")}");

            var minTaxLots = new List <TaxLotDetail>();

            var openlots = BaseTaxLotMethodology.OpenTaxLots(env, element, workingQuantity).ToList();

            var results = openlots.Select(i => new {
                trade        = i.Trade,
                taxRate      = i.TaxRate,
                taxLotStatus = i.TaxLotStatus,
                potentialPnl = CalculateUnrealizedPnl(env, i, element, workingQuantity),
                taxAmount    = CalculateTaxImplication(env, i, element, workingQuantity)
            }).ToList();

            minTaxLots = results.Where(i => i.taxLotStatus.Quantity != 0).OrderBy(i => Math.Abs(i.taxAmount)).Select(i => new TaxLotDetail {
                TaxRate      = i.taxRate,
                Trade        = i.trade,
                TaxLotStatus = i.taxLotStatus,
                PotentialPnl = i.potentialPnl,
                TaxLiability = i.taxAmount
            }).ToList();

            BaseTaxLotMethodology.Log(Logger, minTaxLots);

            return(minTaxLots);
        }
        /// <summary>
        /// Dealing with the settlement event
        /// </summary>
        /// <param name="element"></param>
        /// <param name="debit"></param>
        /// <param name="credit"></param>
        /// <returns></returns>
        internal AccountToFrom GetFromToAccountOnSettlement(PostingEngineEnvironment env, Transaction element)
        {
            var accountTypes = AccountType.All;

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

            if (_settledCash == null)
            {
                _settledCash         = accountTypes.Where(i => i.Name.Equals("Settled Cash")).FirstOrDefault();
                _pbUnsettledActivity = accountTypes.Where(i => i.Name.Equals("DUE FROM/(TO) PRIME BROKERS ( Unsettled Activity )")).FirstOrDefault();
            }

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

            switch (element.Side.ToLowerInvariant())
            {
            case "buy":
                fromAccount = new AccountUtils()
                              .CreateAccount(_pbUnsettledActivity, listOfTags, element);
                toAccount = new AccountUtils()
                            .CreateAccount(_settledCash, listOfTags, element);
                break;

            case "sell":
                fromAccount = new AccountUtils()
                              .CreateAccount(_pbUnsettledActivity, listOfTags, element);
                toAccount = new AccountUtils()
                            .CreateAccount(_settledCash, listOfTags, element);
                break;

            case "short":
                fromAccount = new AccountUtils()
                              .CreateAccount(_pbUnsettledActivity, listOfTags, element);
                toAccount = new AccountUtils()
                            .CreateAccount(_settledCash, listOfTags, element);
                break;

            case "cover":
                fromAccount = new AccountUtils()
                              .CreateAccount(_pbUnsettledActivity, listOfTags, element);
                toAccount = new AccountUtils()
                            .CreateAccount(_settledCash, listOfTags, element);
                break;
            }

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

            return(new AccountToFrom
            {
                From = fromAccount,
                To = toAccount
            });
        }
示例#10
0
        public Account GetAccount(PostingEngineEnvironment env, string accountType, List <string> tags)
        {
            var account = CreateAccount(AccountType.Find(accountType), tags);

            SaveAccountDetails(env, account);

            return(account);
        }
        private double CalculateTaxImplication(PostingEngineEnvironment env, TaxLotDetail i, Transaction trade, double workingQuantity)
        {
            var unrealizedPnl = CalculateUnrealizedPnl(env, i, trade, workingQuantity);

            var taxrate = Convert.ToDouble(i.TaxRate.Rate);

            var taxImplication = unrealizedPnl * taxrate;

            return(taxImplication);
        }
示例#12
0
        public static MarketPrice GetPrice(PostingEngineEnvironment env, DateTime valueDate, Transaction element)
        {
            var eodMarketPrice = Find(valueDate, element);

            if (!eodMarketPrice.Valid)
            {
                env.AddMessage(eodMarketPrice.Error);
            }

            return(eodMarketPrice);
        }
示例#13
0
        public void SettlementDateEvent(PostingEngineEnvironment env, Transaction element)
        {
            // Entry has already been processed
            if (element.TradeDate.Date.Equals(element.SettleDate.Date) && element.SecurityType.ToLowerInvariant().Equals("cash"))
            {
                CommonRules.GenerateSettlementDateJournals(env, element);
                return;
            }

            return;
        }
示例#14
0
        public AccountToFrom GetAccounts(PostingEngineEnvironment env, string fromType, string toType, List <string> tags)
        {
            var fromAccount = CreateAccount(AccountType.Find(fromType), tags);
            var toAccount   = CreateAccount(AccountType.Find(toType), tags);

            SaveAccountDetails(env, fromAccount);
            SaveAccountDetails(env, toAccount);

            return(new AccountToFrom {
                From = fromAccount, To = toAccount
            });
        }
        public bool Run(PostingEngineEnvironment env)
        {
            env.CallBack?.Invoke($"{Module} Calculation Started");

            var dates = "select minDate = min([when]), maxDate = max([when]) from vwJournal";
            var table = new DataTable();

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

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

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

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

                    try
                    {
                        var transaction = connection.BeginTransaction();
                        CostBasisDto.Calculate(connection, transaction, valueDate);
                        transaction.Commit();
                    }
                    catch (Exception ex)
                    {
                        env.CallBack?.Invoke($"{Module} Exception on {valueDate.ToString("MM-dd-yyyy")}, {ex.Message}");
                    }

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

                connection.Close();
            }

            env.CallBack?.Invoke($"{Module} Calculation Finished");

            return(true);
        }
示例#16
0
        /// <summary>
        /// TradeCurrency == Base
        /// SettleCurrency == Risk
        /// </summary>
        /// <param name="env"></param>
        /// <param name="element"></param>
        public void TradeDateEvent(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 t1 = env.GenerateOpenTaxLot(element, fxrate);

            Logger.Info($"Generated Open TaxLot {t1.Symbol}::{t1.Side}::{element.SecurityType}");
        }
示例#17
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 });
        }
示例#18
0
        /// <summary>
        /// Calcualte the Unrealized Pnl for this Tax lot
        /// </summary>
        /// <param name="env"></param>
        /// <returns></returns>
        public static double CalculateUnrealizedPnl(PostingEngineEnvironment env, TaxLotStatus taxLotStatus, double residualQuantity = 0, double endPrice = 0)
        {
            double multiplier = 1.0;

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

            double fxrate = 1.0;

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

            var eodPrice     = 0.0;
            var prevEodPrice = 0.0;

            if (env.ValueDate == taxLotStatus.Trade.TradeDate)
            {
                prevEodPrice = taxLotStatus.Trade.SettleNetPrice;
                var eodMarketPrice = MarketPrices.GetPrice(env, env.ValueDate, taxLotStatus.Trade);

                if (!eodMarketPrice.Valid)
                {
                    env.AddMessage(eodMarketPrice.Error);
                }

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

            eodPrice = endPrice != 0 ? endPrice : eodPrice;

            // Use residual Quantity if specified
            var quantity = residualQuantity != 0.0 ? residualQuantity : taxLotStatus.Quantity;

            var priceDiff = (eodPrice - prevEodPrice);

            var unrealizedPnl = priceDiff * quantity;

            return(unrealizedPnl * fxrate * multiplier);
        }
示例#19
0
        public bool IsValid(PostingEngineEnvironment env, Transaction element)
        {
            if (element.AccrualId == null)
            {
                return(true);
            }

            var validAccrual = env.IsValidAccrual(element.AccrualId);

            if (!validAccrual)
            {
                env.AddMessage($"trade does not tie back to a valid accrual {element.AccrualId}");
            }
            return(validAccrual);
        }
        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 }));
        }
示例#21
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);
        }
示例#22
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 });
        }
        public bool Run(PostingEngineEnvironment env)
        {
            env.CallBack?.Invoke($"{Module} Started");

            env.CallBack?.Invoke("Getting Daily Pnl Data");

            var performanceRecords = DailyPnL.GetList(env.ConnectionString);

            env.CallBack?.Invoke($"{Module} Running the calculation");

            var dailyPerformanceResult = new DailyPnlCalculator().CalculateDailyPerformance(performanceRecords);
            var dailyPerformance       = dailyPerformanceResult.GetType().GetProperty("payload")
                                         ?.GetValue(dailyPerformanceResult, null);
            bool insertDailyPnl = UpdateDailyPnl((List <DailyPnL>)dailyPerformance, env.ConnectionString);

            env.CallBack?.Invoke($"{Module} Finished");

            return(true);
        }
示例#24
0
        public void TradeDateEvent(PostingEngineEnvironment env, Transaction element)
        {
            if (element.AccrualId == null)
            {
                // We have just cash here so what do we do ?
                CommonRules.GenerateTradeDateJournals(env, element);
                return;
            }

            var accrual = env.Accruals.ContainsKey(element.AccrualId) ? env.Accruals[element.AccrualId] : null;

            if (accrual != null)
            {
                AccrualPayment(env, element, accrual);
                return;
            }

            return;
        }
        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 }));
        }
示例#26
0
        /// <summary>
        /// Calculate the Realized Pnl based on the relieved Tax Lot
        /// </summary>
        /// <param name="createdTaxLot">The Relief</param>
        /// <param name="taxLotToRelieve">The target taxlot</param>
        public static double CalculateRealizedPnl(PostingEngineEnvironment env, TaxLot createdTaxLot)
        {
            var priceDiff   = (createdTaxLot.CostBasis - createdTaxLot.TradePrice);
            var realizedPnl = 0.0;

            double multiplier = 1.0;

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

            double fxrate = 1.0;

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

            if (createdTaxLot.Trade.IsBuy())
            {
                realizedPnl = priceDiff * createdTaxLot.Quantity;
            }
            else if (createdTaxLot.Trade.IsSell())
            {
                realizedPnl = priceDiff * Math.Abs(createdTaxLot.Quantity);
            }
            else if (createdTaxLot.Trade.IsShort())
            {
                realizedPnl = priceDiff * createdTaxLot.Quantity;
            }
            else if (createdTaxLot.Trade.IsCover())
            {
                realizedPnl = priceDiff * createdTaxLot.Quantity * -1;
            }

            createdTaxLot.RealizedPnl = realizedPnl * fxrate * multiplier;

            return(createdTaxLot.RealizedPnl);
        }
示例#27
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 });
        }
        internal 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 taxLotStatus = env.TaxLotStatus[element.LpOrderId];

                // Check to see if the TaxLot is still open and it has a non zero Quantity
                if (!taxLotStatus.Status.ToLowerInvariant().Equals("closed") && Math.Abs(taxLotStatus.Quantity) > 0)
                {
                    GenerateDailyUnrealized(env, taxLotStatus, element, taxLotStatus.Quantity, fxrate);
                }
            }
            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);
                    }
                }
            }
        }
        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 }));
        }
示例#30
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 });
        }