packages feed

oanda-rest-api 0.3.0.0 → 0.4.0

raw patch · 19 files changed

+1174/−649 lines, 19 filesdep +conduitdep +http-clientdep +resourcetdep ~basePVP ok

version bump matches the API change (PVP)

Dependencies added: conduit, http-client, resourcet, transformers

Dependency ranges changed: base

API changes (from Hackage documentation)

- OANDA.Accounts: AccountInfo :: Integer -> Text -> Decimal -> Decimal -> Decimal -> Decimal -> Decimal -> Integer -> Integer -> Decimal -> Text -> AccountInfo
- OANDA.Accounts: [accountAccountCurrency] :: Account -> Text
- OANDA.Accounts: [accountAccountId] :: Account -> Int
- OANDA.Accounts: [accountAccountName] :: Account -> Text
- OANDA.Accounts: [accountInfoAccountCurrency] :: AccountInfo -> Text
- OANDA.Accounts: [accountInfoAccountId] :: AccountInfo -> Integer
- OANDA.Accounts: [accountInfoAccountName] :: AccountInfo -> Text
- OANDA.Accounts: [accountInfoBalance] :: AccountInfo -> Decimal
- OANDA.Accounts: [accountInfoMarginAvail] :: AccountInfo -> Decimal
- OANDA.Accounts: [accountInfoMarginRate] :: AccountInfo -> Decimal
- OANDA.Accounts: [accountInfoMarginUsed] :: AccountInfo -> Decimal
- OANDA.Accounts: [accountInfoOpenOrders] :: AccountInfo -> Integer
- OANDA.Accounts: [accountInfoOpenTrades] :: AccountInfo -> Integer
- OANDA.Accounts: [accountInfoRealizedPl] :: AccountInfo -> Decimal
- OANDA.Accounts: [accountInfoUnrealizedPl] :: AccountInfo -> Decimal
- OANDA.Accounts: accountInfo :: OandaEnv -> AccountID -> IO AccountInfo
- OANDA.Accounts: accounts :: OandaEnv -> IO (Vector Account)
- OANDA.Accounts: data AccountInfo
- OANDA.Accounts: instance Data.Aeson.Types.FromJSON.FromJSON OANDA.Accounts.AccountInfo
- OANDA.Accounts: instance GHC.Generics.Generic OANDA.Accounts.Account
- OANDA.Accounts: instance GHC.Generics.Generic OANDA.Accounts.AccountInfo
- OANDA.Accounts: instance GHC.Show.Show OANDA.Accounts.AccountInfo
- OANDA.Environment: AccessToken :: ByteString -> AccessToken
- OANDA.Environment: AccountID :: Int -> AccountID
- OANDA.Environment: Buy :: Side
- OANDA.Environment: Live :: APIType
- OANDA.Environment: Practice :: APIType
- OANDA.Environment: Sandbox :: APIType
- OANDA.Environment: Sell :: Side
- OANDA.Environment: [unAccessToken] :: AccessToken -> ByteString
- OANDA.Environment: [unAccountID] :: AccountID -> Int
- OANDA.Environment: accessToken :: OandaEnv -> Maybe AccessToken
- OANDA.Environment: apiType :: OandaEnv -> APIType
- OANDA.Environment: data APIType
- OANDA.Environment: data OandaEnv
- OANDA.Environment: data Side
- OANDA.Environment: liveAuth :: AccessToken -> OandaEnv
- OANDA.Environment: newtype AccessToken
- OANDA.Environment: newtype AccountID
- OANDA.Environment: practiceAuth :: AccessToken -> OandaEnv
- OANDA.Environment: sandboxAuth :: OandaEnv
- OANDA.Environment: type InstrumentText = Text
- OANDA.Orders: [orderExpiry] :: Order -> ZonedTime
- OANDA.Orders: [orderLowerBound] :: Order -> Decimal
- OANDA.Orders: [orderSide] :: Order -> Side
- OANDA.Orders: [orderStopLoss] :: Order -> Decimal
- OANDA.Orders: [orderTakeProfit] :: Order -> Decimal
- OANDA.Orders: [orderTime] :: Order -> ZonedTime
- OANDA.Orders: [orderTrailingStop] :: Order -> Decimal
- OANDA.Orders: [orderUpperBound] :: Order -> Decimal
- OANDA.Orders: instance GHC.Generics.Generic OANDA.Orders.Order
- OANDA.Orders: openOrders :: OandaEnv -> AccountID -> IO (Vector Order)
- OANDA.Positions: CloseResponse :: Vector Int -> InstrumentText -> Int -> Decimal -> CloseResponse
- OANDA.Positions: Position :: Text -> Int -> Side -> Decimal -> Position
- OANDA.Positions: [closeResponseIds] :: CloseResponse -> Vector Int
- OANDA.Positions: [closeResponseInstrument] :: CloseResponse -> InstrumentText
- OANDA.Positions: [closeResponsePrice] :: CloseResponse -> Decimal
- OANDA.Positions: [closeResponseTotalUnits] :: CloseResponse -> Int
- OANDA.Positions: [positionAvgPrice] :: Position -> Decimal
- OANDA.Positions: [positionInstrument] :: Position -> Text
- OANDA.Positions: [positionSide] :: Position -> Side
- OANDA.Positions: [positionUnits] :: Position -> Int
- OANDA.Positions: closePosition :: OandaEnv -> AccountID -> InstrumentText -> IO CloseResponse
- OANDA.Positions: data CloseResponse
- OANDA.Positions: data Position
- OANDA.Positions: instance Data.Aeson.Types.FromJSON.FromJSON OANDA.Positions.CloseResponse
- OANDA.Positions: instance Data.Aeson.Types.FromJSON.FromJSON OANDA.Positions.Position
- OANDA.Positions: instance GHC.Generics.Generic OANDA.Positions.CloseResponse
- OANDA.Positions: instance GHC.Generics.Generic OANDA.Positions.Position
- OANDA.Positions: instance GHC.Show.Show OANDA.Positions.CloseResponse
- OANDA.Positions: instance GHC.Show.Show OANDA.Positions.Position
- OANDA.Positions: openPositions :: OandaEnv -> AccountID -> IO (Vector Position)
- OANDA.Positions: position :: OandaEnv -> AccountID -> InstrumentText -> IO Position
- OANDA.Rates: BidAskCandlestick :: ZonedTime -> Decimal -> Decimal -> Decimal -> Decimal -> Decimal -> Decimal -> Decimal -> Decimal -> Int -> Bool -> BidAskCandlestick
- OANDA.Rates: CandlesArgs :: Maybe CandlesCount -> Maybe Granularity -> Maybe Int -> Maybe Text -> Maybe DayOfWeek -> CandlesArgs
- OANDA.Rates: Count :: Int -> CandlesCount
- OANDA.Rates: D :: Granularity
- OANDA.Rates: EndCount :: ZonedTime -> Int -> CandlesCount
- OANDA.Rates: Friday :: DayOfWeek
- OANDA.Rates: H1 :: Granularity
- OANDA.Rates: H12 :: Granularity
- OANDA.Rates: H2 :: Granularity
- OANDA.Rates: H3 :: Granularity
- OANDA.Rates: H4 :: Granularity
- OANDA.Rates: H6 :: Granularity
- OANDA.Rates: H8 :: Granularity
- OANDA.Rates: Instrument :: Text -> Maybe Decimal -> Maybe Integer -> Maybe Text -> Maybe Decimal -> Maybe Decimal -> Maybe Decimal -> Maybe Decimal -> Maybe Bool -> Maybe Object -> Instrument
- OANDA.Rates: InstrumentsArgs :: Maybe [Text] -> Maybe [Text] -> InstrumentsArgs
- OANDA.Rates: M :: Granularity
- OANDA.Rates: M1 :: Granularity
- OANDA.Rates: M10 :: Granularity
- OANDA.Rates: M15 :: Granularity
- OANDA.Rates: M2 :: Granularity
- OANDA.Rates: M3 :: Granularity
- OANDA.Rates: M30 :: Granularity
- OANDA.Rates: M4 :: Granularity
- OANDA.Rates: M5 :: Granularity
- OANDA.Rates: MidpointCandlestick :: ZonedTime -> Decimal -> Decimal -> Decimal -> Decimal -> Int -> Bool -> MidpointCandlestick
- OANDA.Rates: Monday :: DayOfWeek
- OANDA.Rates: Price :: InstrumentText -> ZonedTime -> Decimal -> Decimal -> Price
- OANDA.Rates: S10 :: Granularity
- OANDA.Rates: S15 :: Granularity
- OANDA.Rates: S30 :: Granularity
- OANDA.Rates: S5 :: Granularity
- OANDA.Rates: Saturday :: DayOfWeek
- OANDA.Rates: StartCount :: ZonedTime -> Int -> Bool -> CandlesCount
- OANDA.Rates: StartEnd :: ZonedTime -> ZonedTime -> Bool -> CandlesCount
- OANDA.Rates: Sunday :: DayOfWeek
- OANDA.Rates: Thursday :: DayOfWeek
- OANDA.Rates: Tuesday :: DayOfWeek
- OANDA.Rates: W :: Granularity
- OANDA.Rates: Wednesday :: DayOfWeek
- OANDA.Rates: [bidaskCandlestickCloseAsk] :: BidAskCandlestick -> Decimal
- OANDA.Rates: [bidaskCandlestickCloseBid] :: BidAskCandlestick -> Decimal
- OANDA.Rates: [bidaskCandlestickComplete] :: BidAskCandlestick -> Bool
- OANDA.Rates: [bidaskCandlestickHighAsk] :: BidAskCandlestick -> Decimal
- OANDA.Rates: [bidaskCandlestickHighBid] :: BidAskCandlestick -> Decimal
- OANDA.Rates: [bidaskCandlestickLowAsk] :: BidAskCandlestick -> Decimal
- OANDA.Rates: [bidaskCandlestickLowBid] :: BidAskCandlestick -> Decimal
- OANDA.Rates: [bidaskCandlestickOpenAsk] :: BidAskCandlestick -> Decimal
- OANDA.Rates: [bidaskCandlestickOpenBid] :: BidAskCandlestick -> Decimal
- OANDA.Rates: [bidaskCandlestickTime] :: BidAskCandlestick -> ZonedTime
- OANDA.Rates: [bidaskCandlestickVolume] :: BidAskCandlestick -> Int
- OANDA.Rates: [candlesAlignmentTZ] :: CandlesArgs -> Maybe Text
- OANDA.Rates: [candlesCount] :: CandlesArgs -> Maybe CandlesCount
- OANDA.Rates: [candlesDailyAlignment] :: CandlesArgs -> Maybe Int
- OANDA.Rates: [candlesGranularity] :: CandlesArgs -> Maybe Granularity
- OANDA.Rates: [candlesWeeklyAlignment] :: CandlesArgs -> Maybe DayOfWeek
- OANDA.Rates: [count] :: CandlesCount -> Int
- OANDA.Rates: [end] :: CandlesCount -> ZonedTime
- OANDA.Rates: [includeFirst] :: CandlesCount -> Bool
- OANDA.Rates: [instrumentDisplayName] :: Instrument -> Maybe Text
- OANDA.Rates: [instrumentHalted] :: Instrument -> Maybe Bool
- OANDA.Rates: [instrumentInstrument] :: Instrument -> Text
- OANDA.Rates: [instrumentInterestRate] :: Instrument -> Maybe Object
- OANDA.Rates: [instrumentMarginRate] :: Instrument -> Maybe Decimal
- OANDA.Rates: [instrumentMaxTradeUnits] :: Instrument -> Maybe Integer
- OANDA.Rates: [instrumentMaxTrailingStop] :: Instrument -> Maybe Decimal
- OANDA.Rates: [instrumentMinTrailingStop] :: Instrument -> Maybe Decimal
- OANDA.Rates: [instrumentPip] :: Instrument -> Maybe Decimal
- OANDA.Rates: [instrumentPrecision] :: Instrument -> Maybe Decimal
- OANDA.Rates: [instrumentsFields] :: InstrumentsArgs -> Maybe [Text]
- OANDA.Rates: [instrumentsInstruments] :: InstrumentsArgs -> Maybe [Text]
- OANDA.Rates: [midpointCandlestickCloseMid] :: MidpointCandlestick -> Decimal
- OANDA.Rates: [midpointCandlestickComplete] :: MidpointCandlestick -> Bool
- OANDA.Rates: [midpointCandlestickHighMid] :: MidpointCandlestick -> Decimal
- OANDA.Rates: [midpointCandlestickLowMid] :: MidpointCandlestick -> Decimal
- OANDA.Rates: [midpointCandlestickOpenMid] :: MidpointCandlestick -> Decimal
- OANDA.Rates: [midpointCandlestickTime] :: MidpointCandlestick -> ZonedTime
- OANDA.Rates: [midpointCandlestickVolume] :: MidpointCandlestick -> Int
- OANDA.Rates: [priceAsk] :: Price -> Decimal
- OANDA.Rates: [priceBid] :: Price -> Decimal
- OANDA.Rates: [priceInstrument] :: Price -> InstrumentText
- OANDA.Rates: [priceTime] :: Price -> ZonedTime
- OANDA.Rates: [start] :: CandlesCount -> ZonedTime
- OANDA.Rates: bidaskCandles :: OandaEnv -> InstrumentText -> CandlesArgs -> IO (Vector BidAskCandlestick)
- OANDA.Rates: candlesArgs :: CandlesArgs
- OANDA.Rates: data BidAskCandlestick
- OANDA.Rates: data CandlesArgs
- OANDA.Rates: data CandlesCount
- OANDA.Rates: data DayOfWeek
- OANDA.Rates: data Granularity
- OANDA.Rates: data Instrument
- OANDA.Rates: data InstrumentsArgs
- OANDA.Rates: data MidpointCandlestick
- OANDA.Rates: data Price
- OANDA.Rates: granularityToDiffTime :: Granularity -> NominalDiffTime
- OANDA.Rates: instance Data.Aeson.Types.FromJSON.FromJSON OANDA.Rates.BidAskCandlesResponse
- OANDA.Rates: instance Data.Aeson.Types.FromJSON.FromJSON OANDA.Rates.BidAskCandlestick
- OANDA.Rates: instance Data.Aeson.Types.FromJSON.FromJSON OANDA.Rates.Instrument
- OANDA.Rates: instance Data.Aeson.Types.FromJSON.FromJSON OANDA.Rates.MidpointCandlesResponse
- OANDA.Rates: instance Data.Aeson.Types.FromJSON.FromJSON OANDA.Rates.MidpointCandlestick
- OANDA.Rates: instance Data.Aeson.Types.FromJSON.FromJSON OANDA.Rates.Price
- OANDA.Rates: instance GHC.Generics.Generic OANDA.Rates.BidAskCandlesResponse
- OANDA.Rates: instance GHC.Generics.Generic OANDA.Rates.BidAskCandlestick
- OANDA.Rates: instance GHC.Generics.Generic OANDA.Rates.Instrument
- OANDA.Rates: instance GHC.Generics.Generic OANDA.Rates.MidpointCandlesResponse
- OANDA.Rates: instance GHC.Generics.Generic OANDA.Rates.MidpointCandlestick
- OANDA.Rates: instance GHC.Generics.Generic OANDA.Rates.Price
- OANDA.Rates: instance GHC.Show.Show OANDA.Rates.BidAskCandlesResponse
- OANDA.Rates: instance GHC.Show.Show OANDA.Rates.BidAskCandlestick
- OANDA.Rates: instance GHC.Show.Show OANDA.Rates.CandlesArgs
- OANDA.Rates: instance GHC.Show.Show OANDA.Rates.CandlesCount
- OANDA.Rates: instance GHC.Show.Show OANDA.Rates.DayOfWeek
- OANDA.Rates: instance GHC.Show.Show OANDA.Rates.Granularity
- OANDA.Rates: instance GHC.Show.Show OANDA.Rates.Instrument
- OANDA.Rates: instance GHC.Show.Show OANDA.Rates.InstrumentsArgs
- OANDA.Rates: instance GHC.Show.Show OANDA.Rates.MidpointCandlesResponse
- OANDA.Rates: instance GHC.Show.Show OANDA.Rates.MidpointCandlestick
- OANDA.Rates: instance GHC.Show.Show OANDA.Rates.Price
- OANDA.Rates: instruments :: OandaEnv -> AccountID -> InstrumentsArgs -> IO (Vector Instrument)
- OANDA.Rates: instrumentsArgs :: InstrumentsArgs
- OANDA.Rates: midpointCandles :: OandaEnv -> InstrumentText -> CandlesArgs -> IO (Vector MidpointCandlestick)
- OANDA.Rates: prices :: OandaEnv -> [InstrumentText] -> Maybe ZonedTime -> IO (Vector Price)
- OANDA.Trades: Trade :: !Int -> !Int -> !Side -> !Text -> !ZonedTime -> !Decimal -> !Decimal -> !Decimal -> !Decimal -> !Decimal -> Trade
- OANDA.Trades: [tradeId] :: Trade -> !Int
- OANDA.Trades: [tradeInstrument] :: Trade -> !Text
- OANDA.Trades: [tradePrice] :: Trade -> !Decimal
- OANDA.Trades: [tradeSide] :: Trade -> !Side
- OANDA.Trades: [tradeStopLoss] :: Trade -> !Decimal
- OANDA.Trades: [tradeTakeProfit] :: Trade -> !Decimal
- OANDA.Trades: [tradeTime] :: Trade -> !ZonedTime
- OANDA.Trades: [tradeTrailingAmount] :: Trade -> !Decimal
- OANDA.Trades: [tradeTrailingStop] :: Trade -> !Decimal
- OANDA.Trades: [tradeUnits] :: Trade -> !Int
- OANDA.Trades: data Trade
- OANDA.Trades: instance Data.Aeson.Types.FromJSON.FromJSON OANDA.Trades.Trade
- OANDA.Trades: instance GHC.Generics.Generic OANDA.Trades.Trade
- OANDA.Trades: instance GHC.Show.Show OANDA.Trades.Trade
- OANDA.Trades: openTrades :: OandaEnv -> AccountID -> IO (Vector Trade)
- OANDA.Trades: tradeInfo :: OandaEnv -> AccountID -> TradeID -> IO Trade
- OANDA.Transactions: [transactionAccountId] :: Transaction -> Integer
- OANDA.Transactions: [transactionInterest] :: Transaction -> Maybe Decimal
- OANDA.Transactions: [transactionLowerBound] :: Transaction -> Maybe Decimal
- OANDA.Transactions: [transactionPL] :: Transaction -> Maybe Decimal
- OANDA.Transactions: [transactionSide] :: Transaction -> Maybe Side
- OANDA.Transactions: [transactionStopLossPrice] :: Transaction -> Maybe Decimal
- OANDA.Transactions: [transactionTakeProfitPrice] :: Transaction -> Maybe Decimal
- OANDA.Transactions: [transactionTrailingStopLossDistance] :: Transaction -> Maybe Decimal
- OANDA.Transactions: [transactionUpperBound] :: Transaction -> Maybe Decimal
- OANDA.Transactions: instance GHC.Generics.Generic OANDA.Transactions.Transaction
- OANDA.Transactions: transactionHistory :: OandaEnv -> AccountID -> IO (Vector Transaction)
+ OANDA.Accounts: AccountChanges :: [Order] -> [Order] -> [Order] -> [Order] -> [Position] -> [Transaction] -> AccountChanges
+ OANDA.Accounts: AccountChangesResponse :: AccountChanges -> AccountChangesState -> TransactionID -> AccountChangesResponse
+ OANDA.Accounts: AccountChangesState :: AccountUnits -> AccountUnits -> AccountUnits -> AccountUnits -> Maybe AccountUnits -> Maybe AccountUnits -> Maybe AccountUnits -> Maybe Decimal -> Maybe Decimal -> AccountUnits -> AccountUnits -> Decimal -> AccountChangesState
+ OANDA.Accounts: AccountDetailsResponse :: Account -> TransactionID -> AccountDetailsResponse
+ OANDA.Accounts: AccountProperties :: AccountID -> Maybe Text -> [Text] -> AccountProperties
+ OANDA.Accounts: AccountsResponse :: Vector AccountProperties -> AccountsResponse
+ OANDA.Accounts: Position :: InstrumentName -> AccountUnits -> Maybe AccountUnits -> Maybe AccountUnits -> PositionSide -> PositionSide -> Position
+ OANDA.Accounts: PositionSide :: Decimal -> Maybe PriceValue -> Maybe [TradeID] -> AccountUnits -> Maybe AccountUnits -> Maybe AccountUnits -> PositionSide
+ OANDA.Accounts: [accountAlias] :: Account -> Text
+ OANDA.Accounts: [accountBalance] :: Account -> AccountUnits
+ OANDA.Accounts: [accountChangesOrdersCancelled] :: AccountChanges -> [Order]
+ OANDA.Accounts: [accountChangesOrdersCreated] :: AccountChanges -> [Order]
+ OANDA.Accounts: [accountChangesOrdersFilled] :: AccountChanges -> [Order]
+ OANDA.Accounts: [accountChangesOrdersTriggered] :: AccountChanges -> [Order]
+ OANDA.Accounts: [accountChangesPositions] :: AccountChanges -> [Position]
+ OANDA.Accounts: [accountChangesResponseChanges] :: AccountChangesResponse -> AccountChanges
+ OANDA.Accounts: [accountChangesResponseLastTransactionID] :: AccountChangesResponse -> TransactionID
+ OANDA.Accounts: [accountChangesResponseState] :: AccountChangesResponse -> AccountChangesState
+ OANDA.Accounts: [accountChangesStateMarginAvailable] :: AccountChangesState -> AccountUnits
+ OANDA.Accounts: [accountChangesStateMarginCallMarginUsed] :: AccountChangesState -> AccountUnits
+ OANDA.Accounts: [accountChangesStateMarginCallPercent] :: AccountChangesState -> Decimal
+ OANDA.Accounts: [accountChangesStateMarginCloseoutMarginUsed] :: AccountChangesState -> Maybe AccountUnits
+ OANDA.Accounts: [accountChangesStateMarginCloseoutNAV] :: AccountChangesState -> Maybe AccountUnits
+ OANDA.Accounts: [accountChangesStateMarginCloseoutPercent] :: AccountChangesState -> Maybe Decimal
+ OANDA.Accounts: [accountChangesStateMarginCloseoutPositionValue] :: AccountChangesState -> Maybe Decimal
+ OANDA.Accounts: [accountChangesStateMarginCloseoutUnrealizedPL] :: AccountChangesState -> Maybe AccountUnits
+ OANDA.Accounts: [accountChangesStateMarginUsed] :: AccountChangesState -> AccountUnits
+ OANDA.Accounts: [accountChangesStatePositionValue] :: AccountChangesState -> AccountUnits
+ OANDA.Accounts: [accountChangesStateUnrealizedPL] :: AccountChangesState -> AccountUnits
+ OANDA.Accounts: [accountChangesStateWithdrawalLimit] :: AccountChangesState -> AccountUnits
+ OANDA.Accounts: [accountChangesTransactions] :: AccountChanges -> [Transaction]
+ OANDA.Accounts: [accountCreatedByUserID] :: Account -> Integer
+ OANDA.Accounts: [accountCreatedTime] :: Account -> OandaZonedTime
+ OANDA.Accounts: [accountCurrency] :: Account -> Currency
+ OANDA.Accounts: [accountDetailsResponseAccount] :: AccountDetailsResponse -> Account
+ OANDA.Accounts: [accountDetailsResponseLastTransactionID] :: AccountDetailsResponse -> TransactionID
+ OANDA.Accounts: [accountHedgingEnabled] :: Account -> Bool
+ OANDA.Accounts: [accountId] :: Account -> AccountID
+ OANDA.Accounts: [accountLastMarginCallExtensionTime] :: Account -> Maybe OandaZonedTime
+ OANDA.Accounts: [accountLastTransactionID] :: Account -> TransactionID
+ OANDA.Accounts: [accountMarginAvailable] :: Account -> AccountUnits
+ OANDA.Accounts: [accountMarginCallEnterTime] :: Account -> Maybe OandaZonedTime
+ OANDA.Accounts: [accountMarginCallExtensionCount] :: Account -> Maybe Integer
+ OANDA.Accounts: [accountMarginCallMarginUsed] :: Account -> AccountUnits
+ OANDA.Accounts: [accountMarginCallPercent] :: Account -> Decimal
+ OANDA.Accounts: [accountMarginCloseoutMarginUsed] :: Account -> AccountUnits
+ OANDA.Accounts: [accountMarginCloseoutNAV] :: Account -> AccountUnits
+ OANDA.Accounts: [accountMarginCloseoutPercent] :: Account -> Decimal
+ OANDA.Accounts: [accountMarginCloseoutUnrealizedPL] :: Account -> AccountUnits
+ OANDA.Accounts: [accountMarginUsed] :: Account -> AccountUnits
+ OANDA.Accounts: [accountOpenPositionCount] :: Account -> Integer
+ OANDA.Accounts: [accountOpenTradeCount] :: Account -> Integer
+ OANDA.Accounts: [accountOrders] :: Account -> [Order]
+ OANDA.Accounts: [accountPendingOrderCount] :: Account -> Integer
+ OANDA.Accounts: [accountPl] :: Account -> AccountUnits
+ OANDA.Accounts: [accountPositionValue] :: Account -> AccountUnits
+ OANDA.Accounts: [accountPositions] :: Account -> [Position]
+ OANDA.Accounts: [accountPropertiesId] :: AccountProperties -> AccountID
+ OANDA.Accounts: [accountPropertiesMt4AccountID] :: AccountProperties -> Maybe Text
+ OANDA.Accounts: [accountPropertiesTags] :: AccountProperties -> [Text]
+ OANDA.Accounts: [accountResettablePLTime] :: Account -> Maybe OandaZonedTime
+ OANDA.Accounts: [accountResettablePL] :: Account -> AccountUnits
+ OANDA.Accounts: [accountUnrealizedPL] :: Account -> AccountUnits
+ OANDA.Accounts: [accountWithdrawalLimit] :: Account -> AccountUnits
+ OANDA.Accounts: [accountsResponseAccounts] :: AccountsResponse -> Vector AccountProperties
+ OANDA.Accounts: [positionInstrument] :: Position -> InstrumentName
+ OANDA.Accounts: [positionLong] :: Position -> PositionSide
+ OANDA.Accounts: [positionPl] :: Position -> AccountUnits
+ OANDA.Accounts: [positionResettablePL] :: Position -> Maybe AccountUnits
+ OANDA.Accounts: [positionShort] :: Position -> PositionSide
+ OANDA.Accounts: [positionSideAveragePrice] :: PositionSide -> Maybe PriceValue
+ OANDA.Accounts: [positionSidePl] :: PositionSide -> AccountUnits
+ OANDA.Accounts: [positionSideResettablePL] :: PositionSide -> Maybe AccountUnits
+ OANDA.Accounts: [positionSideTradeIDs] :: PositionSide -> Maybe [TradeID]
+ OANDA.Accounts: [positionSideUnits] :: PositionSide -> Decimal
+ OANDA.Accounts: [positionSideUnrealizedPL] :: PositionSide -> Maybe AccountUnits
+ OANDA.Accounts: [positionUnrealizedPL] :: Position -> Maybe AccountUnits
+ OANDA.Accounts: data AccountChanges
+ OANDA.Accounts: data AccountChangesResponse
+ OANDA.Accounts: data AccountChangesState
+ OANDA.Accounts: data AccountDetailsResponse
+ OANDA.Accounts: data AccountProperties
+ OANDA.Accounts: data AccountsResponse
+ OANDA.Accounts: data Position
+ OANDA.Accounts: data PositionSide
+ OANDA.Accounts: instance Data.Aeson.Types.FromJSON.FromJSON OANDA.Accounts.AccountChanges
+ OANDA.Accounts: instance Data.Aeson.Types.FromJSON.FromJSON OANDA.Accounts.AccountChangesResponse
+ OANDA.Accounts: instance Data.Aeson.Types.FromJSON.FromJSON OANDA.Accounts.AccountChangesState
+ OANDA.Accounts: instance Data.Aeson.Types.FromJSON.FromJSON OANDA.Accounts.AccountDetailsResponse
+ OANDA.Accounts: instance Data.Aeson.Types.FromJSON.FromJSON OANDA.Accounts.AccountProperties
+ OANDA.Accounts: instance Data.Aeson.Types.FromJSON.FromJSON OANDA.Accounts.AccountsResponse
+ OANDA.Accounts: instance Data.Aeson.Types.FromJSON.FromJSON OANDA.Accounts.Position
+ OANDA.Accounts: instance Data.Aeson.Types.FromJSON.FromJSON OANDA.Accounts.PositionSide
+ OANDA.Accounts: instance Data.Aeson.Types.ToJSON.ToJSON OANDA.Accounts.Account
+ OANDA.Accounts: instance Data.Aeson.Types.ToJSON.ToJSON OANDA.Accounts.AccountChanges
+ OANDA.Accounts: instance Data.Aeson.Types.ToJSON.ToJSON OANDA.Accounts.AccountChangesResponse
+ OANDA.Accounts: instance Data.Aeson.Types.ToJSON.ToJSON OANDA.Accounts.AccountChangesState
+ OANDA.Accounts: instance Data.Aeson.Types.ToJSON.ToJSON OANDA.Accounts.AccountDetailsResponse
+ OANDA.Accounts: instance Data.Aeson.Types.ToJSON.ToJSON OANDA.Accounts.AccountProperties
+ OANDA.Accounts: instance Data.Aeson.Types.ToJSON.ToJSON OANDA.Accounts.AccountsResponse
+ OANDA.Accounts: instance Data.Aeson.Types.ToJSON.ToJSON OANDA.Accounts.Position
+ OANDA.Accounts: instance Data.Aeson.Types.ToJSON.ToJSON OANDA.Accounts.PositionSide
+ OANDA.Accounts: instance GHC.Show.Show OANDA.Accounts.AccountChanges
+ OANDA.Accounts: instance GHC.Show.Show OANDA.Accounts.AccountChangesResponse
+ OANDA.Accounts: instance GHC.Show.Show OANDA.Accounts.AccountChangesState
+ OANDA.Accounts: instance GHC.Show.Show OANDA.Accounts.AccountDetailsResponse
+ OANDA.Accounts: instance GHC.Show.Show OANDA.Accounts.AccountProperties
+ OANDA.Accounts: instance GHC.Show.Show OANDA.Accounts.AccountsResponse
+ OANDA.Accounts: instance GHC.Show.Show OANDA.Accounts.Position
+ OANDA.Accounts: instance GHC.Show.Show OANDA.Accounts.PositionSide
+ OANDA.Accounts: oandaAccountChanges :: OandaEnv -> AccountID -> TransactionID -> OANDARequest AccountChangesResponse
+ OANDA.Accounts: oandaAccountDetails :: OandaEnv -> AccountID -> OANDARequest AccountDetailsResponse
+ OANDA.Accounts: oandaAccounts :: OandaEnv -> OANDARequest AccountsResponse
+ OANDA.Instrument: Candlestick :: OandaZonedTime -> Maybe CandlestickData -> Maybe CandlestickData -> Maybe CandlestickData -> Integer -> Bool -> Candlestick
+ OANDA.Instrument: CandlestickArgs :: InstrumentName -> Maybe Text -> CandlestickGranularity -> Maybe Int -> Maybe ZonedTime -> Maybe ZonedTime -> Maybe Bool -> Maybe Bool -> Maybe Int -> Maybe String -> Maybe WeeklyAlignment -> CandlestickArgs
+ OANDA.Instrument: CandlestickData :: PriceValue -> PriceValue -> PriceValue -> PriceValue -> CandlestickData
+ OANDA.Instrument: CandlestickResponse :: InstrumentName -> CandlestickGranularity -> [Candlestick] -> CandlestickResponse
+ OANDA.Instrument: D :: CandlestickGranularity
+ OANDA.Instrument: Friday :: WeeklyAlignment
+ OANDA.Instrument: H1 :: CandlestickGranularity
+ OANDA.Instrument: H12 :: CandlestickGranularity
+ OANDA.Instrument: H2 :: CandlestickGranularity
+ OANDA.Instrument: H3 :: CandlestickGranularity
+ OANDA.Instrument: H4 :: CandlestickGranularity
+ OANDA.Instrument: H6 :: CandlestickGranularity
+ OANDA.Instrument: H8 :: CandlestickGranularity
+ OANDA.Instrument: M :: CandlestickGranularity
+ OANDA.Instrument: M1 :: CandlestickGranularity
+ OANDA.Instrument: M10 :: CandlestickGranularity
+ OANDA.Instrument: M15 :: CandlestickGranularity
+ OANDA.Instrument: M2 :: CandlestickGranularity
+ OANDA.Instrument: M30 :: CandlestickGranularity
+ OANDA.Instrument: M4 :: CandlestickGranularity
+ OANDA.Instrument: M5 :: CandlestickGranularity
+ OANDA.Instrument: Monday :: WeeklyAlignment
+ OANDA.Instrument: PriceValue :: Text -> PriceValue
+ OANDA.Instrument: S10 :: CandlestickGranularity
+ OANDA.Instrument: S15 :: CandlestickGranularity
+ OANDA.Instrument: S30 :: CandlestickGranularity
+ OANDA.Instrument: S5 :: CandlestickGranularity
+ OANDA.Instrument: Saturday :: WeeklyAlignment
+ OANDA.Instrument: Sunday :: WeeklyAlignment
+ OANDA.Instrument: Thursday :: WeeklyAlignment
+ OANDA.Instrument: Tuesday :: WeeklyAlignment
+ OANDA.Instrument: W :: CandlestickGranularity
+ OANDA.Instrument: Wednesday :: WeeklyAlignment
+ OANDA.Instrument: [_candlestickArgsAlignmentTimezone] :: CandlestickArgs -> Maybe String
+ OANDA.Instrument: [_candlestickArgsCount] :: CandlestickArgs -> Maybe Int
+ OANDA.Instrument: [_candlestickArgsDailyAlignment] :: CandlestickArgs -> Maybe Int
+ OANDA.Instrument: [_candlestickArgsFrom] :: CandlestickArgs -> Maybe ZonedTime
+ OANDA.Instrument: [_candlestickArgsGranularity] :: CandlestickArgs -> CandlestickGranularity
+ OANDA.Instrument: [_candlestickArgsIncludeFirst] :: CandlestickArgs -> Maybe Bool
+ OANDA.Instrument: [_candlestickArgsInstrument] :: CandlestickArgs -> InstrumentName
+ OANDA.Instrument: [_candlestickArgsPrice] :: CandlestickArgs -> Maybe Text
+ OANDA.Instrument: [_candlestickArgsSmooth] :: CandlestickArgs -> Maybe Bool
+ OANDA.Instrument: [_candlestickArgsTo] :: CandlestickArgs -> Maybe ZonedTime
+ OANDA.Instrument: [_candlestickArgsWeeklyAlignment] :: CandlestickArgs -> Maybe WeeklyAlignment
+ OANDA.Instrument: [candlestickAsk] :: Candlestick -> Maybe CandlestickData
+ OANDA.Instrument: [candlestickBid] :: Candlestick -> Maybe CandlestickData
+ OANDA.Instrument: [candlestickComplete] :: Candlestick -> Bool
+ OANDA.Instrument: [candlestickDataC] :: CandlestickData -> PriceValue
+ OANDA.Instrument: [candlestickDataH] :: CandlestickData -> PriceValue
+ OANDA.Instrument: [candlestickDataL] :: CandlestickData -> PriceValue
+ OANDA.Instrument: [candlestickDataO] :: CandlestickData -> PriceValue
+ OANDA.Instrument: [candlestickMid] :: Candlestick -> Maybe CandlestickData
+ OANDA.Instrument: [candlestickResponseCandles] :: CandlestickResponse -> [Candlestick]
+ OANDA.Instrument: [candlestickResponseGranularity] :: CandlestickResponse -> CandlestickGranularity
+ OANDA.Instrument: [candlestickResponseInstrument] :: CandlestickResponse -> InstrumentName
+ OANDA.Instrument: [candlestickTime] :: Candlestick -> OandaZonedTime
+ OANDA.Instrument: [candlestickVolume] :: Candlestick -> Integer
+ OANDA.Instrument: [unPriceValue] :: PriceValue -> Text
+ OANDA.Instrument: candlestickArgs :: InstrumentName -> CandlestickGranularity -> CandlestickArgs
+ OANDA.Instrument: candlestickArgsAlignmentTimezone :: Lens' CandlestickArgs (Maybe String)
+ OANDA.Instrument: candlestickArgsCount :: Lens' CandlestickArgs (Maybe Int)
+ OANDA.Instrument: candlestickArgsDailyAlignment :: Lens' CandlestickArgs (Maybe Int)
+ OANDA.Instrument: candlestickArgsFrom :: Lens' CandlestickArgs (Maybe ZonedTime)
+ OANDA.Instrument: candlestickArgsGranularity :: Lens' CandlestickArgs CandlestickGranularity
+ OANDA.Instrument: candlestickArgsIncludeFirst :: Lens' CandlestickArgs (Maybe Bool)
+ OANDA.Instrument: candlestickArgsInstrument :: Lens' CandlestickArgs InstrumentName
+ OANDA.Instrument: candlestickArgsPrice :: Lens' CandlestickArgs (Maybe Text)
+ OANDA.Instrument: candlestickArgsSmooth :: Lens' CandlestickArgs (Maybe Bool)
+ OANDA.Instrument: candlestickArgsTo :: Lens' CandlestickArgs (Maybe ZonedTime)
+ OANDA.Instrument: candlestickArgsWeeklyAlignment :: Lens' CandlestickArgs (Maybe WeeklyAlignment)
+ OANDA.Instrument: data Candlestick
+ OANDA.Instrument: data CandlestickArgs
+ OANDA.Instrument: data CandlestickData
+ OANDA.Instrument: data CandlestickGranularity
+ OANDA.Instrument: data CandlestickResponse
+ OANDA.Instrument: data WeeklyAlignment
+ OANDA.Instrument: granularityFromDiffTime :: NominalDiffTime -> Maybe CandlestickGranularity
+ OANDA.Instrument: granularityToDiffTime :: CandlestickGranularity -> NominalDiffTime
+ OANDA.Instrument: instance Data.Aeson.Types.FromJSON.FromJSON OANDA.Instrument.Candlestick
+ OANDA.Instrument: instance Data.Aeson.Types.FromJSON.FromJSON OANDA.Instrument.CandlestickData
+ OANDA.Instrument: instance Data.Aeson.Types.FromJSON.FromJSON OANDA.Instrument.CandlestickGranularity
+ OANDA.Instrument: instance Data.Aeson.Types.FromJSON.FromJSON OANDA.Instrument.CandlestickResponse
+ OANDA.Instrument: instance Data.Aeson.Types.FromJSON.FromJSON OANDA.Instrument.PriceValue
+ OANDA.Instrument: instance Data.Aeson.Types.ToJSON.ToJSON OANDA.Instrument.Candlestick
+ OANDA.Instrument: instance Data.Aeson.Types.ToJSON.ToJSON OANDA.Instrument.CandlestickData
+ OANDA.Instrument: instance Data.Aeson.Types.ToJSON.ToJSON OANDA.Instrument.CandlestickGranularity
+ OANDA.Instrument: instance Data.Aeson.Types.ToJSON.ToJSON OANDA.Instrument.CandlestickResponse
+ OANDA.Instrument: instance Data.Aeson.Types.ToJSON.ToJSON OANDA.Instrument.PriceValue
+ OANDA.Instrument: instance GHC.Show.Show OANDA.Instrument.Candlestick
+ OANDA.Instrument: instance GHC.Show.Show OANDA.Instrument.CandlestickData
+ OANDA.Instrument: instance GHC.Show.Show OANDA.Instrument.CandlestickGranularity
+ OANDA.Instrument: instance GHC.Show.Show OANDA.Instrument.CandlestickResponse
+ OANDA.Instrument: instance GHC.Show.Show OANDA.Instrument.PriceValue
+ OANDA.Instrument: instance GHC.Show.Show OANDA.Instrument.WeeklyAlignment
+ OANDA.Instrument: newtype PriceValue
+ OANDA.Instrument: oandaCandles :: OandaEnv -> CandlestickArgs -> OANDARequest CandlestickResponse
+ OANDA.Orders: CreateOrderResponse :: Transaction -> Maybe Transaction -> Maybe Transaction -> Maybe Transaction -> Maybe Transaction -> [TransactionID] -> TransactionID -> CreateOrderResponse
+ OANDA.Orders: OrderRequest :: OrderType -> Maybe ClientExtensions -> Maybe InstrumentName -> Maybe Decimal -> Maybe TimeInForce -> Maybe PriceValue -> Maybe PriceValue -> Maybe OrderPositionFill -> Maybe TradeID -> Maybe Text -> Maybe PriceValue -> Maybe TakeProfitDetails -> Maybe StopLossDetails -> Maybe TrailingStopLossDetails -> Maybe ClientExtensions -> Maybe ZonedTime -> OrderRequest
+ OANDA.Orders: OrdersArgs :: Maybe [OrderID] -> Maybe OrderState -> Maybe InstrumentName -> Maybe Int -> Maybe OrderID -> OrdersArgs
+ OANDA.Orders: OrdersResponse :: [Order] -> TransactionID -> OrdersResponse
+ OANDA.Orders: [_orderRequestClientExtensions] :: OrderRequest -> Maybe ClientExtensions
+ OANDA.Orders: [_orderRequestClientTradeID] :: OrderRequest -> Maybe Text
+ OANDA.Orders: [_orderRequestDistance] :: OrderRequest -> Maybe PriceValue
+ OANDA.Orders: [_orderRequestGtdTime] :: OrderRequest -> Maybe ZonedTime
+ OANDA.Orders: [_orderRequestInstrument] :: OrderRequest -> Maybe InstrumentName
+ OANDA.Orders: [_orderRequestPositionFill] :: OrderRequest -> Maybe OrderPositionFill
+ OANDA.Orders: [_orderRequestPriceBound] :: OrderRequest -> Maybe PriceValue
+ OANDA.Orders: [_orderRequestPrice] :: OrderRequest -> Maybe PriceValue
+ OANDA.Orders: [_orderRequestStopLossOnFill] :: OrderRequest -> Maybe StopLossDetails
+ OANDA.Orders: [_orderRequestTakeProfitOnFill] :: OrderRequest -> Maybe TakeProfitDetails
+ OANDA.Orders: [_orderRequestTimeInForce] :: OrderRequest -> Maybe TimeInForce
+ OANDA.Orders: [_orderRequestTradeClientExtensions] :: OrderRequest -> Maybe ClientExtensions
+ OANDA.Orders: [_orderRequestTradeID] :: OrderRequest -> Maybe TradeID
+ OANDA.Orders: [_orderRequestTrailingStopLossOnFill] :: OrderRequest -> Maybe TrailingStopLossDetails
+ OANDA.Orders: [_orderRequestType] :: OrderRequest -> OrderType
+ OANDA.Orders: [_orderRequestUnits] :: OrderRequest -> Maybe Decimal
+ OANDA.Orders: [_ordersArgsBeforeID] :: OrdersArgs -> Maybe OrderID
+ OANDA.Orders: [_ordersArgsCount] :: OrdersArgs -> Maybe Int
+ OANDA.Orders: [_ordersArgsIds] :: OrdersArgs -> Maybe [OrderID]
+ OANDA.Orders: [_ordersArgsInstrument] :: OrdersArgs -> Maybe InstrumentName
+ OANDA.Orders: [_ordersArgsState] :: OrdersArgs -> Maybe OrderState
+ OANDA.Orders: [createOrderResponseLastTransactionID] :: CreateOrderResponse -> TransactionID
+ OANDA.Orders: [createOrderResponseOrderCancelTransaction] :: CreateOrderResponse -> Maybe Transaction
+ OANDA.Orders: [createOrderResponseOrderCreateTransaction] :: CreateOrderResponse -> Transaction
+ OANDA.Orders: [createOrderResponseOrderFillTransaction] :: CreateOrderResponse -> Maybe Transaction
+ OANDA.Orders: [createOrderResponseOrderReissueRejectTransaction] :: CreateOrderResponse -> Maybe Transaction
+ OANDA.Orders: [createOrderResponseOrderReissueTransaction] :: CreateOrderResponse -> Maybe Transaction
+ OANDA.Orders: [createOrderResponseRelatedTransactionIDs] :: CreateOrderResponse -> [TransactionID]
+ OANDA.Orders: [orderCancelledTime] :: Order -> Maybe OandaZonedTime
+ OANDA.Orders: [orderCancellingTransactionID] :: Order -> Maybe TransactionID
+ OANDA.Orders: [orderClientExtensions] :: Order -> Maybe ClientExtensions
+ OANDA.Orders: [orderClientTradeID] :: Order -> Maybe Text
+ OANDA.Orders: [orderCreateTime] :: Order -> OandaZonedTime
+ OANDA.Orders: [orderDelayedTradeClose] :: Order -> Maybe MarketOrderDelayedTradeClose
+ OANDA.Orders: [orderDistance] :: Order -> Maybe PriceValue
+ OANDA.Orders: [orderFilledTime] :: Order -> Maybe OandaZonedTime
+ OANDA.Orders: [orderFillingTransactionID] :: Order -> Maybe TransactionID
+ OANDA.Orders: [orderGtdTime] :: Order -> Maybe OandaZonedTime
+ OANDA.Orders: [orderInitialMarketPrice] :: Order -> Maybe PriceValue
+ OANDA.Orders: [orderLongPositionCloseout] :: Order -> Maybe MarketOrderPositionCloseout
+ OANDA.Orders: [orderMarginCloseout] :: Order -> Maybe MarketOrderMarginCloseout
+ OANDA.Orders: [orderPositionFill] :: Order -> Maybe OrderPositionFill
+ OANDA.Orders: [orderPriceBound] :: Order -> Maybe PriceValue
+ OANDA.Orders: [orderReplacedByOrderID] :: Order -> Maybe OrderID
+ OANDA.Orders: [orderReplacesOrderID] :: Order -> Maybe OrderID
+ OANDA.Orders: [orderShortPositionCloseout] :: Order -> Maybe MarketOrderPositionCloseout
+ OANDA.Orders: [orderState] :: Order -> OrderState
+ OANDA.Orders: [orderStopLossOnFill] :: Order -> Maybe StopLossDetails
+ OANDA.Orders: [orderTakeProfitOnFill] :: Order -> Maybe TakeProfitDetails
+ OANDA.Orders: [orderTimeInForce] :: Order -> Maybe TimeInForce
+ OANDA.Orders: [orderTradeClientExtensions] :: Order -> Maybe ClientExtensions
+ OANDA.Orders: [orderTradeClose] :: Order -> Maybe MarketOrderTradeClose
+ OANDA.Orders: [orderTradeClosedIDs] :: Order -> Maybe [TradeID]
+ OANDA.Orders: [orderTradeID] :: Order -> Maybe TradeID
+ OANDA.Orders: [orderTradeOpenedID] :: Order -> Maybe TradeID
+ OANDA.Orders: [orderTradeReducedID] :: Order -> Maybe TradeID
+ OANDA.Orders: [orderTrailingStopLossOnFill] :: Order -> Maybe TrailingStopLossDetails
+ OANDA.Orders: [ordersResponseLastTransactionID] :: OrdersResponse -> TransactionID
+ OANDA.Orders: [ordersResponseOrders] :: OrdersResponse -> [Order]
+ OANDA.Orders: data CreateOrderResponse
+ OANDA.Orders: data OrderRequest
+ OANDA.Orders: data OrdersArgs
+ OANDA.Orders: data OrdersResponse
+ OANDA.Orders: instance Data.Aeson.Types.FromJSON.FromJSON OANDA.Orders.CreateOrderResponse
+ OANDA.Orders: instance Data.Aeson.Types.FromJSON.FromJSON OANDA.Orders.OrderRequest
+ OANDA.Orders: instance Data.Aeson.Types.FromJSON.FromJSON OANDA.Orders.OrdersResponse
+ OANDA.Orders: instance Data.Aeson.Types.ToJSON.ToJSON OANDA.Orders.CreateOrderResponse
+ OANDA.Orders: instance Data.Aeson.Types.ToJSON.ToJSON OANDA.Orders.Order
+ OANDA.Orders: instance Data.Aeson.Types.ToJSON.ToJSON OANDA.Orders.OrderRequest
+ OANDA.Orders: instance Data.Aeson.Types.ToJSON.ToJSON OANDA.Orders.OrdersResponse
+ OANDA.Orders: instance GHC.Show.Show OANDA.Orders.CreateOrderResponse
+ OANDA.Orders: instance GHC.Show.Show OANDA.Orders.OrderRequest
+ OANDA.Orders: instance GHC.Show.Show OANDA.Orders.OrdersArgs
+ OANDA.Orders: instance GHC.Show.Show OANDA.Orders.OrdersResponse
+ OANDA.Orders: oandaCreateOrder :: OandaEnv -> AccountID -> OrderRequest -> OANDARequest CreateOrderResponse
+ OANDA.Orders: oandaOrders :: OandaEnv -> AccountID -> OrdersArgs -> OANDARequest OrdersResponse
+ OANDA.Orders: orderRequest :: OrderType -> OrderRequest
+ OANDA.Orders: orderRequestClientExtensions :: Lens' OrderRequest (Maybe ClientExtensions)
+ OANDA.Orders: orderRequestClientTradeID :: Lens' OrderRequest (Maybe Text)
+ OANDA.Orders: orderRequestDistance :: Lens' OrderRequest (Maybe PriceValue)
+ OANDA.Orders: orderRequestGtdTime :: Lens' OrderRequest (Maybe ZonedTime)
+ OANDA.Orders: orderRequestInstrument :: Lens' OrderRequest (Maybe InstrumentName)
+ OANDA.Orders: orderRequestPositionFill :: Lens' OrderRequest (Maybe OrderPositionFill)
+ OANDA.Orders: orderRequestPrice :: Lens' OrderRequest (Maybe PriceValue)
+ OANDA.Orders: orderRequestPriceBound :: Lens' OrderRequest (Maybe PriceValue)
+ OANDA.Orders: orderRequestStopLossOnFill :: Lens' OrderRequest (Maybe StopLossDetails)
+ OANDA.Orders: orderRequestTakeProfitOnFill :: Lens' OrderRequest (Maybe TakeProfitDetails)
+ OANDA.Orders: orderRequestTimeInForce :: Lens' OrderRequest (Maybe TimeInForce)
+ OANDA.Orders: orderRequestTradeClientExtensions :: Lens' OrderRequest (Maybe ClientExtensions)
+ OANDA.Orders: orderRequestTradeID :: Lens' OrderRequest (Maybe TradeID)
+ OANDA.Orders: orderRequestTrailingStopLossOnFill :: Lens' OrderRequest (Maybe TrailingStopLossDetails)
+ OANDA.Orders: orderRequestType :: Lens' OrderRequest OrderType
+ OANDA.Orders: orderRequestUnits :: Lens' OrderRequest (Maybe Decimal)
+ OANDA.Orders: ordersArgs :: OrdersArgs
+ OANDA.Orders: ordersArgsBeforeID :: Lens' OrdersArgs (Maybe OrderID)
+ OANDA.Orders: ordersArgsCount :: Lens' OrdersArgs (Maybe Int)
+ OANDA.Orders: ordersArgsIds :: Lens' OrdersArgs (Maybe [OrderID])
+ OANDA.Orders: ordersArgsInstrument :: Lens' OrdersArgs (Maybe InstrumentName)
+ OANDA.Orders: ordersArgsState :: Lens' OrdersArgs (Maybe OrderState)
+ OANDA.Pricing: Price :: InstrumentName -> OandaZonedTime -> Text -> [PriceBucket] -> [PriceBucket] -> PriceValue -> PriceValue -> Price
+ OANDA.Pricing: PriceBucket :: PriceValue -> Integer -> PriceBucket
+ OANDA.Pricing: PricingArgs :: [InstrumentName] -> Maybe ZonedTime -> PricingArgs
+ OANDA.Pricing: PricingHeartbeat :: OandaZonedTime -> PricingHeartbeat
+ OANDA.Pricing: PricingResponse :: [Price] -> PricingResponse
+ OANDA.Pricing: PricingStreamArgs :: [InstrumentName] -> Maybe Bool -> PricingStreamArgs
+ OANDA.Pricing: StreamPrice :: Price -> PricingStreamResponse
+ OANDA.Pricing: StreamPricingHeartbeat :: PricingHeartbeat -> PricingStreamResponse
+ OANDA.Pricing: [_pricingArgsInstruments] :: PricingArgs -> [InstrumentName]
+ OANDA.Pricing: [_pricingArgsSince] :: PricingArgs -> Maybe ZonedTime
+ OANDA.Pricing: [_pricingStreamArgsInstruments] :: PricingStreamArgs -> [InstrumentName]
+ OANDA.Pricing: [_pricingStreamArgsSnapshot] :: PricingStreamArgs -> Maybe Bool
+ OANDA.Pricing: [priceAsks] :: Price -> [PriceBucket]
+ OANDA.Pricing: [priceBids] :: Price -> [PriceBucket]
+ OANDA.Pricing: [priceBucketLiquidity] :: PriceBucket -> Integer
+ OANDA.Pricing: [priceBucketPrice] :: PriceBucket -> PriceValue
+ OANDA.Pricing: [priceCloseoutAsk] :: Price -> PriceValue
+ OANDA.Pricing: [priceCloseoutBid] :: Price -> PriceValue
+ OANDA.Pricing: [priceInstrument] :: Price -> InstrumentName
+ OANDA.Pricing: [priceStatus] :: Price -> Text
+ OANDA.Pricing: [priceTime] :: Price -> OandaZonedTime
+ OANDA.Pricing: [pricingHeartbeatTime] :: PricingHeartbeat -> OandaZonedTime
+ OANDA.Pricing: [pricingResponsePrices] :: PricingResponse -> [Price]
+ OANDA.Pricing: data Price
+ OANDA.Pricing: data PriceBucket
+ OANDA.Pricing: data PricingArgs
+ OANDA.Pricing: data PricingHeartbeat
+ OANDA.Pricing: data PricingResponse
+ OANDA.Pricing: data PricingStreamArgs
+ OANDA.Pricing: data PricingStreamResponse
+ OANDA.Pricing: instance Data.Aeson.Types.FromJSON.FromJSON OANDA.Pricing.Price
+ OANDA.Pricing: instance Data.Aeson.Types.FromJSON.FromJSON OANDA.Pricing.PriceBucket
+ OANDA.Pricing: instance Data.Aeson.Types.FromJSON.FromJSON OANDA.Pricing.PricingHeartbeat
+ OANDA.Pricing: instance Data.Aeson.Types.FromJSON.FromJSON OANDA.Pricing.PricingResponse
+ OANDA.Pricing: instance Data.Aeson.Types.FromJSON.FromJSON OANDA.Pricing.PricingStreamResponse
+ OANDA.Pricing: instance Data.Aeson.Types.ToJSON.ToJSON OANDA.Pricing.Price
+ OANDA.Pricing: instance Data.Aeson.Types.ToJSON.ToJSON OANDA.Pricing.PriceBucket
+ OANDA.Pricing: instance Data.Aeson.Types.ToJSON.ToJSON OANDA.Pricing.PricingHeartbeat
+ OANDA.Pricing: instance Data.Aeson.Types.ToJSON.ToJSON OANDA.Pricing.PricingResponse
+ OANDA.Pricing: instance Data.Aeson.Types.ToJSON.ToJSON OANDA.Pricing.PricingStreamResponse
+ OANDA.Pricing: instance GHC.Show.Show OANDA.Pricing.Price
+ OANDA.Pricing: instance GHC.Show.Show OANDA.Pricing.PriceBucket
+ OANDA.Pricing: instance GHC.Show.Show OANDA.Pricing.PricingArgs
+ OANDA.Pricing: instance GHC.Show.Show OANDA.Pricing.PricingHeartbeat
+ OANDA.Pricing: instance GHC.Show.Show OANDA.Pricing.PricingResponse
+ OANDA.Pricing: instance GHC.Show.Show OANDA.Pricing.PricingStreamArgs
+ OANDA.Pricing: instance GHC.Show.Show OANDA.Pricing.PricingStreamResponse
+ OANDA.Pricing: oandaPricing :: OandaEnv -> AccountID -> PricingArgs -> OANDARequest PricingResponse
+ OANDA.Pricing: oandaPricingStream :: OandaEnv -> AccountID -> PricingStreamArgs -> OANDAStreamingRequest PricingStreamResponse
+ OANDA.Pricing: pricingArgs :: [InstrumentName] -> PricingArgs
+ OANDA.Pricing: pricingArgsInstruments :: Lens' PricingArgs [InstrumentName]
+ OANDA.Pricing: pricingArgsSince :: Lens' PricingArgs (Maybe ZonedTime)
+ OANDA.Pricing: pricingStreamArgs :: [InstrumentName] -> PricingStreamArgs
+ OANDA.Pricing: pricingStreamArgsInstruments :: Lens' PricingStreamArgs [InstrumentName]
+ OANDA.Pricing: pricingStreamArgsSnapshot :: Lens' PricingStreamArgs (Maybe Bool)
+ OANDA.Transactions: CANCELLED :: OrderState
+ OANDA.Transactions: CLIENT_CONFIGURE :: TransactionType
+ OANDA.Transactions: CLIENT_CONFIGURE_REJECT :: TransactionType
+ OANDA.Transactions: CLOSE :: TransactionType
+ OANDA.Transactions: CREATE :: TransactionType
+ OANDA.Transactions: ClientExtensions :: Text -> Text -> Text -> ClientExtensions
+ OANDA.Transactions: DAILY_FINANCING :: TransactionType
+ OANDA.Transactions: DELAYED_TRADE_CLOSURE :: TransactionType
+ OANDA.Transactions: FILLED :: OrderState
+ OANDA.Transactions: FOK :: TimeInForce
+ OANDA.Transactions: GFD :: TimeInForce
+ OANDA.Transactions: GTC :: TimeInForce
+ OANDA.Transactions: GTD :: TimeInForce
+ OANDA.Transactions: IOC :: TimeInForce
+ OANDA.Transactions: LIMIT :: OrderType
+ OANDA.Transactions: LIMIT_ORDER :: TransactionType
+ OANDA.Transactions: LIMIT_ORDER_REJECT :: TransactionType
+ OANDA.Transactions: MARGIN_CALL_ENTER :: TransactionType
+ OANDA.Transactions: MARGIN_CALL_EXIT :: TransactionType
+ OANDA.Transactions: MARGIN_CALL_EXTEND :: TransactionType
+ OANDA.Transactions: MARKET :: OrderType
+ OANDA.Transactions: MARKET_IF_TOUCHED :: OrderType
+ OANDA.Transactions: MARKET_IF_TOUCHED_ORDER :: TransactionType
+ OANDA.Transactions: MARKET_IF_TOUCHED_ORDER_REJECT :: TransactionType
+ OANDA.Transactions: MARKET_ORDER :: TransactionType
+ OANDA.Transactions: MARKET_ORDER_REJECT :: TransactionType
+ OANDA.Transactions: MarketOrderDelayedTradeClose :: TradeID -> Text -> TransactionID -> MarketOrderDelayedTradeClose
+ OANDA.Transactions: MarketOrderMarginCloseout :: Text -> MarketOrderMarginCloseout
+ OANDA.Transactions: MarketOrderPositionCloseout :: InstrumentName -> Text -> MarketOrderPositionCloseout
+ OANDA.Transactions: MarketOrderTradeClose :: TradeID -> Text -> Text -> MarketOrderTradeClose
+ OANDA.Transactions: OPEN_ONLY :: OrderPositionFill
+ OANDA.Transactions: ORDER_CANCEL :: TransactionType
+ OANDA.Transactions: ORDER_CANCEL_REJECT :: TransactionType
+ OANDA.Transactions: ORDER_CLIENT_EXTENSIONS_MODIFY :: TransactionType
+ OANDA.Transactions: ORDER_CLIENT_EXTENSIONS_MODIFY_REJECT :: TransactionType
+ OANDA.Transactions: ORDER_FILL :: TransactionType
+ OANDA.Transactions: OpenTradeFinancing :: TradeID -> AccountUnits -> OpenTradeFinancing
+ OANDA.Transactions: OrderID :: Int -> OrderID
+ OANDA.Transactions: PENDING :: OrderState
+ OANDA.Transactions: POSITION_DEFAULT :: OrderPositionFill
+ OANDA.Transactions: PositionFinancing :: InstrumentName -> AccountUnits -> [OpenTradeFinancing] -> PositionFinancing
+ OANDA.Transactions: REDUCE_FIRST :: OrderPositionFill
+ OANDA.Transactions: REDUCE_ONLY :: OrderPositionFill
+ OANDA.Transactions: REOPEN :: TransactionType
+ OANDA.Transactions: RESET_RESETTABLE_PL :: TransactionType
+ OANDA.Transactions: STOP :: OrderType
+ OANDA.Transactions: STOP_LOSS :: OrderType
+ OANDA.Transactions: STOP_LOSS_ORDER :: TransactionType
+ OANDA.Transactions: STOP_LOSS_ORDER_REJECT :: TransactionType
+ OANDA.Transactions: STOP_ORDER :: TransactionType
+ OANDA.Transactions: STOP_ORDER_REJECT :: TransactionType
+ OANDA.Transactions: StopLossDetails :: Text -> TimeInForce -> OandaZonedTime -> Maybe ClientExtensions -> StopLossDetails
+ OANDA.Transactions: StreamTransaction :: Transaction -> TransactionsStreamResponse
+ OANDA.Transactions: StreamTransactionHeartbeat :: TransactionHeartbeat -> TransactionsStreamResponse
+ OANDA.Transactions: TAKE_PROFIT :: OrderType
+ OANDA.Transactions: TAKE_PROFIT_ORDER :: TransactionType
+ OANDA.Transactions: TAKE_PROFIT_ORDER_REJECT :: TransactionType
+ OANDA.Transactions: TRADE_CLIENT_EXTENSIONS_MODIFY :: TransactionType
+ OANDA.Transactions: TRADE_CLIENT_EXTENSIONS_MODIFY_REJECT :: TransactionType
+ OANDA.Transactions: TRAILING_STOP_LOSS :: OrderType
+ OANDA.Transactions: TRAILING_STOP_LOSS_ORDER :: TransactionType
+ OANDA.Transactions: TRAILING_STOP_LOSS_ORDER_REJECT :: TransactionType
+ OANDA.Transactions: TRANSFER_FUNDS :: TransactionType
+ OANDA.Transactions: TRANSFER_FUNDS_REJECT :: TransactionType
+ OANDA.Transactions: TRIGGERED :: OrderState
+ OANDA.Transactions: TakeProfitDetails :: Text -> TimeInForce -> OandaZonedTime -> Maybe ClientExtensions -> TakeProfitDetails
+ OANDA.Transactions: TradeID :: Int -> TradeID
+ OANDA.Transactions: TradeOpen :: TradeID -> Decimal -> Maybe ClientExtensions -> TradeOpen
+ OANDA.Transactions: TradeReduce :: TradeID -> Decimal -> AccountUnits -> AccountUnits -> TradeReduce
+ OANDA.Transactions: TrailingStopLossDetails :: Text -> TimeInForce -> OandaZonedTime -> Maybe ClientExtensions -> TrailingStopLossDetails
+ OANDA.Transactions: TransactionHeartbeat :: TransactionID -> OandaZonedTime -> TransactionHeartbeat
+ OANDA.Transactions: TransactionID :: Int -> TransactionID
+ OANDA.Transactions: TransactionsSinceIDResponse :: [Transaction] -> TransactionID -> TransactionsSinceIDResponse
+ OANDA.Transactions: [clientExtensionsComment] :: ClientExtensions -> Text
+ OANDA.Transactions: [clientExtensionsID] :: ClientExtensions -> Text
+ OANDA.Transactions: [clientExtensionsTag] :: ClientExtensions -> Text
+ OANDA.Transactions: [marketOrderDelayedTradeCloseClientTradeID] :: MarketOrderDelayedTradeClose -> Text
+ OANDA.Transactions: [marketOrderDelayedTradeCloseSourceTransactionID] :: MarketOrderDelayedTradeClose -> TransactionID
+ OANDA.Transactions: [marketOrderDelayedTradeCloseTradeID] :: MarketOrderDelayedTradeClose -> TradeID
+ OANDA.Transactions: [marketOrderMarginCloseoutReason] :: MarketOrderMarginCloseout -> Text
+ OANDA.Transactions: [marketOrderPositionCloseoutInstrument] :: MarketOrderPositionCloseout -> InstrumentName
+ OANDA.Transactions: [marketOrderPositionCloseoutUnits] :: MarketOrderPositionCloseout -> Text
+ OANDA.Transactions: [marketOrderTradeCloseClientTradeID] :: MarketOrderTradeClose -> Text
+ OANDA.Transactions: [marketOrderTradeCloseTradeID] :: MarketOrderTradeClose -> TradeID
+ OANDA.Transactions: [marketOrderTradeCloseUnits] :: MarketOrderTradeClose -> Text
+ OANDA.Transactions: [openTradeFinancingFinancing] :: OpenTradeFinancing -> AccountUnits
+ OANDA.Transactions: [openTradeFinancingTradeID] :: OpenTradeFinancing -> TradeID
+ OANDA.Transactions: [positionFinancingFinancing] :: PositionFinancing -> AccountUnits
+ OANDA.Transactions: [positionFinancingInstrument] :: PositionFinancing -> InstrumentName
+ OANDA.Transactions: [positionFinancingOpenTradeFinancings] :: PositionFinancing -> [OpenTradeFinancing]
+ OANDA.Transactions: [stopLossDetailsClientExtensions] :: StopLossDetails -> Maybe ClientExtensions
+ OANDA.Transactions: [stopLossDetailsGtdTime] :: StopLossDetails -> OandaZonedTime
+ OANDA.Transactions: [stopLossDetailsPrice] :: StopLossDetails -> Text
+ OANDA.Transactions: [stopLossDetailsTimeInForce] :: StopLossDetails -> TimeInForce
+ OANDA.Transactions: [takeProfitDetailsClientExtensions] :: TakeProfitDetails -> Maybe ClientExtensions
+ OANDA.Transactions: [takeProfitDetailsGtdTime] :: TakeProfitDetails -> OandaZonedTime
+ OANDA.Transactions: [takeProfitDetailsPrice] :: TakeProfitDetails -> Text
+ OANDA.Transactions: [takeProfitDetailsTimeInForce] :: TakeProfitDetails -> TimeInForce
+ OANDA.Transactions: [tradeOpenClientExtensions] :: TradeOpen -> Maybe ClientExtensions
+ OANDA.Transactions: [tradeOpenTradeID] :: TradeOpen -> TradeID
+ OANDA.Transactions: [tradeOpenUnits] :: TradeOpen -> Decimal
+ OANDA.Transactions: [tradeReduceFinancing] :: TradeReduce -> AccountUnits
+ OANDA.Transactions: [tradeReduceRealizedPL] :: TradeReduce -> AccountUnits
+ OANDA.Transactions: [tradeReduceTradeID] :: TradeReduce -> TradeID
+ OANDA.Transactions: [tradeReduceUnits] :: TradeReduce -> Decimal
+ OANDA.Transactions: [trailingStopLossDetailsClientExtensions] :: TrailingStopLossDetails -> Maybe ClientExtensions
+ OANDA.Transactions: [trailingStopLossDetailsDistance] :: TrailingStopLossDetails -> Text
+ OANDA.Transactions: [trailingStopLossDetailsGtdTime] :: TrailingStopLossDetails -> OandaZonedTime
+ OANDA.Transactions: [trailingStopLossDetailsTimeInForce] :: TrailingStopLossDetails -> TimeInForce
+ OANDA.Transactions: [transactionAccountFinancingMode] :: Transaction -> Maybe Text
+ OANDA.Transactions: [transactionAccountID] :: Transaction -> AccountID
+ OANDA.Transactions: [transactionAccountNumber] :: Transaction -> Maybe Integer
+ OANDA.Transactions: [transactionAccountUserID] :: Transaction -> Maybe Integer
+ OANDA.Transactions: [transactionAlias] :: Transaction -> Maybe Text
+ OANDA.Transactions: [transactionAmount] :: Transaction -> Maybe AccountUnits
+ OANDA.Transactions: [transactionBatchID] :: Transaction -> TransactionID
+ OANDA.Transactions: [transactionClientExtensions] :: Transaction -> Maybe ClientExtensions
+ OANDA.Transactions: [transactionClientOrderID] :: Transaction -> Maybe Text
+ OANDA.Transactions: [transactionDelayedTradeClose] :: Transaction -> Maybe MarketOrderDelayedTradeClose
+ OANDA.Transactions: [transactionDistance] :: Transaction -> Maybe Text
+ OANDA.Transactions: [transactionDivisionID] :: Transaction -> Maybe Integer
+ OANDA.Transactions: [transactionExtensionNumber] :: Transaction -> Maybe Integer
+ OANDA.Transactions: [transactionFinancing] :: Transaction -> Maybe AccountUnits
+ OANDA.Transactions: [transactionFundingReason] :: Transaction -> Maybe Text
+ OANDA.Transactions: [transactionGtdTime] :: Transaction -> Maybe OandaZonedTime
+ OANDA.Transactions: [transactionHeartbeatLastTransactionID] :: TransactionHeartbeat -> TransactionID
+ OANDA.Transactions: [transactionHeartbeatTime] :: TransactionHeartbeat -> OandaZonedTime
+ OANDA.Transactions: [transactionHomeCurrency] :: Transaction -> Maybe Currency
+ OANDA.Transactions: [transactionIntendedReplacesOrderID] :: Transaction -> Maybe OrderID
+ OANDA.Transactions: [transactionLongPositionCloseout] :: Transaction -> Maybe MarketOrderPositionCloseout
+ OANDA.Transactions: [transactionMarginCloseout] :: Transaction -> Maybe MarketOrderMarginCloseout
+ OANDA.Transactions: [transactionMarginRate] :: Transaction -> Maybe Decimal
+ OANDA.Transactions: [transactionMarketOrderTradeClose] :: Transaction -> Maybe MarketOrderTradeClose
+ OANDA.Transactions: [transactionOrderID] :: Transaction -> Maybe OrderID
+ OANDA.Transactions: [transactionPl] :: Transaction -> Maybe AccountUnits
+ OANDA.Transactions: [transactionPositionFill] :: Transaction -> Maybe Text
+ OANDA.Transactions: [transactionPositionFinancings] :: Transaction -> Maybe [PositionFinancing]
+ OANDA.Transactions: [transactionPriceBound] :: Transaction -> Maybe Text
+ OANDA.Transactions: [transactionReason] :: Transaction -> Maybe Text
+ OANDA.Transactions: [transactionRejectReason] :: Transaction -> Maybe Text
+ OANDA.Transactions: [transactionReplacedOrderCancelTransactionID] :: Transaction -> Maybe TransactionID
+ OANDA.Transactions: [transactionReplacesOrderID] :: Transaction -> Maybe OrderID
+ OANDA.Transactions: [transactionShortPositionCloseout] :: Transaction -> Maybe MarketOrderPositionCloseout
+ OANDA.Transactions: [transactionSiteID] :: Transaction -> Maybe Integer
+ OANDA.Transactions: [transactionStopLossOnFill] :: Transaction -> Maybe StopLossDetails
+ OANDA.Transactions: [transactionTakeProfitOnFill] :: Transaction -> Maybe TakeProfitDetails
+ OANDA.Transactions: [transactionTimeInForce] :: Transaction -> Maybe TimeInForce
+ OANDA.Transactions: [transactionTradeClientExtensionsModify] :: Transaction -> Maybe ClientExtensions
+ OANDA.Transactions: [transactionTradeClientExtensions] :: Transaction -> Maybe ClientExtensions
+ OANDA.Transactions: [transactionTradeIDs] :: Transaction -> Maybe TradeID
+ OANDA.Transactions: [transactionTradeOpened] :: Transaction -> Maybe TradeOpen
+ OANDA.Transactions: [transactionTradeReduced] :: Transaction -> Maybe TradeReduce
+ OANDA.Transactions: [transactionTradesClosed] :: Transaction -> Maybe [TradeReduce]
+ OANDA.Transactions: [transactionTrailingStopLossOnFill] :: Transaction -> Maybe TrailingStopLossDetails
+ OANDA.Transactions: [transactionUserID] :: Transaction -> Integer
+ OANDA.Transactions: [transactionsSinceIDResponseLastTransactionID] :: TransactionsSinceIDResponse -> TransactionID
+ OANDA.Transactions: [transactionsSinceIDResponseTransactions] :: TransactionsSinceIDResponse -> [Transaction]
+ OANDA.Transactions: [unOrderID] :: OrderID -> Int
+ OANDA.Transactions: [unTradeID] :: TradeID -> Int
+ OANDA.Transactions: [unTransactionID] :: TransactionID -> Int
+ OANDA.Transactions: data ClientExtensions
+ OANDA.Transactions: data MarketOrderDelayedTradeClose
+ OANDA.Transactions: data MarketOrderMarginCloseout
+ OANDA.Transactions: data MarketOrderPositionCloseout
+ OANDA.Transactions: data MarketOrderTradeClose
+ OANDA.Transactions: data OpenTradeFinancing
+ OANDA.Transactions: data OrderPositionFill
+ OANDA.Transactions: data OrderState
+ OANDA.Transactions: data OrderType
+ OANDA.Transactions: data PositionFinancing
+ OANDA.Transactions: data StopLossDetails
+ OANDA.Transactions: data TakeProfitDetails
+ OANDA.Transactions: data TimeInForce
+ OANDA.Transactions: data TradeOpen
+ OANDA.Transactions: data TradeReduce
+ OANDA.Transactions: data TrailingStopLossDetails
+ OANDA.Transactions: data TransactionHeartbeat
+ OANDA.Transactions: data TransactionType
+ OANDA.Transactions: data TransactionsSinceIDResponse
+ OANDA.Transactions: data TransactionsStreamResponse
+ OANDA.Transactions: instance Data.Aeson.Types.FromJSON.FromJSON OANDA.Transactions.ClientExtensions
+ OANDA.Transactions: instance Data.Aeson.Types.FromJSON.FromJSON OANDA.Transactions.MarketOrderDelayedTradeClose
+ OANDA.Transactions: instance Data.Aeson.Types.FromJSON.FromJSON OANDA.Transactions.MarketOrderMarginCloseout
+ OANDA.Transactions: instance Data.Aeson.Types.FromJSON.FromJSON OANDA.Transactions.MarketOrderPositionCloseout
+ OANDA.Transactions: instance Data.Aeson.Types.FromJSON.FromJSON OANDA.Transactions.MarketOrderTradeClose
+ OANDA.Transactions: instance Data.Aeson.Types.FromJSON.FromJSON OANDA.Transactions.OpenTradeFinancing
+ OANDA.Transactions: instance Data.Aeson.Types.FromJSON.FromJSON OANDA.Transactions.OrderID
+ OANDA.Transactions: instance Data.Aeson.Types.FromJSON.FromJSON OANDA.Transactions.OrderPositionFill
+ OANDA.Transactions: instance Data.Aeson.Types.FromJSON.FromJSON OANDA.Transactions.OrderState
+ OANDA.Transactions: instance Data.Aeson.Types.FromJSON.FromJSON OANDA.Transactions.OrderType
+ OANDA.Transactions: instance Data.Aeson.Types.FromJSON.FromJSON OANDA.Transactions.PositionFinancing
+ OANDA.Transactions: instance Data.Aeson.Types.FromJSON.FromJSON OANDA.Transactions.StopLossDetails
+ OANDA.Transactions: instance Data.Aeson.Types.FromJSON.FromJSON OANDA.Transactions.TakeProfitDetails
+ OANDA.Transactions: instance Data.Aeson.Types.FromJSON.FromJSON OANDA.Transactions.TimeInForce
+ OANDA.Transactions: instance Data.Aeson.Types.FromJSON.FromJSON OANDA.Transactions.TradeID
+ OANDA.Transactions: instance Data.Aeson.Types.FromJSON.FromJSON OANDA.Transactions.TradeOpen
+ OANDA.Transactions: instance Data.Aeson.Types.FromJSON.FromJSON OANDA.Transactions.TradeReduce
+ OANDA.Transactions: instance Data.Aeson.Types.FromJSON.FromJSON OANDA.Transactions.TrailingStopLossDetails
+ OANDA.Transactions: instance Data.Aeson.Types.FromJSON.FromJSON OANDA.Transactions.TransactionHeartbeat
+ OANDA.Transactions: instance Data.Aeson.Types.FromJSON.FromJSON OANDA.Transactions.TransactionID
+ OANDA.Transactions: instance Data.Aeson.Types.FromJSON.FromJSON OANDA.Transactions.TransactionType
+ OANDA.Transactions: instance Data.Aeson.Types.FromJSON.FromJSON OANDA.Transactions.TransactionsSinceIDResponse
+ OANDA.Transactions: instance Data.Aeson.Types.FromJSON.FromJSON OANDA.Transactions.TransactionsStreamResponse
+ OANDA.Transactions: instance Data.Aeson.Types.ToJSON.ToJSON OANDA.Transactions.ClientExtensions
+ OANDA.Transactions: instance Data.Aeson.Types.ToJSON.ToJSON OANDA.Transactions.MarketOrderDelayedTradeClose
+ OANDA.Transactions: instance Data.Aeson.Types.ToJSON.ToJSON OANDA.Transactions.MarketOrderMarginCloseout
+ OANDA.Transactions: instance Data.Aeson.Types.ToJSON.ToJSON OANDA.Transactions.MarketOrderPositionCloseout
+ OANDA.Transactions: instance Data.Aeson.Types.ToJSON.ToJSON OANDA.Transactions.MarketOrderTradeClose
+ OANDA.Transactions: instance Data.Aeson.Types.ToJSON.ToJSON OANDA.Transactions.OpenTradeFinancing
+ OANDA.Transactions: instance Data.Aeson.Types.ToJSON.ToJSON OANDA.Transactions.OrderID
+ OANDA.Transactions: instance Data.Aeson.Types.ToJSON.ToJSON OANDA.Transactions.OrderPositionFill
+ OANDA.Transactions: instance Data.Aeson.Types.ToJSON.ToJSON OANDA.Transactions.OrderState
+ OANDA.Transactions: instance Data.Aeson.Types.ToJSON.ToJSON OANDA.Transactions.OrderType
+ OANDA.Transactions: instance Data.Aeson.Types.ToJSON.ToJSON OANDA.Transactions.PositionFinancing
+ OANDA.Transactions: instance Data.Aeson.Types.ToJSON.ToJSON OANDA.Transactions.StopLossDetails
+ OANDA.Transactions: instance Data.Aeson.Types.ToJSON.ToJSON OANDA.Transactions.TakeProfitDetails
+ OANDA.Transactions: instance Data.Aeson.Types.ToJSON.ToJSON OANDA.Transactions.TimeInForce
+ OANDA.Transactions: instance Data.Aeson.Types.ToJSON.ToJSON OANDA.Transactions.TradeID
+ OANDA.Transactions: instance Data.Aeson.Types.ToJSON.ToJSON OANDA.Transactions.TradeOpen
+ OANDA.Transactions: instance Data.Aeson.Types.ToJSON.ToJSON OANDA.Transactions.TradeReduce
+ OANDA.Transactions: instance Data.Aeson.Types.ToJSON.ToJSON OANDA.Transactions.TrailingStopLossDetails
+ OANDA.Transactions: instance Data.Aeson.Types.ToJSON.ToJSON OANDA.Transactions.Transaction
+ OANDA.Transactions: instance Data.Aeson.Types.ToJSON.ToJSON OANDA.Transactions.TransactionHeartbeat
+ OANDA.Transactions: instance Data.Aeson.Types.ToJSON.ToJSON OANDA.Transactions.TransactionID
+ OANDA.Transactions: instance Data.Aeson.Types.ToJSON.ToJSON OANDA.Transactions.TransactionType
+ OANDA.Transactions: instance Data.Aeson.Types.ToJSON.ToJSON OANDA.Transactions.TransactionsSinceIDResponse
+ OANDA.Transactions: instance Data.Aeson.Types.ToJSON.ToJSON OANDA.Transactions.TransactionsStreamResponse
+ OANDA.Transactions: instance GHC.Classes.Eq OANDA.Transactions.OrderID
+ OANDA.Transactions: instance GHC.Classes.Eq OANDA.Transactions.OrderPositionFill
+ OANDA.Transactions: instance GHC.Classes.Eq OANDA.Transactions.OrderState
+ OANDA.Transactions: instance GHC.Classes.Eq OANDA.Transactions.OrderType
+ OANDA.Transactions: instance GHC.Classes.Eq OANDA.Transactions.TimeInForce
+ OANDA.Transactions: instance GHC.Classes.Eq OANDA.Transactions.TradeID
+ OANDA.Transactions: instance GHC.Classes.Eq OANDA.Transactions.TransactionID
+ OANDA.Transactions: instance GHC.Classes.Eq OANDA.Transactions.TransactionType
+ OANDA.Transactions: instance GHC.Show.Show OANDA.Transactions.ClientExtensions
+ OANDA.Transactions: instance GHC.Show.Show OANDA.Transactions.MarketOrderDelayedTradeClose
+ OANDA.Transactions: instance GHC.Show.Show OANDA.Transactions.MarketOrderMarginCloseout
+ OANDA.Transactions: instance GHC.Show.Show OANDA.Transactions.MarketOrderPositionCloseout
+ OANDA.Transactions: instance GHC.Show.Show OANDA.Transactions.MarketOrderTradeClose
+ OANDA.Transactions: instance GHC.Show.Show OANDA.Transactions.OpenTradeFinancing
+ OANDA.Transactions: instance GHC.Show.Show OANDA.Transactions.OrderID
+ OANDA.Transactions: instance GHC.Show.Show OANDA.Transactions.OrderPositionFill
+ OANDA.Transactions: instance GHC.Show.Show OANDA.Transactions.OrderState
+ OANDA.Transactions: instance GHC.Show.Show OANDA.Transactions.OrderType
+ OANDA.Transactions: instance GHC.Show.Show OANDA.Transactions.PositionFinancing
+ OANDA.Transactions: instance GHC.Show.Show OANDA.Transactions.StopLossDetails
+ OANDA.Transactions: instance GHC.Show.Show OANDA.Transactions.TakeProfitDetails
+ OANDA.Transactions: instance GHC.Show.Show OANDA.Transactions.TimeInForce
+ OANDA.Transactions: instance GHC.Show.Show OANDA.Transactions.TradeID
+ OANDA.Transactions: instance GHC.Show.Show OANDA.Transactions.TradeOpen
+ OANDA.Transactions: instance GHC.Show.Show OANDA.Transactions.TradeReduce
+ OANDA.Transactions: instance GHC.Show.Show OANDA.Transactions.TrailingStopLossDetails
+ OANDA.Transactions: instance GHC.Show.Show OANDA.Transactions.TransactionHeartbeat
+ OANDA.Transactions: instance GHC.Show.Show OANDA.Transactions.TransactionID
+ OANDA.Transactions: instance GHC.Show.Show OANDA.Transactions.TransactionType
+ OANDA.Transactions: instance GHC.Show.Show OANDA.Transactions.TransactionsSinceIDResponse
+ OANDA.Transactions: instance GHC.Show.Show OANDA.Transactions.TransactionsStreamResponse
+ OANDA.Transactions: newtype OrderID
+ OANDA.Transactions: newtype TradeID
+ OANDA.Transactions: newtype TransactionID
+ OANDA.Transactions: oandaTransaction :: OandaEnv -> AccountID -> TransactionID -> OANDARequest Transaction
+ OANDA.Transactions: oandaTransactionStream :: OandaEnv -> AccountID -> OANDAStreamingRequest TransactionsStreamResponse
+ OANDA.Transactions: oandaTransactionsSinceID :: OandaEnv -> AccountID -> TransactionID -> OANDARequest TransactionsSinceIDResponse
- OANDA.Accounts: Account :: Int -> Text -> Text -> Decimal -> Account
+ OANDA.Accounts: Account :: AccountID -> Text -> Currency -> AccountUnits -> Integer -> OandaZonedTime -> AccountUnits -> AccountUnits -> Maybe OandaZonedTime -> Decimal -> Maybe OandaZonedTime -> Maybe Integer -> Maybe OandaZonedTime -> Integer -> Integer -> Integer -> Bool -> AccountUnits -> AccountUnits -> AccountUnits -> AccountUnits -> AccountUnits -> AccountUnits -> AccountUnits -> Decimal -> AccountUnits -> AccountUnits -> Decimal -> TransactionID -> [Position] -> [Order] -> Account
- OANDA.Orders: Order :: Integer -> InstrumentText -> Integer -> Side -> Text -> ZonedTime -> Decimal -> Decimal -> Decimal -> ZonedTime -> Decimal -> Decimal -> Decimal -> Order
+ OANDA.Orders: Order :: OrderID -> OandaZonedTime -> OrderState -> Maybe ClientExtensions -> OrderType -> Maybe InstrumentName -> Maybe Decimal -> Maybe TimeInForce -> Maybe PriceValue -> Maybe PriceValue -> Maybe OrderPositionFill -> Maybe PriceValue -> Maybe MarketOrderTradeClose -> Maybe TradeID -> Maybe Text -> Maybe PriceValue -> Maybe MarketOrderPositionCloseout -> Maybe MarketOrderPositionCloseout -> Maybe MarketOrderMarginCloseout -> Maybe MarketOrderDelayedTradeClose -> Maybe TakeProfitDetails -> Maybe StopLossDetails -> Maybe TrailingStopLossDetails -> Maybe ClientExtensions -> Maybe TransactionID -> Maybe OandaZonedTime -> Maybe TradeID -> Maybe TradeID -> Maybe [TradeID] -> Maybe TransactionID -> Maybe OandaZonedTime -> Maybe OandaZonedTime -> Maybe OrderID -> Maybe OrderID -> Order
- OANDA.Orders: [orderId] :: Order -> Integer
+ OANDA.Orders: [orderId] :: Order -> OrderID
- OANDA.Orders: [orderInstrument] :: Order -> InstrumentText
+ OANDA.Orders: [orderInstrument] :: Order -> Maybe InstrumentName
- OANDA.Orders: [orderPrice] :: Order -> Decimal
+ OANDA.Orders: [orderPrice] :: Order -> Maybe PriceValue
- OANDA.Orders: [orderType] :: Order -> Text
+ OANDA.Orders: [orderType] :: Order -> OrderType
- OANDA.Orders: [orderUnits] :: Order -> Integer
+ OANDA.Orders: [orderUnits] :: Order -> Maybe Decimal
- OANDA.Transactions: Transaction :: Integer -> Integer -> ZonedTime -> String -> Maybe InstrumentText -> Maybe Side -> Maybe Decimal -> Maybe Decimal -> Maybe Decimal -> Maybe Decimal -> Maybe Decimal -> Maybe Decimal -> Maybe Decimal -> Maybe Decimal -> Maybe Decimal -> Maybe Decimal -> Transaction
+ OANDA.Transactions: Transaction :: TransactionID -> OandaZonedTime -> AccountID -> Integer -> TransactionID -> TransactionType -> Maybe Integer -> Maybe Integer -> Maybe Integer -> Maybe Integer -> Maybe Currency -> Maybe Text -> Maybe Decimal -> Maybe Text -> Maybe AccountUnits -> Maybe Text -> Maybe AccountUnits -> Maybe InstrumentText -> Maybe Decimal -> Maybe Decimal -> Maybe TimeInForce -> Maybe Text -> Maybe Text -> Maybe MarketOrderTradeClose -> Maybe MarketOrderPositionCloseout -> Maybe MarketOrderPositionCloseout -> Maybe MarketOrderMarginCloseout -> Maybe MarketOrderDelayedTradeClose -> Maybe Text -> Maybe ClientExtensions -> Maybe TakeProfitDetails -> Maybe StopLossDetails -> Maybe TrailingStopLossDetails -> Maybe ClientExtensions -> Maybe OandaZonedTime -> Maybe OrderID -> Maybe TransactionID -> Maybe OrderID -> Maybe Text -> Maybe OrderID -> Maybe Text -> Maybe AccountUnits -> Maybe AccountUnits -> Maybe TradeOpen -> Maybe [TradeReduce] -> Maybe TradeReduce -> Maybe ClientExtensions -> Maybe Integer -> Maybe TradeID -> Maybe Text -> Maybe [PositionFinancing] -> Transaction
- OANDA.Transactions: [transactionAccountBalance] :: Transaction -> Maybe Decimal
+ OANDA.Transactions: [transactionAccountBalance] :: Transaction -> Maybe AccountUnits
- OANDA.Transactions: [transactionId] :: Transaction -> Integer
+ OANDA.Transactions: [transactionId] :: Transaction -> TransactionID
- OANDA.Transactions: [transactionTime] :: Transaction -> ZonedTime
+ OANDA.Transactions: [transactionTime] :: Transaction -> OandaZonedTime
- OANDA.Transactions: [transactionType] :: Transaction -> String
+ OANDA.Transactions: [transactionType] :: Transaction -> TransactionType

