@ -81,6 +81,7 @@ import Data.Aeson
@@ -81,6 +81,7 @@ import Data.Aeson
import qualified Data.List as L
import qualified Data.Map as M
import qualified Data.Text as T
import qualified Data.Text.Lazy as TL
import Data.Time.Clock
data PositionState = PositionWaitingOpenSubmission Order
@ -206,49 +207,49 @@ dispatchPosition event pos = case posState pos of
@@ -206,49 +207,49 @@ dispatchPosition event pos = case posState pos of
then
if posBalance pos == 0
then do
appendToLog $ [ s t| " In PositionWaitingOpen: execution timeout: %?/%? " | ] ( posExecutionDeadline pos ) lastTs
appendToLog $ TL . toStrict $ [ t | " In PositionWaitingOpen: execution timeout: %?/%? " | ] ( posExecutionDeadline pos ) lastTs
cancelOrder $ orderId order
return $ pos { posState = PositionWaitingPendingCancellation , posNextState = Just PositionCancelled }
else do
appendToLog $ [ s t| Order executed ( partially , %? / %? ) : %?| ] ( posBalance pos ) ( orderQuantity order ) order
appendToLog $ TL . toStrict $ [ t | Order executed ( partially , %? / %? ) : %?| ] ( posBalance pos ) ( orderQuantity order ) order
return pos { posState = PositionOpen , posCurrentOrder = Nothing , posExecutionDeadline = Nothing , posEntryTime = Just lastTs }
else case event of
OrderUpdate oid newstate ->
if oid == orderId order
then case newstate of
Cancelled -> do
appendToLog $ [ s t| Order cancelled in PositionWaitingOpen : balance % d , max % d | ] ( posBalance pos ) ( orderQuantity order )
appendToLog $ TL . toStrict $ [ t | Order cancelled in PositionWaitingOpen : balance % d , max % d | ] ( posBalance pos ) ( orderQuantity order )
if posBalance pos /= 0
then return pos { posState = PositionOpen , posCurrentOrder = Nothing , posExecutionDeadline = Nothing , posEntryTime = Just lastTs }
else return pos { posState = PositionCancelled }
Executed -> do
appendToLog $ [ s t| Order executed : %?| ] order
appendToLog $ TL . toStrict $ [ t | Order executed : %?| ] order
return pos { posState = PositionOpen , posCurrentOrder = Nothing , posExecutionDeadline = Nothing , posBalance = balanceForOrder order , posEntryTime = Just lastTs }
Rejected -> do
appendToLog $ [ s t| Order rejected : %?| ] order
appendToLog $ TL . toStrict $ [ t | Order rejected : %?| ] order
return pos { posState = PositionCancelled , posCurrentOrder = Nothing , posExecutionDeadline = Nothing , posBalance = 0 , posEntryTime = Nothing }
_ -> do
appendToLog $ [ s t| In PositionWaitingOpen : order state update : %?| ] newstate
appendToLog $ TL . toStrict $ [ t | In PositionWaitingOpen : order state update : %?| ] newstate
return pos
else return pos -- Update for another position's order
NewTrade trade -> do
appendToLog $ [ s t| Order new trade : %?/%?| ] order trade
appendToLog $ TL . toStrict $ [ t | Order new trade : %?/%?| ] order trade
return $ if tradeOrderId trade == orderId order
then pos { posBalance = if tradeOperation trade == Buy then posBalance pos + tradeQuantity trade else posBalance pos - tradeQuantity trade }
else pos
_ -> return pos
Nothing -> do
appendToLog $ [ s t| W : No current order in PositionWaitingOpen state : %?| ] pos
appendToLog $ TL . toStrict $ [ t | W : No current order in PositionWaitingOpen state : %?| ] pos
return pos
handlePositionOpen = do
lastTs <- view seLastTimestamp <$> getEnvironment
if
| orderDeadline ( posSubmissionDeadline pos ) lastTs -> do
appendToLog $ [ s t| PositionId : %? : Missed submission deadline : %? , remaining in PositionOpen state | ] ( posId pos ) ( posSubmissionDeadline pos )
appendToLog $ TL . toStrict $ [ t | PositionId : %? : Missed submission deadline : %? , remaining in PositionOpen state | ] ( posId pos ) ( posSubmissionDeadline pos )
return pos { posSubmissionDeadline = Nothing , posExecutionDeadline = Nothing }
| orderDeadline ( posExecutionDeadline pos ) lastTs -> do
appendToLog $ [ s t| PositionId : %? : Missed execution deadline : %? , remaining in PositionOpen state | ] ( posId pos ) ( posExecutionDeadline pos )
appendToLog $ TL . toStrict $ [ t | PositionId : %? : Missed execution deadline : %? , remaining in PositionOpen state | ] ( posId pos ) ( posExecutionDeadline pos )
return pos { posExecutionDeadline = Nothing }
| otherwise -> case event of
NewTick tick -> if
@ -307,7 +308,7 @@ dispatchPosition event pos = case posState pos of
@@ -307,7 +308,7 @@ dispatchPosition event pos = case posState pos of
case posCurrentOrder pos of
Just order -> cancelOrder ( orderId order )
_ -> doNothing
appendToLog $ [ s t| Was unable to close position , remaining balance : %?| ] ( posBalance pos )
appendToLog $ TL . toStrict $ [ t | Was unable to close position , remaining balance : %?| ] ( posBalance pos )
return $ pos { posState = PositionOpen , posSubmissionDeadline = Nothing , posExecutionDeadline = Nothing } -- TODO call TimeoutHandler if present
else case ( event , posCurrentOrder pos ) of
( OrderUpdate oid newstate , Just order ) ->
@ -347,7 +348,7 @@ newPosition :: (StateHasPositions s, MonadRobot m c s) => Order -> T.Text -> Tic
@@ -347,7 +348,7 @@ newPosition :: (StateHasPositions s, MonadRobot m c s) => Order -> T.Text -> Tic
newPosition order account tickerId operation quantity submissionDeadline = do
lastTs <- view seLastTimestamp <$> getEnvironment
let position = Position {
posId = [ s t|%?/%?/%?/%?/%?| ] account tickerId operation quantity lastTs ,
posId = TL . toStrict $ [ t |%?/%?/%?/%?/%?| ] account tickerId operation quantity lastTs ,
posAccount = account ,
posTicker = tickerId ,
posBalance = 0 ,
@ -364,7 +365,7 @@ newPosition order account tickerId operation quantity submissionDeadline = do
@@ -364,7 +365,7 @@ newPosition order account tickerId operation quantity submissionDeadline = do
}
modifyPositions ( \ p -> position : p )
positions <- getPositions <$> getState
appendToLog $ [ s t| All positions : %?| ] positions
appendToLog $ TL . toStrict $ [ t | All positions : %?| ] positions
return position
reapDeadPositions :: ( StateHasPositions s ) => EventCallback c s
@ -509,7 +510,7 @@ enterAtLimitForTickerWithParams :: (StateHasPositions s, MonadRobot m c s) => Ti
@@ -509,7 +510,7 @@ enterAtLimitForTickerWithParams :: (StateHasPositions s, MonadRobot m c s) => Ti
enterAtLimitForTickerWithParams tickerId timeToCancel account quantity signalId price operation = do
lastTs <- view seLastTimestamp <$> getEnvironment
submitOrder order
appendToLog $ [ s t| enterAtLimit : %? , deadline : %?| ] tickerId ( timeToCancel ` addUTCTime ` lastTs )
appendToLog $ TL . toStrict $ [ t | enterAtLimit : %? , deadline : %?| ] tickerId ( timeToCancel ` addUTCTime ` lastTs )
newPosition order account tickerId operation quantity 20 >>=
modifyPosition ( \ p -> p { posExecutionDeadline = Just $ timeToCancel ` addUTCTime ` lastTs } )
where
@ -579,7 +580,7 @@ exitAtLimit timeToCancel price position operationSignalName = do
@@ -579,7 +580,7 @@ exitAtLimit timeToCancel price position operationSignalName = do
Just order -> cancelOrder ( orderId order )
Nothing -> doNothing
submitOrder ( closeOrder inst )
appendToLog $ [ s t| exitAtLimit : %? , deadline : %?| ] ( posTicker position ) ( timeToCancel ` addUTCTime ` lastTs )
appendToLog $ TL . toStrict $ [ t | exitAtLimit : %? , deadline : %?| ] ( posTicker position ) ( timeToCancel ` addUTCTime ` lastTs )
modifyPosition ( \ pos ->
pos { posCurrentOrder = Nothing ,
posState = PositionWaitingCloseSubmission ( closeOrder inst ) ,