diff --git a/Client/WebServer/index.html b/Client/WebServer/index.html index efec5e5b5..200023f75 100644 --- a/Client/WebServer/index.html +++ b/Client/WebServer/index.html @@ -120,6 +120,7 @@ + diff --git a/Projects/Superalgos/Schemas/Docs-Nodes/data-tasks.json b/Projects/Superalgos/Schemas/Docs-Nodes/data-tasks.json index 830bbbb43..920e62ba2 100644 --- a/Projects/Superalgos/Schemas/Docs-Nodes/data-tasks.json +++ b/Projects/Superalgos/Schemas/Docs-Nodes/data-tasks.json @@ -1,4 +1,3 @@ { - "type": "Data Tasks", - "definition": "This is the definition of Data Tasks" + "type": "Data Tasks" } \ No newline at end of file diff --git a/Projects/Superalgos/Schemas/Docs-Nodes/dataset-definition.json b/Projects/Superalgos/Schemas/Docs-Nodes/dataset-definition.json index 2343268ca..27155ef63 100644 --- a/Projects/Superalgos/Schemas/Docs-Nodes/dataset-definition.json +++ b/Projects/Superalgos/Schemas/Docs-Nodes/dataset-definition.json @@ -1,6 +1,6 @@ { "type": "Dataset Definition", - "definition": "A dataset definition contains a configuration file that defines many aspects of the dataset. There are two types of dataset definitions: Multi-Period-Market and Multi-Period-Daily.", + "definition": "A data set is a collection of files stored in the designated location, as per the definitions on the referenced data product in the corresponding data mine.", "paragraphs": [ { "style": "Title", diff --git a/Projects/Superalgos/Schemas/Docs-Nodes/formula.json b/Projects/Superalgos/Schemas/Docs-Nodes/formula.json index af18947b6..d85bd591e 100644 --- a/Projects/Superalgos/Schemas/Docs-Nodes/formula.json +++ b/Projects/Superalgos/Schemas/Docs-Nodes/formula.json @@ -8,151 +8,15 @@ }, { "style": "Text", - "text": "In the context of a trading system, formulas are used to determine the values for several properties, such as the target rate, target size, managed stop loss, managed take profit, and so on." + "text": "In the context of the trading engine, formulas are used to create user defined statistics." }, { "style": "Text", - "text": "Formulas may use indicators and trading engine properties. The main difference between writing a formula and writing a condition is that while conditions must evaluate to true or false, formulas must evaluate to a number." - }, - { - "style": "Text", - "text": "A simple math example:" - }, - { - "style": "Text", - "text": "This simple formula may be used to define an initial take profit target 3% above the rate at which the position was taken." - }, - { - "style": "Text", - "text": "tradingEngine.current.position.entryTargetRate.value * 1.03" + "text": "Formulas may use indicators and object properties made available by the trading engine. They must evaluate to a number." }, { "style": "Note", - "text": "You may use any variable made available by the trading engine, as explained on the accessing runtime data page." - }, - { - "style": "Text", - "text": "A simple JavaScript example:" - }, - { - "style": "Text", - "text": "A bit of very basic JavaScript, introducing conditional statements, allows more intelligence. For example, in this case, we ask if the proposed formula results in a number greater than the current stop loss value; if it does, then the proposed formula is used; if not, then the current stop loss value is left as is." - }, - { - "style": "Text", - "text": "This is—basically—a trailing stop loss 2% below the moving average that may go higher if the moving average goes up, but it may never come down—thanks to the use of the IF ELSE clause." - }, - { - "style": "Text", - "text": "if (chart.at01hs.bollingerBand.movingAverage * 0.98 > tradingEngine.current.position.stopLoss.value)" - }, - { - "style": "Text", - "text": " {chart.at01hs.bollingerBand.movingAverage * 0.98}" - }, - { - "style": "Text", - "text": " else" - }, - { - "style": "Text", - "text": " {tradingEngine.current.position.stopLoss.value}" - }, - { - "style": "Text", - "text": "For developers:" - }, - { - "style": "Text", - "text": "To build more complex logic within a formula, create a function that implements the logic and returns a numerical value, and then call the function:" - }, - { - "style": "Text", - "text": "function orderRate() {" - }, - { - "style": "Text", - "text": " const ORDER_STEP_NUMBER = 1 // Secuential step number, starting with 1 from the closest to the price." - }, - { - "style": "Text", - "text": " const BUY_SELL_SIGN = -1 // 1 for buy orders, -1 for sell orders." - }, - { - "style": "Text", - "text": " const STEP_SEPARATION = 0.15 // % of separation of stair steps between them." - }, - { - "style": "Text", - "text": " const BASE_FACTOR = 0.2 // % above or below bollinger band without bias." - }, - { - "style": "Text", - "text": " const BIAS_FACTOR = 0.3 // % to move the whole stair of orders up or down depending on the bias." - }, - { - "style": "Text", - "text": " const BAND_RATE = chart.at01min.bollingerBand.lowerBand // Upper Bollinger Band for sell orders, and Lower for buy orders." - }, - { - "style": "Text", - "text": " let inbalance = tradingEngine.current.episode.episodeBaseAsset.beginBalance.value - tradingEngine.current.episode.episodeBaseAsset.balance.value" - }, - { - "style": "Text", - "text": " let BIAS_SIGN" - }, - { - "style": "Text", - "text": " if (inbalance === 0) {" - }, - { - "style": "Text", - "text": " BIAS_SIGN = 0" - }, - { - "style": "Text", - "text": " }" - }, - { - "style": "Text", - "text": " if (inbalance < 0) {" - }, - { - "style": "Text", - "text": " BIAS_SIGN = + 1" - }, - { - "style": "Text", - "text": " }" - }, - { - "style": "Text", - "text": " if (inbalance > 0) {" - }, - { - "style": "Text", - "text": " BIAS_SIGN = - 1" - }, - { - "style": "Text", - "text": " }" - }, - { - "style": "Text", - "text": " let rate = BAND_RATE + BUY_SELL_SIGN BAND_RATE (BASE_FACTOR + ORDER_STEP_NUMBER STEP_SEPARATION + BIAS_SIGN BIAS_FACTOR) / 100" - }, - { - "style": "Text", - "text": " return rate" - }, - { - "style": "Text", - "text": "}" - }, - { - "style": "Text", - "text": "orderRate()" + "text": "To learn how to write formulas, see syntax overview." }, { "style": "Title", @@ -160,7 +24,7 @@ }, { "style": "Text", - "text": "To add a formula, select Add Formula on the corresponding parent node menu." + "text": "To add the formula node, select Add Missing Items on the parent node menu." } ] } \ No newline at end of file diff --git a/Projects/Superalgos/Schemas/Docs-Nodes/plotter-module.json b/Projects/Superalgos/Schemas/Docs-Nodes/plotter-module.json index 5e3bc8af7..f8bf2896a 100644 --- a/Projects/Superalgos/Schemas/Docs-Nodes/plotter-module.json +++ b/Projects/Superalgos/Schemas/Docs-Nodes/plotter-module.json @@ -68,39 +68,39 @@ }, { "style": "Text", - "text": "" + "text": "| Value | Image|" }, { "style": "Text", - "text": "" + "text": "| :---: | :---: |" }, { "style": "Text", - "text": "" + "text": "| default | |" }, { "style": "Text", - "text": "" + "text": "| histogram | |" }, { "style": "Text", - "text": "" + "text": "| band | |" }, { "style": "Text", - "text": "" + "text": "| moving-average | |" }, { "style": "Text", - "text": "" + "text": "| oscillator | |" }, { "style": "Text", - "text": "" + "text": "| trend | |" }, { "style": "Text", - "text": "
Value Image
:---: :---:
default
histogram
band
moving-average
oscillator
trend
Custom images may be added too. To do that:" + "text": "Custom images may be added too. To do that:" }, { "style": "Text", diff --git a/Projects/Superalgos/Schemas/Docs-Nodes/space-style.json b/Projects/Superalgos/Schemas/Docs-Nodes/space-style.json index a6ffc3cb4..4ec9a6e12 100644 --- a/Projects/Superalgos/Schemas/Docs-Nodes/space-style.json +++ b/Projects/Superalgos/Schemas/Docs-Nodes/space-style.json @@ -128,75 +128,75 @@ }, { "style": "Text", - "text": "" + "text": "| Variable Value | RGB Value | Color Sample |" }, { "style": "Text", - "text": "" + "text": "| :--- | :---: | :------------------- |" }, { "style": "Text", - "text": "" + "text": "| DARK | 48, 48, 54 |   |" }, { "style": "Text", - "text": "" + "text": "| LIGHT | 234, 226, 222 |   |" }, { "style": "Text", - "text": "" + "text": "| GREY | 150, 150, 150 |   |" }, { "style": "Text", - "text": "" + "text": "| LIGHT_GREY | 247, 247, 247 |   |" }, { "style": "Text", - "text": "" + "text": "| WHITE | 255, 255, 255 |   |" }, { "style": "Text", - "text": "" + "text": "| BLACK | 0, 0, 0 |   |" }, { "style": "Text", - "text": "" + "text": "| GOLDEN_ORANGE | 240, 162, 2 |   |" }, { "style": "Text", - "text": "" + "text": "| RUSTED_RED | 204, 88, 53 |   |" }, { "style": "Text", - "text": "" + "text": "| GREEN | 188, 214, 67 |   |" }, { "style": "Text", - "text": "" + "text": "| RED | 223, 70, 60 |   |" }, { "style": "Text", - "text": "" + "text": "| PATINATED_TURQUOISE | 27, 153, 139 |   |" }, { "style": "Text", - "text": "" + "text": "| TITANIUM_YELLOW | 244, 228, 9 |   |" }, { "style": "Text", - "text": "" + "text": "| MANGANESE_PURPLE | 91,80, 122 |   |" }, { "style": "Text", - "text": "" + "text": "| TURQUOISE | 74, 207, 217 |   |" }, { "style": "Text", - "text": "" + "text": "| DARK_TURQUOISE | 2, 149, 170 |   |" }, { "style": "Text", - "text": "
Variable Value RGB Value Color Sample
:--- :---: :-------------------
DARK 48, 48, 54  
LIGHT 234, 226, 222  
GREY 150, 150, 150  
LIGHT_GREY 247, 247, 247  
WHITE 255, 255, 255  
BLACK 0, 0, 0  
GOLDEN_ORANGE 240, 162, 2  
RUSTED_RED 204, 88, 53  
GREEN 188, 214, 67  
RED 223, 70, 60  
PATINATED_TURQUOISE 27, 153, 139  
TITANIUM_YELLOW 244, 228, 9  
MANGANESE_PURPLE 91,80, 122  
TURQUOISE 74, 207, 217  
DARK_TURQUOISE 2, 149, 170  
." + "text": "." } ] } \ No newline at end of file diff --git a/Projects/Superalgos/Schemas/Docs-Nodes/style.json b/Projects/Superalgos/Schemas/Docs-Nodes/style.json index f255baae7..ee3db1d4b 100644 --- a/Projects/Superalgos/Schemas/Docs-Nodes/style.json +++ b/Projects/Superalgos/Schemas/Docs-Nodes/style.json @@ -148,75 +148,75 @@ }, { "style": "Text", - "text": "" + "text": "| Variable Value | RGB Value | Color Sample |" }, { "style": "Text", - "text": "" + "text": "| :--- | :---: | :------------------- |" }, { "style": "Text", - "text": "" + "text": "| DARK | 48, 48, 54 |   |" }, { "style": "Text", - "text": "" + "text": "| LIGHT | 234, 226, 222 |   |" }, { "style": "Text", - "text": "" + "text": "| GREY | 150, 150, 150 |   |" }, { "style": "Text", - "text": "" + "text": "| LIGHT_GREY | 247, 247, 247 |   |" }, { "style": "Text", - "text": "" + "text": "| WHITE | 255, 255, 255 |   |" }, { "style": "Text", - "text": "" + "text": "| BLACK | 0, 0, 0 |   |" }, { "style": "Text", - "text": "" + "text": "| GOLDEN_ORANGE | 240, 162, 2 |   |" }, { "style": "Text", - "text": "" + "text": "| RUSTED_RED | 204, 88, 53 |   |" }, { "style": "Text", - "text": "" + "text": "| GREEN | 188, 214, 67 |   |" }, { "style": "Text", - "text": "" + "text": "| RED | 223, 70, 60 |   |" }, { "style": "Text", - "text": "" + "text": "| PATINATED_TURQUOISE | 27, 153, 139 |   |" }, { "style": "Text", - "text": "" + "text": "| TITANIUM_YELLOW | 244, 228, 9 |   |" }, { "style": "Text", - "text": "" + "text": "| MANGANESE_PURPLE | 91,80, 122 |   |" }, { "style": "Text", - "text": "" + "text": "| TURQUOISE | 74, 207, 217 |   |" }, { "style": "Text", - "text": "" + "text": "| DARK_TURQUOISE | 2, 149, 170 |   |" }, { - "style": "Text", - "text": "
Variable Value RGB Value Color Sample
:--- :---: :-------------------
DARK 48, 48, 54  
LIGHT 234, 226, 222  
GREY 150, 150, 150  
LIGHT_GREY 247, 247, 247  
WHITE 255, 255, 255  
BLACK 0, 0, 0  
GOLDEN_ORANGE 240, 162, 2  
RUSTED_RED 204, 88, 53  
GREEN 188, 214, 67  
RED 223, 70, 60  
PATINATED_TURQUOISE 27, 153, 139  
TITANIUM_YELLOW 244, 228, 9  
MANGANESE_PURPLE 91,80, 122  
TURQUOISE 74, 207, 217  
DARK_TURQUOISE 2, 149, 170  
* lineWidth is the width of the border line, which should be greater than 0." + "style": "List", + "text": "lineWidth is the width of the border line, which should be greater than 0." }, { "style": "List", diff --git a/Projects/Superalgos/UI/Spaces/Docs-Space/DocsSpace.js b/Projects/Superalgos/UI/Spaces/Docs-Space/DocsSpace.js index b2b02e53e..7652b399b 100644 --- a/Projects/Superalgos/UI/Spaces/Docs-Space/DocsSpace.js +++ b/Projects/Superalgos/UI/Spaces/Docs-Space/DocsSpace.js @@ -65,7 +65,8 @@ function newSuperalgosDocSpace() { toWarning: toWarning, toImportant: toImportant, toSuccess: toSuccess, - toList: toList + toList: toList, + toTable: toTable } function editParagraph() { @@ -178,6 +179,12 @@ function newSuperalgosDocSpace() { docSchemaParagraph.style = 'List' renderPage() } + + function toTable() { + let docSchemaParagraph = docSchemaParagraphMap.get(selectedParagraph.id) + docSchemaParagraph.style = 'Table' + renderPage() + } } function setUpMenuItemsMap() { @@ -256,12 +263,12 @@ function newSuperalgosDocSpace() { let paragraphs = [] let paragraph = '' let splittedSelectedParagraph = selectedParagraph.id.split('-') - let selectedParagraphIndex = Number(splittedSelectedParagraph[1]) - let selectedParagraphStyle = splittedSelectedParagraph[2] + let selectedParagraphIndex = Number(splittedSelectedParagraph[2]) + let selectedParagraphStyle = splittedSelectedParagraph[3] let style = selectedParagraphStyle.charAt(0).toUpperCase() + selectedParagraphStyle.slice(1); for (let i = 0; i < textArea.value.length; i++) { - if (textArea.value.charCodeAt(i) === 10 && style !== 'Javascript' && style !== 'Json') { + if (textArea.value.charCodeAt(i) === 10 && style !== 'Javascript' && style !== 'Json' && style !== 'Table') { if (paragraph !== '') { paragraphs.push(paragraph) } @@ -381,45 +388,58 @@ function newSuperalgosDocSpace() { if (paragraphNode.id === undefined || paragraphNode.id.indexOf('paragraph') < 0) { paragraphNode = paragraphNode.parentNode } + if (paragraphNode.id === undefined || paragraphNode.id.indexOf('paragraph') < 0) { + paragraphNode = paragraphNode.parentNode + } + if (paragraphNode.id === undefined || paragraphNode.id.indexOf('paragraph') < 0) { + paragraphNode = paragraphNode.parentNode + } + if (paragraphNode.id === undefined || paragraphNode.id.indexOf('paragraph') < 0) { + paragraphNode = paragraphNode.parentNode + } if (paragraphNode.id === undefined || paragraphNode.id.indexOf('paragraph') < 0) { return false } + /* Depending on the Style of Paragraph we will need to remove some info from the innerText. */ - if (paragraphNode.id.indexOf('definition') >= 0) { + if (paragraphNode.id.indexOf('-definition') >= 0) { selectedParagraphData = paragraphNode.innerText } - if (paragraphNode.id.indexOf('text') >= 0) { + if (paragraphNode.id.indexOf('-text') >= 0) { selectedParagraphData = paragraphNode.innerText } - if (paragraphNode.id.indexOf('title') >= 0) { + if (paragraphNode.id.indexOf('-title') >= 0) { selectedParagraphData = paragraphNode.innerText } - if (paragraphNode.id.indexOf('subtitle') >= 0) { + if (paragraphNode.id.indexOf('-subtitle') >= 0) { selectedParagraphData = paragraphNode.innerText } - if (paragraphNode.id.indexOf('note') >= 0) { + if (paragraphNode.id.indexOf('-note') >= 0) { selectedParagraphData = paragraphNode.innerText.substring(6, paragraphNode.innerText.length) } - if (paragraphNode.id.indexOf('success') >= 0) { + if (paragraphNode.id.indexOf('-success') >= 0) { selectedParagraphData = paragraphNode.innerText.substring(5, paragraphNode.innerText.length) } - if (paragraphNode.id.indexOf('important') >= 0) { + if (paragraphNode.id.indexOf('-important') >= 0) { selectedParagraphData = paragraphNode.innerText.substring(11, paragraphNode.innerText.length) } - if (paragraphNode.id.indexOf('warning') >= 0) { + if (paragraphNode.id.indexOf('-warning') >= 0) { selectedParagraphData = paragraphNode.innerText.substring(10, paragraphNode.innerText.length) } - if (paragraphNode.id.indexOf('list') >= 0) { + if (paragraphNode.id.indexOf('-list') >= 0) { selectedParagraphData = paragraphNode.innerText } - if (paragraphNode.id.indexOf('javascript') >= 0) { + if (paragraphNode.id.indexOf('-table') >= 0) { + selectedParagraphData = reverseParseTable(paragraphNode.innerHTML) + } + if (paragraphNode.id.indexOf('-javascript') >= 0) { selectedParagraphData = paragraphNode.innerText.substring(1, paragraphNode.innerText.length - 1) } - if (paragraphNode.id.indexOf('json') >= 0) { + if (paragraphNode.id.indexOf('-json') >= 0) { selectedParagraphData = paragraphNode.innerText.substring(1, paragraphNode.innerText.length - 1) } @@ -576,7 +596,6 @@ function newSuperalgosDocSpace() { let key = 'editable-paragraph-' + paragraphIndex let paragraph = nodeDocsDefinition.paragraphs[i] renderParagraph(paragraph, key) - docSchemaParagraphMap.set(key, paragraph) paragraphIndex++ } } @@ -745,7 +764,7 @@ function newSuperalgosDocSpace() { generateReferencingRules() generateConfiguration() generateCode() - generateFormula() + generateFormula() function generateMenuItems() { /* @@ -1339,7 +1358,19 @@ function newSuperalgosDocSpace() { sufix = '' role = '' key = key + '-list' - innerHTML = addBold(paragraph.text) + innerHTML = addBold(innerHTML) + innerHTML = addItalics(innerHTML) + innerHTML = addToolTips(innerHTML) + break + } + case 'Table': { + styleClass = '' + prefix = '' + sufix = '
' + role = '' + key = key + '-table' + innerHTML = parseTable(paragraph.text) + innerHTML = addBold(innerHTML) innerHTML = addItalics(innerHTML) innerHTML = addToolTips(innerHTML) break @@ -1365,6 +1396,8 @@ function newSuperalgosDocSpace() { } HTML = HTML + '

' + prefix + ' ' + innerHTML + sufix + '

' + docSchemaParagraphMap.set(key, paragraph) + } function hightlightEmbeddedCode() { @@ -1408,6 +1441,72 @@ function newSuperalgosDocSpace() { } } + function parseTable(text) { + let HTML = '' + let odd = false + let rows = text.split(String.fromCharCode(10)) + for (let i = 0; i < rows.length; i++) { + let row = rows[i] + let colums = row.split('|') + if (i === 0) { + HTML = HTML + '' + } + if (i === 1) { + HTML = HTML + '' + } + if (odd === true) { + HTML = HTML + '' + odd = false + } else { + HTML = HTML + '' + odd = true + } + if (colums.length < 2) { + return text + } else { + /* We discard anything before the first | and after the last | */ + for (let j = 1; j < colums.length - 1; j++) { + let column = colums[j] + if (i === 0) { + HTML = HTML + '' + column + '' + } else { + HTML = HTML + '' + column + '' + } + } + } + + HTML = HTML + '' + if (i === 0) { + HTML = HTML + '' + } + if (i === rows.length - 1) { + HTML = HTML + '' + } + } + return HTML + } + + function reverseParseTable(HTML) { + text = HTML + text = text.replace(' ', '') + text = text.replace('
', '') + text = text.replace('', '') + text = text.replace('', '') + text = text.replace('', '') + text = text.replace('', '') + + text = text.replaceAll('', '') + text = text.replaceAll('', '') + text = text.replaceAll('', '|') + text = text.replaceAll('', '|') + text = text.replaceAll('', String.fromCharCode(10)) + text = text.replaceAll('', '|') + text = text.replaceAll('', '|') + text = text.replaceAll('', '|') + text = text.replaceAll('', '|') + return text + } + function addBold(text) { let splittedText = text.split(':') if (splittedText.length > 1 && splittedText[1].length > 0) {