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); }
public static void Save(this Journal[] entries, PostingEngineEnvironment env) { foreach (var i in entries) { i.Save(env.Connection, env.Transaction); } }
/// <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); }
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 }); }
public new void TradeDateEvent(PostingEngineEnvironment env, Transaction element) { if (element.Symbol.StartsWith("COST")) { } base.TradeDateEvent(env, element); }
/// <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); }
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 }); }
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); }
public static MarketPrice GetPrice(PostingEngineEnvironment env, DateTime valueDate, Transaction element) { var eodMarketPrice = Find(valueDate, element); if (!eodMarketPrice.Valid) { env.AddMessage(eodMarketPrice.Error); } return(eodMarketPrice); }
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; }
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); }
/// <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}"); }
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 }); }
/// <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); }
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 })); }
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); }
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); }
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 })); }
/// <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); }
/// <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 })); }
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 }); }