Stage Target Size Working

This commit is contained in:
Luis Fernando Molina committed 2020-08-04 18:33:24 +02:00
1 parent 84027b6d68
commit c5b44822c7
10 files changed
+1406 -1202

No files matched your search

+3 -4
View File
@@ -5,7 +5,7 @@ exports.newSnapshots = function newSnapshots(bot, logger) {
const MODULE_NAME = 'Snapshots'
let thisObject = {
reset: reset,
updateChart: updateChart,
strategyEntry: strategyEntry,
strategyExit: strategyExit,
positionEntry: positionEntry,
@@ -60,9 +60,8 @@ exports.newSnapshots = function newSnapshots(bot, logger) {
chart = undefined
}
function reset(pChart) {
/* This function helps reset data structures at every cycle of the simulation loop/=. */
chart = pChart // We need chat to be a local object accessible from conditions and formulas.
function updateChart(pChart) {
chart = pChart
}
function strategyEntry() {
@@ -5,7 +5,7 @@ exports.newTradingExecution = function newTradingExecution(bot, logger, tradingE
const MODULE_NAME = 'Trading Execution'
let thisObject = {
checkExecution: checkExecution,
runExecution: runExecution,
initialize: initialize,
finalize: finalize
}
@@ -43,49 +43,25 @@ exports.newTradingExecution = function newTradingExecution(bot, logger, tradingE
announcementsModule = undefined
}
async function checkExecution(
async function runExecution(
executionNode,
stageIsOpening,
stageIsClosing,
stageSizeLimitInBaseAsset,
stageSizeLimitInQuotedAsset,
tradingEngineStage
) {
try {
/* Trading Engine Stage Validations */
if (tradingEngineStage.stageBaseAsset === undefined) { badDefinitionUnhandledException(undefined, 'tradingEngineStage.stageBaseAsset === undefined', tradingEngineStage) }
if (tradingEngineStage.stageBaseAsset.size === undefined) { badDefinitionUnhandledException(undefined, 'tradingEngineStage.size === undefined', tradingEngineStage) }
if (tradingEngineStage.stageBaseAsset.sizeFilled === undefined) { badDefinitionUnhandledException(undefined, 'tradingEngineStage.sizeFilled === undefined', tradingEngineStage) }
if (tradingEngineStage.stageBaseAsset.feesPaid === undefined) { badDefinitionUnhandledException(undefined, 'tradingEngineStage.feesPaid === undefined', tradingEngineStage) }
if (tradingEngineStage.stageQuotedAsset === undefined) { badDefinitionUnhandledException(undefined, 'stageQuotedAsset.size === undefined', tradingEngineStage) }
if (tradingEngineStage.stageQuotedAsset.size === undefined) { badDefinitionUnhandledException(undefined, 'stageQuotedAsset.size === undefined', tradingEngineStage) }
if (tradingEngineStage.stageBaseAsset === undefined) { badDefinitionUnhandledException(undefined, 'stageBaseAsset === undefined', tradingEngineStage) }
if (tradingEngineStage.stageBaseAsset.targetSize === undefined) { badDefinitionUnhandledException(undefined, 'stageBaseAsset.targetSize === undefined', tradingEngineStage) }
if (tradingEngineStage.stageBaseAsset.sizePlaced === undefined) { badDefinitionUnhandledException(undefined, 'stageBaseAsset.sizePlaced === undefined', tradingEngineStage) }
if (tradingEngineStage.stageBaseAsset.sizeFilled === undefined) { badDefinitionUnhandledException(undefined, 'stageBaseAsset.sizeFilled === undefined', tradingEngineStage) }
if (tradingEngineStage.stageBaseAsset.feesPaid === undefined) { badDefinitionUnhandledException(undefined, 'stageBaseAsset.feesPaid === undefined', tradingEngineStage) }
if (tradingEngineStage.stageQuotedAsset === undefined) { badDefinitionUnhandledException(undefined, 'stageQuotedAsset === undefined', tradingEngineStage) }
if (tradingEngineStage.stageQuotedAsset.targetSize === undefined) { badDefinitionUnhandledException(undefined, 'stageQuotedAsset.targetSize === undefined', tradingEngineStage) }
if (tradingEngineStage.stageQuotedAsset.sizePlaced === undefined) { badDefinitionUnhandledException(undefined, 'stageQuotedAsset.sizePlaced === undefined', tradingEngineStage) }
if (tradingEngineStage.stageQuotedAsset.sizeFilled === undefined) { badDefinitionUnhandledException(undefined, 'stageQuotedAsset.sizeFilled === undefined', tradingEngineStage) }
if (tradingEngineStage.stageQuotedAsset.feesPaid === undefined) { badDefinitionUnhandledException(undefined, 'stageQuotedAsset.feesPaid === undefined', tradingEngineStage) }
/*
The user choice of asset to define the size of the position,
defines the asset that will track the information kept about the
stage at the trading engine data structure. We set this asset
to be used here in this way:
*/
let tradingEngineStageAsset
if (tradingEngine.current.position.positionBaseAsset.size.value > 0) {
tradingEngineStageAsset = tradingEngineStage.stageBaseAsset
} else {
tradingEngineStageAsset = tradingEngineStage.stageQuotedAsset
}
/*
The asset type of the position size chosen by the user, also defines
the stage limit to be on the same asset type.
*/
let stageSizeLimit
if (tradingEngine.current.position.positionBaseAsset.size.value > 0) {
stageSizeLimit = stageSizeLimitInBaseAsset
} else {
stageSizeLimit = stageSizeLimitInQuotedAsset
}
await checkExecutionAlgorithms(executionNode)
async function checkExecutionAlgorithms(executionNode) {
@@ -132,18 +108,6 @@ exports.newTradingExecution = function newTradingExecution(bot, logger, tradingE
if (tradingEngineOrder.orderQuotedAsset.sizeFilled === undefined) { badDefinitionUnhandledException(undefined, 'tradingEngineOrder.orderQuotedAsset.sizeFilled === undefined', tradingEngineOrder) }
if (tradingEngineOrder.orderQuotedAsset.feesPaid === undefined) { badDefinitionUnhandledException(undefined, 'tradingEngineOrder.orderQuotedAsset.feesPaid === undefined', tradingEngineOrder) }
/*
The asset type of the position size chosen by the user, defines
the asset at the order data strutcture where information is going to
be stored.
*/
let traingEngineOrderAsset
if (tradingEngine.current.position.positionBaseAsset.size.value > 0) {
traingEngineOrderAsset = tradingEngineOrder.orderBaseAsset
} else {
traingEngineOrderAsset = tradingEngineOrder.orderQuotedAsset
}
switch (tradingEngineOrder.status.value) {
case 'Not Open': {
{
@@ -164,7 +128,7 @@ exports.newTradingExecution = function newTradingExecution(bot, logger, tradingE
if (situationName !== undefined) {
/* Open a new order */
await tryToOpenOrder(executionAlgorithm, tradingSystemOrder, tradingEngineOrder, traingEngineOrderAsset, situationName)
await tryToOpenOrder(executionAlgorithm, tradingSystemOrder, tradingEngineOrder, situationName)
}
}
break
@@ -205,23 +169,23 @@ exports.newTradingExecution = function newTradingExecution(bot, logger, tradingE
}
}
async function tryToOpenOrder(executionAlgorithm, tradingSystemOrder, tradingEngineOrder, traingEngineOrderAsset, situationName) {
async function tryToOpenOrder(executionAlgorithm, tradingSystemOrder, tradingEngineOrder, situationName) {
calculateOrderRate()
calculateOrderSize()
/* Check Size: We are not going to create Orders which size is equal or less to zero. */
if (traingEngineOrderAsset.size.value <= 0) { return }
if (tradingEngineOrder.orderBaseAsset.size.value <= 0 || tradingEngineOrder.orderQuotedAsset.size.value <= 0) { return }
/* Place Order at the Exchange, if needed. */
let result = await createOrderAtExchange(tradingSystemOrder, tradingEngineOrder)
if (result !== true) { return }
/* 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
tradingEngineStage.stageQuotedAsset.size.value = global.PRECISE(tradingEngineStage.stageQuotedAsset.size.value, 10)
/* Update Stage Placed Size */
tradingEngineStage.stageBaseAsset.sizePlaced.value = tradingEngineStage.stageBaseAsset.sizePlaced.value + tradingEngineOrder.orderBaseAsset.size.value
tradingEngineStage.stageBaseAsset.sizePlaced.value = global.PRECISE(tradingEngineStage.stageBaseAsset.sizePlaced.value, 10)
tradingEngineStage.stageQuotedAsset.sizePlaced.value = tradingEngineStage.stageQuotedAsset.sizePlaced.value + tradingEngineOrder.orderQuotedAsset.size.value
tradingEngineStage.stageQuotedAsset.sizePlaced.value = global.PRECISE(tradingEngineStage.stageQuotedAsset.sizePlaced.value, 10)
/* Updating Episode Counters */
tradingEngine.episode.episodeCounters.orders.value++
@@ -282,27 +246,30 @@ exports.newTradingExecution = function newTradingExecution(bot, logger, tradingE
/* Validate that this config exists */
if (tradingSystemOrder.config.positionSizePercentage === undefined) { badDefinitionUnhandledException(undefined, 'tradingSystemOrder.config.positionSizePercentage === undefined', executionAlgorithm) }
traingEngineOrderAsset.size.value = algorithmSize * tradingSystemOrder.config.positionSizePercentage / 100
traingEngineOrderAsset.size.value = global.PRECISE(traingEngineOrderAsset.size.value, 10)
if (tradingEngine.current.position.positionBaseAsset.size.value > 0) {
/* Position was defined in Base Asset */
tradingEngineOrder.orderBaseAsset.size.value = algorithmSize * tradingSystemOrder.config.positionSizePercentage / 100
tradingEngineOrder.orderQuotedAsset.size.value = tradingEngineOrder.orderBaseAsset.size.value * tradingEngineOrder.rate.value
} else {
/* Position was defined in Quoted Asset */
tradingEngineOrder.orderQuotedAsset.size.value = algorithmSize * tradingSystemOrder.config.positionSizePercentage / 100
tradingEngineOrder.orderBaseAsset.size.value = tradingEngineOrder.orderQuotedAsset.size.value / tradingEngineOrder.rate.value
}
tradingEngineOrder.orderBaseAsset.size.value = global.PRECISE(tradingEngineOrder.orderBaseAsset.size.value, 10)
tradingEngineOrder.orderBaseAsset.size.value = global.PRECISE(tradingEngineOrder.orderBaseAsset.size.value, 10)
/* Check against the Stage Size Limit */
if (
tradingEngineStageAsset.size.value + traingEngineOrderAsset.size.value > stageSizeLimit.value) {
/* We reduce the size to the remaining size of the position. */
traingEngineOrderAsset.size.value = stageSizeLimit.value - tradingEngineStageAsset.size.value
traingEngineOrderAsset.size.value = global.PRECISE(traingEngineOrderAsset.size.value, 10)
tradingEngineOrder.orderBaseAsset.size.value + tradingEngineStage.stageBaseAsset.sizePlaced.value >
tradingEngineStage.stageBaseAsset.targetSize.value
) {
tradingEngineOrder.orderBaseAsset.size.value = tradingEngineStage.stageBaseAsset.targetSize.value - tradingEngineStage.stageBaseAsset.sizePlaced.value
}
/* We are going to ESTIMATE the size in the oposite asset type, because we will need it later */
switch (traingEngineOrderAsset.type) {
case 'Order Base Asset': {
tradingEngineOrder.orderQuotedAsset.size.value = tradingEngineOrder.orderBaseAsset.size.value * tradingEngineOrder.rate.value
tradingEngineOrder.orderQuotedAsset.size.value = global.PRECISE(tradingEngineOrder.orderQuotedAsset.size.value, 10)
}
case 'Order Quoted Asset': {
tradingEngineOrder.orderBaseAsset.size.value = tradingEngineOrder.orderQuotedAsset.size.value / tradingEngineOrder.rate.value
tradingEngineOrder.orderBaseAsset.size.value = global.PRECISE(tradingEngineOrder.orderBaseAsset.size.value, 10)
}
if (
tradingEngineOrder.orderQuotedAsset.size.value + tradingEngineStage.stageQuotedAsset.sizePlaced.value >
tradingEngineStage.stageQuotedAsset.targetSize.value
) {
tradingEngineOrder.orderQuotedAsset.size.value = tradingEngineStage.stageQuotedAsset.targetSize.value - tradingEngineStage.stageQuotedAsset.sizePlaced.value
}
}
@@ -884,10 +851,10 @@ exports.newTradingExecution = function newTradingExecution(bot, logger, tradingE
}
} catch (err) {
if (typeof err === 'string' || err instanceof String) {
logger.write(MODULE_NAME, '[ERROR] checkExecution -> err = ' + err)
logger.write(MODULE_NAME, '[ERROR] runExecution -> err = ' + err)
}
if (err.stack !== undefined) {
logger.write(MODULE_NAME, '[ERROR] checkExecution -> err = ' + err.stack)
logger.write(MODULE_NAME, '[ERROR] runExecution -> err = ' + err.stack)
}
}
}
@@ -11,7 +11,7 @@ exports.newTradingPosition = function newTradingPosition(bot, logger, tradingEng
applyTakeProfitFormula: applyTakeProfitFormula,
updateStopLoss: updateStopLoss,
updateTakeProfit: updateTakeProfit,
initializeSizeAndRate: initializeSizeAndRate,
initializePositionSizeAndRate: initializePositionSizeAndRate,
updateEnds: updateEnds,
updateStatus: updateStatus,
updateCounters: updateCounters,
@@ -71,6 +71,7 @@ exports.newTradingPosition = function newTradingPosition(bot, logger, tradingEng
function closePosition() {
tradingEngine.current.position.status.value = 'Closed'
tradingEngine.current.position.end.value = tradingEngine.current.candle.end.value
tradingEngine.current.position.endRate.value = tradingEngine.current.candle.close.value
/*
Now that the position is closed, it is the right time to move this position from current to last at the Trading Engine data structure.
*/
@@ -99,7 +100,7 @@ exports.newTradingPosition = function newTradingPosition(bot, logger, tradingEng
tradingEngine.current.position.takeProfit.takeProfitStage.value = stage
}
function initializeSizeAndRate() {
function initializePositionSizeAndRate() {
setPositionSize()
setPositionRate()
@@ -33,14 +33,6 @@ exports.newTradingSimulation = function newTradingSimulation(bot, logger, UTILIT
if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] runSimulation -> initialDatetime = ' + sessionParameters.timeRange.config.initialDatetime) }
if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] runSimulation -> finalDatetime = ' + sessionParameters.timeRange.config.finalDatetime) }
/* Stop Loss Management TODO */
const MIN_STOP_LOSS_VALUE = 0.0000000001 // We can not let the stop be zero to avoid division by 0 error or infinity numbers as a result.
const MAX_STOP_LOSS_VALUE = Number.MAX_SAFE_INTEGER
/* Take Profit Management TODO */
const MIN_TAKE_PROFIT_VALUE = 0.0000000001 // We can not let the buy order be zero to avoid division by 0 error or infinity numbers as a result.
const MAX_TAKE_PROFIT_VALUE = Number.MAX_SAFE_INTEGER
/* These are the Modules we will need to run the Simulation */
const TRADING_ENGINE_MODULE = require('./TradingEngine.js')
let tradingEngineModule = TRADING_ENGINE_MODULE.newTradingEngine(bot, logger)
@@ -131,25 +123,18 @@ exports.newTradingSimulation = function newTradingSimulation(bot, logger, UTILIT
heartBeat()
positionChartAtCurrentCandle()
tradingSystemModule.reset(chart)
tradingSystemModule.mantainPositions()
tradingSystemModule.mantainStrategies()
tradingSystemModule.mantainOrders()
/* The chart was recalculated based on the current candle. */
tradingSystemModule.updateChart(chart)
/* Do the stuff needed previous to the run */
tradingSystemModule.mantain()
tradingEngineModule.updateEpisodeCountersAndStatistics()
tradingEngineModule.updateDistanceToEventsCounters()
/* Run the Trigger Stage */
tradingSystemModule.triggerStage()
/* Run the Open Stage */
await tradingSystemModule.openStage()
/* Run the Manage Stage */
tradingSystemModule.manageStage()
/* Run the Close Stage */
await tradingSystemModule.closeStage()
/* Run one cycle of the Trading System*/
await tradingSystemModule.run()
/* Add new records to the process output */
tradingRecordsModule.appendRecords()
File diff suppressed because it is too large. Load diff
@@ -7,7 +7,6 @@ exports.newTradingStrategy = function newTradingStrategy(bot, logger, tradingEng
openStrategy: openStrategy,
closeStrategy: closeStrategy,
updateEnds: updateEnds,
updateStageStatus: updateStageStatus,
updateStatus: updateStatus,
updateCounters: updateCounters,
resetStrategy: resetStrategy,
@@ -63,33 +62,6 @@ exports.newTradingStrategy = function newTradingStrategy(bot, logger, tradingEng
}
}
function updateStageStatus(stage, status, exitType) {
switch (stage) {
case 'Trigger Stage': {
tradingEngine.current.strategyTriggerStage.status.value = status
break
}
case 'Open Stage': {
tradingEngine.current.strategyOpenStage.status.value = status
if (exitType !== undefined) {
tradingEngine.current.strategyOpenStage.exitType.value = exitType
}
break
}
case 'Manage Stage': {
tradingEngine.current.strategyManageStage.status.value = status
break
}
case 'Close Stage': {
tradingEngine.current.strategyCloseStage.status.value = status
if (exitType !== undefined) {
tradingEngine.current.strategyCloseStage.exitType.value = exitType
}
break
}
}
}
function updateStatus() {
if (tradingEngine.current.strategy.status.value === 'Closed') {
resetStrategy()
File diff suppressed because it is too large. Load diff