Files

CHANGES.md view
@@ -1,5 +1,13 @@ # Changelog +## 0.4.0++- Migrated to the new v20 REST API++## 0.3.1++- Added endpoint to create orders+ ## 0.3.0.0  - Prefer `Text` instead of `String` for arguments. We still use `String` in
README.md view
@@ -2,19 +2,11 @@  [![Build Status](https://travis-ci.org/jdreaver/oanda-rest-api.svg)](https://travis-ci.org/jdreaver/oanda-rest-api) -This library implements Haskell client to the-[OANDA REST API](http://developer.oanda.com/rest-live/introduction/).+This library implements a Haskell client to the+[OANDA v20 REST API](http://developer.oanda.com/rest-live-v20/introduction/).  ## Status -There are still parts of the API that are not yet implemented. Here is the-status of each part of the API:--* Rates: Mostly done, just need to refactor so the parameters are cleaner.-* Accounts: Done.-* Orders: Can only get a list of open orders. Can't yet create or modify-  orders.-* Trades: Almost done, just need to add closing a trade.-* Positions: Done.-* Transaction History: Almost done. Could probably refactor the types to be-  more specific, instead of putting `Maybe` everywhere.+Right now the only methods I have implemented are the ones I currently use.+Feel free to make a PR or open an issue if there is a missing API endpoint that+you need.
oanda-rest-api.cabal view
@@ -1,9 +1,9 @@--- This file has been generated from package.yaml by hpack version 0.15.0.+-- This file has been generated from package.yaml by hpack version 0.17.0. -- -- see: https://github.com/sol/hpack  name:           oanda-rest-api-version:        0.3.0.0+version:        0.4.0 synopsis:       Client to the OANDA REST API description:    Client to the OANDA REST API category:       API@@ -30,28 +30,31 @@ library   hs-source-dirs:       src+  default-extensions: CPP GeneralizedNewtypeDeriving OverloadedStrings RecordWildCards ScopedTypeVariables TemplateHaskell TupleSections   ghc-options: -Wall   build-depends:-      base >= 4.7 && < 5+      base >= 4.8 && < 5     , aeson >= 0.8.0     , bytestring >= 0.10.0+    , conduit     , containers >= 0.5.2     , Decimal >= 0.4.2+    , http-client     , http-conduit     , lens >= 4.0     , old-locale >= 1.0.0.6+    , resourcet     , scientific >= 0.3.3.0     , text >= 1.2.0     , thyme+    , transformers     , vector >= 0.10.0   exposed-modules:       OANDA       OANDA.Accounts-      OANDA.Environment+      OANDA.Instrument       OANDA.Orders-      OANDA.Positions-      OANDA.Rates-      OANDA.Trades+      OANDA.Pricing       OANDA.Transactions   other-modules:       OANDA.Internal@@ -65,19 +68,24 @@   main-is: HLint.hs   hs-source-dirs:       tests+  default-extensions: CPP GeneralizedNewtypeDeriving OverloadedStrings RecordWildCards ScopedTypeVariables TemplateHaskell TupleSections   ghc-options: -Wall   build-depends:-      base >= 4.7 && < 5+      base >= 4.8 && < 5     , aeson >= 0.8.0     , bytestring >= 0.10.0+    , conduit     , containers >= 0.5.2     , Decimal >= 0.4.2+    , http-client     , http-conduit     , lens >= 4.0     , old-locale >= 1.0.0.6+    , resourcet     , scientific >= 0.3.3.0     , text >= 1.2.0     , thyme+    , transformers     , vector >= 0.10.0     , hlint   other-modules:@@ -89,20 +97,25 @@   main-is: Spec.hs   hs-source-dirs:       src-    , tests+      tests+  default-extensions: CPP GeneralizedNewtypeDeriving OverloadedStrings RecordWildCards ScopedTypeVariables TemplateHaskell TupleSections   ghc-options: -Wall   build-depends:-      base >= 4.7 && < 5+      base >= 4.8 && < 5     , aeson >= 0.8.0     , bytestring >= 0.10.0+    , conduit     , containers >= 0.5.2     , Decimal >= 0.4.2+    , http-client     , http-conduit     , lens >= 4.0     , old-locale >= 1.0.0.6+    , resourcet     , scientific >= 0.3.3.0     , text >= 1.2.0     , thyme+    , transformers     , vector >= 0.10.0     , oanda-rest-api     , hspec@@ -110,15 +123,13 @@   other-modules:       OANDA       OANDA.Accounts-      OANDA.Environment+      OANDA.Instrument       OANDA.Internal       OANDA.Internal.Import       OANDA.Internal.Request       OANDA.Internal.Types       OANDA.Orders-      OANDA.Positions-      OANDA.Rates-      OANDA.Trades+      OANDA.Pricing       OANDA.Transactions       HLint   default-language: Haskell2010
src/OANDA.hs view
@@ -1,11 +1,16 @@ module OANDA-    ( module X-    ) where+  ( module X+  ) where  import OANDA.Accounts as X-import OANDA.Environment as X+import OANDA.Instrument as X+import OANDA.Internal as X+  ( OANDARequest+  , makeOandaRequest+  , OANDAStreamingRequest+  , makeOandaStreamingRequest+  )+import OANDA.Internal.Types as X import OANDA.Orders as X-import OANDA.Positions as X-import OANDA.Rates as X-import OANDA.Trades as X+import OANDA.Pricing as X import OANDA.Transactions as X
src/OANDA/Accounts.hs view
@@ -1,61 +1,181 @@-{-# LANGUAGE DeriveGeneric #-}-{-# LANGUAGE OverloadedStrings #-}- -- | Defines the endpoints listed in the--- <http://developer.oanda.com/rest-live/accounts/ Accounts> section of the+-- <http://developer.oanda.com/rest-live-v20/account-ep/ Account> section of the -- API.  module OANDA.Accounts-  ( Account (..)-  , accounts-  , AccountInfo (..)-  , accountInfo+  ( AccountProperties (..)+  , oandaAccounts+  , AccountsResponse (..)+  , oandaAccountDetails+  , AccountDetailsResponse (..)+  , oandaAccountChanges+  , AccountChangesResponse (..)+  , AccountChanges (..)+  , AccountChangesState (..)+  , Account (..)+  , Position (..)+  , PositionSide (..)   ) where +import qualified Data.ByteString.Char8 as BS8 import qualified Data.Vector as V +import OANDA.Instrument import OANDA.Internal+import OANDA.Orders+import OANDA.Transactions  -- | Wraps the JSON response for accounts-data Account = Account-  { accountAccountId       :: Int-  , accountAccountName     :: Text-  , accountAccountCurrency :: Text-  , accountMarginRate      :: Decimal-  } deriving (Show, Generic)+data AccountProperties = AccountProperties+  { accountPropertiesId :: AccountID+  , accountPropertiesMt4AccountID :: Maybe Text+  , accountPropertiesTags :: [Text]+  } deriving (Show) -instance FromJSON Account where-  parseJSON = genericParseJSON $ jsonOpts "account"+deriveJSON (unPrefix "accountProperties") ''AccountProperties --- | Get all accounts for given access token-accounts :: OandaEnv -> IO (V.Vector Account)-accounts od = do-  let url = "GET " ++ baseURL od ++ "/v1/accounts"-  request <- constructRequest od url []-  jsonResponseArray request "accounts"+oandaAccounts :: OandaEnv -> OANDARequest AccountsResponse+oandaAccounts env = OANDARequest $ baseApiRequest env "GET" "/v3/accounts" +data AccountsResponse+  = AccountsResponse+  { accountsResponseAccounts :: V.Vector AccountProperties+  } deriving (Show) --- | Get all account info associated with an account ID.-accountInfo :: OandaEnv -> AccountID -> IO AccountInfo-accountInfo od (AccountID aid) = do-  let url = "GET " ++ baseURL od ++ "/v1/accounts/" ++ show aid-  request <- constructRequest od url []-  jsonResponse request+deriveJSON (unPrefix "accountsResponse") ''AccountsResponse +data PositionSide =+  PositionSide+  { positionSideUnits :: Decimal+  , positionSideAveragePrice :: Maybe PriceValue+  , positionSideTradeIDs :: Maybe [TradeID]+  , positionSidePl :: AccountUnits+  , positionSideUnrealizedPL :: Maybe AccountUnits+  , positionSideResettablePL :: Maybe AccountUnits+  } deriving (Show) -data AccountInfo = AccountInfo-  { accountInfoAccountId       :: Integer-  , accountInfoAccountName     :: Text-  , accountInfoBalance         :: Decimal-  , accountInfoUnrealizedPl    :: Decimal-  , accountInfoRealizedPl      :: Decimal-  , accountInfoMarginUsed      :: Decimal-  , accountInfoMarginAvail     :: Decimal-  , accountInfoOpenTrades      :: Integer-  , accountInfoOpenOrders      :: Integer-  , accountInfoMarginRate      :: Decimal-  , accountInfoAccountCurrency :: Text-  } deriving (Show, Generic)+deriveJSON (unPrefix "positionSide") ''PositionSide -instance FromJSON AccountInfo where-  parseJSON = genericParseJSON $ jsonOpts "accountInfo"+data Position =+  Position+  { positionInstrument :: InstrumentName+  , positionPl :: AccountUnits+  , positionUnrealizedPL :: Maybe AccountUnits+  , positionResettablePL :: Maybe AccountUnits+  , positionLong :: PositionSide+  , positionShort :: PositionSide+  } deriving (Show)++deriveJSON (unPrefix "position") ''Position++data Account =+  Account+  { accountId :: AccountID+  , accountAlias :: Text+  , accountCurrency :: Currency+  , accountBalance :: AccountUnits+  , accountCreatedByUserID :: Integer+  , accountCreatedTime :: OandaZonedTime+  , accountPl :: AccountUnits+  , accountResettablePL :: AccountUnits+  , accountResettablePLTime :: Maybe OandaZonedTime+  , accountMarginRate :: Decimal+  , accountMarginCallEnterTime :: Maybe OandaZonedTime+  , accountMarginCallExtensionCount :: Maybe Integer+  , accountLastMarginCallExtensionTime :: Maybe OandaZonedTime+  , accountOpenTradeCount :: Integer+  , accountOpenPositionCount :: Integer+  , accountPendingOrderCount :: Integer+  , accountHedgingEnabled :: Bool+  , accountUnrealizedPL :: AccountUnits+  -- TODO: accountNAV :: AccountUnits+  , accountMarginUsed :: AccountUnits+  , accountMarginAvailable :: AccountUnits+  , accountPositionValue :: AccountUnits+  , accountMarginCloseoutUnrealizedPL :: AccountUnits+  , accountMarginCloseoutNAV :: AccountUnits+  , accountMarginCloseoutMarginUsed :: AccountUnits+  , accountMarginCloseoutPercent :: Decimal+  , accountWithdrawalLimit :: AccountUnits+  , accountMarginCallMarginUsed :: AccountUnits+  , accountMarginCallPercent :: Decimal+  , accountLastTransactionID :: TransactionID+  -- TODO: accountTrades :: [TradeSummary]+  , accountPositions :: [Position]+  , accountOrders :: [Order]+  } deriving (Show)++deriveJSON (unPrefix "account") ''Account++data AccountDetailsResponse =+  AccountDetailsResponse+  { accountDetailsResponseAccount :: Account+  , accountDetailsResponseLastTransactionID :: TransactionID+  } deriving (Show)++deriveJSON (unPrefix "accountDetailsResponse") ''AccountDetailsResponse++oandaAccountDetails :: OandaEnv -> AccountID -> OANDARequest AccountDetailsResponse+oandaAccountDetails env (AccountID accountId) = OANDARequest request+  where+    request =+      baseApiRequest env "GET" ("/v3/accounts/" ++ accountId)++data AccountChanges =+  AccountChanges+  { accountChangesOrdersCreated :: [Order]+  , accountChangesOrdersCancelled :: [Order]+  , accountChangesOrdersFilled :: [Order]+  , accountChangesOrdersTriggered :: [Order]+  -- TODO: accountChangesTradesOpened :: [TradeSummary]+  -- TODO: accountChangesTradesReduced :: [TradeSummary]+  -- TODO: accountChangesTradesClosed :: [TradeSummary]+  , accountChangesPositions :: [Position]+  , accountChangesTransactions :: [Transaction]+  } deriving (Show)++deriveJSON (unPrefix "accountChanges") ''AccountChanges++data AccountChangesState =+  AccountChangesState+  { accountChangesStateUnrealizedPL :: AccountUnits+  -- TODO: accountChangesStateNAV :: AccountUnits+  , accountChangesStateMarginUsed :: AccountUnits+  , accountChangesStateMarginAvailable :: AccountUnits+  , accountChangesStatePositionValue :: AccountUnits+  , accountChangesStateMarginCloseoutUnrealizedPL :: Maybe AccountUnits+  , accountChangesStateMarginCloseoutNAV :: Maybe AccountUnits+  , accountChangesStateMarginCloseoutMarginUsed :: Maybe AccountUnits+  , accountChangesStateMarginCloseoutPercent :: Maybe Decimal+  , accountChangesStateMarginCloseoutPositionValue :: Maybe Decimal+  , accountChangesStateWithdrawalLimit :: AccountUnits+  , accountChangesStateMarginCallMarginUsed :: AccountUnits+  , accountChangesStateMarginCallPercent :: Decimal+  -- TODO: accountChangesStateOrders :: [DynamicOrderState]+  -- TODO: accountChangesStateTrades :: [CalculatedTradeState]+  -- TODO: accountChangesStatePositions :: [CalculatedPositionState]+  } deriving (Show)++deriveJSON (unPrefix "accountChangesState") ''AccountChangesState++data AccountChangesResponse =+  AccountChangesResponse+  { accountChangesResponseChanges :: AccountChanges+  , accountChangesResponseState :: AccountChangesState+  , accountChangesResponseLastTransactionID :: TransactionID+  } deriving (Show)++deriveJSON (unPrefix "accountChangesResponse") ''AccountChangesResponse++oandaAccountChanges :: OandaEnv -> AccountID -> TransactionID -> OANDARequest AccountChangesResponse+oandaAccountChanges env (AccountID accountId) (TransactionID sinceId) = OANDARequest request+  where+    request =+      baseApiRequest env "GET" ("/v3/accounts/" ++ accountId ++ "/changes")+      & setRequestQueryString params+    params = [("sinceTransactionID", Just (BS8.pack $ show sinceId))]++-- TODO:+-- GET /v3/accounts/{AccoundId}/summary+-- GET /v3/accounts/{AccoundId}/instruments+-- PATCH /v3/accounts/{AccoundId}/configuration
− src/OANDA/Environment.hs
@@ -1,17 +0,0 @@--- | Definition of types used to set up the API.--module OANDA.Environment-  ( OandaEnv-  , apiType-  , accessToken-  , sandboxAuth-  , practiceAuth-  , liveAuth-  , APIType (..)-  , AccessToken (..)-  , AccountID (..)-  , Side (..)-  , InstrumentText-  ) where--import OANDA.Internal
+ src/OANDA/Instrument.hs view
@@ -0,0 +1,207 @@+-- | Defines the endpoints listed in the+-- <http://developer.oanda.com/rest-live-v20/instrument-ep/ Instrument> section of the+-- API.++module OANDA.Instrument+  ( CandlestickGranularity (..)+  , granularityFromDiffTime+  , granularityToDiffTime+  , WeeklyAlignment (..)+  , PriceValue (..)+  , Candlestick (..)+  , CandlestickData (..)+  , CandlestickArgs (..)+  , candlestickArgsInstrument+  , candlestickArgsPrice+  , candlestickArgsGranularity+  , candlestickArgsCount+  , candlestickArgsFrom+  , candlestickArgsTo+  , candlestickArgsSmooth+  , candlestickArgsIncludeFirst+  , candlestickArgsDailyAlignment+  , candlestickArgsAlignmentTimezone+  , candlestickArgsWeeklyAlignment+  , candlestickArgs+  , oandaCandles+  , CandlestickResponse (..)+  ) where++import OANDA.Internal++data CandlestickGranularity+  = S5+  | S10+  | S15+  | S30+  | M1+  | M2+  | M4+  | M5+  | M10+  | M15+  | M30+  | H1+  | H2+  | H3+  | H4+  | H6+  | H8+  | H12+  | D+  | W+  | M+  deriving (Show)++deriveJSON defaultOptions ''CandlestickGranularity++granularityFromDiffTime :: NominalDiffTime -> Maybe CandlestickGranularity+granularityFromDiffTime = go . toSeconds'+  where+    go 5 = Just S5+    go 10 = Just S10+    go 15 = Just S15+    go 30 = Just S30+    go 60 = Just M1+    go 120 = Just M2+    go 240 = Just M4+    go 300 = Just M5+    go 600 = Just M10+    go 900 = Just M15+    go 1800 = Just M30+    go 3600 = Just H1+    go 7200 = Just H2+    go 10800 = Just H3+    go 14400 = Just H4+    go 21600 = Just H6+    go 28800 = Just H8+    go 43200 = Just H12+    go 86400 = Just D+    go 604800 = Just W+    -- go _ = Just M  -- Not well-defined for a month+    go _ = Nothing++-- | Utility function to convert Granularity to NominalDiffTime. __NOTE__: The+-- conversion from month to NominalDiffTime is not correct in general; we just+-- assume 31 days in a month, which is obviously false for 5 months of the+-- year.+granularityToDiffTime :: CandlestickGranularity -> NominalDiffTime+granularityToDiffTime S5 = fromSeconds' 5+granularityToDiffTime S10 = fromSeconds' 10+granularityToDiffTime S15 = fromSeconds' 15+granularityToDiffTime S30 = fromSeconds' 30+granularityToDiffTime M1 = fromSeconds' $ 1 * 60+granularityToDiffTime M2 = fromSeconds' $ 2 * 60+granularityToDiffTime M4 = fromSeconds' $ 4 * 60+granularityToDiffTime M5 = fromSeconds' $ 5 * 60+granularityToDiffTime M10 = fromSeconds' $ 10 * 60+granularityToDiffTime M15 = fromSeconds' $ 15 * 60+granularityToDiffTime M30 = fromSeconds' $ 30 * 60+granularityToDiffTime H1 = fromSeconds' $ 1 * 60 * 60+granularityToDiffTime H2 = fromSeconds' $ 2 * 60 * 60+granularityToDiffTime H3 = fromSeconds' $ 3 * 60 * 60+granularityToDiffTime H4 = fromSeconds' $ 4 * 60 * 60+granularityToDiffTime H6 = fromSeconds' $ 6 * 60 * 60+granularityToDiffTime H8 = fromSeconds' $ 8 * 60 * 60+granularityToDiffTime H12 = fromSeconds' $ 12 * 60 * 60+granularityToDiffTime D = fromSeconds' $ 1 * 60 * 60 * 24+granularityToDiffTime W = fromSeconds' $ 7 * 60 * 60 * 24+granularityToDiffTime M = fromSeconds' $ 31 * 60 * 60 * 24++data WeeklyAlignment+  = Monday+  | Tuesday+  | Wednesday+  | Thursday+  | Friday+  | Saturday+  | Sunday+  deriving (Show)++newtype PriceValue = PriceValue { unPriceValue :: Text }+  deriving (Show, ToJSON, FromJSON)++data CandlestickData+  = CandlestickData+  { candlestickDataO :: PriceValue+  , candlestickDataH :: PriceValue+  , candlestickDataL :: PriceValue+  , candlestickDataC :: PriceValue+  } deriving (Show)++deriveJSON (unPrefix "candlestickData") ''CandlestickData++data Candlestick+  = Candlestick+  { candlestickTime :: OandaZonedTime+  , candlestickBid :: Maybe CandlestickData+  , candlestickAsk :: Maybe CandlestickData+  , candlestickMid :: Maybe CandlestickData+  , candlestickVolume :: Integer+  , candlestickComplete :: Bool+  } deriving (Show)++deriveJSON (unPrefix "candlestick") ''Candlestick++data CandlestickArgs+  = CandlestickArgs+  { _candlestickArgsInstrument :: InstrumentName+  , _candlestickArgsPrice :: Maybe Text+  , _candlestickArgsGranularity :: CandlestickGranularity+  , _candlestickArgsCount :: Maybe Int+  , _candlestickArgsFrom :: Maybe ZonedTime+  , _candlestickArgsTo :: Maybe ZonedTime+  , _candlestickArgsSmooth :: Maybe Bool+  , _candlestickArgsIncludeFirst :: Maybe Bool+  , _candlestickArgsDailyAlignment :: Maybe Int+  , _candlestickArgsAlignmentTimezone :: Maybe String+  , _candlestickArgsWeeklyAlignment :: Maybe WeeklyAlignment+  }++candlestickArgs :: InstrumentName -> CandlestickGranularity -> CandlestickArgs+candlestickArgs instrument granularity =+  CandlestickArgs+  { _candlestickArgsInstrument = instrument+  , _candlestickArgsPrice = Nothing+  , _candlestickArgsGranularity = granularity+  , _candlestickArgsCount = Nothing+  , _candlestickArgsFrom = Nothing+  , _candlestickArgsTo = Nothing+  , _candlestickArgsSmooth = Nothing+  , _candlestickArgsIncludeFirst = Nothing+  , _candlestickArgsDailyAlignment = Nothing+  , _candlestickArgsAlignmentTimezone = Nothing+  , _candlestickArgsWeeklyAlignment = Nothing+  }++makeLenses ''CandlestickArgs++oandaCandles :: OandaEnv -> CandlestickArgs -> OANDARequest CandlestickResponse+oandaCandles env CandlestickArgs{..} = OANDARequest request+  where+    instrumentText = unpack $ unInstrumentName _candlestickArgsInstrument+    request =+      baseApiRequest env "GET" ("/v3/instruments/" ++ instrumentText ++ "/candles")+      & setRequestQueryString params+    params =+      catMaybes+      [ ("price",) . Just . encodeUtf8 <$> _candlestickArgsPrice+      , Just ("granularity", Just . fromString $ show _candlestickArgsGranularity)+      , ("count",) . Just . fromString . show <$> _candlestickArgsCount+      , ("from",) . Just . fromString . formatTimeRFC3339 <$> _candlestickArgsFrom+      , ("to",) . Just . fromString . formatTimeRFC3339 <$> _candlestickArgsTo+      , ("smooth",) . Just . fromString . show <$> _candlestickArgsSmooth+      , ("includeFirst",) . Just . fromString . show <$> _candlestickArgsIncludeFirst+      , ("dailyAlignment",) . Just . fromString . show <$> _candlestickArgsDailyAlignment+      , ("alignmentTimezone",) . Just . fromString . show <$> _candlestickArgsAlignmentTimezone+      , ("weeklyAlignment",) . Just . fromString . show <$> _candlestickArgsWeeklyAlignment+      ]++data CandlestickResponse+  = CandlestickResponse+  { candlestickResponseInstrument :: InstrumentName+  , candlestickResponseGranularity :: CandlestickGranularity+  , candlestickResponseCandles :: [Candlestick]+  } deriving (Show)++deriveJSON (unPrefix "candlestickResponse") ''CandlestickResponse
src/OANDA/Internal.hs view
@@ -1,12 +1,8 @@-{-# LANGUAGE CPP #-}-{-# LANGUAGE OverloadedStrings #-}-{-# OPTIONS_GHC -fno-warn-orphans #-}- -- | Utility functions.  module OANDA.Internal-       ( module X-       ) where+  ( module X+  ) where  import OANDA.Internal.Import as X import OANDA.Internal.Request as X
src/OANDA/Internal/Import.hs view
@@ -3,33 +3,61 @@  module OANDA.Internal.Import   ( module X-  , (.~)-  , (^.)-  , (&)-  , mzero-  , toLower-  , catMaybes-  , Text-  , intercalate-  , unpack-  , pack-  , Generic-  , defaultTimeLocale-  , (<>)+  , unPrefix+  , parseJSONFromString   ) where -import Control.Lens ((.~), (^.), (&))-import Control.Monad (mzero)+import Control.Lens as X+  ( (.~)+  , (^.)+  , (&)+  , makeLenses+  )+import Control.Monad as X (mzero) import Data.Aeson as X-import Data.Char (toLower)+import Data.Aeson.TH as X+import Data.Aeson.Types as X+import Data.Char as X (toLower) import Data.Decimal as X-import Data.Maybe (catMaybes)-import Data.Monoid ((<>))+import Data.Maybe as X (catMaybes)+import Data.Monoid as X ((<>)) import Data.Scientific as X-import Data.Text (Text, intercalate, unpack, pack)+import Data.String as X (IsString (..), fromString)+import Data.Text as X (Text, unpack, pack) import Data.Text.Encoding as X import Data.Thyme as X import Data.Thyme.Format.Aeson as X ()-import GHC.Generics (Generic) import Network.HTTP.Simple as X-import System.Locale (defaultTimeLocale)+import System.Locale as X (defaultTimeLocale)+import Text.Read (readMaybe)++-- | Aeson Options that remove the prefix from fields+unPrefix :: String -> Options+unPrefix prefix = defaultOptions+  { fieldLabelModifier = unCapitalize . dropPrefix prefix+  , omitNothingFields = True+  }++-- | Lower case leading character+unCapitalize :: String -> String+unCapitalize [] = []+unCapitalize (c:cs) = toLower c : cs++-- | Remove given prefix+dropPrefix :: String -> String -> String+dropPrefix prefix input = go prefix input+  where+    go pre [] = error $ contextual $ "prefix leftover: " <> pre+    go [] (c:cs) = c : cs+    go (p:preRest) (c:cRest)+      | p == c = go preRest cRest+      | otherwise = error $ contextual $ "not equal: " <>  (p:preRest)  <> " " <> (c:cRest)++    contextual msg = "dropPrefix: " <> msg <> ". " <> prefix <> " " <> input++parseJSONFromString :: (Read a) => Value -> Parser a+parseJSONFromString v = do+  numString <- parseJSON v+  case readMaybe (numString :: String) of+    Nothing -> fail $ "Invalid number for TransactionID: " ++ show v+    Just n -> return n
src/OANDA/Internal/Request.hs view
@@ -1,67 +1,87 @@-{-# LANGUAGE OverloadedStrings #-}- {-# OPTIONS_GHC -fno-warn-orphans #-} --- | Internal module for dealing with requests via wreq+-- | Internal module for dealing with requests via http-conduit  module OANDA.Internal.Request-  ( constructRequest-  , baseURL-  , commaList-  , jsonOpts-  , jsonResponse-  , jsonResponseArray-  -- , jsonDelete+  ( OANDARequest (..)+  , makeOandaRequest+  , OANDAStreamingRequest (..)+  , makeOandaStreamingRequest+  , baseApiRequest+  , baseStreamingRequest+  , apiBaseURL+  , streamingBaseURL   , formatTimeRFC3339   ) where -import qualified Data.Aeson.TH as TH+import Control.Monad.IO.Class+import Control.Monad.Trans.Resource (MonadResource) import qualified Data.ByteString as BS-import qualified Data.Map as Map+import Data.Conduit+import qualified Network.HTTP.Client as H  import OANDA.Internal.Import import OANDA.Internal.Types +-- | This is the type returned by the API functions. This is meant to be used+-- with some of our request functions, depending on how safe the user wants to+-- be.+newtype OANDARequest a = OANDARequest { unOANDARequest :: Request }+  deriving (Show)++-- | Simplest way to make requests, but throws exception on errors.+makeOandaRequest :: (MonadIO m, FromJSON a) => OANDARequest a -> m a+makeOandaRequest (OANDARequest request) = getResponseBody <$> httpJSON request++-- | This is the type returned by the streaming API functions. This is meant to+-- be used with some of our streaming request functions, depending on how safe+-- the user wants to be.+newtype OANDAStreamingRequest a = OANDAStreamingRequest { unOANDAStreamingRequest :: Request }+  deriving (Show)++-- | Simplest way to make streaming, but throws exception on errors.+makeOandaStreamingRequest :: (MonadResource m, FromJSON a) => OANDAStreamingRequest a -> Source m a+makeOandaStreamingRequest (OANDAStreamingRequest request) = httpSource request parseBody+  where+    --parseBody :: (MonadIO m) => Response (Source m ByteString) -> Source m a+    parseBody response = mapOutput (either error id . eitherDecodeStrict) $ getResponseBody response+ -- | Specifies the endpoints for each `APIType`. These are the base URLs for -- each API call.-baseURL :: OandaEnv -> String-baseURL env = apiEndpoint (apiType env)-  where apiEndpoint Sandbox  = "http://api-sandbox.oanda.com"-        apiEndpoint Practice = "https://api-fxpractice.oanda.com"-        apiEndpoint Live     = "https://api-fxtrade.oanda.com"+apiBaseURL :: OandaEnv -> String+apiBaseURL env = apiEndpoint (apiType env)+  where+    apiEndpoint Practice = "https://api-fxpractice.oanda.com"+    apiEndpoint Live     = "https://api-fxtrade.oanda.com" -constructRequest :: OandaEnv -> String -> [(Text, Maybe [Text])] -> IO Request-constructRequest env url params = do-  initRequest <- parseRequest url-  return $-    initRequest-    & maybe id makeAuthHeader (accessToken env)-    & setRequestQueryString params'+-- | Specifies the streaming endpoints for each `APIType`. These are the base+-- URLs for each streaming call.+streamingBaseURL :: OandaEnv -> String+streamingBaseURL env = apiEndpoint (apiType env)   where-    makeAuthHeader (AccessToken t) = addRequestHeader "Authorization" ("Bearer " `BS.append` t)-    paramToMaybe (name, Just xs') = Just (encodeUtf8 name, Just $ encodeUtf8 $ commaList xs')-    paramToMaybe (_, Nothing) = Nothing-    params' = catMaybes $ fmap paramToMaybe params+    apiEndpoint Practice = "https://stream-fxpractice.oanda.com"+    apiEndpoint Live     = "https://stream-fxtrade.oanda.com" --- | Convert a Maybe [Text] item into empty text or comma-separated text.-commaList :: [Text] -> Text-commaList = intercalate ","+-- | Creates a request with the needed base url and an Authorization header for+-- the Bearer token.+baseRequest :: OandaEnv -> String -> String -> String -> Request+baseRequest env baseUrl requestType url =+  unsafeParseRequest (requestType ++ " " ++ baseUrl ++ url)+  & makeAuthHeader (accessToken env)+  where+    makeAuthHeader (AccessToken t) = addRequestHeader "Authorization" ("Bearer " `BS.append` t) --- | Used to derive FromJSON instances.-jsonOpts :: String -> TH.Options-jsonOpts s = TH.defaultOptions { TH.fieldLabelModifier = firstLower . drop (length s) }-  where firstLower [] = []-        firstLower (x:xs) = toLower x : xs+baseApiRequest :: OandaEnv -> String -> String -> Request+baseApiRequest env = baseRequest env (apiBaseURL env) --- | Boilerplate function to perform a request and extract the response body.-jsonResponse :: (FromJSON a) => Request -> IO a-jsonResponse request = getResponseBody <$> httpJSON request+baseStreamingRequest :: OandaEnv -> String -> String -> Request+baseStreamingRequest env = baseRequest env (streamingBaseURL env) --- | Boilerplate function to perform a request and extract the response body.-jsonResponseArray :: (FromJSON a) => Request -> String -> IO a-jsonResponseArray request name =-  do body <- jsonResponse request-     return $ body Map.! (name :: String)+unsafeParseRequest :: String -> Request+unsafeParseRequest = unsafeParseRequest' . H.parseUrlThrow+  where+    unsafeParseRequest' (Left err) = error $ show err+    unsafeParseRequest' (Right request) = request  -- | Formats time according to RFC3339 (which is the time format used by -- OANDA). Taken from the <https://github.com/HugoDaniel/timerep timerep> library.@@ -72,6 +92,8 @@                     then "Z"                     else take 3 timeZoneStr <> ":" <> drop 3 timeZoneStr +instance (Show a, Integral a) => ToJSON (DecimalRaw a) where+  toJSON = toJSON . show  instance (Integral a) => FromJSON (DecimalRaw a) where   parseJSON (Number n) = readDecimalJSON n
src/OANDA/Internal/Types.hs view
@@ -1,76 +1,88 @@-{-# LANGUAGE CPP #-}-{-# LANGUAGE DeriveGeneric #-}-{-# LANGUAGE OverloadedStrings #-}- -- | Defines types used in the REST API  module OANDA.Internal.Types-       ( OandaEnv-       , apiType-       , accessToken-       , sandboxAuth-       , practiceAuth-       , liveAuth-       , APIType (..)-       , AccessToken (..)-       , AccountID (..)-       , Side (..)-       , InstrumentText-       ) where+  ( OandaEnv+  , apiType+  , accessToken+  , practiceAuth+  , liveAuth+  , APIType (..)+  , AccessToken (..)+  , AccountID (..)+  , InstrumentText+  , InstrumentName (..)+  , AccountUnits (..)+  , Currency (..)+  , OandaZonedTime (..)+  ) where +import Control.Applicative ((<|>))+import Control.Lens (from, view) import qualified Data.ByteString as BS+import Data.Thyme.Clock.POSIX (posixTime)+import Data.Thyme.Time.Core (fromMicroseconds)+ import OANDA.Internal.Import +import Debug.Trace+ -- | Wraps an `APIType` and an `AccessToken`. Mainly just a convenience wrapper -- to make functions have fewer arguments. To instantiate this type, use the--- `sandboxAuth`, `practiceAuth`, or `liveAuth` functions.+-- `practiceAuth` or `liveAuth` functions. data OandaEnv = OandaEnv   { apiType     :: APIType-  , accessToken :: Maybe AccessToken+  , accessToken :: AccessToken   } deriving (Show) --- | Use the sandbox API.-sandboxAuth :: OandaEnv-sandboxAuth = OandaEnv Sandbox Nothing- -- | Use the practice API. practiceAuth :: AccessToken -> OandaEnv-practiceAuth = OandaEnv Practice . Just+practiceAuth = OandaEnv Practice  -- | Use the live API. liveAuth :: AccessToken -> OandaEnv-liveAuth = OandaEnv Live . Just-+liveAuth = OandaEnv Live  -- | The three endpoint types used in the REST API. See the following link for -- details: <http://developer.oanda.com/rest-live/development-guide/>-data APIType = Sandbox-             | Practice-             | Live-             deriving (Show)+data APIType+  = Practice+  | Live+  deriving (Show)  -- | The token given by OANDA used to access the API newtype AccessToken = AccessToken { unAccessToken :: BS.ByteString }-                      deriving (Show)-+  deriving (Show)  -- | Integer representing the Account ID of an account-newtype AccountID = AccountID { unAccountID :: Int}-                    deriving (Show)+newtype AccountID = AccountID { unAccountID :: String }+  deriving (Show, FromJSON, ToJSON) --- | Used when reporting a position in the API-data Side = Buy-          | Sell-          deriving (Show, Generic)+type InstrumentText = Text -instance FromJSON Side where-  parseJSON (String s) = fmap readSide (pure $ unpack s)-  parseJSON _          = mzero+newtype InstrumentName = InstrumentName { unInstrumentName :: Text }+  deriving (Show, FromJSON, ToJSON, IsString) +newtype AccountUnits = AccountUnits { unAccountUnits :: Text }+  deriving (Show, FromJSON, ToJSON, IsString) -readSide :: String -> Side-readSide "buy"  = Buy-readSide "sell" = Sell-readSide _      = error "No parse Side"+newtype Currency = Currency { unCurrency :: Text }+  deriving (Show, FromJSON, ToJSON, IsString) -type InstrumentText = Text+-- | Newtype wrapper around 'ZonedTime' to make a new JSON instance. Apparently+-- OANDA decides to use either UNIX epoch seconds or RFC3339 on the fly.+newtype OandaZonedTime = OandaZonedTime { unOandaZonedTime :: ZonedTime }+  deriving (Show, Eq, ToJSON)++instance FromJSON OandaZonedTime where+  parseJSON v = OandaZonedTime <$> (parseJSON v <|> parseZonedFromEpoch v)+    where+      -- If we reach this branch then OANDA has encoded the time as a string+      -- with a number that represents the seconds since the epoch.+      parseZonedFromEpoch :: Value -> Parser ZonedTime+      parseZonedFromEpoch v' = do+        (secondsSinceEpoch :: Double) <- parseJSONFromString v'+        let+          microsecondsSinceEpoch = secondsSinceEpoch * 1e6+          (timeInUTC :: UTCTime) = view (from posixTime) (fromMicroseconds (round microsecondsSinceEpoch) :: NominalDiffTime)+          (timeInZoned :: ZonedTime) = view zonedTime (utc, timeInUTC)+        return $ traceShow (secondsSinceEpoch, microsecondsSinceEpoch, timeInUTC, timeInZoned) timeInZoned
src/OANDA/Orders.hs view
@@ -1,42 +1,152 @@-{-# LANGUAGE DeriveGeneric #-}- -- | Defines the endpoints listed in the--- <http://developer.oanda.com/rest-live/orders/ Orders> section of the API.-+-- <http://developer.oanda.com/rest-live-v20/orders-df/ Orders> section of the API. -module OANDA.Orders-  ( openOrders-  , Order (..)-  ) where+module OANDA.Orders where -import qualified Data.Vector as V+import Data.List (intercalate) +import OANDA.Instrument import OANDA.Internal+import OANDA.Transactions --- | Get all open orders for an account.-openOrders :: OandaEnv -> AccountID -> IO (V.Vector Order)-openOrders od (AccountID aid) = do-  let url = "GET " ++ baseURL od ++ "/v1/accounts/" ++ show aid ++ "/orders"-  request <- constructRequest od url []-  jsonResponseArray request "orders"+data Order+  = Order+  { orderId :: OrderID+  , orderCreateTime :: OandaZonedTime+  , orderState :: OrderState+  , orderClientExtensions :: Maybe ClientExtensions+  , orderType :: OrderType+  , orderInstrument :: Maybe InstrumentName+  , orderUnits :: Maybe Decimal+  , orderTimeInForce :: Maybe TimeInForce+  , orderPrice :: Maybe PriceValue+  , orderPriceBound :: Maybe PriceValue+  , orderPositionFill :: Maybe OrderPositionFill+  , orderInitialMarketPrice :: Maybe PriceValue+  , orderTradeClose :: Maybe MarketOrderTradeClose+  , orderTradeID :: Maybe TradeID+  , orderClientTradeID :: Maybe Text+  , orderDistance :: Maybe PriceValue+  , orderLongPositionCloseout :: Maybe MarketOrderPositionCloseout+  , orderShortPositionCloseout :: Maybe MarketOrderPositionCloseout+  , orderMarginCloseout :: Maybe MarketOrderMarginCloseout+  , orderDelayedTradeClose :: Maybe MarketOrderDelayedTradeClose+  , orderTakeProfitOnFill :: Maybe TakeProfitDetails+  , orderStopLossOnFill :: Maybe StopLossDetails+  , orderTrailingStopLossOnFill :: Maybe TrailingStopLossDetails+  , orderTradeClientExtensions :: Maybe ClientExtensions+  , orderFillingTransactionID :: Maybe TransactionID+  , orderFilledTime :: Maybe OandaZonedTime+  , orderTradeOpenedID :: Maybe TradeID+  , orderTradeReducedID :: Maybe TradeID+  , orderTradeClosedIDs :: Maybe [TradeID]+  , orderCancellingTransactionID :: Maybe TransactionID+  , orderCancelledTime :: Maybe OandaZonedTime+  , orderGtdTime :: Maybe OandaZonedTime+  , orderReplacesOrderID :: Maybe OrderID+  , orderReplacedByOrderID :: Maybe OrderID+  } deriving (Show) +deriveJSON (unPrefix "order") ''Order -data Order = Order-  { orderId           :: Integer-  , orderInstrument   :: InstrumentText-  , orderUnits        :: Integer-  , orderSide         :: Side-  , orderType         :: Text -- "marketIfTouched",-  , orderTime         :: ZonedTime-  , orderPrice        :: Decimal-  , orderTakeProfit   :: Decimal-  , orderStopLoss     :: Decimal-  , orderExpiry       :: ZonedTime-  , orderUpperBound   :: Decimal-  , orderLowerBound   :: Decimal-  , orderTrailingStop :: Decimal-  } deriving (Show, Generic)+data OrdersArgs+  = OrdersArgs+  { _ordersArgsIds :: Maybe [OrderID]+  , _ordersArgsState :: Maybe OrderState+  , _ordersArgsInstrument :: Maybe InstrumentName+  , _ordersArgsCount :: Maybe Int+  , _ordersArgsBeforeID :: Maybe OrderID+  } deriving (Show) +ordersArgs :: OrdersArgs+ordersArgs = OrdersArgs Nothing Nothing Nothing Nothing Nothing -instance FromJSON Order where-  parseJSON = genericParseJSON $ jsonOpts "order"+makeLenses ''OrdersArgs++data OrdersResponse+  = OrdersResponse+  { ordersResponseOrders :: [Order]+  , ordersResponseLastTransactionID :: TransactionID+  } deriving (Show)++deriveJSON (unPrefix "ordersResponse") ''OrdersResponse++oandaOrders :: OandaEnv -> AccountID -> OrdersArgs -> OANDARequest OrdersResponse+oandaOrders env (AccountID accountId) OrdersArgs{..} = OANDARequest request+  where+    request =+      baseApiRequest env "GET" ("/v3/accounts/" ++ accountId ++ "/orders")+      & setRequestQueryString params+    params =+      catMaybes+      [ ("ids",) . Just . fromString . intercalate "," . fmap (show . unOrderID) <$> _ordersArgsIds+      , ("state",) . Just . fromString . show <$> _ordersArgsState+      , ("instrument",) . Just . fromString . unpack . unInstrumentName <$> _ordersArgsInstrument+      , ("count",) . Just . fromString . show <$> _ordersArgsCount+      , ("beforeID",) . Just . fromString . show . unOrderID <$> _ordersArgsBeforeID+      ]++data OrderRequest+  = OrderRequest+  { _orderRequestType :: OrderType+  , _orderRequestClientExtensions :: Maybe ClientExtensions+  , _orderRequestInstrument :: Maybe InstrumentName+  , _orderRequestUnits :: Maybe Decimal+  , _orderRequestTimeInForce :: Maybe TimeInForce+  , _orderRequestPrice :: Maybe PriceValue+  , _orderRequestPriceBound :: Maybe PriceValue+  , _orderRequestPositionFill :: Maybe OrderPositionFill+  , _orderRequestTradeID :: Maybe TradeID+  , _orderRequestClientTradeID :: Maybe Text+  , _orderRequestDistance :: Maybe PriceValue+  , _orderRequestTakeProfitOnFill :: Maybe TakeProfitDetails+  , _orderRequestStopLossOnFill :: Maybe StopLossDetails+  , _orderRequestTrailingStopLossOnFill :: Maybe TrailingStopLossDetails+  , _orderRequestTradeClientExtensions :: Maybe ClientExtensions+  , _orderRequestGtdTime :: Maybe ZonedTime+  } deriving (Show)++makeLenses ''OrderRequest++orderRequest :: OrderType -> OrderRequest+orderRequest orderType =+  OrderRequest+  { _orderRequestType = orderType+  , _orderRequestClientExtensions = Nothing+  , _orderRequestInstrument = Nothing+  , _orderRequestUnits = Nothing+  , _orderRequestTimeInForce = Nothing+  , _orderRequestPrice = Nothing+  , _orderRequestPriceBound = Nothing+  , _orderRequestPositionFill = Nothing+  , _orderRequestTradeID = Nothing+  , _orderRequestClientTradeID = Nothing+  , _orderRequestDistance = Nothing+  , _orderRequestTakeProfitOnFill = Nothing+  , _orderRequestStopLossOnFill = Nothing+  , _orderRequestTrailingStopLossOnFill = Nothing+  , _orderRequestTradeClientExtensions = Nothing+  , _orderRequestGtdTime = Nothing+  }++deriveJSON (unPrefix "_orderRequest") ''OrderRequest++data CreateOrderResponse+  = CreateOrderResponse+  { createOrderResponseOrderCreateTransaction :: Transaction+  , createOrderResponseOrderFillTransaction :: Maybe Transaction+  , createOrderResponseOrderCancelTransaction :: Maybe Transaction+  , createOrderResponseOrderReissueTransaction :: Maybe Transaction+  , createOrderResponseOrderReissueRejectTransaction :: Maybe Transaction+  , createOrderResponseRelatedTransactionIDs :: [TransactionID]+  , createOrderResponseLastTransactionID :: TransactionID+  } deriving (Show)++deriveJSON (unPrefix "createOrderResponse") ''CreateOrderResponse++oandaCreateOrder :: OandaEnv -> AccountID -> OrderRequest -> OANDARequest CreateOrderResponse+oandaCreateOrder env (AccountID accountId) orderRequest' = OANDARequest request+  where+    request =+      baseApiRequest env "POST" ("/v3/accounts/" ++ accountId ++ "/orders")+      & setRequestBodyJSON (object ["order" .= orderRequest'])
− src/OANDA/Positions.hs
@@ -1,59 +0,0 @@-{-# LANGUAGE DeriveGeneric #-}-{-# LANGUAGE OverloadedStrings #-}---- | Defines the endpoints listed in the--- <http://developer.oanda.com/rest-live/positions/ Positions> section of the--- API.--module OANDA.Positions-  ( Position (..)-  , openPositions-  , position-  , closePosition-  , CloseResponse (..)-  ) where--import qualified Data.Vector as V--import OANDA.Internal---- | Get all open positions for an account.-openPositions :: OandaEnv -> AccountID -> IO (V.Vector Position)-openPositions od (AccountID aid) = do-  let url = "GET " ++ baseURL od ++ "/v1/accounts/" ++ show aid ++ "/positions"-  request <- constructRequest od url []-  jsonResponseArray request "positions"--data Position = Position-  { positionInstrument :: Text-  , positionUnits      :: Int-  , positionSide       :: Side-  , positionAvgPrice   :: Decimal-  } deriving (Show, Generic)--instance FromJSON Position where-  parseJSON = genericParseJSON $ jsonOpts "position"---- | Get open position for an account on a given instrument.-position :: OandaEnv -> AccountID -> InstrumentText -> IO Position-position od (AccountID aid) ins = do-  let url = "GET " ++ baseURL od ++ "/v1/accounts/" ++ show aid ++ "/positions/" ++ unpack ins-  request <- constructRequest od url []-  jsonResponse request---- | Closes an existing position.-closePosition :: OandaEnv -> AccountID -> InstrumentText -> IO CloseResponse-closePosition od (AccountID aid) ins = do-  let url = "DELETE " ++ baseURL od ++ "/v1/accounts/" ++ show aid ++ "/positions/" ++ unpack ins-  request <- constructRequest od url []-  jsonResponse request--data CloseResponse = CloseResponse-  { closeResponseIds        :: V.Vector Int-  , closeResponseInstrument :: InstrumentText-  , closeResponseTotalUnits :: Int-  , closeResponsePrice      :: Decimal-  } deriving (Show, Generic)--instance FromJSON CloseResponse where-  parseJSON = genericParseJSON $ jsonOpts "closeResponse"
+ src/OANDA/Pricing.hs view
@@ -0,0 +1,116 @@+-- | Defines the endpoints listed in the+-- <http://developer.oanda.com/rest-live-v20/pricing-ep/ Pricing> section of+-- the API.++module OANDA.Pricing where++import qualified Data.ByteString.Lazy as BSL+import Data.List (intercalate)++import OANDA.Instrument+import OANDA.Internal++data PriceBucket+  = PriceBucket+  { priceBucketPrice :: PriceValue+  , priceBucketLiquidity :: Integer+  } deriving (Show)++deriveJSON (unPrefix "priceBucket") ''PriceBucket++data Price+  = Price+  { priceInstrument :: InstrumentName+  , priceTime :: OandaZonedTime+  , priceStatus :: Text+  , priceBids :: [PriceBucket]+  , priceAsks :: [PriceBucket]+  , priceCloseoutBid :: PriceValue+  , priceCloseoutAsk :: PriceValue+  } deriving (Show)++deriveJSON (unPrefix "price") ''Price++data PricingArgs+  = PricingArgs+  { _pricingArgsInstruments :: [InstrumentName]+  , _pricingArgsSince :: Maybe ZonedTime+  } deriving (Show)++makeLenses ''PricingArgs++pricingArgs :: [InstrumentName] -> PricingArgs+pricingArgs instruments =+  PricingArgs+  { _pricingArgsInstruments = instruments+  , _pricingArgsSince = Nothing+  }++data PricingResponse+  = PricingResponse+  { pricingResponsePrices :: [Price]+  } deriving (Show)++deriveJSON (unPrefix "pricingResponse") ''PricingResponse++oandaPricing :: OandaEnv -> AccountID -> PricingArgs -> OANDARequest PricingResponse+oandaPricing env (AccountID accountId) PricingArgs{..} = OANDARequest request+  where+    request =+      baseApiRequest env "GET" ("/v3/accounts/" ++ accountId ++ "/pricing")+      & setRequestQueryString params+    params =+      catMaybes+      [ Just ("instruments", Just . fromString . intercalate "," . fmap (unpack . unInstrumentName) $ _pricingArgsInstruments)+      , ("since",) . Just . fromString . formatTimeRFC3339 <$> _pricingArgsSince+      ]++data PricingStreamArgs+  = PricingStreamArgs+  { _pricingStreamArgsInstruments :: [InstrumentName]+  , _pricingStreamArgsSnapshot :: Maybe Bool+  } deriving (Show)++makeLenses ''PricingStreamArgs++pricingStreamArgs :: [InstrumentName] -> PricingStreamArgs+pricingStreamArgs instruments =+  PricingStreamArgs+  { _pricingStreamArgsInstruments = instruments+  , _pricingStreamArgsSnapshot = Nothing+  }++data PricingHeartbeat+  = PricingHeartbeat+  { pricingHeartbeatTime :: OandaZonedTime+  } deriving (Show)++deriveJSON (unPrefix "pricingHeartbeat") ''PricingHeartbeat++data PricingStreamResponse+  = StreamPricingHeartbeat PricingHeartbeat+  | StreamPrice Price+  deriving (Show)++-- The ToJSON instance is just for debugging, it's not actually correct+deriveToJSON defaultOptions ''PricingStreamResponse++instance FromJSON PricingStreamResponse where+  parseJSON (Object o) = do+    type' <- o .: "type" :: Parser String+    case type' of+      "HEARTBEAT" -> StreamPricingHeartbeat <$> parseJSON (Object o)+      _ -> StreamPrice <$> parseJSON (Object o)+  parseJSON _ = mempty++oandaPricingStream :: OandaEnv -> AccountID -> PricingStreamArgs -> OANDAStreamingRequest PricingStreamResponse+oandaPricingStream env (AccountID accountId) PricingStreamArgs{..} = OANDAStreamingRequest request+  where+    request =+      baseStreamingRequest env "GET" ("/v3/accounts/" ++ accountId ++ "/pricing/stream")+      & setRequestQueryString params+    params =+      catMaybes+      [ Just ("instruments", Just . fromString . intercalate "," . fmap (unpack . unInstrumentName) $ _pricingStreamArgsInstruments)+      , ("since",) . Just . BSL.toStrict . encode <$> _pricingStreamArgsSnapshot+      ]
− src/OANDA/Rates.hs
@@ -1,256 +0,0 @@-{-# LANGUAGE DeriveGeneric #-}-{-# LANGUAGE OverloadedStrings #-}---- | Defines the endpoints listed in the--- <http://developer.oanda.com/rest-live/rates/ Rates> section of the API.--module OANDA.Rates-  ( InstrumentsArgs (..)-  , instrumentsArgs-  , Instrument (..)-  , instruments-  , Price (..)-  , prices-  , MidpointCandlestick (..)-  , midpointCandles-  , BidAskCandlestick (..)-  , bidaskCandles-  , CandlesArgs (..)-  , candlesArgs-  , CandlesCount (..)-  , DayOfWeek (..)-  , Granularity (..)-  , granularityToDiffTime-  ) where--import qualified Data.Vector as V--import OANDA.Internal---data InstrumentsArgs = InstrumentsArgs-  { instrumentsFields      :: Maybe [Text]-  , instrumentsInstruments :: Maybe [Text]-  } deriving (Show)--instrumentsArgs :: InstrumentsArgs-instrumentsArgs = InstrumentsArgs Nothing Nothing--data Instrument = Instrument-  { instrumentInstrument      :: Text-  , instrumentPip             :: Maybe Decimal-  , instrumentMaxTradeUnits   :: Maybe Integer-  , instrumentDisplayName     :: Maybe Text-  , instrumentPrecision       :: Maybe Decimal-  , instrumentMaxTrailingStop :: Maybe Decimal-  , instrumentMinTrailingStop :: Maybe Decimal-  , instrumentMarginRate      :: Maybe Decimal-  , instrumentHalted          :: Maybe Bool-  , instrumentInterestRate    :: Maybe Object-  } deriving (Show, Generic)--instance FromJSON Instrument where-  parseJSON = genericParseJSON $ jsonOpts "instrument"---- | Retrieve a list of instruments from OANDA-instruments :: OandaEnv -> AccountID -> InstrumentsArgs -> IO (V.Vector Instrument)-instruments od (AccountID aid) (InstrumentsArgs fs is) = do-  let url = "GET " ++ baseURL od ++ "/v1/instruments"-  request <- constructRequest od url-    [ ("accountId", Just [pack $ show aid])-    , ("instruments", is)-    , ("fields", fs)-    ]-  jsonResponseArray request "instruments"---- | Retrieve the current prices for a list of instruments.-prices :: OandaEnv -> [InstrumentText] -> Maybe ZonedTime -> IO (V.Vector Price)-prices od is zt = do-  let-    url = "GET " ++ baseURL od ++ "/v1/prices"-    ztOpt = maybe [] (\zt' -> [("since", Just [pack $ formatTimeRFC3339 zt'])]) zt-  request <- constructRequest od url (("instruments", Just is) : ztOpt)-  jsonResponseArray request "prices"--data Price = Price-  { priceInstrument :: InstrumentText-  , priceTime       :: ZonedTime-  , priceBid        :: Decimal-  , priceAsk        :: Decimal-  } deriving (Show, Generic)--instance FromJSON Price where-  parseJSON = genericParseJSON $ jsonOpts "price"----- | Retrieve the price history of a single instrument in midpoint candles-midpointCandles :: OandaEnv -> InstrumentText -> CandlesArgs ->-                   IO (V.Vector MidpointCandlestick)-midpointCandles od i args = do-  request <- candleOpts od i args "midpoint"-  response <- jsonResponse request :: IO MidpointCandlesResponse-  return $ _midcandlesResponseCandles response---- | Retrieve the price history of a single instrument in bid/ask candles-bidaskCandles :: OandaEnv -> InstrumentText -> CandlesArgs ->-                 IO (V.Vector BidAskCandlestick)-bidaskCandles od i args = do-  request <- candleOpts od i args "bidask"-  response <- jsonResponse request :: IO BidAskCandlesResponse-  return $ _bidaskResponseCandles response----- | Utility function for both candle history functions-candleOpts :: OandaEnv -> InstrumentText -> CandlesArgs -> String -> IO Request-candleOpts od i (CandlesArgs c g di atz wa) fmt = constructRequest od url opts-  where url = "GET " ++ baseURL od ++ "/v1/candles"-        opts =-          [ ("instrument", Just [i])-          , ("granularity", (:[]) . pack . show <$> g)-          , ("candleFormat", Just [pack fmt])-          , ("dailyAlignment", (:[]) . pack . show <$> di)-          , ("alignmentTimeZone", (:[]) <$> atz)-          , ("weeklyAlignment", (:[]) . pack . show <$> wa)-          ] ++ maybe [] countOpts c-        countOpts (Count c') = [("count", Just [pack $ show c'])]-        countOpts (StartEnd st ed incf) =-          [ ("start", Just [pack $ formatTimeRFC3339 st])-          , ("end", Just [pack $ formatTimeRFC3339 ed])-          , ("includeFirst", Just [pack $ map toLower (show incf)])-          ]-        countOpts (StartCount st c' incf) =-          [ ("start", Just [pack $ formatTimeRFC3339 st])-          , ("count", Just [pack $ show c'])-          , ("includeFirst", Just [pack $ map toLower (show incf)])-          ]-        countOpts (EndCount ed c') =-          [ ("end", Just [pack $ formatTimeRFC3339 ed])-          , ("count", Just [pack $ show c'])-          ]--data MidpointCandlestick = MidpointCandlestick-  { midpointCandlestickTime     :: ZonedTime-  , midpointCandlestickOpenMid  :: Decimal-  , midpointCandlestickHighMid  :: Decimal-  , midpointCandlestickLowMid   :: Decimal-  , midpointCandlestickCloseMid :: Decimal-  , midpointCandlestickVolume   :: Int-  , midpointCandlestickComplete :: Bool-  } deriving (Show, Generic)--instance FromJSON MidpointCandlestick where-  parseJSON = genericParseJSON $ jsonOpts "midpointCandlestick"---data BidAskCandlestick = BidAskCandlestick-  { bidaskCandlestickTime     :: ZonedTime-  , bidaskCandlestickOpenBid  :: Decimal-  , bidaskCandlestickOpenAsk  :: Decimal-  , bidaskCandlestickHighBid  :: Decimal-  , bidaskCandlestickHighAsk  :: Decimal-  , bidaskCandlestickLowBid   :: Decimal-  , bidaskCandlestickLowAsk   :: Decimal-  , bidaskCandlestickCloseBid :: Decimal-  , bidaskCandlestickCloseAsk :: Decimal-  , bidaskCandlestickVolume   :: Int-  , bidaskCandlestickComplete :: Bool-  } deriving (Show, Generic)--instance FromJSON BidAskCandlestick where-  parseJSON = genericParseJSON $ jsonOpts "bidaskCandlestick"--data CandlesArgs = CandlesArgs-  { candlesCount           :: Maybe CandlesCount-  , candlesGranularity     :: Maybe Granularity-  , candlesDailyAlignment  :: Maybe Int-  , candlesAlignmentTZ     :: Maybe Text-  , candlesWeeklyAlignment :: Maybe DayOfWeek-  } deriving (Show)--candlesArgs :: CandlesArgs-candlesArgs = CandlesArgs Nothing Nothing Nothing Nothing Nothing--data CandlesCount = Count Int-                  | StartEnd-                    { start :: ZonedTime-                    , end :: ZonedTime-                    , includeFirst :: Bool-                    }-                  | StartCount-                    { start :: ZonedTime-                    , count :: Int-                    , includeFirst :: Bool-                    }-                  | EndCount-                    { end :: ZonedTime-                    , count :: Int-                    }-                  deriving (Show)--data DayOfWeek = Monday-               | Tuesday-               | Wednesday-               | Thursday-               | Friday-               | Saturday-               | Sunday-               deriving (Show)--data Granularity = S5 | S10 | S15 | S30-                 | M1 | M2 | M3 | M4 | M5 | M10 | M15 | M30-                 | H1 | H2 | H3 | H4 | H6 | H8 | H12-                 | D-                 | W-                 | M-                 deriving (Show)---- | Utility function to convert Granularity to NominalDiffTime. __NOTE__: The--- conversion from month to NominalDiffTime is not correct in general; we just--- assume 31 days in a month, which is obviously false for 5 months of the--- year.-granularityToDiffTime :: Granularity -> NominalDiffTime-granularityToDiffTime S5 = fromSeconds' 5-granularityToDiffTime S10 = fromSeconds' 10-granularityToDiffTime S15 = fromSeconds' 15-granularityToDiffTime S30 = fromSeconds' 30-granularityToDiffTime M1 = fromSeconds' $ 1 * 60-granularityToDiffTime M2 = fromSeconds' $ 2 * 60-granularityToDiffTime M3 = fromSeconds' $ 3 * 60-granularityToDiffTime M4 = fromSeconds' $ 4 * 60-granularityToDiffTime M5 = fromSeconds' $ 5 * 60-granularityToDiffTime M10 = fromSeconds' $ 10 * 60-granularityToDiffTime M15 = fromSeconds' $ 15 * 60-granularityToDiffTime M30 = fromSeconds' $ 30 * 60-granularityToDiffTime H1 = fromSeconds' $ 1 * 60 * 60-granularityToDiffTime H2 = fromSeconds' $ 2 * 60 * 60-granularityToDiffTime H3 = fromSeconds' $ 3 * 60 * 60-granularityToDiffTime H4 = fromSeconds' $ 4 * 60 * 60-granularityToDiffTime H6 = fromSeconds' $ 6 * 60 * 60-granularityToDiffTime H8 = fromSeconds' $ 8 * 60 * 60-granularityToDiffTime H12 = fromSeconds' $ 12 * 60 * 60-granularityToDiffTime D = fromSeconds' $ 1 * 60 * 60 * 24-granularityToDiffTime W = fromSeconds' $ 7 * 60 * 60 * 24-granularityToDiffTime M = fromSeconds' $ 31 * 60 * 60 * 24---- | Utility type for `midpointCandles` function response. Not exported.-data MidpointCandlesResponse = MidpointCandlesResponse-  { _midcandlesResponseInstrument  :: InstrumentText-  , _midcandlesResponseGranularity :: Text-  , _midcandlesResponseCandles     :: V.Vector MidpointCandlestick-  } deriving (Show, Generic)---instance FromJSON MidpointCandlesResponse where-  parseJSON = genericParseJSON $ jsonOpts "_midcandlesResponse"----- | Utility type for `bidaskCandles` function response. Not exported.-data BidAskCandlesResponse = BidAskCandlesResponse-  { _bidaskResponseInstrument  :: InstrumentText-  , _bidaskResponseGranularity :: Text-  , _bidaskResponseCandles     :: V.Vector BidAskCandlestick-  } deriving (Show, Generic)---instance FromJSON BidAskCandlesResponse where-  parseJSON = genericParseJSON $ jsonOpts "_bidaskResponse"
− src/OANDA/Trades.hs
@@ -1,47 +0,0 @@-{-# LANGUAGE DeriveGeneric #-}---- | Defines the endpoints listed in the--- <http://developer.oanda.com/rest-live/trades/ Trades History> section of the--- API.--module OANDA.Trades-  ( Trade (..)-  , openTrades-  , tradeInfo-  ) where--import qualified Data.Vector as V--import OANDA.Internal--data Trade = Trade-  { tradeId             :: !Int-  , tradeUnits          :: !Int-  , tradeSide           :: !Side-  , tradeInstrument     :: !Text-  , tradeTime           :: !ZonedTime-  , tradePrice          :: !Decimal-  , tradeTakeProfit     :: !Decimal-  , tradeStopLoss       :: !Decimal-  , tradeTrailingStop   :: !Decimal-  , tradeTrailingAmount :: !Decimal-  } deriving (Show, Generic)--instance FromJSON Trade where-  parseJSON = genericParseJSON $ jsonOpts "trade"---- | Gets a list of all open trades in an account.-openTrades :: OandaEnv -> AccountID -> IO (V.Vector Trade)-openTrades od (AccountID aid) = do-  let url = "GET " ++ baseURL od ++ "/v1/accounts/" ++ show aid ++ "/trades"-  request <- constructRequest od url []-  jsonResponseArray request "trades"--type TradeID = Int---- | Get info for a specific trade.-tradeInfo :: OandaEnv -> AccountID -> TradeID -> IO Trade-tradeInfo od (AccountID aid) tid = do-  let url = "GET " ++ baseURL od ++ "/v1/accounts/" ++ show aid ++ "/trades/" ++ show tid-  request <- constructRequest od url []-  jsonResponse request
src/OANDA/Transactions.hs view
@@ -1,54 +1,330 @@-{-# LANGUAGE DeriveGeneric #-}-{-# LANGUAGE OverloadedStrings #-}- -- | Defines the endpoints listed in the--- <http://developer.oanda.com/rest-live/transaction-history/ Transaction+-- <http://developer.oanda.com/rest-live-v20/transactions-ep/ Transaction -- History> section of the API. -module OANDA.Transactions-  ( Transaction (..)-  , transactionHistory-  ) where+module OANDA.Transactions where -import qualified Data.Vector as V+import qualified Data.ByteString.Char8 as BS8  import OANDA.Internal --- data TransactionArgs = TransactionArgs---   { transactionsMaxID      :: Maybe Integer---   , transactionsMinID      :: Maybe Integer---   , transactionsCount      :: Maybe Integer---   , transactionsInstrument :: Maybe InstrumentText---   , transactionsIds        :: [Integer]---   } deriving (Show)+newtype OrderID = OrderID { unOrderID :: Int }+  deriving (Show, Eq) --- | Get a list of transactions for the account.-transactionHistory :: OandaEnv -> AccountID -> IO (V.Vector Transaction)-transactionHistory od (AccountID aid) =-  do let url = "GET " ++ baseURL od ++ "/v1/accounts/" ++ show aid ++ "/transactions"-     request <- constructRequest od url []-     jsonResponseArray request "transactions"+instance ToJSON OrderID where+  toJSON = toJSON . show . unOrderID +instance FromJSON OrderID where+  parseJSON = fmap OrderID . parseJSONFromString +newtype TransactionID = TransactionID { unTransactionID :: Int }+  deriving (Show, Eq)++instance ToJSON TransactionID where+  toJSON = toJSON . show . unTransactionID++instance FromJSON TransactionID where+  parseJSON = fmap TransactionID . parseJSONFromString++newtype TradeID = TradeID { unTradeID :: Int }+  deriving (Show, Eq)++instance ToJSON TradeID where+  toJSON = toJSON . show . unTradeID++instance FromJSON TradeID where+  parseJSON = fmap TradeID . parseJSONFromString++data OrderType+  = MARKET+  | LIMIT+  | STOP+  | MARKET_IF_TOUCHED+  | TAKE_PROFIT+  | STOP_LOSS+  | TRAILING_STOP_LOSS+  deriving (Show, Eq)++deriveJSON defaultOptions ''OrderType++data OrderState+  = PENDING+  | FILLED+  | TRIGGERED+  | CANCELLED+  deriving (Show, Eq)++deriveJSON defaultOptions ''OrderState++data ClientExtensions+  = ClientExtensions+  { clientExtensionsID :: Text+  , clientExtensionsTag :: Text+  , clientExtensionsComment :: Text+  } deriving (Show)++deriveJSON (unPrefix "clientExtensions") ''ClientExtensions++data TimeInForce+  = GTC+  | GTD+  | GFD+  | FOK+  | IOC+  deriving (Show, Eq)++deriveJSON defaultOptions ''TimeInForce++data OrderPositionFill+  = OPEN_ONLY+  | REDUCE_FIRST+  | REDUCE_ONLY+  | POSITION_DEFAULT+  deriving (Show, Eq)++deriveJSON defaultOptions ''OrderPositionFill++data MarketOrderPositionCloseout+  = MarketOrderPositionCloseout+  { marketOrderPositionCloseoutInstrument :: InstrumentName+  , marketOrderPositionCloseoutUnits :: Text+  } deriving (Show)++deriveJSON (unPrefix "marketOrderPositionCloseout") ''MarketOrderPositionCloseout++data MarketOrderTradeClose+  = MarketOrderTradeClose+  { marketOrderTradeCloseTradeID :: TradeID+  , marketOrderTradeCloseClientTradeID :: Text+  , marketOrderTradeCloseUnits :: Text+  } deriving (Show)++deriveJSON (unPrefix "marketOrderTradeClose") ''MarketOrderTradeClose++data MarketOrderMarginCloseout+  = MarketOrderMarginCloseout+  { marketOrderMarginCloseoutReason :: Text+  } deriving (Show)++deriveJSON (unPrefix "marketOrderMarginCloseout") ''MarketOrderMarginCloseout++data MarketOrderDelayedTradeClose+  = MarketOrderDelayedTradeClose+  { marketOrderDelayedTradeCloseTradeID :: TradeID+  , marketOrderDelayedTradeCloseClientTradeID :: Text+  , marketOrderDelayedTradeCloseSourceTransactionID :: TransactionID+  } deriving (Show)++deriveJSON (unPrefix "marketOrderDelayedTradeClose") ''MarketOrderDelayedTradeClose++data TakeProfitDetails+  = TakeProfitDetails+  { takeProfitDetailsPrice :: Text+  , takeProfitDetailsTimeInForce :: TimeInForce+  , takeProfitDetailsGtdTime :: OandaZonedTime+  , takeProfitDetailsClientExtensions :: Maybe ClientExtensions+  } deriving (Show)++deriveJSON (unPrefix "takeProfitDetails") ''TakeProfitDetails++data StopLossDetails+  = StopLossDetails+  { stopLossDetailsPrice :: Text+  , stopLossDetailsTimeInForce :: TimeInForce+  , stopLossDetailsGtdTime :: OandaZonedTime+  , stopLossDetailsClientExtensions :: Maybe ClientExtensions+  } deriving (Show)++deriveJSON (unPrefix "stopLossDetails") ''StopLossDetails++data TrailingStopLossDetails+  = TrailingStopLossDetails+  { trailingStopLossDetailsDistance :: Text+  , trailingStopLossDetailsTimeInForce :: TimeInForce+  , trailingStopLossDetailsGtdTime :: OandaZonedTime+  , trailingStopLossDetailsClientExtensions :: Maybe ClientExtensions+  } deriving (Show)++deriveJSON (unPrefix "trailingStopLossDetails") ''TrailingStopLossDetails++data TransactionType+  = CREATE+  | CLOSE+  | REOPEN+  | CLIENT_CONFIGURE+  | CLIENT_CONFIGURE_REJECT+  | TRANSFER_FUNDS+  | TRANSFER_FUNDS_REJECT+  | MARKET_ORDER+  | MARKET_ORDER_REJECT+  | LIMIT_ORDER+  | LIMIT_ORDER_REJECT+  | STOP_ORDER+  | STOP_ORDER_REJECT+  | MARKET_IF_TOUCHED_ORDER+  | MARKET_IF_TOUCHED_ORDER_REJECT+  | TAKE_PROFIT_ORDER+  | TAKE_PROFIT_ORDER_REJECT+  | STOP_LOSS_ORDER+  | STOP_LOSS_ORDER_REJECT+  | TRAILING_STOP_LOSS_ORDER+  | TRAILING_STOP_LOSS_ORDER_REJECT+  | ORDER_FILL+  | ORDER_CANCEL+  | ORDER_CANCEL_REJECT+  | ORDER_CLIENT_EXTENSIONS_MODIFY+  | ORDER_CLIENT_EXTENSIONS_MODIFY_REJECT+  | TRADE_CLIENT_EXTENSIONS_MODIFY+  | TRADE_CLIENT_EXTENSIONS_MODIFY_REJECT+  | MARGIN_CALL_ENTER+  | MARGIN_CALL_EXTEND+  | MARGIN_CALL_EXIT+  | DELAYED_TRADE_CLOSURE+  | DAILY_FINANCING+  | RESET_RESETTABLE_PL+  deriving (Show, Eq)++deriveJSON defaultOptions ''TransactionType++data TradeOpen+  = TradeOpen+  { tradeOpenTradeID :: TradeID+  , tradeOpenUnits :: Decimal+  , tradeOpenClientExtensions :: Maybe ClientExtensions+  } deriving (Show)++deriveJSON (unPrefix "tradeOpen") ''TradeOpen++data TradeReduce+  = TradeReduce+  { tradeReduceTradeID :: TradeID+  , tradeReduceUnits :: Decimal+  , tradeReduceRealizedPL :: AccountUnits+  , tradeReduceFinancing :: AccountUnits+  } deriving (Show)++deriveJSON (unPrefix "tradeReduce") ''TradeReduce++data OpenTradeFinancing+  = OpenTradeFinancing+  { openTradeFinancingTradeID :: TradeID+  , openTradeFinancingFinancing :: AccountUnits+  } deriving (Show)++deriveJSON (unPrefix "openTradeFinancing") ''OpenTradeFinancing++data PositionFinancing+  = PositionFinancing+  { -- BUG: Their docs say instrumentID but the field is actually called instrument+    positionFinancingInstrument :: InstrumentName+  , positionFinancingFinancing :: AccountUnits+  , positionFinancingOpenTradeFinancings :: [OpenTradeFinancing]+  } deriving (Show)++deriveJSON (unPrefix "positionFinancing") ''PositionFinancing+ data Transaction = Transaction-  { transactionId                       :: Integer-  , transactionAccountId                :: Integer-  , transactionTime                     :: ZonedTime-  , transactionType                     :: String  -- Can be an enum type in the future-  , transactionInstrument               :: Maybe InstrumentText-  , transactionSide                     :: Maybe Side-  , transactionUnits                    :: Maybe Decimal-  , transactionPrice                    :: Maybe Decimal-  , transactionLowerBound               :: Maybe Decimal-  , transactionUpperBound               :: Maybe Decimal-  , transactionTakeProfitPrice          :: Maybe Decimal-  , transactionStopLossPrice            :: Maybe Decimal-  , transactionTrailingStopLossDistance :: Maybe Decimal-  , transactionPL                       :: Maybe Decimal-  , transactionInterest                 :: Maybe Decimal-  , transactionAccountBalance           :: Maybe Decimal-  } deriving (Show, Generic)+  { -- Common to all transactions+    transactionId :: TransactionID+  , transactionTime :: OandaZonedTime+  , transactionAccountID :: AccountID+  , transactionUserID :: Integer+  , transactionBatchID :: TransactionID+  , transactionType :: TransactionType +  -- Specific to individual transactions+  , transactionDivisionID :: Maybe Integer+  , transactionSiteID :: Maybe Integer+  , transactionAccountUserID :: Maybe Integer+  , transactionAccountNumber :: Maybe Integer+  , transactionHomeCurrency :: Maybe Currency+  , transactionAlias :: Maybe Text+  , transactionMarginRate :: Maybe Decimal+  , transactionRejectReason :: Maybe Text+  , transactionAmount :: Maybe AccountUnits+  , transactionFundingReason :: Maybe Text+  , transactionAccountBalance :: Maybe AccountUnits+  , transactionInstrument :: Maybe InstrumentText+  , transactionUnits :: Maybe Decimal+  , transactionPrice :: Maybe Decimal+  , transactionTimeInForce :: Maybe TimeInForce+  , transactionPriceBound :: Maybe Text+  , transactionPositionFill :: Maybe Text+  , transactionMarketOrderTradeClose :: Maybe MarketOrderTradeClose+  , transactionLongPositionCloseout :: Maybe MarketOrderPositionCloseout+  , transactionShortPositionCloseout :: Maybe MarketOrderPositionCloseout+  , transactionMarginCloseout :: Maybe MarketOrderMarginCloseout+  , transactionDelayedTradeClose :: Maybe MarketOrderDelayedTradeClose+  , transactionReason :: Maybe Text+  , transactionClientExtensions :: Maybe ClientExtensions+  , transactionTakeProfitOnFill :: Maybe TakeProfitDetails+  , transactionStopLossOnFill :: Maybe StopLossDetails+  , transactionTrailingStopLossOnFill :: Maybe TrailingStopLossDetails+  , transactionTradeClientExtensions :: Maybe ClientExtensions+  , transactionGtdTime :: Maybe OandaZonedTime+  , transactionReplacesOrderID :: Maybe OrderID+  , transactionReplacedOrderCancelTransactionID :: Maybe TransactionID+  , transactionIntendedReplacesOrderID :: Maybe OrderID+  , transactionDistance :: Maybe Text+  , transactionOrderID :: Maybe OrderID+  , transactionClientOrderID :: Maybe Text+  , transactionPl :: Maybe AccountUnits+  , transactionFinancing :: Maybe AccountUnits+  , transactionTradeOpened :: Maybe TradeOpen+  , transactionTradesClosed :: Maybe [TradeReduce]+  , transactionTradeReduced :: Maybe TradeReduce+  , transactionTradeClientExtensionsModify :: Maybe ClientExtensions+  , transactionExtensionNumber :: Maybe Integer+  , transactionTradeIDs :: Maybe TradeID+  , transactionAccountFinancingMode :: Maybe Text+  , transactionPositionFinancings :: Maybe [PositionFinancing]+  } deriving (Show) -instance FromJSON Transaction where-  parseJSON = genericParseJSON $ jsonOpts "transaction"+deriveJSON (unPrefix "transaction") ''Transaction++oandaTransaction :: OandaEnv -> AccountID -> TransactionID -> OANDARequest Transaction+oandaTransaction env (AccountID accountId) (TransactionID transId) =+  OANDARequest $ baseApiRequest env "GET" ("/v3/accounts/" ++ accountId ++ "/transactions/" ++ show transId)++data TransactionsSinceIDResponse+  = TransactionsSinceIDResponse+  { transactionsSinceIDResponseTransactions :: [Transaction]+  , transactionsSinceIDResponseLastTransactionID :: TransactionID+  } deriving (Show)++deriveJSON (unPrefix "transactionsSinceIDResponse") ''TransactionsSinceIDResponse++oandaTransactionsSinceID :: OandaEnv -> AccountID -> TransactionID -> OANDARequest TransactionsSinceIDResponse+oandaTransactionsSinceID env (AccountID accountId) (TransactionID transId) = OANDARequest request+  where+    request =+      baseApiRequest env "GET" ("/v3/accounts/" ++ accountId ++ "/transactions/sinceid")+      & setRequestQueryString [("id", Just $ BS8.pack $ show transId)]++data TransactionHeartbeat+  = TransactionHeartbeat+  { transactionHeartbeatLastTransactionID :: TransactionID+  , transactionHeartbeatTime :: OandaZonedTime+  } deriving (Show)++deriveJSON (unPrefix "transactionHeartbeat") ''TransactionHeartbeat++data TransactionsStreamResponse+  = StreamTransactionHeartbeat TransactionHeartbeat+  | StreamTransaction Transaction+  deriving (Show)++-- The ToJSON instance is just for debugging, it's not actually correct+deriveToJSON defaultOptions ''TransactionsStreamResponse++instance FromJSON TransactionsStreamResponse where+  parseJSON (Object o) = do+    type' <- o .: "type" :: Parser String+    case type' of+      "HEARTBEAT" -> StreamTransactionHeartbeat <$> parseJSON (Object o)+      _ -> StreamTransaction <$> parseJSON (Object o)+  parseJSON _ = mempty++oandaTransactionStream :: OandaEnv -> AccountID -> OANDAStreamingRequest TransactionsStreamResponse+oandaTransactionStream env (AccountID accountId) =+  OANDAStreamingRequest $ baseStreamingRequest env "GET" ("/v3/accounts/" ++ accountId ++ "/transactions/stream")
stack.yaml view
@@ -1,3 +1,3 @@-resolver: lts-7.9+resolver: nightly-2017-03-02 packages:   - '.'
tests/HLint.hs view
@@ -5,10 +5,11 @@  arguments :: [String] arguments =-    [ "--cpp-simple"-    , "src"-    , "tests"-    ]+  [ "--cpp-simple"+  , "src"+  , "tests"+  , "-i", "Use newtype instead of data"+  ]  main :: IO () main = do