From b4ead563668b59eb8a3a1a65c418b15ad40e0cc2 Mon Sep 17 00:00:00 2001 From: Denis Tereshkin Date: Sun, 15 Oct 2017 21:08:02 +0700 Subject: [PATCH] Price: more tests --- src/ATrade/Price.hs | 13 ++++++++----- src/ATrade/Types.hs | 5 ++++- test/TestTypes.hs | 15 ++++++++++++++- 3 files changed, 26 insertions(+), 7 deletions(-) diff --git a/src/ATrade/Price.hs b/src/ATrade/Price.hs index 19e70bb..a44515a 100644 --- a/src/ATrade/Price.hs +++ b/src/ATrade/Price.hs @@ -16,27 +16,30 @@ data Price = Price { giga :: Int64 giga = 1000000000 +mega :: Int64 +mega = 1000000 + instance Num Price where a + b = Price { priceQuants = priceQuants a + priceQuants b } a * b = Price { - priceQuants = (priceQuants a * priceQuants b) `div` giga } + priceQuants = (priceQuants a * priceQuants b) `div` mega } abs a = a { priceQuants = abs (priceQuants a) } signum a = a { priceQuants = signum (priceQuants a)} - fromInteger int = Price { priceQuants = giga * fromInteger int} + fromInteger int = Price { priceQuants = mega * fromInteger int} negate a = a { priceQuants = negate (priceQuants a) } toDouble :: Price -> Double -toDouble p = fromIntegral (priceQuants p) / fromIntegral giga +toDouble p = fromIntegral (priceQuants p) / fromIntegral mega fromDouble :: Double -> Price -fromDouble d = Price { priceQuants = truncate (d * fromIntegral giga) } +fromDouble d = Price { priceQuants = truncate (d * fromIntegral mega) } decompose :: Price -> (Int64, Int32) -decompose Price{priceQuants = p} = (p `div` giga, (fromInteger . toInteger) $ p `mod` giga) +decompose Price{priceQuants = p} = (p `div` mega, (fromInteger . toInteger) $ p `mod` mega) diff --git a/src/ATrade/Types.hs b/src/ATrade/Types.hs index 9c4b2c8..8f07f37 100644 --- a/src/ATrade/Types.hs +++ b/src/ATrade/Types.hs @@ -21,11 +21,14 @@ module ATrade.Types ( ServerSecurityParams(..), defaultServerSecurityParams, ClientSecurityParams(..), - defaultClientSecurityParams + defaultClientSecurityParams, + module ATrade.Price ) where import GHC.Generics +import ATrade.Price + import Control.Monad import Data.Aeson import Data.Aeson.Types diff --git a/test/TestTypes.hs b/test/TestTypes.hs index f3c0216..4047e36 100644 --- a/test/TestTypes.hs +++ b/test/TestTypes.hs @@ -36,6 +36,9 @@ properties = testGroup "Types" [ , testPrice1 , testPrice2 , testPriceDecompose + , testPriceAddition + , testPriceMultiplication + , testPriceSubtraction ] testTickSerialization = QC.testProperty "Deserialize serialized tick" @@ -95,5 +98,15 @@ testPrice2 = QC.testProperty "toDouble . fromDouble $ Price" $ testPriceDecompose = QC.testProperty "Price decompose" (\p -> let (i, f) = decompose p in - i * 1000000000 + (fromInteger . fromIntegral) f == priceQuants p) + i * 1000000 + (fromInteger . fromIntegral) f == priceQuants p) + +testPriceAddition = QC.testProperty "Price addition" + (\(p1, p2) -> abs (toDouble p1 + toDouble p2 - toDouble (p1 + p2)) < 0.00001) + +testPriceMultiplication = QC.testProperty "Price multiplication" $ + QC.forAll (arbitrary `suchThat` (\(p1, p2) -> p1 < 100000 && p2 < 100000)) + (\(p1, p2) -> abs (toDouble p1 + toDouble p2 - toDouble (p1 + p2)) < 0.00001) + +testPriceSubtraction = QC.testProperty "Price subtraction" + (\(p1, p2) -> abs (toDouble p1 - toDouble p2 - toDouble (p1 - p2)) < 0.00001)