Merge pull request #116 from AAMasters/develop

Beta 6 Implementation Finished
This commit is contained in:
Luis Fernando Molina authored and GitHub committed 2020-07-25 09:22:54 +02:00
commit f09317f5bf
26 files changed
+1007 -223

No files matched your search

+61 -70
View File
@@ -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 */
+5 -10
View File
@@ -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) {
+187 -54
View File
@@ -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++) {
+1 -1
View File
@@ -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 -8
View File
@@ -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)
+2 -2
View File
@@ -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
View File
@@ -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
+9 -4
View File
@@ -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: {
+5 -4
View File
@@ -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
View File
@@ -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
View File
@@ -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) {
+3 -7
View File
@@ -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) {
+46
View File
@@ -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)
}
}
+47
View File
@@ -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)
}
}
}
+42
View File
@@ -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)
}
}
+47
View File
@@ -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)
}
}
+47
View File
@@ -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()
}
}
+47
View File
@@ -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)
}
}
+47
View File
@@ -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)
}
}
+106 -18
View File
@@ -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) {
+92
View File
@@ -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
View File
@@ -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,
+47
View File
@@ -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
}
}
}
}
}
}