All calculated

This commit is contained in:
Luis Fernando Molina committed 2020-08-02 13:04:00 +02:00
1 parent 89d6edc343
commit 0fc5cb2929
4 files changed
+318 -261

No files matched your search

+1 -11
View File
@@ -77,17 +77,7 @@
let type // CCXT: a string literal type of order, ccxt currently unifies market and limit orders only
let side // CCXT: a string literal for the direction of your order, buy or sell
let symbol = bot.market.baseAsset + '/' + bot.market.quotedAsset // CCXT: a string literal symbol of the market you wish to trade on, like BTC/USD, ZEC/ETH, DOGE/DASH, etc
let amount // CCXT: how much of currency you want to trade
/*
We need at the amount a value denominated in Base Asset, if we do not
have it, then we convert the value we have in Quoteed Asset.
*/
if (tradingEngineOrder.orderBaseAsset.size.value > 0) {
amount = tradingEngineOrder.orderBaseAsset.size.value
} else {
amount = tradingEngineOrder.orderQuotedAsset.size.value / tradingEngineOrder.rate.value
}
let amount = tradingEngineOrder.orderBaseAsset.size.value // CCXT: how much of currency you want to trade, in Base Asset.
switch (tradingSystemOrder.type) {
case 'Market Buy Order': {
+165 -125
View File
@@ -217,11 +217,11 @@ exports.newTradingExecution = function newTradingExecution(bot, logger, tradingE
/* Check Size: We are not going to create Orders which size is equal or less to zero. */
if (traingEngineOrderAsset.size.value <= 0) { return }
/* Place Order at the Exchange */
/* Place Order at the Exchange, if needed. */
let result = await createOrderAtExchange(tradingSystemOrder, tradingEngineOrder)
if (result !== true) { return }
/* Update Stage Counters */
/* Update Stage Size */
tradingEngineStage.stageBaseAsset.size.value = tradingEngineStage.stageBaseAsset.size.value + tradingEngineOrder.orderBaseAsset.size.value
tradingEngineStage.stageBaseAsset.size.value = global.PRECISE(tradingEngineStage.stageBaseAsset.size.value, 10)
tradingEngineStage.stageQuotedAsset.size.value = tradingEngineStage.stageQuotedAsset.size.value + tradingEngineOrder.orderQuotedAsset.size.value
@@ -392,18 +392,24 @@ exports.newTradingExecution = function newTradingExecution(bot, logger, tradingE
/* Filter by what is defined at the Strategy */
if (tradingSystemOrder.simulatedExchangeEvents === undefined) { return }
let previousSizeFilled = tradingEngineOrderAsset.sizeFilled.value
let previousPercentageFilled = tradingEngineOrder.orderStatistics.percentageFilled.value
let previousAmountReceived = tradingEngineOrder.orderStatistics.amountReceived.value
let previousFeesPaid = tradingEngineOrder.orderStatistics.feesPaid.value
let previousBaseAssetSizeFilled = tradingEngineOrder.orderBaseAsset.sizeFilled.value
let previousQuotedAssetSizeFilled = tradingEngineOrder.orderQuotedAsset.sizeFilled.value
let previousBaseAssetFeesPaid = tradingEngineOrder.orderBaseAsset.feesPaid.value
let previousQuotedAssetFeesPaid = tradingEngineOrder.orderQuotedAsset.feesPaid.value
actualRateSimulation()
feesPaidSimulation()
orderFillingSimulation()
percentageFilledSimulation()
sizeFilledSimulation()
amountReceivedSimulation()
doTheAccounting(tradingSystemOrder, tradingEngineOrder, previousSizeFilled, previousPercentageFilled, previousFeesPaid)
doTheAccounting(
tradingSystemOrder,
tradingEngineOrder,
previousBaseAssetSizeFilled,
previousQuotedAssetSizeFilled,
previousBaseAssetFeesPaid,
previousQuotedAssetFeesPaid
)
/* If the Stage is Closing and this order is still open, we need to cancel it now */
if (stageIsClosing === true && tradingEngineOrder.status.value !== 'Closed') {
@@ -462,8 +468,21 @@ exports.newTradingExecution = function newTradingExecution(bot, logger, tradingE
/* Based on the Trading System Definition */
if (tradingSystemOrder.simulatedExchangeEvents.simulatedFeesPaid !== undefined) {
if (tradingSystemOrder.simulatedExchangeEvents.simulatedFeesPaid.config.percentage !== undefined) {
if (tradingEngineOrder.orderStatistics.feesPaid.value === tradingEngineOrder.orderStatistics.feesPaid.config.initialValue) {
tradingEngineOrder.orderStatistics.feesPaid.value = tradingEngineOrder.size.value * tradingSystemOrder.simulatedExchangeEvents.simulatedFeesPaid.config.percentage / 100
if (tradingEngineOrder.orderBaseAsset.feesPaid.value === tradingEngineOrder.orderBaseAsset.feesPaid.config.initialValue) {
tradingEngineOrder.orderBaseAsset.feesPaid.value =
tradingEngineOrder.orderBaseAsset.size.value *
tradingSystemOrder.simulatedExchangeEvents.simulatedFeesPaid.config.percentage / 100
calculatedBasedOnTradingSystem = true
}
if (tradingEngineOrder.orderQuotedAsset.feesPaid.value === tradingEngineOrder.orderQuotedAsset.feesPaid.config.initialValue) {
tradingEngineOrder.orderQuotedAsset.feesPaid.value =
tradingEngineOrder.orderQuotedAsset.size.value *
tradingSystemOrder.simulatedExchangeEvents.simulatedFeesPaid.config.percentage / 100
calculatedBasedOnTradingSystem = true
}
}
@@ -474,19 +493,36 @@ exports.newTradingExecution = function newTradingExecution(bot, logger, tradingE
/* Fees are simulated based on the Session Paremeters */
switch (tradingEngineOrder.type) {
case 'Market Order': {
tradingEngineOrder.orderStatistics.feesPaid.value = tradingEngineOrder.size.value * bot.SESSION.parameters.feeStructure.config.taker / 100
tradingEngineOrder.orderBaseAsset.feesPaid.value =
tradingEngineOrder.orderBaseAsset.size.value *
bot.SESSION.parameters.feeStructure.config.taker / 100
tradingEngineOrder.orderQuotedAsset.feesPaid.value =
tradingEngineOrder.orderQuotedAsset.size.value *
bot.SESSION.parameters.feeStructure.config.taker / 100
break
}
case 'Limit Order': {
tradingEngineOrder.orderStatistics.feesPaid.value = tradingEngineOrder.size.value * bot.SESSION.parameters.feeStructure.config.maker / 100
tradingEngineOrder.orderBaseAsset.feesPaid.value =
tradingEngineOrder.orderBaseAsset.size.value *
bot.SESSION.parameters.feeStructure.config.maker / 100
tradingEngineOrder.orderQuotedAsset.feesPaid.value =
tradingEngineOrder.orderQuotedAsset.size.value *
bot.SESSION.parameters.feeStructure.config.maker / 100
break
}
}
}
tradingEngineOrder.orderStatistics.feesPaid.value = global.PRECISE(tradingEngineOrder.orderStatistics.feesPaid.value, 10)
tradingEngineOrder.orderBaseAsset.feesPaid.value = global.PRECISE(tradingEngineOrder.orderBaseAsset.feesPaid.value, 10)
tradingEngineOrder.orderQuotedAsset.feesPaid.value = global.PRECISE(tradingEngineOrder.orderQuotedAsset.feesPaid.value, 10)
}
function orderFillingSimulation() {
function percentageFilledSimulation() {
/* Order Filling Simulation */
if (tradingSystemOrder.simulatedExchangeEvents.simulatedPartialFill !== undefined) {
if (tradingSystemOrder.simulatedExchangeEvents.simulatedPartialFill.config.fillProbability !== undefined) {
@@ -515,34 +551,16 @@ exports.newTradingExecution = function newTradingExecution(bot, logger, tradingE
function sizeFilledSimulation() {
/* Size Filled */
tradingEngineOrder.orderStatistics.sizeFilled.value = tradingEngineOrder.size.value * tradingEngineOrder.orderStatistics.percentageFilled.value / 100
tradingEngineOrder.orderStatistics.sizeFilled.value = global.PRECISE(tradingEngineOrder.orderStatistics.sizeFilled.value, 10)
}
tradingEngineOrder.orderBaseAsset.sizeFilled.value =
tradingEngineOrder.orderBaseAsset.size.value *
tradingEngineOrder.orderStatistics.percentageFilled.value / 100
function amountReceivedSimulation() {
/* Amount Received */
let calculatedBasedOnOrderDefinition = false
tradingEngineOrder.orderQuotedAsset.sizeFilled.value =
tradingEngineOrder.orderQuotedAsset.size.value *
tradingEngineOrder.orderStatistics.percentageFilled.value / 100
/* Based on the Order Definition */
if (tradingSystemOrder.simulatedExchangeEvents !== undefined) {
if (tradingSystemOrder.simulatedExchangeEvents.simulatedActualRate !== undefined) {
if (tradingSystemOrder.simulatedExchangeEvents.simulatedActualRate.formula !== undefined) {
let simulatedActualRate = tradingSystem.formulas.get(tradingSystemOrder.simulatedExchangeEvents.simulatedActualRate.formula.id)
if (simulatedActualRate !== undefined) {
tradingEngineOrder.orderStatistics.amountReceived.value = tradingEngineOrder.orderStatistics.sizeFilled.value * simulatedActualRate
tradingEngineOrder.orderStatistics.amountReceived.value = global.PRECISE(tradingEngineOrder.orderStatistics.amountReceived.value, 10)
calculatedBasedOnOrderDefinition = true
}
}
}
}
/* Based on Candle Close Value */
if (calculatedBasedOnOrderDefinition === false) {
let simulatedActualRate = tradingEngine.current.candle.close.value
tradingEngineOrder.orderStatistics.amountReceived.value = tradingEngineOrder.orderStatistics.sizeFilled.value * simulatedActualRate
tradingEngineOrder.orderStatistics.amountReceived.value = global.PRECISE(tradingEngineOrder.orderStatistics.amountReceived.value, 10)
}
tradingEngineOrder.orderBaseAsset.sizeFilled.value = global.PRECISE(tradingEngineOrder.orderBaseAsset.sizeFilled.value, 10)
tradingEngineOrder.orderQuotedAsset.sizeFilled.value = global.PRECISE(tradingEngineOrder.orderQuotedAsset.sizeFilled.value, 10)
}
}
@@ -776,24 +794,57 @@ exports.newTradingExecution = function newTradingExecution(bot, logger, tradingE
tradingEngine.current.balance.quotedAsset.value = global.PRECISE(tradingEngine.current.balance.quotedAsset.value, 10)
}
function simulateCancelOrder(tradingSystemOrder, tradingEngineOrder, exitType) {
}
/* Filter by Session Type */
switch (bot.SESSION.type) {
case 'Backtesting Session': {
break
}
case 'Live Trading Session': {
return
}
case 'Fordward Testing Session': {
return
}
case 'Paper Trading Session': {
break
}
function simulateCancelOrder(tradingSystemOrder, tradingEngineOrder, exitType) {
/* Filter by Session Type */
switch (bot.SESSION.type) {
case 'Backtesting Session': {
break
}
case 'Live Trading Session': {
return
}
case 'Fordward Testing Session': {
return
}
case 'Paper Trading Session': {
break
}
}
/* Close this Order */
tradingEngineOrder.status.value = 'Closed'
tradingEngineOrder.exitType.value = exitType
/* Initialize this */
tradingEngine.current.distanceToEvent.closeOrder.value = 1
recalculateStageSize(tradingEngineOrder)
}
async function exchangeCancelOrder(tradingSystemOrder, tradingEngineOrder, exitType) {
/* Filter by Session Type */
switch (bot.SESSION.type) {
case 'Backtesting Session': {
return
}
case 'Live Trading Session': {
break
}
case 'Fordward Testing Session': {
break
}
case 'Paper Trading Session': {
return
}
}
/* Check if we can cancel the order at the Exchange. */
let result = await exchangeAPIModule.cancelOrder(tradingSystemOrder, tradingEngineOrder)
if (result === true) {
/* Close this Order */
tradingEngineOrder.status.value = 'Closed'
tradingEngineOrder.exitType.value = exitType
@@ -801,85 +852,74 @@ exports.newTradingExecution = function newTradingExecution(bot, logger, tradingE
/* Initialize this */
tradingEngine.current.distanceToEvent.closeOrder.value = 1
/* Since the order was cancelled, we remove the unfilled amount of the order from here */
let unfilledPercentage = 100 - tradingEngineOrder.orderStatistics.percentageFilled.value
let unfilledSize = tradingEngineOrder.size.value * unfilledPercentage / 100
stageOrdersSize.value = stageOrdersSize.value - unfilledSize
stageOrdersSize.value = global.PRECISE(stageOrdersSize.value, 10)
/*
Perhaps the order was filled a bit more between the last time we checked and when it was cancelled.
To sync our accounting, we need to check the order one last time and if it changed, fix it.
*/
let order = await exchangeAPIModule.getOrder(tradingSystemOrder, tradingEngineOrder)
if (order === undefined) { return }
syncWithExchange(tradingSystemOrder, tradingEngineOrder, order)
recalculateStageSize()
}
}
async function exchangeCancelOrder(tradingSystemOrder, tradingEngineOrder, exitType) {
function recalculateStageSize(tradingEngineOrder) {
/*
Since the order is Cancelled, we need to adjust the stage size. Remember that the Stage Size
accumulates for each asset, the order size placed at the exchange. A cancelation means that
only the part filled can be considered placed, so we need to substract from the stage size
the remainder. To achieve this with the information we currently have, we are going first
to unaccount the order size, and the account only the sizeFilled + the feesPaid.
*/
tradingEngineStage.stageBaseAsset.size.value =
tradingEngineStage.stageBaseAsset.size.value -
tradingEngineOrder.orderBaseAsset.size.value
tradingEngineStage.stageQuotedAsset.size.value =
tradingEngineStage.stageQuotedAsset.size.value -
tradingEngineOrder.orderQuotedAsset.size.value
/* Filter by Session Type */
switch (bot.SESSION.type) {
case 'Backtesting Session': {
return
tradingEngineStage.stageBaseAsset.size.value =
tradingEngineStage.stageBaseAsset.size.value +
tradingEngineOrder.orderBaseAsset.sizeFilled.value +
tradingEngineOrder.orderBaseAsset.feesPaid.value
tradingEngineStage.stageQuotedAsset.size.value =
tradingEngineStage.stageQuotedAsset.size.value +
tradingEngineOrder.orderQuotedAsset.sizeFilled.value +
tradingEngineOrder.orderQuotedAsset.feesPaid.value
tradingEngineStage.stageBaseAsset.size.value = global.PRECISE(tradingEngineStage.stageBaseAsset.size.value, 10)
tradingEngineStage.stageQuotedAsset.size.value = global.PRECISE(tradingEngineStage.stageQuotedAsset.size.value, 10)
}
function checkOrderEvent(event, order, executionAlgorithm, executionNode) {
if (event !== undefined) {
for (let k = 0; k < event.situations.length; k++) {
let situation = event.situations[k]
let passed
if (situation.conditions.length > 0) {
passed = true
}
case 'Live Trading Session': {
break
}
case 'Fordward Testing Session': {
break
}
case 'Paper Trading Session': {
return
}
}
/* Check if we can cancel the order at the Exchange. */
let result = await exchangeAPIModule.cancelOrder(tradingSystemOrder, tradingEngineOrder)
if (result === true) {
/* Close this Order */
tradingEngineOrder.status.value = 'Closed'
tradingEngineOrder.exitType.value = exitType
passed = tradingSystem.checkConditions(situation, passed)
/* Initialize this */
tradingEngine.current.distanceToEvent.closeOrder.value = 1
tradingSystem.values.push([situation.id, passed])
if (passed) {
tradingSystem.highlights.push(situation.id)
tradingSystem.highlights.push(event.id)
tradingSystem.highlights.push(order.id)
tradingSystem.highlights.push(executionAlgorithm.id)
tradingSystem.highlights.push(executionNode.id)
/* Since the order was cancelled, we remove the unfilled amount of the order from here */
let unfilledPercentage = 100 - tradingEngineOrder.orderStatistics.percentageFilled.value
let unfilledSize = tradingEngineOrder.size.value * unfilledPercentage / 100
stageOrdersSize.value = stageOrdersSize.value - unfilledSize
stageOrdersSize.value = global.PRECISE(stageOrdersSize.value, 10)
/*
Perhaps the order was filled a bit more between the last time we checked and when it was cancelled.
To sync our accounting, we need to check the order one last time and if it changed, fix it.
*/
let order = await exchangeAPIModule.getOrder(tradingSystemOrder, tradingEngineOrder)
if (order === undefined) { return }
syncWithExchange(tradingSystemOrder, tradingEngineOrder, order)
}
}
function checkOrderEvent(event, order, executionAlgorithm, executionNode) {
if (event !== undefined) {
for (let k = 0; k < event.situations.length; k++) {
let situation = event.situations[k]
let passed
if (situation.conditions.length > 0) {
passed = true
}
passed = tradingSystem.checkConditions(situation, passed)
tradingSystem.values.push([situation.id, passed])
if (passed) {
tradingSystem.highlights.push(situation.id)
tradingSystem.highlights.push(event.id)
tradingSystem.highlights.push(order.id)
tradingSystem.highlights.push(executionAlgorithm.id)
tradingSystem.highlights.push(executionNode.id)
announcementsModule.makeAnnoucements(event)
return situation.name // if the event is triggered, we return the name of the situation that passed
}
announcementsModule.makeAnnoucements(event)
return situation.name // if the event is triggered, we return the name of the situation that passed
}
}
}
}
}
}
+35 -101
View File
@@ -9,10 +9,6 @@ exports.newTradingPosition = function newTradingPosition(bot, logger, tradingEng
closePosition: closePosition,
applyStopLossFormula: applyStopLossFormula,
applyTakeProfitFormula: applyTakeProfitFormula,
preventStopLossDistortion: preventStopLossDistortion,
applySlippageToStopLoss: applySlippageToStopLoss,
preventTakeProfitDistortion: preventTakeProfitDistortion,
applySlippageToTakeProfit: applySlippageToTakeProfit,
updateStopLoss: updateStopLoss,
updateTakeProfit: updateTakeProfit,
initializeSizeAndRate: initializeSizeAndRate,
@@ -20,6 +16,7 @@ exports.newTradingPosition = function newTradingPosition(bot, logger, tradingEng
updateStatus: updateStatus,
updateCounters: updateCounters,
updateStatistics: updateStatistics,
updateResults: updateResults,
resetPosition: resetPosition,
initialize: initialize,
finalize: finalize
@@ -179,71 +176,6 @@ exports.newTradingPosition = function newTradingPosition(bot, logger, tradingEng
}
}
function preventStopLossDistortion() {
/*
Hit Point Validation
This prevents misscalculations when a formula places the stop loss in this case way beyond the market price.
If we take the stop loss value at those situation would be a huge distortion of facts.
*/
if (bot.sessionAndMarketBaseAssetsAreEqual) {
if (tradingEngine.current.position.stopLoss.value < tradingEngine.current.candle.min.value) {
tradingEngine.current.position.stopLoss.value = tradingEngine.current.candle.min.value
}
} else {
if (tradingEngine.current.position.stopLoss.value > tradingEngine.current.candle.max.value) {
tradingEngine.current.position.stopLoss.value = tradingEngine.current.candle.max.value
}
}
}
function applySlippageToStopLoss() {
let slippedStopLoss = tradingEngine.current.position.stopLoss.value
/* Apply the Slippage */
let slippageAmount = slippedStopLoss * bot.SESSION.parameters.slippage.config.stopLoss / 100
if (bot.sessionAndMarketBaseAssetsAreEqual) {
slippedStopLoss = slippedStopLoss + slippageAmount
} else {
slippedStopLoss = slippedStopLoss - slippageAmount
}
tradingEngine.current.position.endRate.value = slippedStopLoss
}
function preventTakeProfitDistortion() {
/*
Hit Point Validation:
This prevents misscalculations when a formula places the take profit in this case way beyond the market price.
If we take the stop loss value at those situation would be a huge distortion of facts.
*/
if (bot.sessionAndMarketBaseAssetsAreEqual) {
if (tradingEngine.current.position.takeProfit.value > tradingEngine.current.candle.max.value) {
tradingEngine.current.position.takeProfit.value = tradingEngine.current.candle.max.value
}
} else {
if (tradingEngine.current.position.takeProfit.value < tradingEngine.current.candle.min.value) {
tradingEngine.current.position.takeProfit.value = tradingEngine.current.candle.min.value
}
}
}
function applySlippageToTakeProfit() {
let slippedTakeProfit = tradingEngine.current.position.takeProfit.value
/* Apply the Slippage */
let slippageAmount = slippedTakeProfit * bot.SESSION.parameters.slippage.config.takeProfit / 100
if (bot.sessionAndMarketBaseAssetsAreEqual) {
slippedTakeProfit = slippedTakeProfit + slippageAmount
} else {
slippedTakeProfit = slippedTakeProfit - slippageAmount
}
tradingEngine.current.position.endRate.value = slippedTakeProfit
}
function updateEnds() {
if (tradingEngine.current.position.status.value === 'Open') {
tradingEngine.current.position.end.value = tradingEngine.current.candle.end.value
@@ -264,45 +196,47 @@ exports.newTradingPosition = function newTradingPosition(bot, logger, tradingEng
function updateStatistics() {
if (bot.sessionAndMarketBaseAssetsAreEqual) {
/* Profit Loss Calculation */
tradingEngine.current.position.positionStatistics.profitLoss.value =
tradingEngine.current.balance.baseAsset.value -
tradingEngine.previous.balance.baseAsset.value +
tradingEngine.current.balance.quotedAsset.value / tradingEngine.current.position.endRate.value -
tradingEngine.previous.balance.quotedAsset.value / tradingEngine.current.position.beginRate.value
/* ROI Calculation */
tradingEngine.current.position.positionStatistics.ROI.value =
tradingEngine.current.position.positionStatistics.profitLoss.value * 100 /
tradingEngine.current.position.size.value
} else {
/* Profit Loss Calculation */
tradingEngine.current.position.positionStatistics.profitLoss.value =
tradingEngine.current.balance.baseAsset.value * tradingEngine.current.position.endRate.value -
tradingEngine.previous.balance.baseAsset.value * tradingEngine.current.position.beginRate.value +
tradingEngine.current.balance.quotedAsset.value -
tradingEngine.previous.balance.quotedAsset.value
/* ROI Calculation */
tradingEngine.current.position.positionStatistics.ROI.value =
tradingEngine.current.position.positionStatistics.profitLoss.value * 100 /
(tradingEngine.current.position.size.value * tradingEngine.current.position.beginRate.value)
}
/* Days Calculation */
tradingEngine.current.position.positionStatistics.days.value = tradingEngine.current.position.positionCounters.periods.value *
tradingEngine.current.position.positionStatistics.days.value =
tradingEngine.current.position.positionCounters.periods.value *
sessionParameters.timeFrame.config.value / global.ONE_DAY_IN_MILISECONDS
tradingEngine.current.position.positionStatistics.profitLoss.value = global.PRECISE(tradingEngine.current.position.positionStatistics.profitLoss.value, 10)
tradingEngine.current.position.positionStatistics.ROI.value = global.PRECISE(tradingEngine.current.position.positionStatistics.ROI.value, 10)
tradingEngine.current.position.positionStatistics.days.value = global.PRECISE(tradingEngine.current.position.positionStatistics.days.value, 10)
}
function updateResults() {
/* Profit Loss Calculation */
tradingEngine.current.position.positionBaseAsset.profitLoss.value =
tradingEngine.current.balance.baseAsset.value -
tradingEngine.previous.balance.baseAsset.value
tradingEngine.current.position.positionQuotedAsset.profitLoss.value =
tradingEngine.current.balance.quotedAsset.value -
tradingEngine.previous.balance.quotedAsset.value
tradingEngine.current.position.positionBaseAsset.profitLoss.value = global.PRECISE(tradingEngine.current.position.positionBaseAsset.profitLoss.value, 10)
/* ROI Calculation */
tradingEngine.current.position.positionBaseAsset.ROI.value =
tradingEngine.current.position.positionBaseAsset.profitLoss.value * 100 /
tradingEngine.current.position.positionBaseAsset.size.value
tradingEngine.current.position.positionQuotedAsset.ROI.value =
tradingEngine.current.position.positionQuotedAsset.profitLoss.value * 100 /
tradingEngine.current.position.positionQuotedAsset.size.value
tradingEngine.current.position.positionBaseAsset.ROI.value = global.PRECISE(tradingEngine.current.position.positionBaseAsset.ROI.value, 10)
/* Hit Fail Calculation */
if (tradingEngine.current.position.positionStatistics.ROI.value > 0) {
tradingEngine.current.position.positionStatistics.hitFail.value = 'HIT'
if (tradingEngine.current.position.positionBaseAsset.ROI.value > 0) {
tradingEngine.current.position.positionBaseAsset.hitFail.value = 'HIT'
} else {
tradingEngine.current.position.positionStatistics.hitFail.value = 'FAIL'
tradingEngine.current.position.positionBaseAsset.hitFail.value = 'FAIL'
}
if (tradingEngine.current.position.positionQuotedAsset.ROI.value > 0) {
tradingEngine.current.position.positionQuotedAsset.hitFail.value = 'HIT'
} else {
tradingEngine.current.position.positionQuotedAsset.hitFail.value = 'FAIL'
}
}
}
+117 -24
View File
@@ -902,8 +902,6 @@ exports.newTradingSystem = function newTradingSystem(bot, logger, tradingEngineM
) {
logger.write(MODULE_NAME, '[INFO] checkStopLossOrTakeProfitWasHit -> Stop Loss was hit.')
tradingPositionModule.preventStopLossDistortion()
tradingPositionModule.applySlippageToStopLoss()
tradingPositionModule.closingPosition('Stop Loss')
tradingStrategyModule.updateStageStatus('Close Stage', 'Opening')
tradingStrategyModule.updateStageStatus('Manage Stage', 'Closed')
@@ -918,8 +916,6 @@ exports.newTradingSystem = function newTradingSystem(bot, logger, tradingEngineM
) {
logger.write(MODULE_NAME, '[INFO] checkStopLossOrTakeProfitWasHit -> Take Profit was hit.')
tradingPositionModule.preventTakeProfitDistortion()
tradingPositionModule.applySlippageToTakeProfit()
tradingPositionModule.closingPosition('Take Profit')
tradingStrategyModule.updateStageStatus('Close Stage', 'Opening')
tradingStrategyModule.updateStageStatus('Manage Stage', 'Closed')
@@ -997,28 +993,12 @@ exports.newTradingSystem = function newTradingSystem(bot, logger, tradingEngineM
function exitPositionAndStrategy() {
/* Needed for Episode Statistics */
/* Position Statistics & Results */
tradingPositionModule.updateStatistics()
tradingPositionModule.updateResults()
/* Recalculating Episode Counters */
if (tradingEngine.current.position.positionStatistics.profitLoss.value > 0) {
tradingEngine.episode.episodeCounters.hits.value++
} else {
tradingEngine.episode.episodeCounters.fails.value++
}
/* Recalculating Episode Statistics */
if (bot.sessionAndMarketBaseAssetsAreEqual) {
tradingEngine.episode.episodeStatistics.profitLoss.value = tradingEngine.current.balance.baseAsset.value - sessionParameters.sessionBaseAsset.config.initialBalance
tradingEngine.episode.episodeStatistics.ROI.value = (sessionParameters.sessionBaseAsset.config.initialBalance + tradingEngine.episode.episodeStatistics.profitLoss.value) / sessionParameters.sessionBaseAsset.config.initialBalance - 1
tradingEngine.episode.episodeStatistics.hitRatio.value = tradingEngine.episode.episodeCounters.hits.value / tradingEngine.episode.episodeCounters.positions.value
tradingEngine.episode.episodeStatistics.anualizedRateOfReturn.value = tradingEngine.episode.episodeStatistics.ROI.value / tradingEngine.episode.episodeStatistics.days.value * 365
} else {
tradingEngine.episode.episodeStatistics.profitLoss.value = tradingEngine.current.balance.quotedAsset.value - sessionParameters.sessionQuotedAsset.config.initialBalance
tradingEngine.episode.episodeStatistics.ROI.value = (sessionParameters.sessionQuotedAsset.config.initialBalance + tradingEngine.episode.episodeStatistics.profitLoss.value) / sessionParameters.sessionQuotedAsset.config.initialBalance - 1
tradingEngine.episode.episodeStatistics.hitRatio.value = tradingEngine.episode.episodeCounters.hits.value / tradingEngine.episode.episodeCounters.positions.value
tradingEngine.episode.episodeStatistics.anualizedRateOfReturn.value = tradingEngine.episode.episodeStatistics.ROI.value / tradingEngine.episode.episodeStatistics.days.value * 365
}
updatingEpisodeAssets()
updatingEpisodeStatistics()
/* Taking Position Snapshot */
if (bot.SESSION.type === 'Backtesting Session') {
@@ -1047,6 +1027,119 @@ exports.newTradingSystem = function newTradingSystem(bot, logger, tradingEngineM
/* Distance to Events Updates */
tradingEngine.current.distanceToEvent.closePosition.value = 1
tradingEngine.current.distanceToEvent.triggerOff.value = 1
function updatingEpisodeAssets() {
/* Updating Hits & Fails */
if (tradingEngine.current.position.positionBaseAsset.profitLoss.value > 0) {
tradingEngine.episode.episodeBaseAsset.hits.value++
} else {
tradingEngine.episode.episodeBaseAsset.fails.value++
}
if (tradingEngine.current.position.positionQuotedAsset.profitLoss.value > 0) {
tradingEngine.episode.episodeQuotedAsset.hits.value++
} else {
tradingEngine.episode.episodeQuotedAsset.fails.value++
}
/* Updating Profit Loss */
tradingEngine.episode.episodeBaseAsset.profitLoss.value =
tradingEngine.current.balance.baseAsset.value -
sessionParameters.sessionBaseAsset.config.initialBalance
tradingEngine.episode.episodeQuotedAsset.profitLoss.value =
tradingEngine.current.balance.quotedAsset.value -
sessionParameters.sessionQuotedAsset.config.initialBalance
tradingEngine.episode.episodeBaseAsset.profitLoss.value = global.PRECISE(tradingEngine.episode.episodeBaseAsset.profitLoss.value, 10)
tradingEngine.episode.episodeQuotedAsset.profitLoss.value = global.PRECISE(tradingEngine.episode.episodeQuotedAsset.profitLoss.value, 10)
/* Updating ROI */
tradingEngine.episode.episodeBaseAsset.ROI.value =
(sessionParameters.sessionBaseAsset.config.initialBalance + tradingEngine.episode.episodeBaseAsset.profitLoss.value) /
sessionParameters.sessionBaseAsset.config.initialBalance - 1
tradingEngine.episode.episodeQuotedAsset.ROI.value =
(sessionParameters.sessionQuotedAsset.config.initialBalance + tradingEngine.episode.episodeQuotedAsset.profitLoss.value) /
sessionParameters.sessionQuotedAsset.config.initialBalance - 1
tradingEngine.episode.episodeBaseAsset.ROI.value = global.PRECISE(tradingEngine.episode.episodeBaseAsset.ROI.value, 10)
tradingEngine.episode.episodeQuotedAsset.ROI.value = global.PRECISE(tradingEngine.episode.episodeQuotedAsset.ROI.value, 10)
/* Updating Hit Ratio */
tradingEngine.episode.episodeBaseAsset.hitRatio.value =
tradingEngine.episode.episodeBaseAsset.hits.value /
tradingEngine.episode.episodeCounters.positions.value
tradingEngine.episode.episodeQuotedAsset.hitRatio.value =
tradingEngine.episode.episodeQuotedAsset.hits.value /
tradingEngine.episode.episodeCounters.positions.value
tradingEngine.episode.episodeBaseAsset.hitRatio.value = global.PRECISE(tradingEngine.episode.episodeBaseAsset.hitRatio.value, 10)
tradingEngine.episode.episodeQuotedAsset.hitRatio.value = global.PRECISE(tradingEngine.episode.episodeQuotedAsset.hitRatio.value, 10)
/* Updating Anualized Rate Of Return */
tradingEngine.episode.episodeBaseAsset.anualizedRateOfReturn.value =
tradingEngine.episode.episodeBaseAsset.ROI.value /
tradingEngine.episode.episodeStatistics.days.value * 365
tradingEngine.episode.episodeQuotedAsset.anualizedRateOfReturn.value =
tradingEngine.episode.episodeQuotedAsset.ROI.value /
tradingEngine.episode.episodeStatistics.days.value * 365
tradingEngine.episode.episodeBaseAsset.anualizedRateOfReturn.value = global.PRECISE(tradingEngine.episode.episodeBaseAsset.anualizedRateOfReturn.value, 10)
tradingEngine.episode.episodeQuotedAsset.anualizedRateOfReturn.value = global.PRECISE(tradingEngine.episode.episodeQuotedAsset.anualizedRateOfReturn.value, 10)
/* Updating Hit or Fail */
if (tradingEngine.episode.episodeBaseAsset.profitLoss.value > 0) {
tradingEngine.episode.episodeBaseAsset.hitFail.value = 'Hit'
} else {
tradingEngine.episode.episodeBaseAsset.hitFail.value = 'Fail'
}
if (tradingEngine.episode.episodeQuotedAsset.profitLoss.value > 0) {
tradingEngine.episode.episodeQuotedAsset.hitFail.value = 'Hit'
} else {
tradingEngine.episode.episodeQuotedAsset.hitFail.value = 'Fail'
}
}
function updatingEpisodeStatistics() {
/* Updating Profit Loss */
tradingEngine.episode.episodeStatistics.profitLoss.value =
tradingEngine.episode.episodeBaseAsset.profitLoss.value * tradingEngine.current.candle.close.value +
tradingEngine.episode.episodeQuotedAsset.profitLoss.value
tradingEngine.episode.episodeStatistics.profitLoss.value = global.PRECISE(tradingEngine.episode.episodeStatistics.profitLoss.value, 10)
/* Updating ROI */
tradingEngine.episode.episodeStatistics.ROI.value =
(
sessionParameters.sessionBaseAsset.config.initialBalance * tradingEngine.current.candle.close.value +
tradingEngine.episode.episodeBaseAsset.profitLoss.value * tradingEngine.current.candle.close.value +
sessionParameters.sessionQuotedAsset.config.initialBalance +
tradingEngine.episode.episodeQuotedAsset.profitLoss.value
) / (
sessionParameters.sessionBaseAsset.config.initialBalance * tradingEngine.current.candle.close.value +
sessionParameters.sessionQuotedAsset.config.initialBalance
) - 1
tradingEngine.episode.episodeStatistics.ROI.value = global.PRECISE(tradingEngine.episode.episodeStatistics.ROI.value, 10)
/* Updating Anualized Rate Of Return */
tradingEngine.episode.episodeStatistics.anualizedRateOfReturn.value =
tradingEngine.episode.episodeStatistics.ROI.value /
tradingEngine.episode.episodeStatistics.days.value * 365
tradingEngine.episode.episodeStatistics.anualizedRateOfReturn.value = global.PRECISE(tradingEngine.episode.episodeStatistics.anualizedRateOfReturn.value, 10)
/* Updating Hit or Fail */
if (tradingEngine.episode.episodeStatistics.profitLoss.value > 0) {
tradingEngine.episode.episodeStatistics.hitFail.value = 'Hit'
} else {
tradingEngine.episode.episodeStatistics.hitFail.value = 'Fail'
}
}
}
}