/// <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}"); }
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); } var tradeAllocations = env.Allocations.Where(i => i.LpOrderId == element.LpOrderId).ToList(); 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; } //tl.Save(env.Connection, env.Transaction); } 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, tradeAllocations[0].Fund); break; } else { var taxlot = CommonRules.RelieveTaxLot(env, lot, element, taxlotStatus.Quantity * -1); workingQuantity -= Math.Abs(taxlotStatus.Quantity); CommonRules.PostRealizedPnl(env, element, taxlot.RealizedPnl, taxlot.TradePrice, taxlot.CostBasis); taxlotStatus.Quantity = 0; taxlotStatus.Status = "Closed"; } } } } } else { // We have a Debit / Credit Dividends } }
internal void TradeDateEvent(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); } if (element.IsCredit() || element.IsDebit()) { if (element.TransactionCategory == "Cash Dividends") { // We have a Cash Dividend, so how do we treat this return; } } if (element.IsBuy() || element.IsShort()) { 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; } var tl = env.GenerateOpenTaxLot(element, fxrate); } else if (element.IsSell() || element.IsCover()) { // Get Matching Lots var taxLotMethodology = ConfigurationManager.AppSettings["TaxMethod"].ToString(); var workingQuantity = element.Quantity; if (taxLotMethodology.Equals("MINTAX")) { while (workingQuantity != 0.0) { var localOpenTaxLots = env.Methodology.GetOpenLots(env, element, workingQuantity); var lot = localOpenTaxLots[0]; if (!env.TaxLotStatus.ContainsKey(lot.Trade.LpOrderId)) { // TODO: For this open lot there should be a corresponding open to env.AddMessage($"Unable to Find Tax Lot for {lot.Trade.Symbol}::{lot.Trade.Side}::{lot.Trade.Status}"); //Logger.Warn($"Unable to Find Tax Lot for {element.Symbol}::{element.Side}::{element.Status}"); continue; } var taxlotStatus = env.TaxLotStatus[lot.Trade.LpOrderId]; if (taxlotStatus != null && taxlotStatus.Quantity != 0 && !taxlotStatus.Status.ToLowerInvariant().Equals("closed")) { Logger.Info($"Relieving Tax Lot {taxlotStatus.Symbol}::{taxlotStatus.TradePrice}::{taxlotStatus.TradeDate.ToString("MM-dd-yyyy")}::{taxlotStatus.OpenId}::{lot.TaxLiability}::{lot.TaxRate.Rate}::{lot.PotentialPnl}"); // Does the open Lot fully fullfill the quantity ? if (Math.Abs(taxlotStatus.Quantity) >= Math.Abs(workingQuantity)) { // Lets generate all the journal entries we need GenerateJournals(env, lot, taxlotStatus, element, workingQuantity, fxrate, multiplier); break; } else { var quantity = taxlotStatus.Quantity; GenerateJournals(env, lot, taxlotStatus, element, taxlotStatus.Quantity * -1, fxrate, multiplier); workingQuantity += quantity; } } } } else { var openLots = env.Methodology.GetOpenLots(env, element, workingQuantity); 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 env.AddMessage($"Unable to Find Tax Lot for {lot.Trade.Symbol}::{lot.Trade.Side}::{lot.Trade.Status}"); //Logger.Warn($"Unable to Find Tax Lot for {element.Symbol}::{element.Side}::{element.Status}"); continue; } var taxlotStatus = env.TaxLotStatus[lot.Trade.LpOrderId]; if (taxlotStatus != null && taxlotStatus.Quantity != 0 && !taxlotStatus.Status.ToLowerInvariant().Equals("closed")) { Logger.Info($"Relieving Tax Lot {taxlotStatus.TradeDate.ToString("MM-dd-yyyy")}::{taxlotStatus.Symbol}::{taxlotStatus.OpenId}::{lot.TaxLiability}::{lot.TaxRate.Rate}::{lot.PotentialPnl}"); // Does the open Lot fully fullfill the quantity ? if (Math.Abs(taxlotStatus.Quantity) >= Math.Abs(workingQuantity)) { // Lets generate all the journal entries we need GenerateJournals(env, lot, taxlotStatus, element, workingQuantity, fxrate, multiplier); break; } else { var quantity = taxlotStatus.Quantity; GenerateJournals(env, lot, taxlotStatus, element, taxlotStatus.Quantity * -1, fxrate, multiplier); workingQuantity += quantity; } } } } } else { // We have a Debit / Credit Dividends } CommonRules.GenerateTradeDateJournals(env, element); }
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 } }