3 changed files with 117 additions and 1 deletions
@ -0,0 +1,110 @@
@@ -0,0 +1,110 @@
|
||||
|
||||
{-# LANGUAGE OverloadedStrings #-} |
||||
|
||||
module Test.RoboCom.Positions |
||||
( |
||||
unitTests |
||||
) where |
||||
|
||||
import Test.Tasty |
||||
import Test.Tasty.HUnit |
||||
import Test.Tasty.QuickCheck as QC |
||||
import Test.Tasty.SmallCheck as SC |
||||
|
||||
import ATrade.Types |
||||
import qualified Data.Text as T |
||||
import qualified Data.Map.Strict as M |
||||
import Data.Time.Calendar |
||||
import Data.Time.Clock |
||||
import qualified Data.List as L |
||||
|
||||
import ATrade.RoboCom.Monad |
||||
import ATrade.RoboCom.Positions |
||||
import ATrade.RoboCom.Types |
||||
|
||||
data TestState = TestState |
||||
{ |
||||
positions :: [Position], |
||||
testInt :: Int |
||||
} |
||||
|
||||
defaultState = TestState { |
||||
positions = [], |
||||
testInt = 0 |
||||
} |
||||
|
||||
data TestConfig = TestConfig |
||||
|
||||
instance ParamsHasMainTicker TestConfig where |
||||
mainTicker _ = "TEST_TICKER" |
||||
|
||||
instance StateHasPositions TestState where |
||||
getPositions = positions |
||||
setPositions a p = a { positions = p } |
||||
|
||||
defaultStrategyEnvironment = StrategyEnvironment |
||||
{ |
||||
seInstanceId = "test_instance", |
||||
seAccount = "test_account", |
||||
seVolume = 1, |
||||
seBars = M.empty, |
||||
seLastTimestamp = (UTCTime (fromGregorian 1970 1 1) 0) |
||||
} |
||||
|
||||
unitTests = testGroup "RoboCom.Positions" [ |
||||
testEnterAtMarket, |
||||
testEnterAtMarketSendsAction, |
||||
testEnterAtMarketSubmissionDeadline |
||||
] |
||||
|
||||
testEnterAtMarket = testCase "enterAtMarket creates position in PositionWaitingOpenSubmission state" $ do |
||||
let (newState, actions, _) = runStrategyElement TestConfig defaultState defaultStrategyEnvironment element |
||||
assertBool "Should be exactly 1 position" ((length . positions) newState == 1) |
||||
let pos = head . positions $ newState |
||||
assertBool "Should be in PositionWaitingOpenSubmission" (isPositionWaitingOpenSubmission . posState $ pos) |
||||
let (PositionWaitingOpenSubmission order) = posState pos |
||||
assertBool "Account should be 'test_account'" (orderAccountId order == "test_account") |
||||
assertBool "Security should be 'TEST_TICKER'" (orderSecurity order == "TEST_TICKER") |
||||
assertBool "Order price should be Market" (orderPrice order == Market) |
||||
assertBool "Order quantity should be 1" (orderQuantity order == 1) |
||||
assertBool "Executed order quantity should be 0" (orderExecutedQuantity order == 0) |
||||
assertBool "Order operation should be Buy" (orderOperation order == Buy) |
||||
assertBool "Order signal id should be correct" (orderSignalId order == (SignalId "test_instance" "long" "")) |
||||
where |
||||
element = enterAtMarket "long" Buy |
||||
|
||||
isPositionWaitingOpenSubmission (PositionWaitingOpenSubmission _) = True |
||||
isPositionWaitingOpenSubmission _ = False |
||||
|
||||
testEnterAtMarketSendsAction = testCase "enterAtMarket sends ActionSubmitOrder" $ do |
||||
let (newState, actions, _) = runStrategyElement TestConfig defaultState defaultStrategyEnvironment element |
||||
case (L.find isActionOrder actions) of |
||||
Just (ActionOrder order) -> do |
||||
assertBool "Account should be 'test_account'" (orderAccountId order == "test_account") |
||||
assertBool "Security should be 'TEST_TICKER'" (orderSecurity order == "TEST_TICKER") |
||||
assertBool "Order price should be Market" (orderPrice order == Market) |
||||
assertBool "Order quantity should be 1" (orderQuantity order == 1) |
||||
assertBool "Executed order quantity should be 0" (orderExecutedQuantity order == 0) |
||||
assertBool "Order operation should be Buy" (orderOperation order == Buy) |
||||
assertBool "Order signal id should be correct" (orderSignalId order == (SignalId "test_instance" "long" "")) |
||||
Nothing -> assertFailure "Should be exactly 1 ActionOrder" |
||||
where |
||||
element = enterAtMarket "long" Buy |
||||
|
||||
isActionOrder (ActionOrder _) = True |
||||
isActionOrder _ = False |
||||
|
||||
testEnterAtMarketSubmissionDeadline = testCase "defaultHandler after submission deadline marks position as cancelled" $ do |
||||
let (newState, actions, _) = runStrategyElement TestConfig defaultState defaultStrategyEnvironment element |
||||
let (newState', actions', _) = runStrategyElement TestConfig newState defaultStrategyEnvironment { seLastTimestamp = afterDeadline } $ defaultHandler (NewTick tick) |
||||
let pos = head . positions $ newState' |
||||
assertBool "Cancelled position" (posState pos == PositionCancelled) |
||||
where |
||||
element = enterAtMarket "long" Buy |
||||
afterDeadline = (UTCTime (fromGregorian 1970 1 1) 100) |
||||
tick = Tick { |
||||
security = "TEST_TICKER", |
||||
datatype = LastTradePrice, |
||||
timestamp = afterDeadline, |
||||
value = fromDouble 12.00, |
||||
volume = 1 } |
||||
Loading…
Reference in new issue