diff --git a/LowFrequencyTrading/TradingOrders.js b/LowFrequencyTrading/TradingOrders.js index 9bbec13b2..e7258a578 100644 --- a/LowFrequencyTrading/TradingOrders.js +++ b/LowFrequencyTrading/TradingOrders.js @@ -151,25 +151,23 @@ exports.newTradingOrders = function newTradingOrders(bot, logger, tradingEngineM /* During the Second cycle we can not cancel orders. That is reserved for the First cycle. */ if (tradingEngine.current.episode.cycle.value === 'Second') { continue } - /* - In the previous steps, we might have discovered that the order was cancelled - at the exchange, or filled, so the order might still not be Open. - If the stage is closing or the order is not Open, we wont be cancelling orders - based on defined events. + + /* Check if we need to cancel the order */ + await checkCancelOrderEvent(tradingEngineStage, executionAlgorithm, executionNode, tradingEngineOrder, tradingSystemOrder) + /* + If by this time the order is closed, we need to clone it and get the close + to the Last node at the Trading Engine data structure. */ - if (tradingEngineStage.status.value !== 'Closing' && tradingEngineOrder.status.value === 'Open') { - - /* Check if we need to Cancel this Order */ - let situationName = checkOrderEvent(tradingSystemOrder.cancelOrderEvent, tradingSystemOrder, executionAlgorithm, executionNode) - if (situationName !== undefined) { - - /* Simulate Order Cancelation, if needed. */ - simulateCancelOrder(tradingEngineStage, tradingSystemOrder, tradingEngineOrder, 'Cancel Event') - - /* Cancel the order at the Exchange, if needed. */ - await exchangeCancelOrder(tradingEngineStage, tradingSystemOrder, tradingEngineOrder, 'Cancel Event') - - updateEndsWithCycle(tradingEngineOrder) + if (tradingEngineOrder.status.value === 'Closed') { + switch (tradingEngineOrder.type) { + case 'Market Order': { + tradingEngineModule.cloneValues(tradingEngineOrder, tradingEngine.last.marketOrders) + break + } + case 'Limit Order': { + tradingEngineModule.cloneValues(tradingEngineOrder, tradingEngine.last.limitOrders) + break + } } } } @@ -177,6 +175,30 @@ exports.newTradingOrders = function newTradingOrders(bot, logger, tradingEngineM } } + async function checkCancelOrderEvent(tradingEngineStage, executionAlgorithm, executionNode, tradingEngineOrder, tradingSystemOrder) { + /* + In the previous steps, we might have discovered that the order was cancelled + at the exchange, or filled, so the order might still not be Open. + If the stage is closing or the order is not Open, we wont be cancelling orders + based on defined events. + */ + if (tradingEngineStage.status.value !== 'Closing' && tradingEngineOrder.status.value === 'Open') { + + /* Check if we need to Cancel this Order */ + let situationName = checkOrderEvent(tradingSystemOrder.cancelOrderEvent, tradingSystemOrder, executionAlgorithm, executionNode) + if (situationName !== undefined) { + + /* Simulate Order Cancelation, if needed. */ + simulateCancelOrder(tradingEngineStage, tradingSystemOrder, tradingEngineOrder, 'Cancel Event') + + /* Cancel the order at the Exchange, if needed. */ + await exchangeCancelOrder(tradingEngineStage, tradingSystemOrder, tradingEngineOrder, 'Cancel Event') + + updateEndsWithCycle(tradingEngineOrder) + } + } + } + function tradingSystemValidations(tradingSystemOrder) { /* Trading System Validations */ if (tradingSystemOrder.config.percentageOfAlgorithmSize === undefined) { badDefinitionUnhandledException(undefined, 'tradingSystemOrder.config.percentageOfAlgorithmSize === undefined', tradingSystemOrder) } diff --git a/LowFrequencyTrading/TradingStages.js b/LowFrequencyTrading/TradingStages.js index ff01988e9..df7848a91 100644 --- a/LowFrequencyTrading/TradingStages.js +++ b/LowFrequencyTrading/TradingStages.js @@ -891,11 +891,14 @@ exports.newTradingStages = function newTradingStages(bot, logger, tradingEngineM either on Base Asset or Quoted Asset. This can happens at any time when we update the sizeFilled and the feesPaid values when we see at the exchange that orders were filled. + Note that the comparison is made with a Rounding Factor in order to avoid rounding problems. */ + const ROUNDING_ERROR_CORRECTION_FACTOR = 1.0000001 + switch (tradingEngineStage.stageDefinedIn.value) { case 'Base Asset': { if ( - tradingEngineStage.stageBaseAsset.sizeFilled.value + tradingEngineStage.stageBaseAsset.sizeFilled.value * ROUNDING_ERROR_CORRECTION_FACTOR >= tradingEngineStage.stageBaseAsset.targetSize.value ) { @@ -907,7 +910,7 @@ exports.newTradingStages = function newTradingStages(bot, logger, tradingEngineM } case 'Quoted Asset': { if ( - tradingEngineStage.stageQuotedAsset.sizeFilled.value + tradingEngineStage.stageQuotedAsset.sizeFilled.value * ROUNDING_ERROR_CORRECTION_FACTOR >= tradingEngineStage.stageQuotedAsset.targetSize.value ) {