import Decimal from 'decimal.js' ; import { createOrderCreator } from '../util/orders' ; import { Store , StreamAction , Middleware , CreatedOrder , ExecutedOrder } from '../types' ; import { ORDER_REQUESTED , ORDER_CREATED , ORDER_PLACED , ORDER_FILLED , ORDER_FAILED , ORDER_CANCEL , ORDER_CANCELLED } from '../constants' ; private param { function } createClient return { Middleware } export function createBrokerRealtime ( createClient ) { return ( store ) => { const client = createClient ( { onFill : ( order ) => { const placedOrder = store . getState ( ) . orders [ order . id ] ; const filledOrder = { id : order . id , identifier : order . identifier , price : new Decimal ( order . price ) , quantity : new Decimal ( order . quantity ) , commission : new Decimal ( order . commission ) , timestamp : order . timestamp } ; store . dispatch ( { type : ORDER_FILLED , payload : { placedOrder , filledOrder , timestamp : order . timestamp } } ) ; } } ) ; const createOrder = createOrderCreator ( store ) ( client . calculateCommission ) ; return ( next ) => ( action ) => { switch ( action . type ) { case ORDER_REQUESTED : { const order = { ... action . payload } ; const createdOrder = createOrder ( order ) ; store . dispatch ( { type : ORDER_CREATED , payload : createdOrder } ) ; break ; } case ORDER_CREATED : { client . executeOrder ( { ... action . payload } ) . then ( ( res ) => { const executedOrder = { id : res . id , identifier : res . identifier , price : res . price , quantity : res . quantity , commission : res . commission , timestamp : res . timestamp } ; store . dispatch ( { type : ORDER_PLACED , payload : { ... executedOrder } } ) ; } ) . catch ( ( error ) => { store . dispatch ( { type : ORDER_FAILED , payload : { timestamp : Date . now ( ) , error } } ) ; } ) ; break ; } case ORDER_CANCEL : { const id = action . payload . id ; if ( store . getState ( ) . orders [ id ] ) { client . cancelOrder ( { id } ) . then ( ( ) => { const cancelledOrder = store . getState ( ) . orders [ id ] ; store . dispatch ( { type : ORDER_CANCELLED , payload : { ... cancelledOrder } } ) ; } ) . catch ( ( error ) => { store . dispatch ( { type : ORDER_FAILED , payload : { timestamp : Date . now ( ) , error } } ) ; } ) ; } else { store . dispatch ( { type : ORDER_FAILED , payload : { timestamp : Date . now ( ) , error : new Error ( `could not find order with id ${ id }` ) } } ) ; } break ; } default : break ; } return next ( action ) ; } ; } ; }