real time errors, warnings and infos

This commit is contained in:
Luis Fernando Molina committed 2020-08-29 17:49:22 +02:00
1 parent 92577e2fd0
commit ae62b783fb
19 files changed
+541 -77

No files matched your search

+54
View File
@@ -38,6 +38,18 @@
"childType": "Nodes Errors",
"autoAdd": false
},
{
"name": "nodesWarnings",
"type": "node",
"childType": "Nodes Warnings",
"autoAdd": false
},
{
"name": "nodesInfos",
"type": "node",
"childType": "Nodes Infos",
"autoAdd": false
},
{
"name": "nodesStatus",
"type": "node",
@@ -193,6 +205,48 @@
"icon": "band",
"propertyNameAtParent": "nodesErrors"
},
{
"type": "Nodes Warnings",
"menuItems": [
{
"action": "Delete UI Object",
"askConfirmation": true,
"confirmationLabel": "Confirm to Delete",
"actionFunction": "payload.onMenuItemClick",
"label": "Delete",
"iconPathOn": "delete",
"iconPathOff": "delete"
}
],
"addLeftIcons": true,
"level": 3,
"chainAttachesTo": {
"compatibleTypes": "->Plotter Module->"
},
"icon": "pyramid",
"propertyNameAtParent": "nodesWarnings"
},
{
"type": "Nodes Infos",
"menuItems": [
{
"action": "Delete UI Object",
"askConfirmation": true,
"confirmationLabel": "Confirm to Delete",
"actionFunction": "payload.onMenuItemClick",
"label": "Delete",
"iconPathOn": "delete",
"iconPathOff": "delete"
}
],
"addLeftIcons": true,
"level": 3,
"chainAttachesTo": {
"compatibleTypes": "->Plotter Module->"
},
"icon": "user-account",
"propertyNameAtParent": "nodesInfos"
},
{
"type": "Nodes Status",
"menuItems": [
+2
View File
@@ -121,6 +121,8 @@ function newAppLoader() {
'Plotting/Plotter.js',
'Plotting/NodesHighlights.js',
'Plotting/NodesErrors.js',
'Plotting/NodesWarnings.js',
'Plotting/NodesInfos.js',
'Plotting/NodesValues.js',
'Plotting/NodesStatus.js',
'Plotting/NodesProgress.js',
@@ -271,6 +271,30 @@ function newPlottersManager() {
}
connector.nodesErrors.onRecordChangeEventsSubscriptionId = connector.plotter.container.eventHandler.listenToEvent('Current Record Changed', connector.nodesErrors.onRecordChange)
}
if (plotterModule.nodesWarnings !== undefined && plotterModule.config.connectTo !== undefined) {
connector.nodesWarnings = newNodesWarnings()
switch (plotterModule.config.connectTo) {
case 'Trading System':
connector.nodesWarnings.initialize(tradingSystem)
break
case 'Trading Engine':
connector.nodesWarnings.initialize(tradingEngine)
break
}
connector.nodesWarnings.onRecordChangeEventsSubscriptionId = connector.plotter.container.eventHandler.listenToEvent('Current Record Changed', connector.nodesWarnings.onRecordChange)
}
if (plotterModule.nodesInfos !== undefined && plotterModule.config.connectTo !== undefined) {
connector.nodesInfos = newNodesInfos()
switch (plotterModule.config.connectTo) {
case 'Trading System':
connector.nodesInfos.initialize(tradingSystem)
break
case 'Trading Engine':
connector.nodesInfos.initialize(tradingEngine)
break
}
connector.nodesInfos.onRecordChangeEventsSubscriptionId = connector.plotter.container.eventHandler.listenToEvent('Current Record Changed', connector.nodesInfos.onRecordChange)
}
if (plotterModule.nodesRunning !== undefined && plotterModule.config.connectTo !== undefined) {
connector.nodesRunning = newNodesRunning()
switch (plotterModule.config.connectTo) {
@@ -392,6 +416,14 @@ function newPlottersManager() {
connector.plotter.container.eventHandler.stopListening(connector.nodesErrors.onRecordChangeEventsSubscriptionId)
connector.nodesErrors.finalize()
}
if (connector.nodesWarnings !== undefined) {
connector.plotter.container.eventHandler.stopListening(connector.nodesWarnings.onRecordChangeEventsSubscriptionId)
connector.nodesWarnings.finalize()
}
if (connector.nodesInfos !== undefined) {
connector.plotter.container.eventHandler.stopListening(connector.nodesInfos.onRecordChangeEventsSubscriptionId)
connector.nodesInfos.finalize()
}
if (connector.nodesStatus !== undefined) {
connector.plotter.container.eventHandler.stopListening(connector.nodesStatus.onRecordChangeEventsSubscriptionId)
connector.nodesStatus.finalize()
@@ -3,6 +3,7 @@ function newUiObjectsFromNodes() {
runTasks: runTasks,
runSessions: runSessions,
recreateWorkspace: recreateWorkspace,
getNodeById: getNodeById,
tryToConnectChildrenWithReferenceParents: tryToConnectChildrenWithReferenceParents,
createUiObjectFromNode: createUiObjectFromNode,
addUIObject: addUIObject,
@@ -16,6 +17,10 @@ function newUiObjectsFromNodes() {
return thisObject
function getNodeById(nodeId) {
return mapOfNodes.get(nodeId)
}
function recreateWorkspace(node, callBackFunction) {
mapOfNodes = new Map()
tasksToRun = []
@@ -17,6 +17,7 @@ function newWorkspace() {
getHierarchyHeadsById: getHierarchyHeadsById,
getNodeThatIsOnFocus: getNodeThatIsOnFocus,
getNodeByShortcutKey: getNodeByShortcutKey,
getNodeById: getNodeById,
stopAllRunningTasks: stopAllRunningTasks,
onMenuItemClick: onMenuItemClick,
physics: physics,
@@ -226,6 +227,10 @@ function newWorkspace() {
}
}
function getNodeById(nodeId) {
return functionLibraryUiObjectsFromNodes.getNodeById(nodeId)
}
function physics() {
eventsServerClientsPhysics()
replacingWorkspacePhysics()
+221 -4
View File
@@ -24,6 +24,8 @@ function newUiObject() {
shortcutKey: undefined,
isShowing: undefined,
hasError: undefined,
hasWarning: undefined,
hasInfo: undefined,
run: run,
stop: stop,
heartBeat: heartBeat,
@@ -35,6 +37,10 @@ function newUiObject() {
runningAtBackend: runningAtBackend,
setErrorMessage: setErrorMessage,
resetErrorMessage: resetErrorMessage,
setWarningMessage: setWarningMessage,
resetWarningMessage: resetWarningMessage,
setInfoMessage: setInfoMessage,
resetInfoMessage: resetInfoMessage,
setValue: setValue,
resetValue: resetValue,
setPercentage: setPercentage,
@@ -76,6 +82,8 @@ function newUiObject() {
let runningAtBackendCounter = 0
let errorMessageCounter = 0
let warningMessageCounter = 0
let infoMessageCounter = 0
let hasValue
let valueCounter = 0
@@ -109,6 +117,9 @@ function newUiObject() {
let isDragging = false
let errorMessage = ''
let warningMessage = ''
let infoMessage = ''
let currentValue = 0
let valueMinDecimals = undefined
let currentPercentage = ''
@@ -116,8 +127,11 @@ function newUiObject() {
let rightDragging = false
let eventSubscriptionIdOnError
let eventSubscriptionIdOnWarning
let eventSubscriptionIdOnInfo
let eventSubscriptionIdOnRunning
let eventSubscriptionIdOnStopped
let lastHeartBeat
let onRunningCallBackFunction
let onRunningCallBackFunctionWasCalled = false
@@ -190,6 +204,12 @@ function newUiObject() {
if (eventSubscriptionIdOnError !== undefined) {
eventsServerClient.stopListening(key, eventSubscriptionIdOnError, 'UiObject')
}
if (eventSubscriptionIdOnWarning !== undefined) {
eventsServerClient.stopListening(key, eventSubscriptionIdOnWarning, 'UiObject')
}
if (eventSubscriptionIdOnInfo !== undefined) {
eventsServerClient.stopListening(key, eventSubscriptionIdOnInfo, 'UiObject')
}
}
}
@@ -327,6 +347,8 @@ function newUiObject() {
highlightPhisycs()
runningAtBackendPhisycs()
errorMessagePhisycs()
warningMessagePhisycs()
infoMessagePhisycs()
valuePhisycs()
percentagePhisycs()
statusPhisycs()
@@ -694,6 +716,22 @@ function newUiObject() {
}
}
function warningMessagePhisycs() {
warningMessageCounter--
if (warningMessageCounter < 0) {
warningMessageCounter = 0
thisObject.hasWarning = false
}
}
function infoMessagePhisycs() {
infoMessageCounter--
if (infoMessageCounter < 0) {
infoMessageCounter = 0
thisObject.hasInfo = false
}
}
function valuePhisycs() {
valueCounter--
if (valueCounter < 0) {
@@ -767,6 +805,76 @@ function newUiObject() {
thisObject.hasError = false
}
function setWarningMessage(message, duration) {
if (message !== undefined) {
warningMessage = message
thisObject.hasWarning = true
if (duration === undefined) { duration = 1 }
warningMessageCounter = 100 * duration
/*
Next, we are going to try to inform the parent that this
node has an warning, as a way to show the end user where the
node with warning is. This is useful to detect warnings in nodes
that are located at braches that are collapsed.
*/
if (thisObject.payload !== undefined) {
if (thisObject.payload.parentNode !== undefined) {
if (thisObject.payload.parentNode.payload !== undefined) {
if (thisObject.payload.parentNode.payload.floatingObject !== undefined) {
if (thisObject.payload.parentNode.payload.floatingObject.isCollapsed === true || thisObject.payload.parentNode.payload.floatingObject.isParentCollapsed === true) {
if (thisObject.payload.parentNode.payload.uiObject !== true) {
thisObject.payload.parentNode.payload.uiObject.setWarningMessage('Warning Inside this Branch')
}
}
}
}
}
}
}
}
function resetWarningMessage() {
warningMessage = undefined
thisObject.hasWarning = false
}
function setInfoMessage(message, duration) {
if (message !== undefined) {
infoMessage = message
thisObject.hasInfo = true
if (duration === undefined) { duration = 1 }
infoMessageCounter = 100 * duration
/*
Next, we are going to try to inform the parent that this
node has an info, as a way to show the end user where the
node with info is. This is useful to detect infos in nodes
that are located at braches that are collapsed.
*/
if (thisObject.payload !== undefined) {
if (thisObject.payload.parentNode !== undefined) {
if (thisObject.payload.parentNode.payload !== undefined) {
if (thisObject.payload.parentNode.payload.floatingObject !== undefined) {
if (thisObject.payload.parentNode.payload.floatingObject.isCollapsed === true || thisObject.payload.parentNode.payload.floatingObject.isParentCollapsed === true) {
if (thisObject.payload.parentNode.payload.uiObject !== true) {
thisObject.payload.parentNode.payload.uiObject.setInfoMessage('Info Inside this Branch')
}
}
}
}
}
}
}
}
function resetInfoMessage() {
infoMessage = undefined
thisObject.hasInfo = false
}
function setValue(value, counter, minDecimals) {
if (value !== undefined) {
currentValue = value
@@ -837,6 +945,8 @@ function newUiObject() {
function run(pEventsServerClient, callBackFunction) {
finalizeEventsServerClient()
resetErrorMessage()
resetWarningMessage()
resetInfoMessage()
resetPercentage()
resetValue()
resetStatus()
@@ -854,6 +964,8 @@ function newUiObject() {
setupRunningEventListener(callBackFunction)
setupErrorEventListener(callBackFunction)
setupWarningEventListener()
setupInfoEventListener()
}
function setupRunningEventListener(callBackFunction) {
@@ -898,6 +1010,21 @@ function newUiObject() {
stop(callBackFunction, event)
}
function getTargetUiObject(message) {
let uiObject = thisObject
if (message.event.nodeId !== undefined) {
let targetNode = canvas.designSpace.workspace.getNodeById(message.event.nodeId)
if (targetNode !== undefined) {
if (targetNode.payload !== undefined) {
if (targetNode.payload.uiObject !== undefined) {
uiObject = targetNode.payload.uiObject
}
}
}
}
return uiObject
}
function setupErrorEventListener(callBackFunction) {
let key = thisObject.payload.node.name + '-' + thisObject.payload.node.type + '-' + thisObject.payload.node.id
eventsServerClient.listenToEvent(key, 'Error', undefined, key, onResponse, onError)
@@ -907,7 +1034,9 @@ function newUiObject() {
}
function onError(message) {
setErrorMessage(message.event.errorMessage, 10)
let uiObject = getTargetUiObject(message)
uiObject.setErrorMessage(message.event.errorMessage, 10)
let event = {
type: 'Secondary Action Already Executed'
@@ -916,6 +1045,34 @@ function newUiObject() {
}
}
function setupWarningEventListener() {
let key = thisObject.payload.node.name + '-' + thisObject.payload.node.type + '-' + thisObject.payload.node.id
eventsServerClient.listenToEvent(key, 'Warning', undefined, key, onResponse, onWarning)
function onResponse(message) {
eventSubscriptionIdOnWarning = message.eventSubscriptionId
}
function onWarning(message) {
let uiObject = getTargetUiObject(message)
uiObject.setWarningMessage(message.event.warningMessage, 10)
}
}
function setupInfoEventListener() {
let key = thisObject.payload.node.name + '-' + thisObject.payload.node.type + '-' + thisObject.payload.node.id
eventsServerClient.listenToEvent(key, 'Info', undefined, key, onResponse, onInfo)
function onResponse(message) {
eventSubscriptionIdOnInfo = message.eventSubscriptionId
}
function onInfo(message) {
let uiObject = getTargetUiObject(message)
uiObject.setInfoMessage(message.event.infoMessage, 10)
}
}
function stop(callBackFunction, event) {
/* We will wait to the event that the execution was terminated in order to call back the menu item */
let key = thisObject.payload.node.name + '-' + thisObject.payload.node.type + '-' + thisObject.payload.node.id
@@ -1090,6 +1247,8 @@ function newUiObject() {
if (thisObject.isOnFocus === false) {
drawBodyAndPicture()
drawErrorMessage()
drawWarningMessage()
drawInfoMessage()
drawValue()
drawPercentage()
drawStatus()
@@ -1170,6 +1329,8 @@ function newUiObject() {
}
drawErrorMessage()
drawWarningMessage()
drawInfoMessage()
drawValue()
drawPercentage()
drawStatus()
@@ -1389,6 +1550,24 @@ function newUiObject() {
function drawErrorMessage() {
if (thisObject.hasError === false) { return }
drawMessage(errorMessage)
}
function drawWarningMessage() {
if (thisObject.hasError === true) { return }
if (thisObject.hasWarning !== true) { return }
drawMessage(warningMessage)
}
function drawInfoMessage() {
if (thisObject.hasError === true) { return }
if (thisObject.hasWarning === true) { return }
if (thisObject.hasInfo !== true) { return }
drawMessage(infoMessage)
}
function drawMessage(message) {
if (canvas.floatingSpace.inMapMode === true) {
return
}
@@ -1414,7 +1593,7 @@ function newUiObject() {
if (radius > 6) {
const MAX_LABEL_LENGTH = 80
label = errorMessage
label = message
if (label !== undefined && label !== null) {
if (label.length > MAX_LABEL_LENGTH) {
@@ -1695,7 +1874,7 @@ function newUiObject() {
let nodeDefinition = getNodeDefinition(thisObject.payload.node)
if (nodeDefinition === undefined) {
console.log('Node ' + thisObject.payload.node + ' without Node Definition at APP SCHEMA.')
console.log('Node ' + thisObject.payload.node + ' without Node Definition at APP SCHEMA.')
return
}
@@ -1708,7 +1887,13 @@ function newUiObject() {
browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.BLACK + ', 0.70)'
browserCanvasContext.fill()
/* Border when node is in focus */
if (thisObject.hasError !== true && nodeDefinition.isHierarchyHead !== true && thisObject.circularProgressBar === undefined) {
if (
thisObject.hasError !== true &&
thisObject.WarningError !== true &&
thisObject.hasInfo !== true &&
nodeDefinition.isHierarchyHead !== true &&
thisObject.circularProgressBar === undefined
) {
browserCanvasContext.beginPath()
browserCanvasContext.arc(visiblePosition.x, visiblePosition.y, VISIBLE_RADIUS, 0, Math.PI * 2, true)
browserCanvasContext.closePath()
@@ -1757,7 +1942,39 @@ function newUiObject() {
browserCanvasContext.stroke()
}
/* Info Ring */
if (thisObject.hasInfo === true) {
VISIBLE_RADIUS = thisObject.payload.floatingObject.container.frame.radius
if (canvas.floatingSpace.inMapMode === true) {
VISIBLE_RADIUS = canvas.floatingSpace.transformRadiusToMap(VISIBLE_RADIUS)
}
let OPACITY = infoMessageCounter / 30
browserCanvasContext.beginPath()
browserCanvasContext.arc(visiblePosition.x, visiblePosition.y, VISIBLE_RADIUS, 0, Math.PI * 2, true)
browserCanvasContext.closePath()
browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.DARK_TURQUOISE + ', ' + OPACITY + ')'
browserCanvasContext.lineWidth = 5
browserCanvasContext.setLineDash([5, 10])
browserCanvasContext.stroke()
}
/* Warning Ring */
if (thisObject.hasWarning === true) {
VISIBLE_RADIUS = thisObject.payload.floatingObject.container.frame.radius
if (canvas.floatingSpace.inMapMode === true) {
VISIBLE_RADIUS = canvas.floatingSpace.transformRadiusToMap(VISIBLE_RADIUS)
}
let OPACITY = warningMessageCounter / 30
browserCanvasContext.beginPath()
browserCanvasContext.arc(visiblePosition.x, visiblePosition.y, VISIBLE_RADIUS, 0, Math.PI * 2, true)
browserCanvasContext.closePath()
browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.TITANIUM_YELLOW + ', ' + OPACITY + ')'
browserCanvasContext.lineWidth = 5
browserCanvasContext.setLineDash([5, 10])
browserCanvasContext.stroke()
}
/* Error Ring */
if (thisObject.hasError === true) {
VISIBLE_RADIUS = thisObject.payload.floatingObject.container.frame.radius
if (canvas.floatingSpace.inMapMode === true) {
+1 -1
View File
@@ -177,7 +177,7 @@ function newLayer() {
'Image->Image Condition->Image Position->Point->' +
'Text->Text Condition->Text Position->Point->Text Formula->Text Style->' +
'Plotter Panel->Javascript Code->Panel Data->Data Formula->' +
'Nodes Highlights->Nodes Values->Nodes Errors->Nodes Status->Nodes Progress->Nodes Running->Nodes Announcements->Record Values->'
'Nodes Highlights->Nodes Values->Nodes Errors->Nodes Warnings->Nodes Infos->Nodes Status->Nodes Progress->Nodes Running->Nodes Announcements->Record Values->'
thisObject.definition = functionLibraryProtocolNode.getProtocolNode(thisObject.payload.node, false, true, true, false, false, lightingPath)
/* Here we validate that we have all the needed information */
+2
View File
@@ -405,6 +405,8 @@ function newLayersPanel() {
function removeFromLocalLayers(id) {
for (let i = 0; i < localLayers.length; i++) {
let layer = localLayers[i]
if (layer.payload === undefined) {continue}
if (layer.payload.node === undefined) {continue}
if (layer.payload.node.id === id) {
thisObject.layers.push(layer)
localLayers.splice(i, 1)
+47
View File
@@ -0,0 +1,47 @@
function newNodesInfos() {
const MODULE_NAME = 'Nodes Infos'
const logger = newWebDebugLog()
logger.fileName = MODULE_NAME
let thisObject = {
onRecordChange: onRecordChange,
initialize: initialize,
finalize: finalize
}
let hiriarchyMap
return thisObject
function finalize() {
hiriarchyMap = undefined
}
function initialize(pRootNode) {
let rootNode = canvas.designSpace.workspace.getHierarchyHeadsById(pRootNode.id)
hiriarchyMap = getHiriarchyMap(rootNode)
}
function onRecordChange(currentRecord) {
if (currentRecord === undefined) { return }
let array = currentRecord.infos
if (array === undefined) { return }
for (let i = 0; i < array.length; i++) {
let arrayItem = array[i]
let nodeId = arrayItem[0]
let value = arrayItem[1]
applyValue(nodeId, value)
}
}
function applyValue(nodeId, value) {
if (canvas.chartingSpace.visible !== true) { return }
let node = hiriarchyMap.get(nodeId)
if (node === undefined) { return }
if (node.payload === undefined) { return }
if (node.payload.uiObject === undefined) { return }
if (value === '') {
node.payload.uiObject.resetInfoMessage()
} else {
node.payload.uiObject.setInfoMessage(value)
}
}
}
+47
View File
@@ -0,0 +1,47 @@
function newNodesWarnings() {
const MODULE_NAME = 'Nodes Warnings'
const logger = newWebDebugLog()
logger.fileName = MODULE_NAME
let thisObject = {
onRecordChange: onRecordChange,
initialize: initialize,
finalize: finalize
}
let hiriarchyMap
return thisObject
function finalize() {
hiriarchyMap = undefined
}
function initialize(pRootNode) {
let rootNode = canvas.designSpace.workspace.getHierarchyHeadsById(pRootNode.id)
hiriarchyMap = getHiriarchyMap(rootNode)
}
function onRecordChange(currentRecord) {
if (currentRecord === undefined) { return }
let array = currentRecord.warnings
if (array === undefined) { return }
for (let i = 0; i < array.length; i++) {
let arrayItem = array[i]
let nodeId = arrayItem[0]
let value = arrayItem[1]
applyValue(nodeId, value)
}
}
function applyValue(nodeId, value) {
if (canvas.chartingSpace.visible !== true) { return }
let node = hiriarchyMap.get(nodeId)
if (node === undefined) { return }
if (node.payload === undefined) { return }
if (node.payload.uiObject === undefined) { return }
if (value === '') {
node.payload.uiObject.resetWarningMessage()
} else {
node.payload.uiObject.setWarningMessage(value)
}
}
}
+1 -1
View File
@@ -1 +1 @@
{"type":"Data Mine","name":"Masters-Trading","config":"{ \n\"codeName\": \"Masters-Trading\"\n}","sensorBots":[],"indicatorBots":[],"tradingBots":[{"type":"Trading Bot","name":"Low Frequency","config":"{\n\"codeName\": \"Low-Frequency\"\n}","processes":[{"type":"Process Definition","name":"Trading","config":"{\n \"codeName\": \"Trading\",\n \"sessionRunWaitTime\": 5000,\n \"retryWaitTime\": 10000,\n \"framework\": {\n \"name\": \"Low-Frequency-Trading-Process\"\n }\n }","processOutput":{"type":"Process Output","name":"New Process Output","outputDatasets":[{"type":"Output Dataset","name":"Multi-Period-Market Episode Counters","id":"6fc3054e-5034-4fc7-bddf-02360e0a6acf","savedPayload":{"position":{"x":15123.41163050094,"y":14131.6654223834},"targetPosition":{"x":19329.624549119937,"y":12258.776357515448},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{},"referenceParent":{"type":"Dataset Definition","name":"Multi-Period-Market","id":"db063d7b-db05-4bf6-941f-999e1ccb38fc"}}},{"type":"Output Dataset","name":"Multi-Period-Daily Episode Counters","id":"c3c2240f-514b-40de-825f-674037117d0b","savedPayload":{"position":{"x":15059.583922735308,"y":13981.6860113914},"targetPosition":{"x":19329.624549119937,"y":12258.776357515448},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{},"referenceParent":{"type":"Dataset Definition","name":"Multi-Period-Daily","id":"0764aaaf-d970-4f23-9df8-55fe5b7dd273"}}},{"type":"Output Dataset","name":"Multi-Period-Market Episode Statistics","id":"1dfdfc0d-842f-4e63-a591-256ac8a06b0f","savedPayload":{"position":{"x":15001.0923286648,"y":13829.555221724748},"targetPosition":{"x":19329.624549119937,"y":12258.776357515448},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{},"referenceParent":{"type":"Dataset Definition","name":"Multi-Period-Market","id":"fc9dc0f7-35e0-4548-bb91-f920825d694f"}}},{"type":"Output Dataset","name":"Multi-Period-Daily Episode Statistics","id":"39360c55-5ba8-413b-b0bd-cac3789ebf5f","savedPayload":{"position":{"x":14948.006652598842,"y":13676.050968178995},"targetPosition":{"x":19329.624549119937,"y":12258.776357515448},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{},"referenceParent":{"type":"Dataset Definition","name":"Multi-Period-Daily","id":"91953362-8751-4440-a898-21245cd47c15"}}},{"type":"Output Dataset","name":"Multi-Period-Market Episode Candle","id":"ba614415-6e4f-4979-97a5-34c72a59e67c","savedPayload":{"position":{"x":14900.392637325853,"y":13521.179581728626},"targetPosition":{"x":19329.624549119937,"y":12258.776357515448},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{},"referenceParent":{"type":"Dataset Definition","name":"Multi-Period-Market","id":"17fb41f5-61b5-4433-9a10-950ff8216a7e"}}},{"type":"Output Dataset","name":"Multi-Period-Daily Episode Candle","id":"1a2e3461-33e6-45b1-bcc1-c56a8c5d275c","savedPayload":{"position":{"x":14858.309491924105,"y":13364.741589835976},"targetPosition":{"x":19329.624549119937,"y":12258.776357515448},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{},"referenceParent":{"type":"Dataset Definition","name":"Multi-Period-Daily","id":"bbc9467d-28bf-432b-9e49-582d1bcabfb9"}}},{"type":"Output Dataset","name":"Multi-Period-Market Episode Balances","id":"567e4dc9-4deb-41e4-9ac9-dde943fb91ba","savedPayload":{"position":{"x":14821.809568281462,"y":13206.928494123413},"targetPosition":{"x":19329.624549119937,"y":12258.776357515448},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{},"referenceParent":{"type":"Dataset Definition","name":"Multi-Period-Market","id":"acddff59-b51b-4b45-b58f-71d4077755ee"}}},{"type":"Output Dataset","name":"Multi-Period-Daily Episode Balances","id":"e94b9bb3-9f0c-4550-94e1-09de444780a8","savedPayload":{"position":{"x":14790.93831241929,"y":13047.935697824543},"targetPosition":{"x":19329.624549119937,"y":12258.776357515448},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{},"referenceParent":{"type":"Dataset Definition","name":"Multi-Period-Daily","id":"213b8fe8-f772-41ea-a3f5-97867be555f7"}}},{"type":"Output Dataset","name":"Multi-Period-Market Distance To Event","id":"a30e7306-7be9-41b6-a465-558fdfe2a903","savedPayload":{"position":{"x":14765.734171531782,"y":12887.960675732134},"targetPosition":{"x":19329.624549119937,Line truncated
{"type":"Data Mine","name":"Masters-Trading","config":"{ \n\"codeName\": \"Masters-Trading\"\n}","sensorBots":[],"indicatorBots":[],"tradingBots":[{"type":"Trading Bot","name":"Low Frequency","config":"{\n\"codeName\": \"Low-Frequency\"\n}","processes":[{"type":"Process Definition","name":"Trading","config":"{\n \"codeName\": \"Trading\",\n \"sessionRunWaitTime\": 5000,\n \"retryWaitTime\": 10000,\n \"framework\": {\n \"name\": \"Low-Frequency-Trading-Process\"\n }\n }","processOutput":{"type":"Process Output","name":"New Process Output","outputDatasets":[{"type":"Output Dataset","name":"Multi-Period-Market Episode Counters","id":"6fc3054e-5034-4fc7-bddf-02360e0a6acf","savedPayload":{"position":{"x":15043.502763626615,"y":13565.633447736122},"targetPosition":{"x":19587.798820144457,"y":11500.464802301472},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{},"referenceParent":{"type":"Dataset Definition","name":"Multi-Period-Market","id":"db063d7b-db05-4bf6-941f-999e1ccb38fc"}}},{"type":"Output Dataset","name":"Multi-Period-Daily Episode Counters","id":"c3c2240f-514b-40de-825f-674037117d0b","savedPayload":{"position":{"x":14976.659274738518,"y":13409.942947906273},"targetPosition":{"x":19587.798820144457,"y":11500.464802301472},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{},"referenceParent":{"type":"Dataset Definition","name":"Multi-Period-Daily","id":"0764aaaf-d970-4f23-9df8-55fe5b7dd273"}}},{"type":"Output Dataset","name":"Multi-Period-Market Episode Statistics","id":"1dfdfc0d-842f-4e63-a591-256ac8a06b0f","savedPayload":{"position":{"x":14914.888630231306,"y":13251.92462190976},"targetPosition":{"x":19587.798820144457,"y":11500.464802301472},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{},"referenceParent":{"type":"Dataset Definition","name":"Multi-Period-Market","id":"fc9dc0f7-35e0-4548-bb91-f920825d694f"}}},{"type":"Output Dataset","name":"Multi-Period-Daily Episode Statistics","id":"39360c55-5ba8-413b-b0bd-cac3789ebf5f","savedPayload":{"position":{"x":14858.381757937008,"y":13091.90908668388},"targetPosition":{"x":19587.798820144457,"y":11500.464802301472},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{},"referenceParent":{"type":"Dataset Definition","name":"Multi-Period-Daily","id":"91953362-8751-4440-a898-21245cd47c15"}}},{"type":"Output Dataset","name":"Multi-Period-Market Episode Candle","id":"ba614415-6e4f-4979-97a5-34c72a59e67c","savedPayload":{"position":{"x":14807.274021473277,"y":12930.139909734808},"targetPosition":{"x":19587.798820144457,"y":11500.464802301472},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{},"referenceParent":{"type":"Dataset Definition","name":"Multi-Period-Market","id":"17fb41f5-61b5-4433-9a10-950ff8216a7e"}}},{"type":"Output Dataset","name":"Multi-Period-Daily Episode Candle","id":"1a2e3461-33e6-45b1-bcc1-c56a8c5d275c","savedPayload":{"position":{"x":14761.634620744779,"y":12766.829832535312},"targetPosition":{"x":19587.798820144457,"y":11500.464802301472},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{},"referenceParent":{"type":"Dataset Definition","name":"Multi-Period-Daily","id":"bbc9467d-28bf-432b-9e49-582d1bcabfb9"}}},{"type":"Output Dataset","name":"Multi-Period-Market Episode Balances","id":"567e4dc9-4deb-41e4-9ac9-dde943fb91ba","savedPayload":{"position":{"x":14721.557593855016,"y":12602.16006759612},"targetPosition":{"x":19587.798820144457,"y":11500.464802301472},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{},"referenceParent":{"type":"Dataset Definition","name":"Multi-Period-Market","id":"acddff59-b51b-4b45-b58f-71d4077755ee"}}},{"type":"Output Dataset","name":"Multi-Period-Daily Episode Balances","id":"e94b9bb3-9f0c-4550-94e1-09de444780a8","savedPayload":{"position":{"x":14687.08147628032,"y":12436.31530565774},"targetPosition":{"x":19587.798820144457,"y":11500.464802301472},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{},"referenceParent":{"type":"Dataset Definition","name":"Multi-Period-Daily","id":"213b8fe8-f772-41ea-a3f5-97867be555f7"}}},{"type":"Output Dataset","name":"Multi-Period-Market Distance To Event","id":"a30e7306-7be9-41b6-a465-558fdfe2a903","savedPayload":{"position":{"x":14658.226523037441,"y":12269.479511483436},"targetPosition":{"x":19587.7988201444Line truncated
+1 -21
View File
@@ -81,9 +81,6 @@
try {
let fixedTimeLoopIntervalHandle;
/* Errors sent to the UI */
bot.processError = processError
/* Heartbeats sent to the UI */
bot.processHeartBeat = processHeartBeat
@@ -763,26 +760,9 @@
global.EVENT_SERVER_CLIENT.raiseEvent(bot.processKey, 'Heartbeat', event)
}
function processError(node, errorMessage) {
let event
if (node !== undefined) {
event = {
nodeName: node.name,
nodeType: node.type,
nodeId: node.id,
errorMessage: errorMessage
}
} else {
event = {
errorMessage: errorMessage
}
}
global.EVENT_SERVER_CLIENT.raiseEvent(bot.processKey, 'Error', event)
}
function processStopped() {
if (global.unexpectedError !== undefined) {
processError(undefined, "An unexpected error caused the Process to stop.")
global.PROCESS_ERROR(bot.processKey, undefined, "An unexpected error caused the Process to stop.")
} else {
global.EVENT_SERVER_CLIENT.raiseEvent(bot.processKey, 'Stopped')
}
@@ -104,8 +104,9 @@ exports.newTradingSimulation = function newTradingSimulation(bot, logger, tradin
*/
for (let i = initialCandle; i < candles.length - 1; i++) {
tradingEngine.current.episode.candle.index.value = i
if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] runSimulation -> loop -> Processing candle # ' + tradingEngine.current.episode.candle.index.value) }
let candle = candles[tradingEngine.current.episode.candle.index.value] // This is the current candle the Simulation is working at.
/* This is the current candle the Simulation is working at. */
let candle = candles[tradingEngine.current.episode.candle.index.value]
if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] runSimulation -> loop -> Candle Begin @ ' + (new Date(candle.begin)).toLocaleString()) }
if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] runSimulation -> loop -> Candle End @ ' + (new Date(candle.end)).toLocaleString()) }
@@ -186,6 +187,10 @@ exports.newTradingSimulation = function newTradingSimulation(bot, logger, tradin
tradingEpisodeModule.reset()
tradingEngineModule.reset()
let infoMessage = 'Processing candle # ' + tradingEngine.current.episode.candle.index.value + ' @ the ' + tradingEngine.current.episode.cycle.value + ' cycle.'
if (FULL_LOG === true) { logger.write(MODULE_NAME, '[INFO] runSimulation -> loop -> ' + infoMessage) }
tradingSystem.infos.push([tradingSystem.id, infoMessage])
await tradingSystemModule.run()
}
@@ -87,6 +87,8 @@ exports.newTradingSystem = function newTradingSystem(bot, logger, tradingEngineM
tradingSystem.highlights = undefined
tradingSystem.errors = undefined
tradingSystem.warnings = undefined
tradingSystem.infos = undefined
tradingSystem.values = undefined
tradingSystem.status = undefined
tradingSystem.progress = undefined
@@ -106,6 +108,8 @@ exports.newTradingSystem = function newTradingSystem(bot, logger, tradingEngineM
tradingSystem.highlights = []
tradingSystem.errors = []
tradingSystem.warnings = []
tradingSystem.infos = []
tradingSystem.values = []
tradingSystem.status = []
tradingSystem.progress = []
+1 -21
View File
@@ -85,9 +85,6 @@
try {
let fixedTimeLoopIntervalHandle;
/* Errors sent to the UI */
bot.processError = processError
/* Heartbeats sent to the UI */
bot.processHeartBeat = processHeartBeat
@@ -571,26 +568,9 @@
global.EVENT_SERVER_CLIENT.raiseEvent(bot.processKey, 'Heartbeat', event)
}
function processError(node, errorMessage) {
let event
if (node !== undefined) {
event = {
nodeName: node.name,
nodeType: node.type,
nodeId: node.id,
errorMessage: errorMessage
}
} else {
event = {
errorMessage: errorMessage
}
}
global.EVENT_SERVER_CLIENT.raiseEvent(bot.processKey, 'Error', event)
}
function processStopped() {
if (global.unexpectedError !== undefined) {
processError(undefined, "An unexpected error caused the Process to stop.")
global.PROCESS_ERROR(bot.processKey, undefined, "An unexpected error caused the Process to stop.")
} else {
global.EVENT_SERVER_CLIENT.raiseEvent(bot.processKey, 'Stopped')
}
+58 -5
View File
@@ -41,8 +41,10 @@
global.EVENT_SERVER_CLIENT.listenToEvent(bot.sessionKey, 'Run Session', undefined, bot.sessionKey, undefined, onSessionRan)
global.EVENT_SERVER_CLIENT.listenToEvent(bot.sessionKey, 'Stop Session', undefined, bot.sessionKey, undefined, onSessionStopped)
/* Errors sent to the UI */
/* Connect this here so that it is accesible from other places */
bot.sessionError = sessionError
bot.sessionWarning = sessionWarning
bot.sessionInfo = sessionInfo
/* Heartbeats sent to the UI */
bot.sessionHeartBeat = sessionHeartBeat
@@ -113,7 +115,7 @@
socialBotsModule.sendMessage(bot.SESSION.type + " '" + bot.SESSION.name + "' is stopping " + commandOrigin)
socialBotsModule.finalize()
bot.STOP_SESSION = true
sessionError(bot.SESSION, commandOrigin)
sessionInfo(bot.SESSION, commandOrigin)
}
function setUpAppSchema() {
@@ -214,10 +216,19 @@
*/
/* Initial Datetime */
if (bot.SESSION.parameters.timeRange.config.initialDatetime === undefined || bot.SESSION.parameters.timeRange.config.allowStartingFromThePast !== true ) {
bot.SESSION.parameters.timeRange.config.initialDatetime = initialDefault
if (bot.SESSION.type === 'Backtesting Session') {
if (bot.SESSION.parameters.timeRange.config.initialDatetime === undefined ) {
bot.SESSION.parameters.timeRange.config.initialDatetime = initialDefault
} else {
bot.SESSION.parameters.timeRange.config.initialDatetime = (new Date(bot.SESSION.parameters.timeRange.config.initialDatetime)).valueOf()
}
} else {
bot.SESSION.parameters.timeRange.config.initialDatetime = (new Date(bot.SESSION.parameters.timeRange.config.initialDatetime)).valueOf()
/* Non backtest session can start from the past only if explicitly configured that way */
if (bot.SESSION.parameters.timeRange.config.initialDatetime === undefined || bot.SESSION.parameters.timeRange.config.allowStartingFromThePast !== true ) {
bot.SESSION.parameters.timeRange.config.initialDatetime = initialDefault
} else {
bot.SESSION.parameters.timeRange.config.initialDatetime = (new Date(bot.SESSION.parameters.timeRange.config.initialDatetime)).valueOf()
}
}
/* Final Datetime */
@@ -412,6 +423,48 @@
}
}
function sessionWarning(node, warningMessage) {
let event
if (node !== undefined) {
event = {
nodeName: node.name,
nodeType: node.type,
nodeId: node.id,
warningMessage: warningMessage
}
} else {
event = {
warningMessage: warningMessage
}
}
global.EVENT_SERVER_CLIENT.raiseEvent(bot.sessionKey, 'Warning', event)
if (global.STOP_TASK_GRACEFULLY === true) {
bot.STOP_SESSION = true
}
}
function sessionInfo(node, infoMessage) {
let event
if (node !== undefined) {
event = {
nodeName: node.name,
nodeType: node.type,
nodeId: node.id,
infoMessage: infoMessage
}
} else {
event = {
infoMessage: infoMessage
}
}
global.EVENT_SERVER_CLIENT.raiseEvent(bot.sessionKey, 'Info', event)
if (global.STOP_TASK_GRACEFULLY === true) {
bot.STOP_SESSION = true
}
}
} catch (err) {
parentLogger.write(MODULE_NAME, "[ERROR] initialize -> err = " + err.stack);
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
+1 -1
View File
@@ -83,7 +83,7 @@
function validationFailed(errorInNode, errorMessage) {
let nodeString = JSON.stringify(errorInNode)
logger.write(MODULE_NAME, "[ERROR] initialize -> " + errorMessage + ' -> nodeString = ' + nodeString)
bot.processError(errorInNode, errorMessage)
bot.global.PROCESS_ERROR(bot.processKey, errorInNode, errorMessage)
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
}
+1 -21
View File
@@ -45,9 +45,6 @@
let fixedTimeLoopIntervalHandle;
bot.STOP_SESSION = true;
/* Errors sent to the UI */
bot.processError = processError
/* Heartbeats sent to the UI */
bot.processHeartBeat = processHeartBeat
@@ -654,26 +651,9 @@
global.EVENT_SERVER_CLIENT.raiseEvent(bot.processKey, 'Heartbeat', event)
}
function processError(node, errorMessage) {
let event
if (node !== undefined) {
event = {
nodeName: node.name,
nodeType: node.type,
nodeId: node.id,
errorMessage: errorMessage
}
} else {
event = {
errorMessage: errorMessage
}
}
global.EVENT_SERVER_CLIENT.raiseEvent(bot.processKey, 'Error', event)
}
function processStopped() {
if (global.unexpectedError !== undefined) {
processError(undefined, "An unexpected error caused the Process to stop.")
global.PROCESS_ERROR(bot.processKey, undefined, "An unexpected error caused the Process to stop.")
} else {
global.EVENT_SERVER_CLIENT.raiseEvent(bot.processKey, 'Stopped')
}
+51
View File
@@ -51,6 +51,57 @@ global.REMOVE_TIME = function (datetime) {
return new Date(date.getUTCFullYear() + "-" + (date.getUTCMonth() + 1) + "-" + date.getUTCDate() + " " + "00:00" + GMT_SECONDS);
}
global.PROCESS_ERROR = function (processKey, node, errorMessage) {
let event
if (node !== undefined) {
event = {
nodeName: node.name,
nodeType: node.type,
nodeId: node.id,
errorMessage: errorMessage
}
} else {
event = {
errorMessage: errorMessage
}
}
global.EVENT_SERVER_CLIENT.raiseEvent(processKey, 'Error', event)
}
global.PROCESS_WARNING = function (processKey, node, warningMessage) {
let event
if (node !== undefined) {
event = {
nodeName: node.name,
nodeType: node.type,
nodeId: node.id,
warningMessage: warningMessage
}
} else {
event = {
warningMessage: warningMessage
}
}
global.EVENT_SERVER_CLIENT.raiseEvent(processKey, 'Warning', event)
}
global.PROCESS_INFO = function (processKey, node, infoMessage) {
let event
if (node !== undefined) {
event = {
nodeName: node.name,
nodeType: node.type,
nodeId: node.id,
infoMessage: infoMessage
}
} else {
event = {
infoMessage: infoMessage
}
}
global.EVENT_SERVER_CLIENT.raiseEvent(processKey, 'Info', event)
}
process.on('uncaughtException', function (err) {
console.log('[ERROR] Task Server -> server -> uncaughtException -> err.message = ' + err.message)
console.log('[ERROR] Task Server -> server -> uncaughtException -> err.stack = ' + err.stack)