import Decimal from 'decimal.js' ; import { Store , StreamAction , CreatedOrder , GuardOptions , Middleware } from '../types' ; import { ORDER_CREATED , ORDER_REJECTED } from '../constants' ; private param { Object } options return { Middleware } export function createGuard ( options ) { return ( store ) => { const isRestrictedAsset = ( order ) => { if ( options . restricted && options . restricted . indexOf ( order . identifier ) > - 1 ) { return true ; } return false ; } ; const isDisallowedShort = ( order ) => { const { quantity , identifier } = order ; if ( ( ! options . shorting ) && quantity . isNegative ( ) ) { const instrument = store . getState ( ) . positions . instruments [ identifier ] ; return ! instrument || new Decimal ( instrument . quantity ) . lt ( Decimal . abs ( quantity ) ) ; } return false ; } ; const isDisallowedMargin = ( order ) => { if ( ! options . margin ) { const { quantity , price , commission } = order ; const cash = store . getState ( ) . capital . cash ; const cost = Decimal . mul ( quantity , price ) . add ( commission ) ; if ( cash . lt ( cost ) ) { return true ; } } return false ; } ; return ( next ) => ( action ) => { switch ( action . type ) { case ORDER_CREATED : { const order = < CreatedOrder > action . payload ; if ( isRestrictedAsset ( order ) || isDisallowedShort ( order ) || isDisallowedMargin ( order ) ) { return next ( { type : ORDER_REJECTED , payload : { ... action . payload } } ) ; } return next ( action ) ; } default : break ; } return next ( action ) ; } ; } ; }