Merge pull request #116 from AAMasters/develop
Beta 6 Implementation Finished
This commit is contained in:
26 files changed
+1007
-223
No files matched your search
+61
-70
@@ -59,89 +59,80 @@ function newAnimation () {
|
||||
|
||||
function animationLoop () {
|
||||
try {
|
||||
if (window.canvasApp.visible === true) {
|
||||
/* We set the canvas to its normal width and height */
|
||||
// browserCanvas.width = window.innerWidth
|
||||
// browserCanvas.height = window.innerHeight - CURRENT_TOP_MARGIN
|
||||
/* First thing is to clear the actual canvas */
|
||||
clearBrowserCanvas()
|
||||
|
||||
/* First thing is to clear the actual canvas */
|
||||
clearBrowserCanvas()
|
||||
|
||||
/* We loop through the callback functions collections and execute them all. */
|
||||
let performanceMap = new Map()
|
||||
let totalTimeConsumed = 0
|
||||
let totalElements = 0
|
||||
let chanceToExecute
|
||||
let randomNumber
|
||||
let mustExecute
|
||||
/* We loop through the callback functions collections and execute them all. */
|
||||
let performanceMap = new Map()
|
||||
let totalTimeConsumed = 0
|
||||
let totalElements = 0
|
||||
let chanceToExecute
|
||||
let randomNumber
|
||||
let mustExecute
|
||||
|
||||
// console.clear()
|
||||
let row = 0
|
||||
for (const [key, callBackFunction] of callBackFunctions.entries()) {
|
||||
row++
|
||||
switch (key) {
|
||||
case 'Floating Space Physics':
|
||||
chanceToExecute = 50
|
||||
randomNumber = Math.random() * 100 * chanceToExecute
|
||||
if (randomNumber > 100 - chanceToExecute) { mustExecute = true } else { mustExecute = false }
|
||||
break
|
||||
default: {
|
||||
mustExecute = true
|
||||
}
|
||||
|
||||
let row = 0
|
||||
for (const [key, callBackFunction] of callBackFunctions.entries()) {
|
||||
row++
|
||||
switch (key) {
|
||||
case 'Floating Space Physics':
|
||||
chanceToExecute = 50
|
||||
randomNumber = Math.random() * 100 * chanceToExecute
|
||||
if (randomNumber > 100 - chanceToExecute) { mustExecute = true } else { mustExecute = false }
|
||||
break
|
||||
default: {
|
||||
mustExecute = true
|
||||
}
|
||||
let timeConsumed = 0
|
||||
if (mustExecute === true) {
|
||||
let t0 = performance.now()
|
||||
callBackFunction()
|
||||
let t1 = performance.now()
|
||||
timeConsumed = t1 - t0
|
||||
if (key === 'Charting Space Draw') {
|
||||
if (Math.random() * 100 > 99) {
|
||||
totalConsumption = 0
|
||||
totalCounter = 0
|
||||
}
|
||||
|
||||
totalConsumption = totalConsumption + timeConsumed
|
||||
totalCounter = totalCounter + 1
|
||||
}
|
||||
performanceMap.set(key, timeConsumed)
|
||||
totalTimeConsumed = totalTimeConsumed + timeConsumed
|
||||
totalElements++
|
||||
}
|
||||
}
|
||||
let timeConsumed = 0
|
||||
if (mustExecute === true) {
|
||||
let t0 = performance.now()
|
||||
callBackFunction()
|
||||
let t1 = performance.now()
|
||||
timeConsumed = t1 - t0
|
||||
if (key === 'Charting Space Draw') {
|
||||
if (Math.random() * 100 > 99) {
|
||||
totalConsumption = 0
|
||||
totalCounter = 0
|
||||
}
|
||||
|
||||
totalConsumption = totalConsumption + timeConsumed
|
||||
totalCounter = totalCounter + 1
|
||||
}
|
||||
performanceMap.set(key, timeConsumed)
|
||||
totalTimeConsumed = totalTimeConsumed + timeConsumed
|
||||
totalElements++
|
||||
}
|
||||
}
|
||||
|
||||
/* Frame per Seconds */
|
||||
|
||||
ANIMATION_FRAME_PER_SECONDS = Math.trunc(1000 / totalTimeConsumed)
|
||||
ANIMATION_FRAME_PER_SECONDS = Math.trunc(1000 / totalTimeConsumed)
|
||||
|
||||
/* Performance Check */
|
||||
if (SHOW_ANIMATION_PERFORMACE === true) {
|
||||
row = 0
|
||||
for (const [key, timeConsumed] of performanceMap.entries()) {
|
||||
row++
|
||||
labelToPrint = key + ' ' + timeConsumed.toFixed(4)
|
||||
printLabel(labelToPrint, 10, 100 + row * 30, 1, 20, UI_COLOR.RED)
|
||||
let percentage = timeConsumed * 100 / totalTimeConsumed
|
||||
labelToPrint = key + ' ' + percentage.toFixed(1) + '%'
|
||||
printLabel(labelToPrint, 300, 100 + row * 30, 1, 20, UI_COLOR.RED)
|
||||
}
|
||||
if (SHOW_ANIMATION_PERFORMACE === true) {
|
||||
row = 0
|
||||
for (const [key, timeConsumed] of performanceMap.entries()) {
|
||||
row++
|
||||
labelToPrint = key + ' ' + timeConsumed.toFixed(4)
|
||||
printLabel(labelToPrint, 10, 100 + row * 30, 1, 20, UI_COLOR.RED)
|
||||
let percentage = timeConsumed * 100 / totalTimeConsumed
|
||||
labelToPrint = key + ' ' + percentage.toFixed(1) + '%'
|
||||
printLabel(labelToPrint, 300, 100 + row * 30, 1, 20, UI_COLOR.RED)
|
||||
}
|
||||
|
||||
/* Other Variables */
|
||||
row++
|
||||
printLabel(DEBUG.variable1, 300, 100 + row * 30, 1, 20, UI_COLOR.RED)
|
||||
row++
|
||||
printLabel(DEBUG.variable2, 300, 100 + row * 30, 1, 20, UI_COLOR.RED)
|
||||
row++
|
||||
printLabel(DEBUG.variable3, 300, 100 + row * 30, 1, 20, UI_COLOR.RED)
|
||||
row++
|
||||
printLabel(DEBUG.variable4, 300, 100 + row * 30, 1, 20, UI_COLOR.RED)
|
||||
row++
|
||||
printLabel('Animation Frame Per Seconds: ' + ANIMATION_FRAME_PER_SECONDS, 300, 100 + row * 30, 1, 20, UI_COLOR.TITANIUM_YELLOW)
|
||||
}
|
||||
} else {
|
||||
browserCanvas.width = 1
|
||||
browserCanvas.height = 1
|
||||
row++
|
||||
printLabel(DEBUG.variable1, 300, 100 + row * 30, 1, 20, UI_COLOR.RED)
|
||||
row++
|
||||
printLabel(DEBUG.variable2, 300, 100 + row * 30, 1, 20, UI_COLOR.RED)
|
||||
row++
|
||||
printLabel(DEBUG.variable3, 300, 100 + row * 30, 1, 20, UI_COLOR.RED)
|
||||
row++
|
||||
printLabel(DEBUG.variable4, 300, 100 + row * 30, 1, 20, UI_COLOR.RED)
|
||||
row++
|
||||
printLabel('Animation Frame Per Seconds: ' + ANIMATION_FRAME_PER_SECONDS, 300, 100 + row * 30, 1, 20, UI_COLOR.TITANIUM_YELLOW)
|
||||
}
|
||||
|
||||
/* Video Recording */
|
||||
|
||||
@@ -97,12 +97,11 @@ function newCanvas () {
|
||||
|
||||
function initialize () {
|
||||
try {
|
||||
browserResized()
|
||||
initializeBrowserCanvas()
|
||||
|
||||
addCanvasEvents()
|
||||
|
||||
/* Instantiate all the children spaces of Canvas object */
|
||||
|
||||
/* Instantiate all the children spaces of Canvas object */
|
||||
thisObject.floatingSpace = newFloatingSpace()
|
||||
thisObject.floatingSpace.initialize()
|
||||
|
||||
@@ -199,14 +198,10 @@ function newCanvas () {
|
||||
}
|
||||
|
||||
function browserResized () {
|
||||
try {
|
||||
browserCanvas = document.getElementById('canvas')
|
||||
browserCanvas = document.getElementById('canvas')
|
||||
|
||||
browserCanvas.width = window.innerWidth
|
||||
browserCanvas.height = window.innerHeight - CURRENT_TOP_MARGIN
|
||||
} catch (err) {
|
||||
if (ERROR_LOG === true) { logger.write('[ERROR] browserResized -> err = ' + err.stack) }
|
||||
}
|
||||
browserCanvas.width = window.innerWidth
|
||||
browserCanvas.height = window.innerHeight - CURRENT_TOP_MARGIN
|
||||
}
|
||||
|
||||
function checkMediaRecording (event) {
|
||||
|
||||
@@ -131,17 +131,31 @@ function newPlottersManager () {
|
||||
baseAsset: baseAsset,
|
||||
quotedAsset: quotedAsset
|
||||
}
|
||||
let product = layer.definition.referenceParent.referenceParent
|
||||
let productDefinition = layer.definition.referenceParent.referenceParent
|
||||
let bot = layer.definition.referenceParent.referenceParent.parentNode
|
||||
let dataMine = layer.definition.referenceParent.referenceParent.parentNode.parentNode
|
||||
let exchange = layer.definition.referenceParent.parentNode.referenceParent.parentNode.parentNode
|
||||
let plotterModule = layer.definition.referenceParent.referenceParent.referenceParent
|
||||
let session
|
||||
let tradingSystem
|
||||
let tradingEngine
|
||||
|
||||
/*
|
||||
A layer can be referencing a Data Product in two different branches of the Network hiriatchy.
|
||||
In one of those braches we can get the Session node, at the other we Cannot.
|
||||
*/
|
||||
if (layer.definition.referenceParent.parentNode.parentNode !== undefined) {
|
||||
if (layer.definition.referenceParent.parentNode.parentNode.type === 'Session Reference') {
|
||||
if (layer.definition.referenceParent.parentNode.parentNode.referenceParent !== undefined) {
|
||||
session = layer.definition.referenceParent.parentNode.parentNode.referenceParent
|
||||
|
||||
/* From the session we might be able to reach the Trading System or the Trading Engine */
|
||||
if (session.tradingSystemReference !== undefined) {
|
||||
tradingSystem = session.tradingSystemReference.referenceParent
|
||||
}
|
||||
if (session.tradingEngineReference !== undefined) {
|
||||
tradingEngine = session.tradingEngineReference.referenceParent
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -157,7 +171,7 @@ function newPlottersManager () {
|
||||
dataMine,
|
||||
bot,
|
||||
session,
|
||||
product,
|
||||
productDefinition,
|
||||
exchange,
|
||||
market,
|
||||
datetime,
|
||||
@@ -169,66 +183,154 @@ function newPlottersManager () {
|
||||
)
|
||||
|
||||
function onProductStorageInitialized (err) {
|
||||
try {
|
||||
if (err.result === GLOBAL.DEFAULT_OK_RESPONSE.result) {
|
||||
if (err.result === GLOBAL.DEFAULT_OK_RESPONSE.result) {
|
||||
/* Now we have all the initial data loaded and ready to be delivered to the new instance of the plotter. */
|
||||
let plotter
|
||||
let plotter
|
||||
|
||||
if (plotterModule.config.isLegacy !== true) {
|
||||
plotter = newPlotter()
|
||||
} else {
|
||||
plotter = getNewPlotter(dataMine.config.codeName, plotterModule.parentNode.config.codeName, plotterModule.config.codeName)
|
||||
if (plotterModule.config.isLegacy !== true) {
|
||||
plotter = newPlotter()
|
||||
} else {
|
||||
plotter = getNewPlotter(dataMine.config.codeName, plotterModule.parentNode.config.codeName, plotterModule.config.codeName)
|
||||
}
|
||||
|
||||
plotter.container.connectToParent(thisObject.container, true, true, false, true, true, true, false, false, true)
|
||||
plotter.container.frame.position.x = thisObject.container.frame.width / 2 - plotter.container.frame.width / 2
|
||||
plotter.container.frame.position.y = thisObject.container.frame.height / 2 - plotter.container.frame.height / 2
|
||||
plotter.fitFunction = thisObject.fitFunction
|
||||
plotter.initialize(storage, datetime, timeFrame, coordinateSystem, onPlotterInizialized, productDefinition)
|
||||
|
||||
function onPlotterInizialized () {
|
||||
let connector = {
|
||||
layer: layer,
|
||||
plotter: plotter,
|
||||
storage: storage
|
||||
}
|
||||
/* Let the Plotter listen to the event of Cursor Files loaded, so that it can react recalculating if needed. */
|
||||
plotter.onDailyFileLoadedPlotterEventsSubscriptionId = storage.eventHandler.listenToEvent('Daily File Loaded', plotter.onDailyFileLoaded)
|
||||
/* Lets load now this plotter panels. */
|
||||
connector.panels = []
|
||||
|
||||
plotter.container.connectToParent(thisObject.container, true, true, false, true, true, true, false, false, true)
|
||||
plotter.container.frame.position.x = thisObject.container.frame.width / 2 - plotter.container.frame.width / 2
|
||||
plotter.container.frame.position.y = thisObject.container.frame.height / 2 - plotter.container.frame.height / 2
|
||||
plotter.fitFunction = thisObject.fitFunction
|
||||
plotter.initialize(storage, datetime, timeFrame, coordinateSystem, onPlotterInizialized, product)
|
||||
if (productDefinition !== undefined) {
|
||||
/* Here we setup the panels associated with this plotter */
|
||||
for (let i = 0; i < plotterModule.panels.length; i++) {
|
||||
let panel = plotterModule.panels[i]
|
||||
|
||||
function onPlotterInizialized () {
|
||||
try {
|
||||
let connector = {
|
||||
layer: layer,
|
||||
plotter: plotter,
|
||||
storage: storage
|
||||
}
|
||||
/* Let the Plotter listen to the event of Cursor Files loaded, so that it can react recalculating if needed. */
|
||||
plotter.onDailyFileLoadedPlotterEventsSubscriptionId = storage.eventHandler.listenToEvent('Daily File Loaded', plotter.onDailyFileLoaded)
|
||||
/* Lets load now this plotter panels. */
|
||||
connector.panels = []
|
||||
|
||||
if (product !== undefined) {
|
||||
for (let i = 0; i < plotterModule.panels.length; i++) {
|
||||
let panel = plotterModule.panels[i]
|
||||
|
||||
let parameters = {
|
||||
dataMine: dataMine.config.codeName,
|
||||
plotterCodeName: plotterModule.parentNode.config.codeName,
|
||||
moduleCodeName: plotterModule.config.codeName,
|
||||
panelNode: panel
|
||||
}
|
||||
|
||||
let owner = thisObject.payload.node.payload.parentNode.id // Panels are owned by the time machine.
|
||||
let plotterPanelHandle = canvas.panelsSpace.createNewPanel('Plotter Panel', parameters, owner, layer.session)
|
||||
let plotterPanel = canvas.panelsSpace.getPanel(plotterPanelHandle)
|
||||
|
||||
/* Connect Panel to the Plotter via an Event. */
|
||||
connector.plotter.onRecordChangeEventsSubscriptionId = connector.plotter.container.eventHandler.listenToEvent('Current Record Changed', plotterPanel.onRecordChange)
|
||||
connector.panels.push(plotterPanelHandle)
|
||||
}
|
||||
|
||||
connector.layer.panels = connector.panels
|
||||
let parameters = {
|
||||
dataMine: dataMine.config.codeName,
|
||||
plotterCodeName: plotterModule.parentNode.config.codeName,
|
||||
moduleCodeName: plotterModule.config.codeName,
|
||||
panelNode: panel
|
||||
}
|
||||
|
||||
thisObject.connectors.push(connector)
|
||||
} catch (err) {
|
||||
if (ERROR_LOG === true) { logger.write('[ERROR] initializePlotter -> onProductStorageInitialized -> onPlotterInizialized -> err = ' + err.stack) }
|
||||
let owner = thisObject.payload.node.payload.parentNode.id // Panels are owned by the time machine.
|
||||
let plotterPanelHandle = canvas.panelsSpace.createNewPanel('Plotter Panel', parameters, owner, layer.session)
|
||||
let plotterPanel = canvas.panelsSpace.getPanel(plotterPanelHandle)
|
||||
|
||||
/* Connect Panel to the Plotter via an Event. */
|
||||
connector.plotter.onRecordChangeEventsSubscriptionId = connector.plotter.container.eventHandler.listenToEvent('Current Record Changed', plotterPanel.onRecordChange)
|
||||
connector.panels.push(plotterPanelHandle)
|
||||
}
|
||||
connector.layer.panels = connector.panels
|
||||
|
||||
/*
|
||||
Next we will check the different types of Plotting related to connecting to an existing node branch.
|
||||
*/
|
||||
if (plotterModule.nodesHighlights !== undefined && plotterModule.config.connectTo !== undefined) {
|
||||
connector.nodesHighlights = newNodesHighlights()
|
||||
switch (plotterModule.config.connectTo) {
|
||||
case 'Trading System':
|
||||
connector.nodesHighlights.initialize(tradingSystem)
|
||||
break
|
||||
case 'Trading Engine':
|
||||
connector.nodesHighlights.initialize(tradingEngine)
|
||||
break
|
||||
}
|
||||
connector.nodesHighlights.onRecordChangeEventsSubscriptionId = connector.plotter.container.eventHandler.listenToEvent('Current Record Changed', connector.nodesHighlights.onRecordChange)
|
||||
}
|
||||
if (plotterModule.nodesValues !== undefined && plotterModule.config.connectTo !== undefined) {
|
||||
connector.nodesValues = newNodesValues()
|
||||
switch (plotterModule.config.connectTo) {
|
||||
case 'Trading System':
|
||||
connector.nodesValues.initialize(tradingSystem)
|
||||
break
|
||||
case 'Trading Engine':
|
||||
connector.nodesValues.initialize(tradingEngine)
|
||||
break
|
||||
}
|
||||
connector.nodesValues.onRecordChangeEventsSubscriptionId = connector.plotter.container.eventHandler.listenToEvent('Current Record Changed', connector.nodesValues.onRecordChange)
|
||||
}
|
||||
if (plotterModule.nodesErrors !== undefined && plotterModule.config.connectTo !== undefined) {
|
||||
connector.nodesErrors = newNodesErrors()
|
||||
switch (plotterModule.config.connectTo) {
|
||||
case 'Trading System':
|
||||
connector.nodesErrors.initialize(tradingSystem)
|
||||
break
|
||||
case 'Trading Engine':
|
||||
connector.nodesErrors.initialize(tradingEngine)
|
||||
break
|
||||
}
|
||||
connector.nodesErrors.onRecordChangeEventsSubscriptionId = connector.plotter.container.eventHandler.listenToEvent('Current Record Changed', connector.nodesErrors.onRecordChange)
|
||||
}
|
||||
if (plotterModule.nodesRunning !== undefined && plotterModule.config.connectTo !== undefined) {
|
||||
connector.nodesRunning = newNodesRunning()
|
||||
switch (plotterModule.config.connectTo) {
|
||||
case 'Trading System':
|
||||
connector.nodesRunning.initialize(tradingSystem)
|
||||
break
|
||||
case 'Trading Engine':
|
||||
connector.nodesRunning.initialize(tradingEngine)
|
||||
break
|
||||
}
|
||||
connector.nodesRunning.onRecordChangeEventsSubscriptionId = connector.plotter.container.eventHandler.listenToEvent('Current Record Changed', connector.nodesRunning.onRecordChange)
|
||||
}
|
||||
if (plotterModule.nodesStatus !== undefined && plotterModule.config.connectTo !== undefined) {
|
||||
connector.nodesStatus = newNodesStatus()
|
||||
switch (plotterModule.config.connectTo) {
|
||||
case 'Trading System':
|
||||
connector.nodesStatus.initialize(tradingSystem)
|
||||
break
|
||||
case 'Trading Engine':
|
||||
connector.nodesStatus.initialize(tradingEngine)
|
||||
break
|
||||
}
|
||||
connector.nodesStatus.onRecordChangeEventsSubscriptionId = connector.plotter.container.eventHandler.listenToEvent('Current Record Changed', connector.nodesStatus.onRecordChange)
|
||||
}
|
||||
if (plotterModule.nodesProgress !== undefined && plotterModule.config.connectTo !== undefined) {
|
||||
connector.nodesProgress = newNodesProgress()
|
||||
switch (plotterModule.config.connectTo) {
|
||||
case 'Trading System':
|
||||
connector.nodesProgress.initialize(tradingSystem)
|
||||
break
|
||||
case 'Trading Engine':
|
||||
connector.nodesProgress.initialize(tradingEngine)
|
||||
break
|
||||
}
|
||||
connector.nodesProgress.onRecordChangeEventsSubscriptionId = connector.plotter.container.eventHandler.listenToEvent('Current Record Changed', connector.nodesProgress.onRecordChange)
|
||||
}
|
||||
if (plotterModule.nodesAnnouncements !== undefined && plotterModule.config.connectTo !== undefined) {
|
||||
connector.nodesAnnounements = newNodesAnnouncements()
|
||||
switch (plotterModule.config.connectTo) {
|
||||
case 'Trading System':
|
||||
connector.nodesAnnounements.initialize(tradingSystem)
|
||||
break
|
||||
case 'Trading Engine':
|
||||
connector.nodesAnnounements.initialize(tradingEngine)
|
||||
break
|
||||
}
|
||||
connector.nodesAnnounements.onRecordChangeEventsSubscriptionId = connector.plotter.container.eventHandler.listenToEvent('Current Record Changed', connector.nodesAnnounements.onRecordChange)
|
||||
}
|
||||
/*
|
||||
Another type of plotting is with Record Values. This method uses the record definition to find the target node
|
||||
and from there is looks into its children all based on the Record Definition configuration.
|
||||
*/
|
||||
if (plotterModule.recordValues !== undefined) {
|
||||
connector.recordValues = newRecordValues()
|
||||
connector.recordValues.initialize(tradingSystem, tradingEngine, productDefinition)
|
||||
connector.recordValues.onRecordChangeEventsSubscriptionId = connector.plotter.container.eventHandler.listenToEvent('Current Record Changed', connector.recordValues.onRecordChange)
|
||||
}
|
||||
}
|
||||
thisObject.connectors.push(connector)
|
||||
}
|
||||
} catch (err) {
|
||||
if (ERROR_LOG === true) { logger.write('[ERROR] initializePlotter -> onProductStorageInitialized -> err = ' + err.stack) }
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
@@ -262,8 +364,8 @@ function newPlottersManager () {
|
||||
for (let j = 0; j < connector.panels.length; j++) {
|
||||
canvas.panelsSpace.destroyPanel(connector.panels[j])
|
||||
}
|
||||
/* Finally the Storage Objects */
|
||||
|
||||
/* Finally the Storage Objects */
|
||||
finalizeNodesPlotting(connector)
|
||||
if (connector.plotter.finalize !== undefined) {
|
||||
connector.plotter.container.eventHandler.stopListening(connector.plotter.onRecordChangeEventsSubscriptionId)
|
||||
connector.plotter.container.finalize()
|
||||
@@ -277,6 +379,37 @@ function newPlottersManager () {
|
||||
}
|
||||
}
|
||||
|
||||
function finalizeNodesPlotting (connector) {
|
||||
if (connector.nodesHighlights !== undefined) {
|
||||
connector.plotter.container.eventHandler.stopListening(connector.nodesHighlights.onRecordChangeEventsSubscriptionId)
|
||||
connector.nodesHighlights.finalize()
|
||||
}
|
||||
if (connector.nodesValues !== undefined) {
|
||||
connector.plotter.container.eventHandler.stopListening(connector.nodesValues.onRecordChangeEventsSubscriptionId)
|
||||
connector.nodesValues.finalize()
|
||||
}
|
||||
if (connector.nodesErrors !== undefined) {
|
||||
connector.plotter.container.eventHandler.stopListening(connector.nodesErrors.onRecordChangeEventsSubscriptionId)
|
||||
connector.nodesErrors.finalize()
|
||||
}
|
||||
if (connector.nodesStatus !== undefined) {
|
||||
connector.plotter.container.eventHandler.stopListening(connector.nodesStatus.onRecordChangeEventsSubscriptionId)
|
||||
connector.nodesStatus.finalize()
|
||||
}
|
||||
if (connector.nodesProgress !== undefined) {
|
||||
connector.plotter.container.eventHandler.stopListening(connector.Progress.onRecordChangeEventsSubscriptionId)
|
||||
connector.Progress.finalize()
|
||||
}
|
||||
if (connector.nodesRunning !== undefined) {
|
||||
connector.plotter.container.eventHandler.stopListening(connector.nodesRunning.onRecordChangeEventsSubscriptionId)
|
||||
connector.nodesRunning.finalize()
|
||||
}
|
||||
if (connector.recordValues !== undefined) {
|
||||
connector.plotter.container.eventHandler.stopListening(connector.recordValues.onRecordChangeEventsSubscriptionId)
|
||||
connector.recordValues.finalize()
|
||||
}
|
||||
}
|
||||
|
||||
function setTimeFrame (pTimeFrame) {
|
||||
timeFrame = pTimeFrame
|
||||
for (let i = 0; i < thisObject.connectors.length; i++) {
|
||||
|
||||
@@ -82,7 +82,7 @@ function newFullScreen () {
|
||||
} else {
|
||||
thisObject.status = 'Off'
|
||||
goOutFullscreen()
|
||||
CURRENT_TOP_MARGIN = window.canvasApp.topMargin
|
||||
CURRENT_TOP_MARGIN = TOP_MARGIN
|
||||
AT_FULL_SCREEN_MODE = false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,9 +5,9 @@ function newOnFocus () {
|
||||
return thisObject
|
||||
|
||||
function getNodeThatIsOnFocus (node) {
|
||||
if (node === undefined) { return }
|
||||
if (node === undefined || node === null) { return }
|
||||
if (node.payload === undefined) { return }
|
||||
let nodeDefinition = getNodeDefinition (node)
|
||||
let nodeDefinition = getNodeDefinition(node)
|
||||
if (nodeDefinition !== undefined) {
|
||||
/* First we ask the question to ourself */
|
||||
if (node.payload.uiObject.isOnFocus === true) {
|
||||
|
||||
@@ -24,46 +24,62 @@ function newSessionFunctions () {
|
||||
'Parameters->' +
|
||||
'Base Asset->Quoted Asset->Time Range->Time Frame->Slippage->Fee Structure->' +
|
||||
'Exchange Account Asset->Asset->' +
|
||||
'Strategy->' +
|
||||
'Trading Strategy->' +
|
||||
'Trigger Stage->Trigger On Event->Trigger Off Event->Take Position Event->' +
|
||||
'Announcement->Formula->' +
|
||||
'Open Stage->Initial Definition->Open Execution->' +
|
||||
'Position Size->Position Rate->Formula->' +
|
||||
'Initial Stop->Initial Take Profit->' +
|
||||
'Manage Stage->' +
|
||||
'Stop->Take Profit->' +
|
||||
'Phase->Formula->Next Phase Event->Move to Phase Event->Phase->' +
|
||||
'Managed Stop Loss->Managed Take Profit->' +
|
||||
'Phase->Formula->Next Phase Event->Move To Phase Event->Phase->' +
|
||||
'Situation->Condition->Javascript Code->' +
|
||||
'Close Stage->Close Execution->' +
|
||||
'Announcement->Formula->'
|
||||
'Announcement->Formula->' +
|
||||
'Execution Algorithm->Market Buy Order->Market Sell Order->Limit Buy Order->Limit Sell Order->' +
|
||||
'Create Order Event->Cancel Order Event->' +
|
||||
'Position Size->Position Rate->Formula->' +
|
||||
'Situation->Condition->Javascript Code->' +
|
||||
'Market Order->Limit Order->' +
|
||||
'Simulated Exchange Events->Simulated Partial Fill->Simulated Actual Rate->Simulated Fees Paid->Formula->'
|
||||
|
||||
let tradingSystem = functionLibraryProtocolNode.getProtocolNode(node.tradingSystemReference.payload.referenceParent, false, true, true, false, false, lightingPath)
|
||||
|
||||
lightingPath = '' +
|
||||
'Trading Engine->' +
|
||||
'Dynamic Indicators->Indicator Function->Formula->' +
|
||||
'Episode->Current->Last->Previous->' +
|
||||
'Episode Counters->Episode Statistics->' +
|
||||
'Periods->Positions->Hits->Fails->' +
|
||||
'Periods->Strategies->Positions->Orders->Hits->Fails->' +
|
||||
'Profit Loss->Hit Ratio->Days->ROI->Anualized Rate Of Return->User Defined Statistic->' +
|
||||
'Formula->' +
|
||||
'Candle->' +
|
||||
'Begin->End->Open->Close->Min->Max->Index->' +
|
||||
'Balance->Base Asset->Quoted Asset->' +
|
||||
'Distance To Event->' +
|
||||
'Trigger On->Trigger Off->Take Position->Close Position->Next Phase->Move To Phase->' +
|
||||
'Trigger On->Trigger Off->Take Position->Close Position->Next Phase->Move To Phase->Create Order->Cancel Order->Close Order->' +
|
||||
'Strategy->' +
|
||||
'Begin->End->Strategy Name->Index->Stage Type->Status->Begin Rate->End Rate->Situation Name->' +
|
||||
'Serial Number->Identifier->Begin->End->Strategy Name->Index->Trigger Stage Status->Open Stage Status->Manage Stage Status->Close Stage Status->Status->Begin Rate->End Rate->Situation Name->' +
|
||||
'Strategy Counters->Periods->' +
|
||||
'Position->' +
|
||||
'Begin->End->Rate->Size->Exit Type->Status->Begin Rate->End Rate->Situation Name->' +
|
||||
'Serial Number->Identifier->Begin->End->Rate->Size->Open Stage Orders Size->Open Stage Filled Size->Close Stage Orders Size->Close Stage Filled Size->Exit Type->Status->Begin Rate->End Rate->Situation Name->' +
|
||||
'Stop Loss->Stop Loss Stage->Stop Loss Phase->' +
|
||||
'Take Profit->Take Profit Stage->Take Profit Phase->' +
|
||||
'Position Counters->Periods->' +
|
||||
'Position Statistics->Days->ROI->User Defined Statistic->' +
|
||||
'Formula'
|
||||
'Position Statistics->Profit Loss->Days->ROI->Hit Fail->User Defined Statistic->' +
|
||||
'Formula->' +
|
||||
'Exchange Orders->Market Buy Orders->Market Sell Orders->Limit Buy Orders->Limit Sell Orders->' +
|
||||
'Market Order->Limit Order->' +
|
||||
'Serial Number->Identifier->Exchange Id->Begin->End->Rate->Size->Exit Type->Status->Order Name->Algorithm Name->Situation Name->' +
|
||||
'Order Counters->Periods->' +
|
||||
'Order Statistics->Size Filled->Percentage Filled->Amount Received->Actual Rate->Fees Paid->Days->User Defined Statistic->'
|
||||
|
||||
let tradingEngine = functionLibraryProtocolNode.getProtocolNode(node.tradingEngineReference.payload.referenceParent, false, true, true, false, false, lightingPath)
|
||||
|
||||
lightingPath = '' +
|
||||
'Backtesting Session->Paper Trading Session->Fordward Testing Session->Live Trading Session->' +
|
||||
'Parameters->' +
|
||||
'Base Asset->Quoted Asset->Time Range->Time Frame->Slippage->Fee Structure->' +
|
||||
'Session Base Asset->Session Quoted Asset->Time Range->Time Frame->Slippage->Fee Structure->Snapshots->User Defined Parameters->' +
|
||||
'Exchange Account Asset->Asset->' +
|
||||
'Social Bots->Telegram Bot->'
|
||||
|
||||
|
||||
@@ -28,11 +28,11 @@ function newTaskFunctions () {
|
||||
|
||||
let taskLightingPath = '->Task->' +
|
||||
'Sensor Bot Instance->' +
|
||||
'Indicator Bot Instance->' +
|
||||
'Indicator Bot Instance->Time Frames Filter->' +
|
||||
'Trading Bot Instance->' +
|
||||
'Sensor Process Instance->Indicator Process Instance->Trading Process Instance->' +
|
||||
'Market Reference->' +
|
||||
'Key Instance->Exchange Account Key->' +
|
||||
'Key Reference->Exchange Account Key->' +
|
||||
'Market->Exchange Markets->Crypto Exchange->' +
|
||||
'Market Base Asset->Market Quoted Asset->Asset->' +
|
||||
'Backtesting Session->Live Trading Session->Paper Trading Session->Fordward Testing Session->' +
|
||||
|
||||
@@ -14,6 +14,7 @@ function newWorkspace () {
|
||||
replaceWorkspaceByLoadingOne: replaceWorkspaceByLoadingOne,
|
||||
save: saveWorkspace,
|
||||
getHierarchyHeads: getHierarchyHeads,
|
||||
getHierarchyHeadsById: getHierarchyHeadsById,
|
||||
getNodeThatIsOnFocus: getNodeThatIsOnFocus,
|
||||
getNodeByShortcutKey: getNodeByShortcutKey,
|
||||
stopAllRunningTasks: stopAllRunningTasks,
|
||||
@@ -66,6 +67,7 @@ function newWorkspace () {
|
||||
|
||||
thisObject.nodeChildren = newNodeChildren()
|
||||
|
||||
let isInitialized = false
|
||||
let workingAtTask = 0
|
||||
let circularProgressBar = newBusyProgressBar()
|
||||
circularProgressBar.fitFunction = canvas.floatingSpace.fitIntoVisibleArea
|
||||
@@ -117,6 +119,7 @@ function newWorkspace () {
|
||||
canvas.cockpitSpace.initializePosition()
|
||||
canvas.splashScreen.initialize()
|
||||
setInterval(saveWorkspace, 60000)
|
||||
isInitialized = true
|
||||
}
|
||||
} catch (err) {
|
||||
if (ERROR_LOG === true) { logger.write('[ERROR] initialize -> err = ' + err.stack) }
|
||||
@@ -185,17 +188,10 @@ function newWorkspace () {
|
||||
}
|
||||
|
||||
function saveWorkspace () {
|
||||
if (isInitialized === false) { return }
|
||||
/* When there is an exception while loading the app, the rootNodes of the workspace get into null value. To avoid saving a corrupt staate we are going to verufy we are not in that situation before saving. */
|
||||
let workspace = canvas.designSpace.workspace.workspaceNode
|
||||
|
||||
for (let i = 0; i < workspace.rootNodes.length; i++) {
|
||||
let rootNode = workspace.rootNodes[i]
|
||||
if (rootNode === null) {
|
||||
canvas.cockpitSpace.setStatus('Could not save the Workspace. The state of the workspace in memory is corrupt, please reload the App.', 150, canvas.cockpitSpace.statusTypes.WARNING)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
let savedSessionTimestamp = window.localStorage.getItem('Session Timestamp')
|
||||
if (Number(savedSessionTimestamp) !== sessionTimestamp) {
|
||||
canvas.cockpitSpace.setStatus('Could not save the Workspace. You have more that one instance of the Superlagos User Interface open at the same time. Plese close this instance as it is older than the others.', 150, canvas.cockpitSpace.statusTypes.WARNING)
|
||||
@@ -355,6 +351,16 @@ function newWorkspace () {
|
||||
return nodes
|
||||
}
|
||||
|
||||
function getHierarchyHeadsById (nodeId) {
|
||||
let hiriatchyHeads = getHierarchyHeads()
|
||||
for (let i = 0; i < hiriatchyHeads.length; i++) {
|
||||
let hiriatchyHead = hiriatchyHeads[i]
|
||||
if (hiriatchyHead.id === nodeId) {
|
||||
return hiriatchyHead
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function replaceWorkspaceByLoadingOne (name) {
|
||||
let blobService = newFileStorage()
|
||||
blobService.getFileFromHost('LoadWorkspace' + '/' + name, onFileReceived, true)
|
||||
|
||||
@@ -9,7 +9,7 @@ function newEventsServerClient (host, port, hostName) {
|
||||
logger.fileName = MODULE_NAME
|
||||
|
||||
if (host === '' || host === undefined) { host = 'localhost' }
|
||||
if (port === '' || port === undefined) { port = '8080' }
|
||||
if (port === '' || port === undefined) { port = '8081' }
|
||||
|
||||
const WEB_SOCKETS_URL = 'ws://' + host + ':' + port + ''
|
||||
let WEB_SOCKETS_CONNECTION
|
||||
@@ -156,7 +156,7 @@ function newEventsServerClient (host, port, hostName) {
|
||||
}
|
||||
|
||||
if (thisObject.isConnected() !== true) {
|
||||
canvas.cockpitSpace.setStatus('Connecting to ' + hostName + ' Network Node. Please wait until the connection is established.', 100, canvas.cockpitSpace.statusTypes.WARNING)
|
||||
canvas.cockpitSpace.setStatus('Connecting to Superalgos Backend at ' + hostName + ' Network Node. Please wait until the connection is established.', 100, canvas.cockpitSpace.statusTypes.WARNING)
|
||||
} else {
|
||||
retryCommandsPhysics()
|
||||
}
|
||||
|
||||
+111
-24
@@ -20,7 +20,6 @@ function newUiObject () {
|
||||
formulaEditor: undefined,
|
||||
uiObjectTitle: undefined,
|
||||
circularProgressBar: undefined,
|
||||
isExecuting: undefined,
|
||||
isRunning: undefined,
|
||||
shortcutKey: undefined,
|
||||
isShowing: undefined,
|
||||
@@ -32,10 +31,15 @@ function newUiObject () {
|
||||
getReadyToReferenceAttach: getReadyToReferenceAttach,
|
||||
showAvailabilityToReferenceAttach: showAvailabilityToReferenceAttach,
|
||||
highlight: highlight,
|
||||
runningAtBackend: runningAtBackend,
|
||||
setErrorMessage: setErrorMessage,
|
||||
resetErrorMessage: resetErrorMessage,
|
||||
setValue: setValue,
|
||||
resetValue: resetValue,
|
||||
setPercentage: setPercentage,
|
||||
resetPercentage: resetPercentage,
|
||||
setStatus: setStatus,
|
||||
resetStatus: resetStatus,
|
||||
physics: physics,
|
||||
invisiblePhysics: invisiblePhysics,
|
||||
drawBackground: drawBackground,
|
||||
@@ -67,6 +71,9 @@ function newUiObject () {
|
||||
let isHighlighted
|
||||
let highlightCounter = 0
|
||||
|
||||
let isRunningAtBackend
|
||||
let runningAtBackendCounter = 0
|
||||
|
||||
let hasError
|
||||
let errorMessageCounter = 0
|
||||
|
||||
@@ -107,6 +114,7 @@ function newUiObject () {
|
||||
let currentStatus = ''
|
||||
let rightDragging = false
|
||||
|
||||
let eventSubscriptionIdOnError
|
||||
let eventSubscriptionIdOnRunning
|
||||
let eventSubscriptionIdOnStopped
|
||||
let lastHeartBeat
|
||||
@@ -178,6 +186,9 @@ function newUiObject () {
|
||||
if (eventSubscriptionIdOnStopped !== undefined) {
|
||||
eventsServerClient.stopListening(key, eventSubscriptionIdOnStopped, 'UiObject')
|
||||
}
|
||||
if (eventSubscriptionIdOnError !== undefined) {
|
||||
eventsServerClient.stopListening(key, eventSubscriptionIdOnError, 'UiObject')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -313,6 +324,7 @@ function newUiObject () {
|
||||
|
||||
iconPhysics()
|
||||
highlightPhisycs()
|
||||
runningAtBackendPhisycs()
|
||||
errorMessagePhisycs()
|
||||
valuePhisycs()
|
||||
percentagePhisycs()
|
||||
@@ -634,6 +646,7 @@ function newUiObject () {
|
||||
if (isDragging !== true) { return }
|
||||
if (thisObject.payload.floatingObject.isFrozen === true) { return }
|
||||
if (rightDragging === false) { return }
|
||||
if (thisObject.payload === undefined) { return }
|
||||
if (thisObject.payload.referenceParent === undefined) { return }
|
||||
|
||||
let distanceToReferenceParent = Math.sqrt(Math.pow(thisObject.payload.position.x - thisObject.payload.referenceParent.payload.position.x, 2) + Math.pow(thisObject.payload.position.y - thisObject.payload.referenceParent.payload.position.y, 2))
|
||||
@@ -664,6 +677,14 @@ function newUiObject () {
|
||||
}
|
||||
}
|
||||
|
||||
function runningAtBackendPhisycs () {
|
||||
runningAtBackendCounter--
|
||||
if (runningAtBackendCounter < 0) {
|
||||
runningAtBackendCounter = 0
|
||||
isRunningAtBackend = false
|
||||
}
|
||||
}
|
||||
|
||||
function errorMessagePhisycs () {
|
||||
errorMessageCounter--
|
||||
if (errorMessageCounter < 0) {
|
||||
@@ -696,9 +717,18 @@ function newUiObject () {
|
||||
}
|
||||
}
|
||||
|
||||
function highlight () {
|
||||
function highlight (counter) {
|
||||
isHighlighted = true
|
||||
highlightCounter = 30
|
||||
if (counter !== undefined) {
|
||||
highlightCounter = counter
|
||||
} else {
|
||||
highlightCounter = 30
|
||||
}
|
||||
}
|
||||
|
||||
function runningAtBackend () {
|
||||
isRunningAtBackend = true
|
||||
runningAtBackendCounter = 5
|
||||
}
|
||||
|
||||
function setErrorMessage (message, duration) {
|
||||
@@ -710,6 +740,11 @@ function newUiObject () {
|
||||
}
|
||||
}
|
||||
|
||||
function resetErrorMessage () {
|
||||
errorMessage = undefined
|
||||
hasError = false
|
||||
}
|
||||
|
||||
function setValue (value, counter) {
|
||||
if (value !== undefined) {
|
||||
currentValue = value
|
||||
@@ -722,6 +757,12 @@ function newUiObject () {
|
||||
}
|
||||
}
|
||||
|
||||
function resetValue () {
|
||||
currentValue = undefined
|
||||
hasValue = false
|
||||
valueCounter = 0
|
||||
}
|
||||
|
||||
function setPercentage (percentage, counter) {
|
||||
if (percentage !== undefined) {
|
||||
currentPercentage = percentage
|
||||
@@ -734,6 +775,12 @@ function newUiObject () {
|
||||
}
|
||||
}
|
||||
|
||||
function resetPercentage () {
|
||||
currentPercentage = undefined
|
||||
hasPercentage = false
|
||||
percentageCounter = 0
|
||||
}
|
||||
|
||||
function setStatus (status, counter) {
|
||||
if (status !== undefined) {
|
||||
currentStatus = status
|
||||
@@ -746,6 +793,12 @@ function newUiObject () {
|
||||
}
|
||||
}
|
||||
|
||||
function resetStatus () {
|
||||
currentStatus = undefined
|
||||
hasStatus = false
|
||||
statusCounter = 0
|
||||
}
|
||||
|
||||
function heartBeat () {
|
||||
lastHeartBeat = new Date()
|
||||
thisObject.isRunning = true
|
||||
@@ -760,6 +813,10 @@ function newUiObject () {
|
||||
|
||||
function run (pEventsServerClient, callBackFunction) {
|
||||
finalizeEventsServerClient()
|
||||
resetErrorMessage()
|
||||
resetPercentage()
|
||||
resetValue()
|
||||
resetStatus()
|
||||
eventsServerClient = pEventsServerClient
|
||||
|
||||
/* We setup the circular progress bar. */
|
||||
@@ -772,7 +829,12 @@ function newUiObject () {
|
||||
thisObject.circularProgressBar.fitFunction = thisObject.fitFunction
|
||||
thisObject.circularProgressBar.container = thisObject.container
|
||||
|
||||
/* We will wait to hear the Running event in order to confirm the execution was really started */
|
||||
setupRunningEventListener(callBackFunction)
|
||||
setupErrorEventListener(callBackFunction)
|
||||
}
|
||||
|
||||
function setupRunningEventListener (callBackFunction) {
|
||||
/* We will wait to hear the Running event in order to confirm the execution was really started */
|
||||
let key = thisObject.payload.node.name + '-' + thisObject.payload.node.type + '-' + thisObject.payload.node.id
|
||||
eventsServerClient.listenToEvent(key, 'Running', undefined, 'UiObject', onResponse, onRunning)
|
||||
|
||||
@@ -813,6 +875,24 @@ function newUiObject () {
|
||||
stop(callBackFunction, event)
|
||||
}
|
||||
|
||||
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)
|
||||
|
||||
function onResponse (message) {
|
||||
eventSubscriptionIdOnError = message.eventSubscriptionId
|
||||
}
|
||||
|
||||
function onError (message) {
|
||||
setErrorMessage(message.event.errorMessage, 10)
|
||||
|
||||
let event = {
|
||||
type: 'Secondary Action Already Executed'
|
||||
}
|
||||
completeStop(callBackFunction, event)
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
@@ -823,23 +903,29 @@ function newUiObject () {
|
||||
}
|
||||
|
||||
function onStopped () {
|
||||
if (thisObject.payload === undefined) { return }
|
||||
if (callBackFunction !== undefined) {
|
||||
callBackFunction(GLOBAL.DEFAULT_OK_RESPONSE, event)
|
||||
}
|
||||
|
||||
if (thisObject.circularProgressBar !== undefined) {
|
||||
thisObject.circularProgressBar.finalize()
|
||||
thisObject.circularProgressBar = undefined
|
||||
}
|
||||
thisObject.isRunning = false
|
||||
hasValue = false
|
||||
hasPercentage = false
|
||||
hasStatus = false
|
||||
lastHeartBeat = undefined
|
||||
completeStop(callBackFunction, event)
|
||||
}
|
||||
}
|
||||
|
||||
function completeStop (callBackFunction, event) {
|
||||
if (thisObject.payload === undefined) { return }
|
||||
if (callBackFunction !== undefined) {
|
||||
callBackFunction(GLOBAL.DEFAULT_OK_RESPONSE, event)
|
||||
}
|
||||
|
||||
if (thisObject.circularProgressBar !== undefined) {
|
||||
thisObject.circularProgressBar.finalize()
|
||||
thisObject.circularProgressBar = undefined
|
||||
}
|
||||
thisObject.isRunning = false
|
||||
hasValue = false
|
||||
hasPercentage = false
|
||||
hasStatus = false
|
||||
lastHeartBeat = undefined
|
||||
|
||||
finalizeEventsServerClient()
|
||||
}
|
||||
|
||||
function iconPhysics () {
|
||||
icon = canvas.designSpace.iconByUiObjectType.get(thisObject.payload.node.type)
|
||||
let nodeDefinition = getNodeDefinition(thisObject.payload.node)
|
||||
@@ -1291,7 +1377,7 @@ function newUiObject () {
|
||||
position = canvas.floatingSpace.transformPointToMap(position)
|
||||
}
|
||||
|
||||
let radius = thisObject.container.frame.radius * 3.5
|
||||
let radius = thisObject.container.frame.radius * 2.5
|
||||
/* Label Text */
|
||||
let labelPoint
|
||||
let fontSize = thisObject.payload.floatingObject.currentFontSize * 3 / 4
|
||||
@@ -1320,6 +1406,7 @@ function newUiObject () {
|
||||
}
|
||||
|
||||
function drawValue () {
|
||||
if (currentValue === null) { return }
|
||||
if (hasValue === false) { return }
|
||||
if (canvas.floatingSpace.inMapMode === true) { return }
|
||||
if (thisObject.payload === undefined) { return }
|
||||
@@ -1349,9 +1436,9 @@ function newUiObject () {
|
||||
const MAX_LABEL_LENGTH = 65
|
||||
|
||||
label = currentValue
|
||||
if (!isNaN(label)) {
|
||||
if (!isNaN(currentValue)) {
|
||||
if (currentValue.toFixed !== undefined) {
|
||||
label = dynamicDecimals(currentValue, 2)
|
||||
label = dynamicDecimals(currentValue)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1637,7 +1724,7 @@ function newUiObject () {
|
||||
|
||||
if (isHighlighted === true) {
|
||||
VISIBLE_RADIUS = thisObject.container.frame.radius * 1
|
||||
let OPACITY = highlightCounter / 30
|
||||
let OPACITY = highlightCounter / 10
|
||||
|
||||
browserCanvasContext.beginPath()
|
||||
browserCanvasContext.arc(visiblePosition.x, visiblePosition.y, VISIBLE_RADIUS, 0, Math.PI * 2, true)
|
||||
@@ -1756,7 +1843,7 @@ function newUiObject () {
|
||||
if (icon !== undefined) {
|
||||
if (icon.canDrawIcon === true) {
|
||||
let additionalImageSize = 0
|
||||
if (thisObject.isExecuting === true || isReadyToReferenceAttach === true || isReadyToChainAttach === true) { additionalImageSize = 20 }
|
||||
if (isRunningAtBackend === true || isReadyToReferenceAttach === true || isReadyToChainAttach === true) { additionalImageSize = 20 }
|
||||
let totalImageSize = additionalImageSize + thisObject.payload.floatingObject.currentImageSize
|
||||
if (canvas.floatingSpace.inMapMode === true) {
|
||||
totalImageSize = canvas.floatingSpace.transformImagesizeToMap(totalImageSize)
|
||||
@@ -1782,7 +1869,7 @@ function newUiObject () {
|
||||
|
||||
if (executingIcon !== undefined) {
|
||||
if (executingIcon.canDrawIcon === true) {
|
||||
if (thisObject.isExecuting === true) {
|
||||
if (isRunningAtBackend === true) {
|
||||
const DISTANCE_FROM_CENTER = thisObject.container.frame.radius / 3 + 50
|
||||
const EXECUTING_ICON_SIZE = 20 + thisObject.container.frame.radius / 6
|
||||
|
||||
|
||||
@@ -74,7 +74,7 @@ function newUiObjectConstructor () {
|
||||
*/
|
||||
|
||||
if (userAddingNew === true) {
|
||||
let definition = getNodeDefinition (payload.parentNode)
|
||||
let definition = getNodeDefinition(payload.parentNode)
|
||||
if (definition.properties !== undefined) {
|
||||
for (let i = 0; i < definition.properties.length; i++) {
|
||||
let property = definition.properties[i]
|
||||
@@ -406,7 +406,7 @@ function newUiObjectConstructor () {
|
||||
function getMenuItemsInitialValues (uiObject, floatingObject, payload) {
|
||||
let menuItemsInitialValues = []
|
||||
|
||||
let nodeDefinition = getNodeDefinition (payload.node)
|
||||
let nodeDefinition = getNodeDefinition(payload.node)
|
||||
if (nodeDefinition !== undefined) {
|
||||
if (nodeDefinition.editors !== undefined) {
|
||||
if (nodeDefinition.editors.config === true) {
|
||||
@@ -450,7 +450,12 @@ function newUiObjectConstructor () {
|
||||
|
||||
/* We need to reference the real function based on its name */
|
||||
if (menutItemDefinition.actionFunction !== undefined) {
|
||||
newMenuItem.actionFunction = eval(menutItemDefinition.actionFunction)
|
||||
try {
|
||||
newMenuItem.actionFunction = eval(menutItemDefinition.actionFunction)
|
||||
} catch (err) {
|
||||
console.log('Error at Menu Item Action Function: ' + menutItemDefinition.actionFunction + ' ' + err.stack)
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
/* Adding default values */
|
||||
@@ -495,7 +500,7 @@ function newUiObjectConstructor () {
|
||||
}
|
||||
|
||||
default: {
|
||||
let nodeDefinition = getNodeDefinition (payload.node)
|
||||
let nodeDefinition = getNodeDefinition(payload.node)
|
||||
if (nodeDefinition !== undefined) {
|
||||
switch (nodeDefinition.level) {
|
||||
case 0: {
|
||||
|
||||
@@ -51,7 +51,7 @@ function newUiObjectTitle () {
|
||||
thisObject.payload = payload
|
||||
|
||||
thisObject.allwaysVisible = false // Default value
|
||||
let nodeDefinition = getNodeDefinition (thisObject.payload.node)
|
||||
let nodeDefinition = getNodeDefinition(thisObject.payload.node)
|
||||
if (nodeDefinition !== undefined) {
|
||||
if (nodeDefinition.isTitleAllwaysVisible === true) {
|
||||
thisObject.allwaysVisible = true
|
||||
@@ -100,7 +100,7 @@ function newUiObjectTitle () {
|
||||
if (thisObject.payload.title === undefined) { return }
|
||||
|
||||
/* It is possible to override the default title by setting the APP SCHEMA property 'title' */
|
||||
let nodeDefinition = getNodeDefinition (thisObject.payload.node)
|
||||
let nodeDefinition = getNodeDefinition(thisObject.payload.node)
|
||||
if (nodeDefinition.title !== undefined) {
|
||||
thisObject.payload.title = ''
|
||||
thisObject.payload.node.name = ''
|
||||
@@ -170,6 +170,7 @@ function newUiObjectTitle () {
|
||||
if (titleReference.indexOf('Use Child @') === 0) {
|
||||
let propertyName = titleReference.substring(titleReference.indexOf('@') + 1, titleReference.length)
|
||||
let childNode = thisObject.payload.node[propertyName]
|
||||
if (childNode === undefined) { break }
|
||||
thisObject.payload.title = thisObject.payload.title + separator + childNode.name
|
||||
thisObject.payload.node.name = thisObject.payload.node.name + separator + childNode.name
|
||||
}
|
||||
@@ -221,7 +222,7 @@ function newUiObjectTitle () {
|
||||
}
|
||||
|
||||
function onMouseClick (event) {
|
||||
let nodeDefinition = getNodeDefinition (thisObject.payload.node)
|
||||
let nodeDefinition = getNodeDefinition(thisObject.payload.node)
|
||||
if (nodeDefinition.title !== undefined) { return }
|
||||
|
||||
let checkPoint = {
|
||||
@@ -329,7 +330,7 @@ function newUiObjectTitle () {
|
||||
labelPoint.x = labelPoint.x - label.length / 2 * fontSize * FONT_ASPECT_RATIO
|
||||
labelPoint.y = labelPoint.y - 35
|
||||
|
||||
let nodeDefinition = getNodeDefinition (thisObject.payload.node)
|
||||
let nodeDefinition = getNodeDefinition(thisObject.payload.node)
|
||||
if (nodeDefinition !== undefined) {
|
||||
if (nodeDefinition.isHierarchyHead !== true) {
|
||||
return
|
||||
|
||||
+2
-1
@@ -178,7 +178,8 @@ let INITIAL_ZOOM_LEVEL = -28.25 // This is the zoom level at the view port
|
||||
let INITIAL_TIME_PERIOD = ONE_DAY_IN_MILISECONDS // This value will be overwritten at the canvas.chartingSpace.viewport.initialize if the user had a prevous session with this same browser.
|
||||
let VERY_LARGE_NUMBER = 100000000000000
|
||||
|
||||
let CURRENT_TOP_MARGIN = window.canvasApp.topMargin
|
||||
const TOP_MARGIN = 0
|
||||
let CURRENT_TOP_MARGIN = TOP_MARGIN
|
||||
let AT_FULL_SCREEN_MODE = false
|
||||
|
||||
let maxDate = new Date();
|
||||
|
||||
+7
-4
@@ -157,6 +157,7 @@ function newLayer () {
|
||||
'Session Reference->Session Independent Data->Session Based Data->Exchange Sessions->Session Based Data->Data Storage->Network Node->' +
|
||||
'Data Storage->Network Node->' +
|
||||
'Backtesting Session->Paper Trading Session->Fordward Testing Session->Live Trading Session->' +
|
||||
'Trading System Reference->Trading Engine Reference->Trading System->Trading Engine->' +
|
||||
'Market->Market Base Asset->Asset->' +
|
||||
'Market Quoted Asset->Asset->' +
|
||||
'Exchange Markets->Crypto Exchange->' +
|
||||
@@ -173,12 +174,15 @@ function newLayer () {
|
||||
'Polygon->Polygon Condition->Polygon Body->Style->Style Condition->Style->' +
|
||||
'Polygon Border->Style->Style Condition->Style->' +
|
||||
'Polygon Vertex->Point->' +
|
||||
'Plotter Panel->Javascript Code->Panel Data->Data Formula->'
|
||||
'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->'
|
||||
thisObject.definition = functionLibraryProtocolNode.getProtocolNode(thisObject.payload.node, false, true, true, false, false, lightingPath)
|
||||
|
||||
/* Here we validate that we have all the needed information */
|
||||
if (thisObject.definition.referenceParent === undefined) { return }
|
||||
if (thisObject.definition.referenceParent.parentNode === undefined) { return }
|
||||
if (thisObject.definition.referenceParent === undefined) { return } // Data Product
|
||||
if (thisObject.definition.referenceParent.parentNode === undefined) { return } // Single Market Data
|
||||
if (thisObject.definition.referenceParent.parentNode.referenceParent === undefined) { return }
|
||||
if (thisObject.definition.referenceParent.parentNode.referenceParent.parentNode === undefined) { return }
|
||||
if (thisObject.definition.referenceParent.parentNode.referenceParent.parentNode.parentNode === undefined) { return }
|
||||
@@ -223,7 +227,6 @@ function newLayer () {
|
||||
}
|
||||
|
||||
thisObject.plotterModule = thisObject.definition.referenceParent.referenceParent.referenceParent
|
||||
|
||||
thisObject.exchangeIcon = getIcon(thisObject.exchange)
|
||||
|
||||
if (thisObject.plotterModule.config.icon !== undefined) {
|
||||
|
||||
@@ -100,9 +100,7 @@ function newPlotterPanel () {
|
||||
const PANEL_HEIGHT = UI_PANEL.HEIGHT.NORMAL
|
||||
|
||||
if (currentRecord === undefined) { return }
|
||||
if (currentRecord.data === undefined) { return }
|
||||
|
||||
let record = currentRecord.data
|
||||
let record = currentRecord
|
||||
|
||||
/* First we execute code if provided. */
|
||||
if (panelNode.javascriptCode !== undefined) {
|
||||
@@ -114,16 +112,14 @@ function newPlotterPanel () {
|
||||
}
|
||||
}
|
||||
|
||||
printLabel('Indicator Properties', X_AXIS, UI_PANEL.HEIGHT.NORMAL * 17 / 100, '1.00', 14, undefined, true, thisObject.container, thisObject.fitFunction)
|
||||
|
||||
/* Second we go through the panel data. */
|
||||
if (panelNode.panelData === undefined) { return }
|
||||
for (let i = 0; i < panelNode.panelData.length; i++) {
|
||||
let panelData = panelNode.panelData[i]
|
||||
|
||||
let labelText = panelData.name
|
||||
let labelPosition = i * 10 + 25
|
||||
let valuePosition = i * 10 + 30
|
||||
let labelPosition = i * 10 + 12
|
||||
let valuePosition = i * 10 + 17
|
||||
let value = 'No value defined.'
|
||||
|
||||
if (valuePosition > 100) {
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
function newNodesAnnouncements () {
|
||||
const MODULE_NAME = 'Nodes Announcements'
|
||||
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.announcements
|
||||
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 === true) { value = 'true' }
|
||||
if (value === false) { value = 'false' }
|
||||
node.payload.uiObject.setValue(value, 20)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
function newNodesErrors () {
|
||||
const MODULE_NAME = 'Nodes Errors'
|
||||
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.errors
|
||||
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.resetErrorMessage()
|
||||
} else {
|
||||
node.payload.uiObject.setErrorMessage(value)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
function newNodesHighlights () {
|
||||
const MODULE_NAME = 'Nodes Highlights'
|
||||
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.highlights
|
||||
if (array === undefined) { return }
|
||||
for (let i = 0; i < array.length; i++) {
|
||||
let nodeId = array[i]
|
||||
highlight(nodeId)
|
||||
}
|
||||
}
|
||||
|
||||
function highlight (nodeId) {
|
||||
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 }
|
||||
node.payload.uiObject.highlight(10)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
function newNodesProgress () {
|
||||
const MODULE_NAME = 'Nodes Progress'
|
||||
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.progress
|
||||
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 === true) { value = 'true' }
|
||||
if (value === false) { value = 'false' }
|
||||
node.payload.uiObject.setPercentage(value, 30)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
function newNodesRunning () {
|
||||
const MODULE_NAME = 'Nodes Running'
|
||||
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.running
|
||||
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 === true) { value = 'true' }
|
||||
if (value === false) { value = 'false' }
|
||||
node.payload.uiObject.runningAtBackend()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
function newNodesStatus () {
|
||||
const MODULE_NAME = 'Nodes Status'
|
||||
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.status
|
||||
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 === true) { value = 'true' }
|
||||
if (value === false) { value = 'false' }
|
||||
node.payload.uiObject.setStatus(value, 30)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
function newNodesValues () {
|
||||
const MODULE_NAME = 'Nodes Values'
|
||||
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.values
|
||||
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 === true) { value = 'true' }
|
||||
if (value === false) { value = 'false' }
|
||||
node.payload.uiObject.setValue(value, 1)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,6 +42,8 @@ function newPlotter () {
|
||||
|
||||
let records = [] // We will have the information to be plotted here.
|
||||
let userPositionDate
|
||||
let minUserPositionRate
|
||||
let maxUserPositionRate
|
||||
|
||||
let onMouseOverEventSuscriptionId
|
||||
let zoomChangedEventSubscriptionId
|
||||
@@ -148,6 +150,18 @@ function newPlotter () {
|
||||
function onMouseOver (event) {
|
||||
let userPosition = getDateFromPointAtBrowserCanvas(event, thisObject.container, coordinateSystem)
|
||||
userPositionDate = userPosition.valueOf()
|
||||
|
||||
let minPositionPoint = {
|
||||
x: event.x,
|
||||
y: event.y + 2
|
||||
}
|
||||
minUserPositionRate = getRateFromPointAtBrowserCanvas(minPositionPoint, thisObject.container, coordinateSystem)
|
||||
|
||||
let maxPositionPoint = {
|
||||
x: event.x,
|
||||
y: event.y - 2
|
||||
}
|
||||
maxUserPositionRate = getRateFromPointAtBrowserCanvas(maxPositionPoint, thisObject.container, coordinateSystem)
|
||||
}
|
||||
|
||||
function onMarketFilesUpdated () {
|
||||
@@ -245,13 +259,14 @@ function newPlotter () {
|
||||
function draw () {
|
||||
try {
|
||||
thisObject.container.frame.draw()
|
||||
plotChart()
|
||||
plot()
|
||||
} catch (err) {
|
||||
if (ERROR_LOG === true) { logger.write('[ERROR] draw -> err = ' + err.stack) }
|
||||
}
|
||||
}
|
||||
|
||||
function recalculate () {
|
||||
if (canvas.chartingSpace.visible !== true) { return }
|
||||
try {
|
||||
if (timeFrame >= _1_HOUR_IN_MILISECONDS) {
|
||||
recalculateUsingMarketFiles()
|
||||
@@ -290,6 +305,7 @@ function newPlotter () {
|
||||
jsonifiedArray.push(record)
|
||||
previous = record
|
||||
|
||||
if (record.begin === undefined || record.end === undefined) { console.log('Could not find the property begin or end which are needed for the plotter to work.') }
|
||||
if (datetime.valueOf() >= record.begin && datetime.valueOf() <= record.end) {
|
||||
thisObject.currentRecord = record
|
||||
thisObject.container.eventHandler.raiseEvent('Current Record Changed', thisObject.currentRecord)
|
||||
@@ -489,13 +505,10 @@ function newPlotter () {
|
||||
}
|
||||
}
|
||||
|
||||
function plotChart () {
|
||||
function plot () {
|
||||
try {
|
||||
/* Clean the pannel at places where there is no record. */
|
||||
let currentRecord = {
|
||||
data: undefined
|
||||
}
|
||||
thisObject.container.eventHandler.raiseEvent('Current Record Changed', currentRecord)
|
||||
thisObject.container.eventHandler.raiseEvent('Current Record Changed', undefined)
|
||||
|
||||
for (let i = 0; i < records.length; i++) {
|
||||
let record = records[i]
|
||||
@@ -505,7 +518,7 @@ function newPlotter () {
|
||||
To enable that we need to link all records to the previous one in this way.
|
||||
*/
|
||||
if (i == 0) {
|
||||
record.previous = record
|
||||
record.previous = {} // this way it wont be undefined
|
||||
} else {
|
||||
record.previous = records[i - 1]
|
||||
}
|
||||
@@ -538,12 +551,17 @@ function newPlotter () {
|
||||
|
||||
let atMousePosition = false
|
||||
if (userPositionDate >= record.begin && userPositionDate <= record.end) {
|
||||
atMousePosition = true
|
||||
|
||||
let currentRecord = {
|
||||
data: record
|
||||
if (record.rate !== undefined && productDefinition.referenceParent.config.useRateAtMousePosition === true) {
|
||||
/* Current Record depends also on rate */
|
||||
if (record.rate >= minUserPositionRate && record.rate <= maxUserPositionRate) {
|
||||
atMousePosition = true
|
||||
thisObject.container.eventHandler.raiseEvent('Current Record Changed', record)
|
||||
}
|
||||
} else {
|
||||
/* Current Record depends only on begin and end. */
|
||||
atMousePosition = true
|
||||
thisObject.container.eventHandler.raiseEvent('Current Record Changed', record)
|
||||
}
|
||||
thisObject.container.eventHandler.raiseEvent('Current Record Changed', currentRecord)
|
||||
}
|
||||
|
||||
/* If there is code we execute it now. */
|
||||
@@ -596,6 +614,7 @@ function newPlotter () {
|
||||
record.dataPoints = dataPoints
|
||||
}
|
||||
|
||||
/* Here we are going to plot all the polygons. */
|
||||
for (let j = 0; j < productDefinition.referenceParent.shapes.polygons.length; j++) {
|
||||
let polygon = productDefinition.referenceParent.shapes.polygons[j]
|
||||
/* We will check if we need to plot this Polygon or not. */
|
||||
@@ -782,6 +801,79 @@ function newPlotter () {
|
||||
browserCanvasContext.stroke()
|
||||
}
|
||||
}
|
||||
|
||||
/* Here we are going to plot images. */
|
||||
for (let j = 0; j < productDefinition.referenceParent.shapes.images.length; j++) {
|
||||
let image = productDefinition.referenceParent.shapes.images[j]
|
||||
if (image.imagePosition === undefined) { continue }
|
||||
if (image.imagePosition.referenceParent === undefined) { continue }
|
||||
if (image.imageCondition !== undefined) {
|
||||
let mustPlot = eval(image.imageCondition.code)
|
||||
if (mustPlot !== true) { continue }
|
||||
}
|
||||
let imageName = ''
|
||||
let imageSize = 0
|
||||
let offsetX = 0
|
||||
let offsetY = 0
|
||||
let imagePosition = {x: 0, y: 0}
|
||||
if (image.config.codeName !== undefined) { imageName = image.config.codeName }
|
||||
if (image.config.size !== undefined) { imageSize = image.config.size }
|
||||
if (image.imagePosition.config.offsetX !== undefined) { offsetX = image.imagePosition.config.offsetX }
|
||||
if (image.imagePosition.config.offsetY !== undefined) { offsetY = image.imagePosition.config.offsetY }
|
||||
let dataPointObject = dataPoints.get(image.imagePosition.referenceParent.id)
|
||||
if (dataPointObject === undefined) { continue }
|
||||
let dataPoint = {
|
||||
x: dataPointObject.x,
|
||||
y: dataPointObject.y
|
||||
}
|
||||
dataPoint = canvas.chartingSpace.viewport.fitIntoVisibleArea(dataPoint)
|
||||
dataPoint = thisObject.fitFunction(dataPoint)
|
||||
imagePosition.x = dataPoint.x
|
||||
imagePosition.y = dataPoint.y
|
||||
let imageToDraw = canvas.designSpace.iconCollection.get(imageName)
|
||||
if (imageToDraw.canDrawIcon === true) {
|
||||
browserCanvasContext.drawImage(imageToDraw, imagePosition.x - imageSize / 2 + offsetX, imagePosition.y - imageSize / 2 - offsetY, imageSize, imageSize)
|
||||
}
|
||||
}
|
||||
|
||||
/* Here we are going to plot texts. */
|
||||
for (let j = 0; j < productDefinition.referenceParent.shapes.texts.length; j++) {
|
||||
let text = productDefinition.referenceParent.shapes.texts[j]
|
||||
if (text.textPosition === undefined) { continue }
|
||||
if (text.textPosition.referenceParent === undefined) { continue }
|
||||
if (text.textCondition !== undefined) {
|
||||
let mustPlot = eval(text.textCondition.code)
|
||||
if (mustPlot !== true) { continue }
|
||||
}
|
||||
if (text.textFormula === undefined) { continue }
|
||||
if (text.textStyle === undefined) { continue }
|
||||
let value = eval(text.textFormula.code)
|
||||
let fontSize = 0
|
||||
let opacity = 0
|
||||
let paletteColor = UI_COLOR.GREY
|
||||
let offsetX = 0
|
||||
let offsetY = 0
|
||||
let textPosition = {x: 0, y: 0}
|
||||
if (text.textStyle.config.fontSize !== undefined) { fontSize = text.textStyle.config.fontSize }
|
||||
if (text.textStyle.config.opacity !== undefined) { opacity = text.textStyle.config.opacity }
|
||||
if (text.textStyle.config.paletteColor !== undefined) { paletteColor = eval(text.textStyle.config.paletteColor) }
|
||||
if (text.textPosition.config.offsetX !== undefined) { offsetX = text.textPosition.config.offsetX }
|
||||
if (text.textPosition.config.offsetY !== undefined) { offsetY = text.textPosition.config.offsetY }
|
||||
let dataPointObject = dataPoints.get(text.textPosition.referenceParent.id)
|
||||
if (dataPointObject === undefined) { continue }
|
||||
let dataPoint = {
|
||||
x: dataPointObject.x,
|
||||
y: dataPointObject.y
|
||||
}
|
||||
dataPoint = canvas.chartingSpace.viewport.fitIntoVisibleArea(dataPoint)
|
||||
dataPoint = thisObject.fitFunction(dataPoint)
|
||||
textPosition.x = dataPoint.x
|
||||
textPosition.y = dataPoint.y
|
||||
|
||||
browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY
|
||||
browserCanvasContext.fillStyle = 'rgba(' + paletteColor + ', ' + opacity + ')'
|
||||
browserCanvasContext.fillText(value, textPosition.x + offsetX, textPosition.y - offsetY)
|
||||
}
|
||||
}
|
||||
|
||||
if (coordinateSystem.autoMinYScale === true || coordinateSystem.autoMinYScale === true) {
|
||||
@@ -792,7 +884,7 @@ function newPlotter () {
|
||||
|
||||
logged = false
|
||||
} catch (err) {
|
||||
if (ERROR_LOG === true) { logger.write('[ERROR] plotChart -> err = ' + err.stack) }
|
||||
if (ERROR_LOG === true) { logger.write('[ERROR] plot -> err = ' + err.stack) }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -806,11 +898,7 @@ function newPlotter () {
|
||||
}
|
||||
|
||||
function onDragFinished () {
|
||||
try {
|
||||
recalculate()
|
||||
} catch (err) {
|
||||
if (ERROR_LOG === true) { logger.write('[ERROR] onDragFinished -> err = ' + err.stack) }
|
||||
}
|
||||
recalculate()
|
||||
}
|
||||
|
||||
function onDisplace (event) {
|
||||
@@ -0,0 +1,92 @@
|
||||
function newRecordValues () {
|
||||
const MODULE_NAME = 'Record Values'
|
||||
const logger = newWebDebugLog()
|
||||
logger.fileName = MODULE_NAME
|
||||
|
||||
let thisObject = {
|
||||
onRecordChange: onRecordChange,
|
||||
initialize: initialize,
|
||||
finalize: finalize
|
||||
}
|
||||
|
||||
let tradingSystem
|
||||
let tradingEngine
|
||||
let productDefinition
|
||||
let propertyTargetNodeMap = new Map()
|
||||
return thisObject
|
||||
|
||||
function finalize () {
|
||||
tradingSystem = undefined
|
||||
tradingEngine = undefined
|
||||
productDefinition = undefined
|
||||
propertyTargetNodeMap = undefined
|
||||
}
|
||||
|
||||
function initialize (pTradingSystem, pTradingEngine, pProductDefinition) {
|
||||
tradingSystem = canvas.designSpace.workspace.getHierarchyHeadsById(pTradingSystem.id)
|
||||
tradingEngine = canvas.designSpace.workspace.getHierarchyHeadsById(pTradingEngine.id)
|
||||
productDefinition = pProductDefinition
|
||||
|
||||
/*
|
||||
The product root can be a node or a node property of type array.
|
||||
*/
|
||||
let productRoot = eval(productDefinition.config.nodePath)
|
||||
|
||||
if (productDefinition.config.nodePathType === 'array') {
|
||||
/*
|
||||
This means that the configured nodePath is not pointing to a node, but to a node property that is an array.
|
||||
For that reason we will assume that each element of the array is a record to be outputed
|
||||
*/
|
||||
for (let index = 0; index < productRoot.length; index++) {
|
||||
/*
|
||||
The Product Root Node is the root of the node hiriarchy from where we are going to extract the record values.
|
||||
*/
|
||||
let productRootNode = productRoot[index]
|
||||
scanProperties(productRootNode, index)
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
This means that the configured nodePath points to a single node, which is the one whose children constitutes
|
||||
the record to be saved at the output file.
|
||||
*/
|
||||
/*
|
||||
The Product Root Node is the root of the node hiriarchy from where we are going to extract the record values.
|
||||
*/
|
||||
let productRootNode = productRoot
|
||||
scanProperties(productRootNode)
|
||||
}
|
||||
|
||||
function scanProperties (productRootNode, index) {
|
||||
for (let i = 0; i < productDefinition.record.properties.length; i++) {
|
||||
let property = productDefinition.record.properties[i]
|
||||
if (property.config.nodePath !== undefined) {
|
||||
let propertyRoot = eval(property.config.nodePath)
|
||||
propertyTargetNodeMap.set(property.id, propertyRoot)
|
||||
} else {
|
||||
propertyTargetNodeMap.set(property.id, productRootNode)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function onRecordChange (currentRecord) {
|
||||
if (currentRecord === undefined) { return }
|
||||
for (let i = 0; i < productDefinition.record.properties.length; i++) {
|
||||
let property = productDefinition.record.properties[i]
|
||||
let value = currentRecord[property.config.codeName]
|
||||
let targetNode = propertyTargetNodeMap.get(property.id)
|
||||
applyValue(targetNode[property.config.codeName], value)
|
||||
}
|
||||
}
|
||||
|
||||
function applyValue (node, value) {
|
||||
if (canvas.chartingSpace.visible !== true) { return }
|
||||
if (node === undefined) { return }
|
||||
if (node === undefined) { return }
|
||||
if (node.payload === undefined) { return }
|
||||
if (node.payload.uiObject === undefined) { return }
|
||||
if (value === true) { value = 'true' }
|
||||
if (value === false) { value = 'false' }
|
||||
node.payload.uiObject.setValue(value, 1)
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -125,7 +125,7 @@ function newSplashScreen () {
|
||||
|
||||
fontSize = 35
|
||||
|
||||
title = 'Beta 5'
|
||||
title = 'Beta 6'
|
||||
|
||||
titlePoint = {
|
||||
x: thisObject.container.frame.width / 2 - title.length / 2 * fontSize * FONT_ASPECT_RATIO - 20,
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
This function scans a node hiriatchy recursively and creates a Map by Id of all the nodes of it.
|
||||
*/
|
||||
|
||||
function getHiriarchyMap (rootNode) {
|
||||
let hiriatchyMap = new Map()
|
||||
evalNode(rootNode)
|
||||
return hiriatchyMap
|
||||
|
||||
function evalNode (node) {
|
||||
if (node === undefined) { return }
|
||||
|
||||
hiriatchyMap.set(node.id, node)
|
||||
|
||||
/* Now we go down through all this node children */
|
||||
let nodeDefinition = APP_SCHEMA_MAP.get(node.type)
|
||||
if (nodeDefinition === undefined) { return }
|
||||
|
||||
if (nodeDefinition.properties !== undefined) {
|
||||
let previousPropertyName // Since there are cases where there are many properties with the same name,because they can hold nodes of different types but only one at the time, we have to avoind counting each property of those as individual children.
|
||||
for (let i = 0; i < nodeDefinition.properties.length; i++) {
|
||||
let property = nodeDefinition.properties[i]
|
||||
|
||||
switch (property.type) {
|
||||
case 'node': {
|
||||
if (property.name !== previousPropertyName) {
|
||||
if (node[property.name] !== undefined) {
|
||||
evalNode(node[property.name])
|
||||
}
|
||||
previousPropertyName = property.name
|
||||
}
|
||||
break
|
||||
}
|
||||
case 'array': {
|
||||
if (node[property.name] !== undefined) {
|
||||
let nodePropertyArray = node[property.name]
|
||||
for (let m = 0; m < nodePropertyArray.length; m++) {
|
||||
evalNode(nodePropertyArray[m])
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user