Simple agent-based exchange simulator
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

60 lines
2.2 KiB

module TestLOB
(
tests
) where
import ATrade.ESim.Core
(MatchingAction (..), PriceTick (PriceTick), Volume (..), addToLob, emptyLob, executeMatchingActions)
import ATrade.Types (Operation (..), Order (..), OrderPrice (..), OrderState (..), Price, SignalId (..))
import Hedgehog
import Hedgehog.Gen qualified as Gen
import Hedgehog.Range qualified as Range
import Test.Tasty
import Test.Tasty.Hedgehog
tests :: TestTree
tests = testGroup "LimitOrderBook"
[
testProperty "add to empty LOB => enqueues order" prop_add_to_empty_lob,
testProperty "full match" prop_full_match
]
prop_add_to_empty_lob :: Property
prop_add_to_empty_lob = property $ do
priceTick <- forAll $ Gen.integral (Range.linear 1 100000)
order <- forAll $
Order <$> Gen.integral (Range.linear 1 100000)
<*> Gen.text (Range.linear 1 50) Gen.unicode
<*> Gen.text (Range.linear 1 50) Gen.unicode
<*> pure (Limit $ fromInteger priceTick * tickSize)
<*> Gen.integral (Range.linear 1 10000)
<*> pure 0
<*> pure Buy
<*> pure Unsubmitted
<*> pure (SignalId "test" "foo" "")
addToLob order lob === [Enqueue (orderId order) (PriceTick . fromInteger $ priceTick) (Volume . fromIntegral $ orderQuantity order) (orderOperation order)]
where
lob = emptyLob "Test" tickSize
tickSize :: Price
tickSize = 0.1
prop_full_match :: Property
prop_full_match = property $ do
priceTick <- forAll $ Gen.integral (Range.linear 1 100000)
order <- forAll $
Order <$> Gen.integral (Range.linear 1 100000)
<*> Gen.text (Range.linear 1 50) Gen.unicode
<*> Gen.text (Range.linear 1 50) Gen.unicode
<*> pure Market
<*> Gen.integral (Range.linear 1 10000)
<*> pure 0
<*> pure Buy
<*> pure Unsubmitted
<*> pure (SignalId "test" "foo" "")
addToLob order (lob order priceTick) === [Match (orderId order) 1 (orderOperation order) (PriceTick priceTick) (Volume . fromIntegral $ orderQuantity order)]
where
lob order priceTick = executeMatchingActions lob0 [Enqueue 1 (PriceTick priceTick) (Volume . fromIntegral $ orderQuantity order) Sell]
lob0 = emptyLob "Test" tickSize
tickSize = 0.1