ally-invest-0.1.0.0: src/AllyInvest/Account.hs
{-# LANGUAGE OverloadedStrings #-}
module AllyInvest.Account (
getAccounts
, AccountSummary(..)
, Balance(..)
, BuyingPower(..)
, MoneyBalance(..)
, SecuritiesBalance(..)
, Holding(..)
, Instrument(..)
, AccountType(..)
) where
import AllyInvest.Credentials
import AllyInvest.Error
import AllyInvest.Internal
import Data.Aeson
import Data.Time
getAccounts :: Credentials -> IO (Either AllyInvestError AccountSummary)
getAccounts cred = fetchAndDecode cred "https://api.tradeking.com/v1/accounts.json"
data AccountSummary
= AccountSummary {
aNumber :: Int
, aBalance :: Balance
, aHoldings :: [Holding]
} deriving Show
instance FromJSON AccountSummary
where
parseJSON (Object o)
= let o' = o .: "response" >>= (.: "accounts") >>= (.: "accountsummary")
in
AccountSummary
<$> (fmap read $ o' >>= (.: "account"))
<*> ( o' >>= (.: "accountbalance"))
<*> ( o' >>= (.: "accountholdings") >>= (.: "holding"))
data Balance
= Balance {
bAccountValue :: Double
, bBuyingPower :: BuyingPower
, bFedCall :: Double
, bHouseCall :: Double
, bMoney :: MoneyBalance
, bSecurities :: SecuritiesBalance
} deriving Show
instance FromJSON Balance
where
parseJSON (Object o)
= Balance
<$> (read <$> o .: "accountvalue")
<*> ( o .: "buyingpower")
<*> (read <$> o .: "fedcall")
<*> (read <$> o .: "housecall")
<*> ( o .: "money")
<*> ( o .: "securities")
data BuyingPower
= BuyingPower {
bpCashAvailableForWithdrawal :: Double
, bpDayTrading :: Double
, bpEquityPercentage :: Double
, bpOptions :: Double
, bpSodDayTrading :: Double
, bpSodOptions :: Double
, bpSodStock :: Double
, bpStock :: Double
} deriving Show
instance FromJSON BuyingPower
where
parseJSON (Object o)
= BuyingPower
<$> (read <$> o .: "cashavailableforwithdrawal")
<*> (read <$> o .: "daytrading")
<*> (read <$> o .: "equitypercentage")
<*> (read <$> o .: "options")
<*> (read <$> o .: "soddaytrading")
<*> (read <$> o .: "sodoptions")
<*> (read <$> o .: "sodstock")
<*> (read <$> o .: "stock")
data MoneyBalance
= MoneyBalance {
mbAccruedInterest :: Double
, mbCash :: Double
, mbCashAvailable :: Double
, mbMarginBalance :: Double
, mbMoneyMarketFund :: Double
, mbTotal :: Double
, mbUnclearedDeposits :: Double
, mbUnsettledFunds :: Double
, mbYield :: Double
} deriving Show
instance FromJSON MoneyBalance
where
parseJSON (Object o)
= MoneyBalance
<$> (read <$> o .: "accruedinterest")
<*> (read <$> o .: "cash")
<*> (read <$> o .: "cashavailable")
<*> (read <$> o .: "marginbalance")
<*> (read <$> o .: "mmf")
<*> (read <$> o .: "total")
<*> (read <$> o .: "uncleareddeposits")
<*> (read <$> o .: "unsettledfunds")
<*> (read <$> o .: "yield")
data SecuritiesBalance
= SecuritiesBalance {
sbLongOptions :: Double
, sbLongStocks :: Double
, sbOptions :: Double
, sbShortOptions :: Double
, sbShortStocks :: Double
, sbStocks :: Double
, sbTotal :: Double
} deriving Show
instance FromJSON SecuritiesBalance
where
parseJSON (Object o)
= SecuritiesBalance
<$> (read <$> o .: "longoptions")
<*> (read <$> o .: "longstocks")
<*> (read <$> o .: "options")
<*> (read <$> o .: "shortoptions")
<*> (read <$> o .: "shortstocks")
<*> (read <$> o .: "stocks")
<*> (read <$> o .: "total")
data Holding
= Holding {
hAccountType :: AccountType
, hCostBasis :: Double
, hGainLoss :: Double
, hInstrument :: Instrument
, hMarketValue :: Double
, hMarketValueChange :: Double
, hPrice :: Double
, hPurchasePrice :: Double
, hQuantity :: Double
, hQuoteChange :: Double
, hQuoteLastPrice :: Double
} deriving Show
instance FromJSON Holding
where
parseJSON (Object o)
= Holding
<$> ( o .: "accounttype")
<*> (read <$> o .: "costbasis")
<*> (read <$> o .: "gainloss")
<*> ( o .: "instrument")
<*> (read <$> o .: "marketvalue")
<*> (read <$> o .: "marketvaluechange")
<*> (read <$> o .: "price")
<*> (read <$> o .: "purchaseprice")
<*> (read <$> o .: "qty")
<*> (read <$> (o .: "quote" >>= (.: "change")))
<*> (read <$> (o .: "quote" >>= (.: "lastprice")))
data Instrument
= Instrument {
iCusip :: String
, iDesc :: String
, iFactor :: Double
, iMaturityDate :: ZonedTime
, iMaturityMonthYear :: Maybe String
, iMultiplier :: Double
, iPutOrCall :: String
, iSecurityType :: String
, iStrikePrice :: Double
, iSymbol :: String
} deriving Show
instance FromJSON Instrument
where
parseJSON (Object o)
= Instrument
<$> ( o .: "cusip")
<*> ( o .: "desc")
<*> (read <$> o .: "factor")
<*> ( o .: "matdt")
<*> ( o .: "mmy")
<*> (read <$> o .: "mult")
<*> ( o .: "putcall")
<*> ( o .: "sectyp")
<*> (read <$> o .: "strkpx")
<*> ( o .: "sym")
data AccountType = CashAccount | MarginLongAccount | MarginShortAccount
deriving Show
instance FromJSON AccountType where
parseJSON v = case (fromJSON v :: Result String) of
Error err -> fail err
Success t -> case t of
"1" -> return CashAccount
"2" -> return MarginLongAccount
"5" -> return MarginShortAccount
_ -> fail "bad accounttype enum"