simfin-1.0.0: src/SimFin/Types/ProfitAndLoss.hs
{-|
Module : SimFin.Types.ProfitAndLoss
Description : Types to represent a company's profit and loss statement.
Copyright : (c) Owen Shepherd, 2022
License : MIT
Maintainer : owen@owen.cafe
-}
{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE FlexibleInstances #-}
module SimFin.Types.ProfitAndLoss
( GeneralProfitAndLossRow(..)
, BankProfitAndLossRow(..)
, InsuranceProfitAndLossRow(..)
, IndustryProfitsAndLosses
, IndustryProfitAndLoss
) where
import Control.Applicative ((<|>))
import Data.Aeson
import Data.Text (Text)
import Data.Time.Calendar (Day)
import SimFin.Types.Industry
import SimFin.Internal
------
-- General
------
-- | Cash flow statement for general companies.
data GeneralProfitAndLossRow
= GeneralProfitAndLossRow
{ simFinId :: Int
, ticker :: Text
, fiscalPeriod :: String
, fiscalYear :: Int
, reportDate :: Day
, publishDate :: Day
, restatedDate :: Day
, source :: Text
, tTM :: Bool
, valueCheck :: Bool
, revenue :: Maybe Integer
, salesAndServicesRevenue :: Maybe Integer
, financingRevenue :: Maybe Integer
, otherRevenue :: Maybe Integer
, costOfRevenue :: Maybe Integer
, costOfGoodsAndServices :: Maybe Integer
, costOfFinancingRevenue :: Maybe Integer
, costOfOtherRevenue :: Maybe Integer
, grossProfit :: Maybe Integer
, otherOperatingIncome :: Maybe Integer
, operatingExpenses :: Maybe Integer
, sellingGeneralAndAdministrative :: Maybe Integer
, sellingAndMarketing :: Maybe Integer
, generalAndAdministrative :: Maybe Integer
, researchAndDevelopment :: Maybe Integer
, depreciationAndAmortization :: Maybe Integer
, provisionForDoubtfulAccounts :: Maybe Integer
, otherOperatingExpenses :: Maybe Integer
, operatingIncomeLoss :: Maybe Integer
, nonOperatingIncomeLoss :: Maybe Integer
, interestExpenseNet :: Maybe Integer
, interestExpense :: Maybe Integer
, interestIncome :: Maybe Integer
, otherInvestmentIncomeLoss :: Maybe Integer
, foreignExchangeGainLoss :: Maybe Integer
, incomeLossFromAffiliates :: Maybe Integer
, otherNonOperatingIncomeLoss :: Maybe Integer
, pretaxIncomeLossAdj :: Maybe Integer
, abnormalGainsLosses :: Maybe Integer
, acquiredInProcessRAndD :: Maybe Integer
, mergerAndAcquisitionExpense :: Maybe Integer
, abnormalDerivatives :: Maybe Integer
, disposalOfAssets :: Maybe Integer
, earlyExtinguishmentOfDebt :: Maybe Integer
, assetWriteDown :: Maybe Integer
, impairmentOfGoodwillAndIntangibles :: Maybe Integer
, saleOfBusiness :: Maybe Integer
, legalSettlement :: Maybe Integer
, restructuringCharges :: Maybe Integer
, saleOfInvestmentsAndUnrealizedInvestments :: Maybe Integer
, insuranceSettlement :: Maybe Integer
, otherAbnormalItems :: Maybe Integer
, pretaxIncomeLoss :: Maybe Integer
, incomeTaxExpenseBenefitNet :: Maybe Integer
, currentIncomeTax :: Maybe Integer
, deferredIncomeTax :: Maybe Integer
, taxAllowanceCredit :: Maybe Integer
, incomeLossFromAffiliatesNetOfTaxes :: Maybe Integer
, incomeLossFromContinuingOperations :: Maybe Integer
, netExtraordinaryGainsLosses :: Maybe Integer
, discontinuedOperations :: Maybe Integer
, accountingChargesAndOther :: Maybe Integer
, incomeLossInclMinorityInterest :: Maybe Integer
, minorityInterest :: Maybe Integer
, netIncome :: Maybe Integer
, preferredDividends :: Maybe Integer
, otherAdjustments :: Maybe Integer
, netIncomeCommon :: Maybe Integer
} deriving Show
instance FromJSON GeneralProfitAndLossRow where
parseJSON = withObject "GeneralProfitAndLossRow" $ \v -> GeneralProfitAndLossRow
<$> v .: "SimFinId"
<*> v .: "Ticker"
<*> v .: "Fiscal Period"
<*> v .: "Fiscal Year"
<*> v .: "Report Date"
<*> v .: "Publish Date"
<*> v .: "Restated Date"
<*> v .: "Source"
<*> v .: "TTM"
<*> v .: "Value Check"
<*> v .: "Revenue"
<*> v .: "Sales & Services Revenue"
<*> v .: "Financing Revenue"
<*> v .: "Other Revenue"
<*> v .: "Cost of Revenue"
<*> v .: "Cost of Goods & Services"
<*> v .: "Cost of Financing Revenue"
<*> v .: "Cost of Other Revenue"
<*> v .: "Gross Profit"
<*> v .: "Other Operating Income"
<*> v .: "Operating Expenses"
<*> v .: "Selling, General & Administrative"
<*> v .: "Selling & Marketing"
<*> v .: "General & Administrative"
<*> v .: "Research & Development"
<*> v .: "Depreciation & Amortization"
<*> v .: "Provision for Doubtful Accounts"
<*> v .: "Other Operating Expenses"
<*> v .: "Operating Income (Loss)"
<*> v .: "Non-Operating Income (Loss)"
<*> v .: "Interest Expense, Net"
<*> v .: "Interest Expense"
<*> v .: "Interest Income"
<*> v .: "Other Investment Income (Loss)"
<*> v .: "Foreign Exchange Gain (Loss)"
<*> v .: "Income (Loss) from Affiliates"
<*> v .: "Other Non-Operating Income (Loss)"
<*> v .: "Pretax Income (Loss), Adj."
<*> v .: "Abnormal Gains (Losses)"
<*> v .: "Acquired In-Process R&D"
<*> v .: "Merger & Acquisition Expense"
<*> v .: "Abnormal Derivatives"
<*> v .: "Disposal of Assets"
<*> v .: "Early Extinguishment of Debt"
<*> v .: "Asset Write-Down"
<*> v .: "Impairment of Goodwill & Intangibles"
<*> v .: "Sale of Business"
<*> v .: "Legal Settlement"
<*> v .: "Restructuring Charges"
<*> v .: "Sale of Investments & Unrealized Investments"
<*> v .: "Insurance Settlement"
<*> v .: "Other Abnormal Items"
<*> v .: "Pretax Income (Loss)"
<*> v .: "Income Tax (Expense) Benefit, Net"
<*> v .: "Current Income Tax"
<*> v .: "Deferred Income Tax"
<*> v .: "Tax Allowance/Credit"
<*> v .: "Income (Loss) from Affiliates, Net of Taxes"
<*> v .: "Income (Loss) from Continuing Operations"
<*> v .: "Net Extraordinary Gains (Losses)"
<*> v .: "Discontinued Operations"
<*> v .: "Accounting Charges & Other"
<*> v .: "Income (Loss) Incl. Minority Interest"
<*> v .: "Minority Interest"
<*> v .: "Net Income"
<*> v .: "Preferred Dividends"
<*> v .: "Other Adjustments"
<*> v .: "Net Income (Common)"
-- | Wrapper to parse a GeneralProfitAndLossRow record from SimFin's JSON format.
newtype GeneralProfitsAndLossesKeyed = GeneralProfitsAndLossesKeyed { unKeyGeneralProfitsAndLosses :: [GeneralProfitAndLossRow] }
instance FromJSON GeneralProfitsAndLossesKeyed where
parseJSON o = GeneralProfitsAndLossesKeyed <$> (traverse parseJSON =<< createKeyedRows o)
------
-- Bank
------
-- | Cash flow statement for banks.
data BankProfitAndLossRow
= BankProfitAndLossRow
{ simFinId :: Int
, ticker :: Text
, fiscalPeriod :: String
, fiscalYear :: Int
, reportDate :: Day
, publishDate :: Day
, restatedDate :: Day
, source :: Text
, tTM :: Bool
, valueCheck :: Bool
, revenue :: Maybe Integer
, netInterestIncome :: Maybe Integer
, totalInterestIncome :: Maybe Integer
, totalInterestExpense :: Maybe Integer
, totalNonInterestIncome :: Maybe Integer
, tradingAccountProfitsLosses :: Maybe Integer
, investmentIncomeLoss :: Maybe Integer
, saleOfLoanIncomeLoss :: Maybe Integer
, commissionsAndFeesEarned :: Maybe Integer
, netOTTILossesRecognisedInEarnings :: Maybe Integer
, otherNonInterestIncome :: Maybe Integer
, provisionForLoanLosses :: Maybe Integer
, netRevenueAfterProvisions :: Maybe Integer
, totalNonInterestExpense :: Maybe Integer
, commissionsAndFeesPaid :: Maybe Integer
, otherOperatingExpenses :: Maybe Integer
, operatingIncomeLoss :: Maybe Integer
, nonOperatingIncomeLoss :: Maybe Integer
, incomeLossFromAffiliates :: Maybe Integer
, otherNonOperatingIncomeLoss :: Maybe Integer
, pretaxIncomeLossAdj :: Maybe Integer
, abnormalGainsLosses :: Maybe Integer
, debtValuationAdjustment :: Maybe Integer
, creditValuationAdjustment :: Maybe Integer
, mergerAndAcquisitionExpense :: Maybe Integer
, disposalOfAssets :: Maybe Integer
, earlyExtinguishmentOfDebt :: Maybe Integer
, assetWriteDown :: Maybe Integer
, impairmentOfGoodwillAndIntangibles :: Maybe Integer
, saleOfBusiness :: Maybe Integer
, legalSettlement :: Maybe Integer
, restructuringCharges :: Maybe Integer
, otherAbnormalItems :: Maybe Integer
, pretaxIncomeLoss :: Maybe Integer
, incomeTaxExpenseBenefitNet :: Maybe Integer
, currentIncomeTax :: Maybe Integer
, deferredIncomeTax :: Maybe Integer
, taxAllowanceCredit :: Maybe Integer
, incomeLossFromAffiliatesNetOfTaxes :: Maybe Integer
, incomeLossFromContinuingOperations :: Maybe Integer
, netExtraordinaryGainsLosses :: Maybe Integer
, discontinuedOperations :: Maybe Integer
, accountingChargesAndOther :: Maybe Integer
, incomeLossInclMinorityInterest :: Maybe Integer
, minorityInterest :: Maybe Integer
, netIncome :: Maybe Integer
, preferredDividends :: Maybe Integer
, otherAdjustments :: Maybe Integer
, netIncomeCommon :: Maybe Integer
} deriving Show
instance FromJSON BankProfitAndLossRow where
parseJSON = withObject "BankProfitAndLossRow" $ \v -> BankProfitAndLossRow
<$> v .: "SimFinId"
<*> v .: "Ticker"
<*> v .: "Fiscal Period"
<*> v .: "Fiscal Year"
<*> v .: "Report Date"
<*> v .: "Publish Date"
<*> v .: "Restated Date"
<*> v .: "Source"
<*> v .: "TTM"
<*> v .: "Value Check"
<*> v .: "Revenue"
<*> v .: "Net Interest Income"
<*> v .: "Total Interest Income"
<*> v .: "Total Interest Expense"
<*> v .: "Total Non-Interest Income"
<*> v .: "Trading Account Profits/Losses"
<*> v .: "Investment Income (Loss)"
<*> v .: "Sale of Loan Income (Loss)"
<*> v .: "Commissions & Fees Earned"
<*> v .: "Net OTTI Losses Recognised in Earnings"
<*> v .: "Other Non-Interest Income"
<*> v .: "Provision for Loan Losses"
<*> v .: "Net Revenue after Provisions"
<*> v .: "Total Non-Interest Expense"
<*> v .: "Commissions & Fees Paid"
<*> v .: "Other Operating Expenses"
<*> v .: "Operating Income (Loss)"
<*> v .: "Non-Operating Income (Loss)"
<*> v .: "Income (Loss) from Affiliates"
<*> v .: "Other Non-Operating Income (Loss)"
<*> v .: "Pretax Income (Loss), Adj."
<*> v .: "Abnormal Gains (Losses)"
<*> v .: "Debt Valuation Adjustment"
<*> v .: "Credit Valuation Adjustment"
<*> v .: "Merger & Acquisition Expense"
<*> v .: "Disposal of Assets"
<*> v .: "Early Extinguishment of Debt"
<*> v .: "Asset Write-Down"
<*> v .: "Impairment of Goodwill & Intangibles"
<*> v .: "Sale of Business"
<*> v .: "Legal Settlement"
<*> v .: "Restructuring Charges"
<*> v .: "Other Abnormal Items"
<*> v .: "Pretax Income (Loss)"
<*> v .: "Income Tax (Expense) Benefit, Net"
<*> v .: "Current Income Tax"
<*> v .: "Deferred Income Tax"
<*> v .: "Tax Allowance/Credit"
<*> v .: "Income (Loss) from Affiliates, Net of Taxes"
<*> v .: "Income (Loss) from Continuing Operations"
<*> v .: "Net Extraordinary Gains (Losses)"
<*> v .: "Discontinued Operations"
<*> v .: "Accounting Charges & Other"
<*> v .: "Income (Loss) Incl. Minority Interest"
<*> v .: "Minority Interest"
<*> v .: "Net Income"
<*> v .: "Preferred Dividends"
<*> v .: "Other Adjustments"
<*> v .: "Net Income (Common)"
-- | Wrapper to parse a BankProfitAndLossRow record from SimFin's JSON format.
newtype BankProfitsAndLossesKeyed = BankProfitsAndLossesKeyed { unKeyBankProfitsAndLosses :: [BankProfitAndLossRow] }
instance FromJSON BankProfitsAndLossesKeyed where
parseJSON o = BankProfitsAndLossesKeyed <$> (traverse parseJSON =<< createKeyedRows o)
------
-- Insurance
------
-- | Cash flow statement for insurance companies.
data InsuranceProfitAndLossRow
= InsuranceProfitAndLossRow
{ simFinId :: Int
, ticker :: Text
, fiscalPeriod :: String
, fiscalYear :: Int
, reportDate :: Day
, publishDate :: Day
, restatedDate :: Day
, source :: Text
, tTM :: Bool
, valueCheck :: Bool
, revenue :: Maybe Integer
, netPremiumsEarned :: Maybe Integer
, investmentIncomeLoss :: Maybe Integer
, incomeFromRealEstate :: Maybe Integer
, otherOperatingIncome :: Maybe Integer
, policyChargesAndFees :: Maybe Integer
, totalRealizedInvestmentGains :: Maybe Integer
, totalOTTIRealized :: Maybe Integer
, otherRealizedInvestmentGains :: Maybe Integer
, otherIncome :: Maybe Integer
, totalClaimsAndLosses :: Maybe Integer
, claimsAndLosses :: Maybe Integer
, longTermCharges :: Maybe Integer
, otherClaimsAndLosses :: Maybe Integer
, underwritingExpenseAndAcquisitionCost :: Maybe Integer
, otherOperatingExpenses :: Maybe Integer
, operatingIncomeLoss :: Maybe Integer
, nonOperatingIncomeLoss :: Maybe Integer
, incomeLossFromAffiliates :: Maybe Integer
, interestExpenseNet :: Maybe Integer
, otherNonOperatingIncomeLoss :: Maybe Integer
, pretaxIncomeLossAdj :: Maybe Integer
, abnormalGainsLosses :: Maybe Integer
, mergerAndAcquisitionExpense :: Maybe Integer
, abnormalDerivatives :: Maybe Integer
, disposalOfAssets :: Maybe Integer
, earlyExtinguishmentOfDebt :: Maybe Integer
, assetWriteDown :: Maybe Integer
, impairmentOfGoodwillAndIntangibles :: Maybe Integer
, saleOfBusiness :: Maybe Integer
, legalSettlement :: Maybe Integer
, restructuringCharges :: Maybe Integer
, netInvestmentLosses :: Maybe Integer
, foreignExchange :: Maybe Integer
, otherAbnormalItems :: Maybe Integer
, pretaxIncomeLoss :: Maybe Integer
, incomeTaxExpenseBenefitNet :: Maybe Integer
, currentIncomeTax :: Maybe Integer
, deferredIncomeTax :: Maybe Integer
, taxAllowanceCredit :: Maybe Integer
, incomeLossFromAffiliatesNetOfTaxes :: Maybe Integer
, incomeLossFromContinuingOperations :: Maybe Integer
, netExtraordinaryGainsLosses :: Maybe Integer
, discontinuedOperations :: Maybe Integer
, accountingChargesAndOther :: Maybe Integer
, incomeLossInclMinorityInterest :: Maybe Integer
, minorityInterest :: Maybe Integer
, netIncome :: Maybe Integer
, preferredDividends :: Maybe Integer
, otherAdjustments :: Maybe Integer
, netIncomeCommon :: Maybe Integer
} deriving Show
instance FromJSON InsuranceProfitAndLossRow where
parseJSON = withObject "InsuranceProfitAndLossRow" $ \v -> InsuranceProfitAndLossRow
<$> v .: "SimFinId"
<*> v .: "Ticker"
<*> v .: "Fiscal Period"
<*> v .: "Fiscal Year"
<*> v .: "Report Date"
<*> v .: "Publish Date"
<*> v .: "Restated Date"
<*> v .: "Source"
<*> v .: "TTM"
<*> v .: "Value Check"
<*> v .: "Revenue"
<*> v .: "Net Premiums Earned"
<*> v .: "Investment Income (Loss)"
<*> v .: "Income from Real Estate"
<*> v .: "Other Operating Income"
<*> v .: "Policy Charges & Fees"
<*> v .: "Total Realized Investment Gains"
<*> v .: "Total OTTI Realized"
<*> v .: "Other Realized Investment Gains"
<*> v .: "Other Income"
<*> v .: "Total Claims & Losses"
<*> v .: "Claims & Losses"
<*> v .: "Long Term Charges"
<*> v .: "Other Claims & Losses"
<*> v .: "Underwriting Expense & Acquisition Cost"
<*> v .: "Other Operating Expenses"
<*> v .: "Operating Income (Loss)"
<*> v .: "Non-Operating Income (Loss)"
<*> v .: "Income (Loss) from Affiliates"
<*> v .: "Interest Expense, Net"
<*> v .: "Other Non-Operating Income (Loss)"
<*> v .: "Pretax Income (Loss), Adj."
<*> v .: "Abnormal Gains (Losses)"
<*> v .: "Merger & Acquisition Expense"
<*> v .: "Abnormal Derivatives"
<*> v .: "Disposal of Assets"
<*> v .: "Early Extinguishment of Debt"
<*> v .: "Asset Write-Down"
<*> v .: "Impairment of Goodwill & Intangibles"
<*> v .: "Sale of Business"
<*> v .: "Legal Settlement"
<*> v .: "Restructuring Charges"
<*> v .: "Net Investment Losses"
<*> v .: "Foreign Exchange"
<*> v .: "Other Abnormal Items"
<*> v .: "Pretax Income (Loss)"
<*> v .: "Income Tax (Expense) Benefit, Net"
<*> v .: "Current Income Tax"
<*> v .: "Deferred Income Tax"
<*> v .: "Tax Allowance/Credit"
<*> v .: "Income (Loss) from Affiliates, Net of Taxes"
<*> v .: "Income (Loss) from Continuing Operations"
<*> v .: "Net Extraordinary Gains (Losses)"
<*> v .: "Discontinued Operations"
<*> v .: "Accounting Charges & Other"
<*> v .: "Income (Loss) Incl. Minority Interest"
<*> v .: "Minority Interest"
<*> v .: "Net Income"
<*> v .: "Preferred Dividends"
<*> v .: "Other Adjustments"
<*> v .: "Net Income (Common)"
-- | Wrapper to parse an InsuranceProfitAndLossRow record from SimFin's JSON format.
newtype InsuranceProfitsAndLossesKeyed = InsuranceProfitsAndLossesKeyed { unKeyInsuranceProfitsAndLosses :: [InsuranceProfitAndLossRow] }
instance FromJSON InsuranceProfitsAndLossesKeyed where
parseJSON o = InsuranceProfitsAndLossesKeyed <$> (traverse parseJSON =<< createKeyedRows o)
------
-- Industry
------
type IndustryProfitsAndLossesKeyed
= Industry GeneralProfitsAndLossesKeyed BankProfitsAndLossesKeyed InsuranceProfitsAndLossesKeyed
-- | Discrimination of profit and loss lists.
type IndustryProfitsAndLosses
= Industry [GeneralProfitAndLossRow] [BankProfitAndLossRow] [InsuranceProfitAndLossRow]
-- | Discrimination of profit and losses.
type IndustryProfitAndLoss
= Industry GeneralProfitAndLossRow BankProfitAndLossRow InsuranceProfitAndLossRow
instance FromJSON IndustryProfitsAndLossesKeyed where
parseJSON root = General <$> parseJSON root
<|> Insurance <$> parseJSON root
<|> Bank <$> parseJSON root
unKeyIndustryProfitsAndLosses :: IndustryProfitsAndLossesKeyed -> IndustryProfitsAndLosses
unKeyIndustryProfitsAndLosses = mapIndustry
unKeyGeneralProfitsAndLosses
unKeyBankProfitsAndLosses
unKeyInsuranceProfitsAndLosses
instance FromJSON IndustryProfitsAndLosses where
parseJSON root = unKeyIndustryProfitsAndLosses <$> parseJSON root