Execution layer for algorithmic trading
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.

131 lines
4.7 KiB

{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE OverloadedStrings #-}
module ATrade.Driver.Junction
(
junctionMain
) where
import ATrade.Driver.Junction.Types (StrategyDescriptor (..),
StrategyInstance (..),
StrategyInstanceDescriptor (..))
import ATrade.RoboCom.Types (Ticker (..))
import Control.Concurrent (forkIO)
import Control.Concurrent.Async (forConcurrently_)
import Control.Concurrent.STM (atomically)
import Control.Concurrent.STM.TQueue (newTQueueIO)
import Control.Concurrent.STM.TVar (newTVarIO)
import Data.Aeson (FromJSON (..), ToJSON (..),
decode, object, withObject,
(.:), (.=))
import qualified Data.ByteString as B
import qualified Data.ByteString.Lazy as BL
import Data.IORef
import qualified Data.Map.Strict as M
import Data.Maybe (fromMaybe)
import Data.Semigroup ((<>))
import qualified Data.Text as T
import Data.Text.IO (readFile)
import Dhall (FromDhall, auto, input)
import GHC.Generics (Generic)
import Options.Applicative (Parser, execParser, fullDesc,
header, help, helper, info,
long, metavar, progDesc, short,
strOption, (<**>))
import Prelude hiding (readFile)
4 years ago
data BigConfig c = BigConfig {
confTickers :: [Ticker],
confStrategy :: c
}
instance (FromJSON c) => FromJSON (BigConfig c) where
parseJSON = withObject "object" (\obj -> BigConfig <$>
obj .: "tickers" <*>
obj .: "params")
instance (ToJSON c) => ToJSON (BigConfig c) where
toJSON conf = object ["tickers" .= confTickers conf,
"params" .= confStrategy conf ]
data ProgramOptions =
ProgramOptions
{
configPath :: FilePath
}
data ProgramConfiguration =
ProgramConfiguration
{
brokerEndpoint :: T.Text,
brokerServerCert :: Maybe FilePath,
brokerClientCert :: Maybe FilePath,
quotesourceEndpoint :: T.Text,
quotesourceServerCert :: Maybe FilePath,
quotesourceClientCert :: Maybe FilePath,
qhpEndpoint :: T.Text,
qtisEndpoint :: T.Text,
redisSocket :: T.Text,
globalLog :: FilePath,
instances :: [StrategyInstanceDescriptor]
} deriving (Generic, Show)
instance FromDhall ProgramConfiguration
4 years ago
load :: T.Text -> IO (Maybe B.ByteString)
load = undefined
junctionMain :: M.Map T.Text StrategyDescriptor -> IO ()
junctionMain descriptors = do
opts <- parseOptions
cfg <- readFile (configPath opts) >>= input auto
bars <- newTVarIO M.empty
strategies <- mkStrategies (instances cfg)
start strategies bars
where
parseOptions = execParser options
options = info (optionsParser <**> helper)
(fullDesc <>
progDesc "Robocom-zero junction mode driver" <>
header "robocom-zero-junction")
mkStrategies :: [StrategyInstanceDescriptor] -> IO [StrategyInstance]
mkStrategies = mapM mkStrategy
mkStrategy :: StrategyInstanceDescriptor -> IO StrategyInstance
mkStrategy desc = do
sState <- load (stateKey desc)
sCfg <- load (configKey desc)
case M.lookup (strategyId desc) descriptors of
4 years ago
Just (StrategyDescriptor _sName sCallback sDefState) ->
case (sCfg >>= decode . BL.fromStrict, fromMaybe sDefState (sState >>= decode . BL.fromStrict)) of
(Just bigConfig, pState) -> do
cfgRef <- newIORef (confStrategy bigConfig)
stateRef <- newIORef pState
return $ StrategyInstance
{
strategyInstanceId = strategyName desc,
strategyEventCallback = sCallback,
strategyState = stateRef,
strategyConfig = cfgRef
}
4 years ago
_ -> error "Can't read state and config"
_ -> error $ "Can't find strategy: " ++ T.unpack (strategyId desc)
start strategies bars = undefined
optionsParser :: Parser ProgramOptions
optionsParser = ProgramOptions
<$> strOption
(long "config" <>
short 'c' <>
metavar "FILENAME" <>
help "Configuration file path")