Merge remote-tracking branch 'upstream/in-app-documentation' into in-app-documentation

This commit is contained in:
Luis Fernando Molina committed 2021-01-10 11:31:09 +01:00
commit 33e6767faa
44 files changed
+3371 -198

No files matched your search

@@ -22,12 +22,21 @@
},
{
"style": "List",
"text": "Condition A: chart.at01hs.candle.close > chart.at01hs.bollingerBand.MovingAverage → This means that the latest candle at the 1 hour chart closed above the Bollinger Bands moving average.",
"updated": 1609595088806
"text": "Condition A: chart.at01hs.candle.close > chart.at01hs.bollingerBand.MovingAverage",
"updated": 1610211782596
},
{
"style": "Note",
"text": "This means that the latest candle at the 1 hour chart closed above the Bollinger Bands moving average."
},
{
"style": "List",
"text": "Condition B: chart.at01hs.candle.previous.max > chart.at01hs.bollingerBand.previous.MovingAverage → This means that the maximum value of the candle before the last one, was higher than the Bollinger Bands moving average."
"text": "Condition B: chart.at01hs.candle.previous.max > chart.at01hs.bollingerBand.previous.MovingAverage",
"updated": 1610211804682
},
{
"style": "Note",
"text": "This means that the maximum value of the candle before the last one, was higher than the Bollinger Bands moving average."
},
{
"style": "Text",
@@ -10,11 +10,13 @@
},
{
"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 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.",
"updated": 1610211948110
},
{
"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."
"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.",
"updated": 1610211971367
},
{
"style": "Block",
@@ -1,3 +1,12 @@
{
"type": "Layer Panels"
"type": "Layer Panels",
"paragraphs": [
{
"style": "Text",
"text": "Left click and Edit to enter edit mode and change this text. ENTER to write new paragraphs. ESC to exit edit mode."
}
],
"definition": {
"text": "Right click to edit this text and replace it with a definition / summary for this page. ESC to exit edit mode."
}
}
@@ -8,15 +8,16 @@
"style": "Block",
"text": "Content"
},
{
"style": "Block",
"text": "Configuring"
},
{
"style": "Success",
"text": "Please read the definition of Limit Buy Order for relevant information about how limit orders work. Also, please read the definition of Market Buy Order for relevant information about how orders in general work, in particular, the section about Size, Filling, Closing, and Spawning Multiple Orders.",
"updated": 1609608882268
},
{
"style": "Block",
"text": "Configuring",
"updated": 1610188212039
},
{
"style": "Title",
"text": "Limit Sell Order Configuration"
@@ -1,24 +1,32 @@
{
"type": "Phase",
"definition": {
"text": "The management of take profit and stop loss targets is done in phases. Phase 1 sets the initial targets, either for the managed stop loss or the managed take profit, and becomes active as soon as the first order is placed. Subsequent phases allows switching to different formulas given certain market situations."
"text": "The management of take profit and stop loss targets is done in phases, each with their own formula that determines the target. ",
"updated": 1610205977723
},
"paragraphs": [
{
"style": "Block",
"text": "Content"
},
{
"style": "Text",
"text": "Phase 1 sets the initial targets, either for the Managed Stop Loss or the Managed Take Profit, and becomes active as soon as the Take Position Event validates true. Subsequent phases allows switching to different formulas given certain market situations.",
"updated": 1610206033350
},
{
"style": "Text",
"text": "The default management of phases is sequential, meaning that phase 2 comes after phase 1, phase 3 comes after phase 2, and so on."
},
{
"style": "Text",
"text": "To switch from one phase to the next phase in the sequence, the next phase event is used. When the situation described in the next phase event validates true, the switch occurs and the next phase becomes the active phase."
"text": "To switch from one phase to the next phase in the sequence, the Next Phase event is used. When the Situation described in the next phase event validates true, the switch occurs and the next phase becomes the active phase.",
"updated": 1610206075265
},
{
"style": "Text",
"text": "However, management does not need to happen sequentially. By using the move to phase event instead of the next phase event, the system may activate any other phase and not just the one next in the sequence."
"text": "However, management does not need to happen sequentially. By using the Move To Phase Event instead of the Next Phase Event, the system may activate any other phase and not just the one next in the sequence.",
"updated": 1610206113858
},
{
"style": "Text",
@@ -1,3 +1,13 @@
{
"type": "Project Dashboards"
"type": "Project Dashboards",
"paragraphs": [
{
"style": "Text",
"text": "Left click and Edit to enter edit mode and change this text. ENTER to write new paragraphs. ESC to exit edit mode."
}
],
"definition": {
"text": "The Project Dashboards node groups dashboards by project, acting as an organizational device.",
"updated": 1610135408616
}
}
@@ -14,10 +14,16 @@
},
{
"style": "Text",
"text": "When set at the level of the time machine, the scale settings affect all charts within the time machine. When set at the level of the timeline chart, the settings override the rate scale at the time machine level. This allows having multiple charts on the same time machine, each with a different rate scale."
"text": "When set at the level of the time machine, the scale settings affect all charts within the time machine. When set at the level of the timeline chart, the settings override the rate scale at the time machine level. ",
"updated": 1610136729523
},
{
"style": "Subtitle",
"style": "Success",
"text": "This allows having multiple charts on the same time machine, each with a different rate scale. This is the way to set up indicators the are designed for a scale different than that of the rate of the assets in the market. For example, the RSI and Percentage Bandwidth indicators oscillate between 0 and 100.",
"updated": 1610136956037
},
{
"style": "Title",
"text": "Scale Minimum and Maximum Values"
},
{
@@ -29,7 +35,7 @@
"text": "In technical terms, the minimum and maximum scale values are constantly changing as, whenever you pan across the charts, you are directly affecting the minimum and maximum scale values. That said, the actual scale may change dynamically or not, depending on the scale-automation settings."
},
{
"style": "Subtitle",
"style": "Title",
"text": "Automatic Scale"
},
{
@@ -49,7 +55,7 @@
"text": "The scale may be automated on either, or both minimum and maximum values at the same time. In the later case, no data point in the span of the chart ever remains out of the visible area of the chart, as the lowest data point aligns with the bottom of the chart and the highest aligns with the top."
},
{
"style": "Subtitle",
"style": "Title",
"text": "Manual Scale"
},
{
@@ -57,80 +63,26 @@
"text": "The system also features a manual mode. When in manual mode the scale does not change, even if the minimum and maximum values change while panning across a chart. This design feature allows comparing different periods using the same scale, which may be valuable in many cases."
},
{
"style": "Subtitle",
"style": "Title",
"text": "Scale Offset"
},
{
"style": "Text",
"text": "The offset is a feature of the rate scale by which the scale may be shifted upwards or downwards. As a result, charts aligned on the vertical axis—synchronized in datetime by a shared time machine—may be put one above the other. In technical terms, what happens is that the scale is shifted upwards or downwards."
},
{
"style": "Block",
"text": "Configuring"
},
{
"style": "Title",
"text": "Configuring Rate Scale"
},
{
"style": "Text",
"text": "Select Configure Rate Scale on the menu to access the configuration."
},
{
"style": "Text",
"text": "{"
},
{
"style": "Text",
"text": " \"minValue\": 388.60416666666424,"
},
{
"style": "Text",
"text": " \"maxValue\": 9715.104166666664,"
},
{
"style": "Text",
"text": " \"autoMinScale\": true,"
},
{
"style": "Text",
"text": " \"autoMaxScale\": true"
},
{
"style": "Text",
"text": "}"
},
{
"style": "List",
"text": "minValue is a numerical value that represents the value of the scale at the bottom of the chart."
},
{
"style": "List",
"text": "maxValue is a numerical value that represents the value of the scale at the top of the chart."
},
{
"style": "List",
"text": "autoMinScale sets the mode of the scale for the minimum value; true sets the value to automatic, false sets the value to manual."
},
{
"style": "List",
"text": "autoMaxScale sets the mode of the scale for the maximum value; true sets the value to automatic, false sets the value to manual."
},
{
"style": "Block",
"text": "Charts"
},
{
"style": "Title",
"text": "Rate Scale at the Charts"
},
{
"style": "Text",
"text": "<H4>Automatic Scale</H4>"
"style": "Subtitle",
"text": "Automatic Scale",
"updated": 1609783271471
},
{
"style": "Text",
"text": "1. To change the automatic scale settings, place the mouse pointer over the corresponding time machine or timeline chart rate box, press the <kbd>Shift</kbd> key and slowly scroll the wheel of the mouse. The action cycles through different possible scale automation settings. Notice a tiny green triangle below and/or above the rate scale icon."
"text": "To change the automatic scale settings, place the mouse pointer over the corresponding time machine or timeline chart rate box, press the <kbd>Shift</kbd> key and slowly scroll the wheel of the mouse. The action cycles through different possible scale automation settings. Notice a tiny green triangle below and/or above the rate scale icon.",
"updated": 1609783256953
},
{
"style": "List",
@@ -149,8 +101,9 @@
"text": "No triangle means that both minimum and maximum values are in manual mode."
},
{
"style": "Text",
"text": "<H4>Manual Scale</H4>"
"style": "Subtitle",
"text": "Manual Scale",
"updated": 1609783276345
},
{
"style": "Text",
@@ -169,8 +122,9 @@
"text": "This action has no effect when both minimum and maximum values are set to automatic mode."
},
{
"style": "Text",
"text": "<H4>Scale Offset</H4>"
"style": "Subtitle",
"text": "Scale Offset",
"updated": 1609783281780
},
{
"style": "Text",
@@ -183,6 +137,37 @@
{
"style": "Note",
"text": "Setting an offset in a timeline chart only makes sense in the context of a time machine with multiple charts. That is, if you are browsing a single chart, an offset behaves the same as moving the single chart up or down."
},
{
"style": "Block",
"text": "Configuring",
"updated": 1609783339189
},
{
"style": "Title",
"text": "Rate Scale Configuration",
"updated": 1609783329574
},
{
"style": "Subtitle",
"text": "Properties"
},
{
"style": "List",
"text": "minValue is a numerical value that represents the value of the scale at the bottom of the chart.",
"updated": 1609783389883
},
{
"style": "List",
"text": "maxValue is a numerical value that represents the value of the scale at the top of the chart."
},
{
"style": "List",
"text": "autoMinScale sets the mode of the scale for the minimum value; true sets the value to automatic, false sets the value to manual."
},
{
"style": "List",
"text": "autoMaxScale sets the mode of the scale for the maximum value; true sets the value to automatic, false sets the value to manual."
}
]
}
@@ -10,43 +10,12 @@
},
{
"style": "Text",
"text": "When the time frame scale is set at the level of the time machine, the scale setting affects all charts within the time machine. When set at the level of the timeline chart, the setting overrides the time frame scale at the time machine level. This allows comparing charts in different time frames, but still synchronized at the datetime level."
"text": "When the time frame scale is set at the level of the time machine, the scale setting affects all charts within the time machine. When set at the level of the timeline chart, the setting overrides the time frame scale at the time machine level.",
"updated": 1610136694170
},
{
"style": "Block",
"text": "Configuring"
},
{
"style": "Title",
"text": "Configuring Time Frame Scale"
},
{
"style": "Text",
"text": "Select Configure Frame Scale on the menu to access the configuration."
},
{
"style": "Text",
"text": "{"
},
{
"style": "Text",
"text": " \"value\":\"06-hs\""
},
{
"style": "Text",
"text": "}"
},
{
"style": "List",
"text": "value can be any of the time frames supported by the system:"
},
{
"style": "Text",
"text": " * 01-hs, 02-hs, 03-hs, 04-hs, 06-hs, 08-hs, 12-hs, and 24-hs."
},
{
"style": "Note",
"text": " The values entered via the design space and the charts are synchronized and stored in the node."
"style": "Success",
"text": "This allows comparing charts in different time frames, but still synchronized at the datetime level."
},
{
"style": "Block",
@@ -58,11 +27,37 @@
},
{
"style": "Text",
"text": "1. To set a time frame value, place the mouse pointer over the corresponding time machine or timeline chart time frame box and scroll the mouse wheel."
"text": "To set a time frame value, place the mouse pointer over the corresponding time machine or timeline chart time frame box and scroll the mouse wheel.",
"updated": 1609783625339
},
{
"style": "Block",
"text": "Configuring",
"updated": 1609783710191
},
{
"style": "Text",
"text": "{% include image.html file='interface/time-frame-scale-00.gif' url='yes' max-width='100' caption='To set a time frame, scroll the wheel of the mouse over the time frame scale box.' %}"
"text": ""
},
{
"style": "Title",
"text": "Time Frame Scale Configuration",
"updated": 1609783714701
},
{
"style": "Subtitle",
"text": "Properties",
"updated": 1609783740323
},
{
"style": "Javascript",
"text": "01-hs\n02-hs\n03-hs\n04-hs\n06-hs\n08-hs\n12-hs\n24-hs",
"updated": 1609783795852
},
{
"style": "Note",
"text": "The values entered via the design space and the charts are synchronized and stored in the node.",
"updated": 1609783812074
}
]
}
@@ -9,7 +9,7 @@
"text": "Content"
},
{
"style": "Subtitle",
"style": "Title",
"text": "Scale Minimum and Maximum Values"
},
{
@@ -21,7 +21,7 @@
"text": "In technical terms, the minimum and maximum scale values are constantly changing as, whenever you pan across the charts, you are directly affecting the minimum and maximum scale values. That said, the actual scale doesn't change when panning across a chart."
},
{
"style": "Subtitle",
"style": "Title",
"text": "Automatic Scale"
},
{
@@ -45,65 +45,13 @@
"text": "Having the time scale set to automatic by default helps finding the data as soon as it starts being processed the first time you run the Masters bot instances."
},
{
"style": "Subtitle",
"style": "Title",
"text": "Manual Scale"
},
{
"style": "Text",
"text": "The scale features a manual mode. When in manual mode the scale does not change, even if the minimum and maximum values change while panning through a chart. This is the natural state of the time scale."
},
{
"style": "Block",
"text": "Configuring"
},
{
"style": "Title",
"text": "Configuring Time Scale"
},
{
"style": "Text",
"text": "Select Configure Rate Scale on the menu to access the configuration."
},
{
"style": "Text",
"text": "{"
},
{
"style": "Text",
"text": " \"fromDate\": \"2019-05-02T20:07:50.872Z\","
},
{
"style": "Text",
"text": " \"toDate\": \"2019-05-22T20:28:21.515Z\","
},
{
"style": "Text",
"text": " \"autoMinScale\": false,"
},
{
"style": "Text",
"text": " \"autoMaxScale\": false"
},
{
"style": "Text",
"text": "}"
},
{
"style": "List",
"text": "minValue is a date in the Epoch time format that represents the value of the scale at the left border of the chart."
},
{
"style": "List",
"text": "maxValue is a date in the Epoch time format that represents the value of the scale at the right border of the chart."
},
{
"style": "List",
"text": "autoMinScale sets the mode of the scale for the minimum value; true sets the value to automatic, false sets the value to manual."
},
{
"style": "List",
"text": "autoMaxScale sets the mode of the scale for the maximum value; true sets the value to automatic, false sets the value to manual."
},
{
"style": "Block",
"text": "Charts"
@@ -113,12 +61,14 @@
"text": "Time Scale at the Charts"
},
{
"style": "Text",
"text": "<H4>Automatic Scale</H4>"
"style": "Subtitle",
"text": "Automatic Scale",
"updated": 1609782523590
},
{
"style": "Text",
"text": "1. To change the automatic scale settings, place the mouse pointer over the corresponding time box, press the <kbd>Shift</kbd> key and slowly scroll the wheel of the mouse. The action cycles through different possible scale automation settings. Notice a tiny green triangle to the sides of the time scale icon."
"text": "To change the automatic scale settings, place the mouse pointer over the corresponding time box, press the <kbd>Shift</kbd> key and slowly scroll the wheel of the mouse. The action cycles through different possible scale automation settings. Notice a tiny green triangle to the sides of the time scale icon.",
"updated": 1609782562160
},
{
"style": "List",
@@ -137,8 +87,9 @@
"text": "No triangle means that both minimum and maximum values are in manual mode."
},
{
"style": "Text",
"text": "<H4>Manual Scale</H4>"
"style": "Subtitle",
"text": "Manual Scale",
"updated": 1609782535042
},
{
"style": "Text",
@@ -155,6 +106,38 @@
{
"style": "Note",
"text": "This action has no effect when both minimum and maximum values are set to automatic mode."
},
{
"style": "Block",
"text": "Configuring",
"updated": 1609782587544
},
{
"style": "Title",
"text": "Time Scale Configuration",
"updated": 1609782618234
},
{
"style": "Subtitle",
"text": "Properties",
"updated": 1609782652970
},
{
"style": "List",
"text": "minValue is a date in the Epoch time format that represents the value of the scale at the left border of the chart.",
"updated": 1609782661151
},
{
"style": "List",
"text": "maxValue is a date in the Epoch time format that represents the value of the scale at the right border of the chart."
},
{
"style": "List",
"text": "autoMinScale sets the mode of the scale for the minimum value; true sets the value to automatic, false sets the value to manual."
},
{
"style": "List",
"text": "autoMaxScale sets the mode of the scale for the maximum value; true sets the value to automatic, false sets the value to manual."
}
]
}
@@ -16,6 +16,15 @@
"style": "Text",
"text": "You may add as many charts as you wish. Charts within the same time machine are synchronized in the y-axis, that is, in the datetime dimension. Charts in different time machines are independent of each other concerning the datetime. In either case, you may also add rate scales and time frame scales at the timeline charts level."
},
{
"style": "Success",
"text": "When a Rate Scale or a Time Frame Scale are set up at the level of the Timeline Chart, they affect the layers on the said timeline chart only. This trick allows users to vertically position data, by manipulating the scale of the layers in the timeline chart independently from the scale of the rest of the charts, which are governed by the scales of the Time Machine.",
"updated": 1610136594836
},
{
"style": "Text",
"text": ""
},
{
"style": "Text",
"text": "The information that each timeline chart makes available on the screen is given by the layers set up in the corresponding layers manager."
@@ -17,25 +17,9 @@
"text": "A strategy is a set of actions occurring in stages"
},
{
"style": "Text",
"text": "A strategy is defined in the following stages:",
"updated": 1609594556724
},
{
"style": "List",
"text": "Trigger Stage"
},
{
"style": "List",
"text": "Open Stage"
},
{
"style": "List",
"text": "Manage Stage"
},
{
"style": "List",
"text": "Close Stage"
"style": "Hierarchy",
"text": "Superalgos->Trading Strategy->2",
"updated": 1610138980124
},
{
"style": "Text",
@@ -28,6 +28,11 @@
"style": "Note",
"text": "The information that is out of focus, that is, out of the viewport, is not read nor rendered graphically, thus, does not consume resources."
},
{
"style": "Block",
"text": "Configuring",
"updated": 1610135327217
},
{
"style": "Title",
"text": "Viewport Configuration"
@@ -0,0 +1,35 @@
{
"topic": "Charting Space",
"pageNumber": "1",
"type": "Fundamental Charting Space Concepts",
"definition": {
"text": "The charting space provides great control over how information generated on other hierarchies is visualized.",
"updated": 1610134431825
},
"paragraphs": [
{
"style": "Text",
"text": "Conceptually, Superalgos places the focus on the visual experience. Not just because it’s nice to see data in a graphical representation, but because our analysis capabilities are extended when we incorporate senses in the mix. Human’s capacity to think abstractly may be more or less developed across individuals, but one thing is clear: our thought process benefits from being able to see.",
"updated": 1610134441689
},
{
"style": "Text",
"text": "The Charting Space is conceived to provide an unprecedented level of flexibility and control over the way information is displayed graphically. Everything that you see in the form of charts when you pull the slider down is configured in the charting space hierarchy while using the information available in other hierarchies.",
"updated": 1610134480039
},
{
"style": "Text",
"text": "In other words, you use the charting space hierarchy to create Time Machines and Timeline Charts, and to configure their scales and so on, but the information feeding those charts come from bots running on the Network hierarchy. Those bots obtain exchange and market information from the Crypto Ecosystem hierarchy via references, and their source code is defined in Data Mines.",
"updated": 1610134533861
},
{
"style": "Text",
"text": "The above means that, in order to have information to visualize, you will first need to run sensor and indicator bots. We call that data mining, and it’s done from the data mining section of the network hierarchy."
},
{
"style": "Text",
"text": "The workspaces shipping with the system feature several configurations of exchanges, markets, and charts that you may start using right away. To configure your own charts, you will need to learn the basics of the Charting Space, and that is exactly the information covered on these pages.",
"updated": 1610134602649
}
]
}
@@ -0,0 +1,93 @@
{
"topic": "Charting Space",
"pageNumber": "2",
"type": "Charting Space Hierarchy",
"definition": {
"text": "The charting space hierarchy organizes the charts on the Viewport and controls their behavior.",
"updated": 1610134676796
},
"paragraphs": [
{
"style": "Include",
"text": "Superalgos->Node->Charting Space->Definition",
"updated": 1610134731920
},
{
"style": "Include",
"text": "Superalgos->Node->Charting Space->Content",
"updated": 1610134734810
},
{
"style": "Include",
"text": "Superalgos->Concept->Reusable Snippets->Note for Hierarchy Tables"
},
{
"style": "Hierarchy",
"text": "Superalgos->Charting Space->3"
},
{
"style": "Title",
"text": "Viewport",
"updated": 1610134925124
},
{
"style": "Include",
"text": "Superalgos->Node->Viewport->Definition",
"updated": 1610134928724
},
{
"style": "Include",
"text": "Superalgos->Node->Viewport->Content",
"updated": 1610134932526
},
{
"style": "Title",
"text": "Space Style",
"updated": 1610134940862
},
{
"style": "Include",
"text": "Superalgos->Node->Space Style->Definition",
"updated": 1610135219837
},
{
"style": "Title",
"text": "Space Settings",
"updated": 1610135200205
},
{
"style": "Include",
"text": "Superalgos->Node->Space Settings->Definition",
"updated": 1610135203747
},
{
"style": "Title",
"text": "Project Dashboards",
"updated": 1610135093870
},
{
"style": "Include",
"text": "Superalgos->Node->Project Dashboards->Definition",
"updated": 1610135099780
},
{
"style": "Title",
"text": "Dashboard",
"updated": 1610135137855
},
{
"style": "Include",
"text": "Superalgos->Node->Dashboard->Definition",
"updated": 1610135143439
},
{
"style": "Include",
"text": "Superalgos->Node->Dashboard->Content",
"updated": 1610135147076
},
{
"style": "Text",
"text": ""
}
]
}
@@ -0,0 +1,54 @@
{
"topic": "Charting Space",
"pageNumber": "3",
"type": "Time Machines and Timeline Charts",
"definition": {
"text": "Time machines and timeline charts are the devices that render graphical information on the Viewport.",
"updated": 1610135709494
},
"paragraphs": [
{
"style": "Title",
"text": "Time Machine",
"updated": 1610135798826
},
{
"style": "Include",
"text": "Superalgos->Node->Time Machine->Definition",
"updated": 1610135810888
},
{
"style": "Include",
"text": "Superalgos->Node->Time Machine->Content",
"updated": 1610135814540
},
{
"style": "Include",
"text": "Superalgos->Concept->Reusable Snippets->Note for Hierarchy Tables"
},
{
"style": "Hierarchy",
"text": "Superalgos->Time Machine->3",
"updated": 1610135969339
},
{
"style": "Title",
"text": "Timeline Chart"
},
{
"style": "Include",
"text": "Superalgos->Node->Timeline Chart->Definition",
"updated": 1610135983766
},
{
"style": "Include",
"text": "Superalgos->Node->Timeline Chart->Content",
"updated": 1610135991211
},
{
"style": "Note",
"text": "We will cover scales and layer managers in separate pages!",
"updated": 1610136541919
}
]
}
@@ -0,0 +1,56 @@
{
"topic": "Charting Space",
"pageNumber": "4",
"type": "Scales",
"definition": {
"text": "Time Machines feature a Time Scale, a Rate Scale, and a Time Frame Scale. Timeline charts may implement the last two.",
"updated": 1610137109400
},
"paragraphs": [
{
"style": "Title",
"text": "Time Scale",
"updated": 1610137166709
},
{
"style": "Include",
"text": "Superalgos->Node->Time Scale->Definition",
"updated": 1610137169800
},
{
"style": "Include",
"text": "Superalgos->Node->Time Scale->Content",
"updated": 1610137173127
},
{
"style": "Title",
"text": "Rate Scale",
"updated": 1610137179866
},
{
"style": "Include",
"text": "Superalgos->Node->Rate Scale->Definition",
"updated": 1610137182583
},
{
"style": "Include",
"text": "Superalgos->Node->Rate Scale->Content",
"updated": 1610137185478
},
{
"style": "Title",
"text": "Time Frame Scale",
"updated": 1610137195480
},
{
"style": "Include",
"text": "Superalgos->Node->Time Frame Scale->Definition",
"updated": 1610137198945
},
{
"style": "Include",
"text": "Superalgos->Node->Time Frame Scale->Content",
"updated": 1610137202224
}
]
}
@@ -0,0 +1,69 @@
{
"topic": "Charting Space",
"pageNumber": "5",
"type": "Layer Managers",
"definition": {
"text": "Layer Managers organize layers and link up to the data products to be displayed on the charts.",
"updated": 1610138345819
},
"paragraphs": [
{
"style": "Include",
"text": "Superalgos->Node->Layer Manager->Definition",
"updated": 1610138034853
},
{
"style": "Include",
"text": "Superalgos->Node->Layer Manager->Content",
"updated": 1610138039651
},
{
"style": "Include",
"text": "Superalgos->Concept->Reusable Snippets->Note for Hierarchy Tables"
},
{
"style": "Hierarchy",
"text": "Superalgos->Layer Manager->3",
"updated": 1610138133484
},
{
"style": "Title",
"text": "Layer",
"updated": 1610138185622
},
{
"style": "Include",
"text": "Superalgos->Node->Layer->Definition",
"updated": 1610138195653
},
{
"style": "Include",
"text": "Superalgos->Node->Layer->Content",
"updated": 1610138199802
},
{
"style": "Title",
"text": "Bot Layers",
"updated": 1610138208284
},
{
"style": "Include",
"text": "Superalgos->Node->Bot Layers->Definition",
"updated": 1610138211248
},
{
"style": "Title",
"text": "Layer Folder",
"updated": 1610138224792
},
{
"style": "Include",
"text": "Superalgos->Node->Layer Folder->Definition",
"updated": 1610138228234
},
{
"style": "Text",
"text": ""
}
]
}
@@ -0,0 +1,26 @@
{
"topic": "Low-Frequency Trading Bot",
"pageNumber": "1",
"type": "Trading Bots in Superalgos",
"definition": {
"text": "A trading bot leverages the Superalgos infrastructure to provide users with advanced trading features.",
"updated": 1610217988042
},
"paragraphs": [
{
"style": "Include",
"text": "Superalgos->Node->Trading Bot->Definition",
"updated": 1610218014743
},
{
"style": "Include",
"text": "Superalgos->Node->Trading Bot->Content",
"updated": 1610218017545
},
{
"style": "Callout",
"text": "The Low-Frequency trading bot is the one and only Trading Bot shipping with Superalgos at this point in time. It is made available by the Masters Trading Mine. The bot is a robust implementation that leverages every piece of infrastructure provided by Superalgos to provide a feature-rich automated trading assistant.",
"updated": 1610218505400
}
]
}
@@ -0,0 +1,47 @@
{
"topic": "Low-Frequency Trading Bot",
"pageNumber": "2",
"type": "Why Low-Frequency",
"definition": {
"text": "The first Trading Bot implementation is optimized for low-frequency trading.",
"updated": 1610218584729
},
"paragraphs": [
{
"style": "Text",
"text": "The Low-Frequency trading bot makes decisions upon the closing of the current candle.",
"updated": 1610218597361
},
{
"style": "Important",
"text": "No matter what property of what indicator you may use, always remember that the trading bot works with the last closed candle by default. What Superalgos refers to as the current candle is effectively the latest closed candle. The trading bot never works with the candle that hasn’t yet closed, as its parameters are not defined. For example, candle.max refers to the maximum price of the last closed candle, and bollingerBand.movingAverage refers to the moving average of the last closed candle.",
"updated": 1610218610371
},
{
"style": "Text",
"text": "Superalgos manages time frames as low as one minute. That is, one minute, is the highest frequency handled by the trading bot."
},
{
"style": "Text",
"text": "When a trading session is run on the 01-min time frame, this is what you should expect to happen in terms of the time it takes to do all the required processing for the trading bot to make a decision and place an order at the exchange:"
},
{
"style": "Table",
"text": "| Process | Estimated Time [s] | Comments |\n| Sensor bot | 0 - 65 | The sensor bot runs (by default) every 60 seconds. Upon each execution, anything between 0 to 60 seconds may have passed since the last one-minute candle closed. On top of this the sensor execution time may range from 1 to 5 seconds, depending on several factors (i.e.: your hardware, internet bandwidth, distance to the exchange, exchange response time, and so on...) |\n| Candles - Volumes indicator | 1 - 5 | This indicator is required most of the time, as it is the one processing the one-minute candles extracted from the exchange to turn it into candles for the rest of the time frames available. In this case, the processing time depends entirely on your hardware. | \n| Other indicators | 1 - 5 | Indicators that depend exclusively on the data products produced by Candles - Volumes may process their products as soon as Candles - Volumes finishes. Indicators with nested dependencies need to wait for their dependencies to finish, thus they are not processed in parallel but in series. |\n| Trading bot | 1 - 5 | Depending on the complexity of your trading system, the number of dependencies that must be loaded, your hardware, and the same connectivity considerations discussed for the sensor bot, the trading bot may take several seconds to do the processing and place the order at the exchange. |",
"updated": 1610219071449
},
{
"style": "Callout",
"text": "In conclusion, depending on how many indicators the trading system uses, and what the dependencies may be, you should expect anything between 15 to 75 seconds or more of lag from the instant the candle closed at the exchange until the order is placed, with the default settings.",
"updated": 1610219109819
},
{
"style": "Text",
"text": ""
},
{
"style": "Text",
"text": ""
}
]
}
@@ -0,0 +1,50 @@
{
"topic": "Order Management",
"pageNumber": "1",
"type": "Overview of the Management Issue",
"definition": {
"text": "The Low-Frequency trading bot manages live orders, produces a simulation that is synchronized with the events occurring at the exchange, and does the accounting to keep all trading information in order.",
"updated": 1610219490073
},
"paragraphs": [
{
"style": "Text",
"text": "The management of orders is at the heart of the Low-Frequency trading bot’s competency.",
"updated": 1610219504082
},
{
"style": "Text",
"text": "The process has some intricacies, as it involves handling orders at the exchange as well as producing a simulation. The system must be synchronized with what happens at the exchange so that the on-screen monitoring of the trading session, the accounts, and all trading information reflects reality."
},
{
"style": "Callout",
"text": "Understanding how the trading bot manages orders will help you make the most out of Superalgos. This knowledge will allow you to transcend simple trading system setups, and stretch the limits of what you may do with more elaborate or unusual definitions."
},
{
"style": "Text",
"text": "The following pages feature a chronological description of the life of an order, from the moment in which the trading system definitions of orders are read, until the accounting is done."
},
{
"style": "Text",
"text": "Once an order is created, it is maintained on each execution of the trading bot. At this point, the bot handles two parallel jobs:"
},
{
"style": "List",
"text": "In the case of forward testing and live trading sessions, the maintenance of orders involves dealing with the exchange and live orders."
},
{
"style": "List",
"text": "In the case of backtesting and paper trading sessions, the bot simulates those interactions, while dealing with simulated orders."
},
{
"style": "Important",
"text": "This whole section assumes that you are familiar with trading systems. Make sure you read about them first in case you are not.",
"updated": 1610219545354
},
{
"style": "Success",
"text": "The rest of the pages in this section are a detailed, step-by-step account of the actions the Low-Frequency trading bot performs while dealing with orders. You would make the most out of this content if you read the whole sequence of pages in the proposed order.",
"updated": 1610219534393
}
]
}
@@ -0,0 +1,100 @@
{
"topic": "Order Management",
"pageNumber": "2",
"type": "Reviewing Defined Orders",
"definition": {
"text": "The trading bot checks all existing orders upon each execution to determine what needs to be done with each of them.",
"updated": 1610219637945
},
"paragraphs": [
{
"style": "Text",
"text": "Each order has a create order event, and limit orders may have a cancel order event. This means that orders may be created and, in the case of limit orders, canceled.",
"updated": 1610219649118
},
{
"style": "Text",
"text": "For each order defined, the bot performs multiple checks which may result in different actions. Two particular cases are analyzed separately: when the order is Not Open and when the order is Open."
},
{
"style": "Title",
"text": "The Order is Not Open",
"updated": 1610219666758
},
{
"style": "Javascript",
"text": "(tradingEngineOrder.status.value === 'Not Open')"
},
{
"style": "Text",
"text": "If the order is Not Open it means that it may need to be created. However, a few checks are in order."
},
{
"style": "List",
"text": "Orders are not created in the first Cycle.",
"updated": 1610219707546
},
{
"style": "Javascript",
"text": "(tradingEngine.current.episode.cycle.value === 'First')"
},
{
"style": "List",
"text": "Orders are not created when the stage is closing."
},
{
"style": "Javascript",
"text": "(tradingEngineStage.status.value === 'Closing')"
},
{
"style": "List",
"text": "For order definitions that do not allow spawning multiple orders, orders are not created when the lock is closed."
},
{
"style": "Javascript",
"text": "(tradingEngineOrder.lock.value === 'Closed')"
},
{
"style": "Text",
"text": "If previous checks pass and one of the situations in the create order event validates true, then the order is created (see Opening Orders).",
"updated": 1610219773322
},
{
"style": "Title",
"text": "The Order is Open",
"updated": 1610219785473
},
{
"style": "Javascript",
"text": "(tradingEngineOrder.status.value === 'Open')"
},
{
"style": "Text",
"text": "If the order is Open and it is a limit order, it may need to be canceled (market orders may not be canceled as they are supposed to fill almost instantaneously). Also, several other system actions may be required. A few checks are in order."
},
{
"style": "List",
"text": "Orders are not canceled in the second cycle, only the first."
},
{
"style": "Javascript",
"text": "(tradingEngine.current.episode.cycle.value === 'Second')"
},
{
"style": "List",
"text": "If it’s a forward testing or live trading session, the events that take place at the exchange must be checked (see Checking exchange events). If the checking of the events at the exchange fails for whatever reason, the order may not be canceled and will need to wait for the next execution."
},
{
"style": "List",
"text": "If it’s a backtesting or paper trading session, the events that take place at the exchange must be simulated (see Simulating check of events)."
},
{
"style": "Text",
"text": "If previous checks pass and one of the situations in the cancel order event validates true, then the order is canceled (see Canceling orders). If the order is indeed closed, the order is cloned to update the corresponding data structure of the tradingEngine.last node."
},
{
"style": "Text",
"text": ""
}
]
}
@@ -0,0 +1,227 @@
{
"topic": "Order Management",
"pageNumber": "3",
"type": "Opening Orders",
"definition": {
"text": "Several calculations and validations are required before creating and placing an order.",
"updated": 1610219973766
},
"paragraphs": [
{
"style": "Text",
"text": "Before creating an order, a few calculations to determine what the order should look like are required, in particular about the rate of the order (see Calculate Order Rate) and the size of the order (see Calculate Order Size).",
"updated": 1610219986275
},
{
"style": "Text",
"text": "Once the calculations are done, some validations are in order."
},
{
"style": "Text",
"text": "The size of an order may not be negative."
},
{
"style": "Javascript",
"text": "(tradingEngineOrder.orderBaseAsset.size.value <= 0)\n(tradingEngineOrder.orderQuotedAsset.size.value <= 0)",
"updated": 1610220014592
},
{
"style": "Callout",
"text": "If previous checks pass and it is a forward testing or live trading session, the order is placed at the exchange. If it is a backtesting or paper trading session, the order exists in the data structure of the trading engine only."
},
{
"style": "Text",
"text": "If the order is placed successfully, then all related data structures in the trading engine are updated accordingly, including size placed for the stage in both assets, episode counters, and the particular order’s details."
},
{
"style": "Title",
"text": "Calculate Order Rate"
},
{
"style": "Text",
"text": "The first thing to consider to determine the rate of the order is whether it is a limit or a market order."
},
{
"style": "Text",
"text": "Limit orders must have a proper definition of the order rate. That is, the order rate node must have a formula that results in a number, and that is greater than zero. If all validations pass, the order rate is stored in tradingEngineOrder.rate.value."
},
{
"style": "Text",
"text": "For market orders, there is no definition of the rate, as the rate is whatever rate the order fills at the exchange. The initial value is therefore the last known market rate, that is, the rate of the last closed candle: ",
"updated": 1610220046300
},
{
"style": "Javascript",
"text": "tradingEngineOrder.rate.value = tradingEngine.current.episode.candle.close.value",
"updated": 1610220056132
},
{
"style": "Title",
"text": "Calculate Order Size"
},
{
"style": "Text",
"text": "The calculation of the size of the order is a bit more elaborate, as several things must be taken into account, with the added intricacy that the user may define the target size for the stage in the base asset or the quoted asset."
},
{
"style": "Text",
"text": "The three main steps to define the size are the following:"
},
{
"style": "List",
"text": "To start with, the definitions regarding the size of the order must be valid (see Required Configuration Validation)."
},
{
"style": "List",
"text": "Then, the size of the order added to the rest of the orders that may have been placed before must not be greater than the target size for the stage (see Not Passing Target Size Validation)."
},
{
"style": "List",
"text": "Finally, the size of the order must not leave any of the assets in the trading engine’s built-in accounting system with a negative balance (see Not Negative Balance Validation)."
},
{
"style": "Subtitle",
"text": "Required Configuration Validation"
},
{
"style": "Text",
"text": "Beyond the target size for the stage, the user produces two more definitions that affect what the order size should be for the particular order: at the level of the execution algorithm’s configuration (percentageOfStageTargetSize parameter) and the level of the order’s configuration (percentageOfAlgorithmSize parameter). Both of these definitions must be valid and numeric."
},
{
"style": "Text",
"text": "Once the corresponding checks pass, the size of the algorithm is determined as per the definitions:"
},
{
"style": "Javascript",
"text": "algorithmSizeInBaseAsset =\ntradingEngineStage.stageBaseAsset.targetSize.value *\nexecutionAlgorithm.config.percentageOfStageTargetSize / 100",
"updated": 1610220102815
},
{
"style": "Text",
"text": "… and…"
},
{
"style": "Javascript",
"text": "algorithmSizeInQuotedAsset = \ntradingEngineStage.stageQuotedAsset.targetSize.value *\nexecutionAlgorithm.config.percentageOfStageTargetSize / 100",
"updated": 1610220138568
},
{
"style": "Note",
"text": "Notice that it is assumed that the target size for the stage is defined both in base asset and the quoted asset. This is because, although the user defines the target size in one asset only, the system converts the definition to the other asset (at an earlier moment), to keep track of accounts on both assets at all times, which is a design requirement.",
"updated": 1610220163303
},
{
"style": "Title",
"text": "Not Passing Target Size Validation"
},
{
"style": "Text",
"text": "This validation requires handling two possible scenarios separately. Did the user define the target size for the stage in base asset or the quoted asset?"
},
{
"style": "Note",
"text": "The system discriminates both scenarios to remain faithful to the intent of the definitions. This is a design feature throughout the system, and it is at the core of allowing maximum flexibility, so that users may use trading systems in various ways to achieve different goals.",
"updated": 1610220186307
},
{
"style": "Subtitle",
"text": "Stage size defined in base asset"
},
{
"style": "Text",
"text": "If the stage size was defined in base asset, then the size of the order derives from the definitions that where validated in the previous step (see Required Configuration Validation):"
},
{
"style": "Javascript",
"text": "tradingEngineOrder.orderBaseAsset.size.value =\nalgorithmSizeInBaseAsset *\ntradingSystemOrder.config.percentageOfAlgorithmSize / 100",
"updated": 1610220217663
},
{
"style": "Text",
"text": "With the above value, the validation is run to determine if the combined sizes of all orders placed up to this point would be larger than the size defined for the stage. Remember that the size defined for the stage is enforced as a cap. If the defined order size does exceed the stage size limit, then the size is lowered to fit the limit. The re-sizing goes out with a warning, to let the user know why the resizing took place."
},
{
"style": "Text",
"text": "Once the order size in base asset is final, then the size in quoted asset may be determined multiplying the size in base asset by the order rate determined earlier:"
},
{
"style": "Javascript",
"text": "tradingEngineOrder.orderQuotedAsset.size.value =\ntradingEngineOrder.orderBaseAsset.size.value *\ntradingEngineOrder.rate.value",
"updated": 1610220243415
},
{
"style": "Subtitle",
"text": "Stage size defined in quoted asset"
},
{
"style": "Text",
"text": "Similarly, in this case the size of the order in quoted asset derives directly from the definitions:"
},
{
"style": "Javascript",
"text": "tradingEngineOrder.orderQuotedAsset.size.value =\nalgorithmSizeInQuotedAsset *\ntradingSystemOrder.config.percentageOfAlgorithmSize / 100",
"updated": 1610220273076
},
{
"style": "Text",
"text": "The same validation is run as with the base asset, and the size of the order in base asset is also determined at the end:"
},
{
"style": "Javascript",
"text": "tradingEngineOrder.orderBaseAsset.size.value =\ntradingEngineOrder.orderQuotedAsset.size.value /\ntradingEngineOrder.rate.value",
"updated": 1610220292334
},
{
"style": "Title",
"text": "Not Negative Balance Validation"
},
{
"style": "Text",
"text": "The final validation is there to make sure that no balances become negative if the order is created with the currently defined size."
},
{
"style": "Subtitle",
"text": "Buy orders"
},
{
"style": "Text",
"text": "For buy orders (both market and limit), the quoted asset balance minus the order size must be equal to or greater than zero."
},
{
"style": "Javascript",
"text": "tradingEngine.current.episode.episodeQuotedAsset.balance.value -\ntradingEngineOrder.orderQuotedAsset.size.value => 0",
"updated": 1610220335526
},
{
"style": "Text",
"text": "If not, the size of the order is redefined to fit the available balance. The resizing goes out with a warning."
},
{
"style": "Javascript",
"text": "tradingEngineOrder.orderQuotedAsset.size.value =\ntradingEngine.current.episode.episodeQuotedAsset.balance.value",
"updated": 1610220358264
},
{
"style": "Text",
"text": "And, remember, every time a property changes for one asset, the same property for the other asset must be updated as well:"
},
{
"style": "Javascript",
"text": "tradingEngineOrder.orderBaseAsset.size.value =\ntradingEngineOrder.orderQuotedAsset.size.value /\ntradingEngineOrder.rate.value",
"updated": 1610220378073
},
{
"style": "Subtitle",
"text": "Sell orders"
},
{
"style": "Text",
"text": "For market and limit sell orders, the validation is reversed, checking the balance of the base asset instead of the quoted asset."
},
{
"style": "Note",
"text": "Remember that a sell order always exchanges the base asset for the quoted asset and a buy order does the opposite.",
"updated": 1610220400837
}
]
}
@@ -0,0 +1,37 @@
{
"topic": "Order Management",
"pageNumber": "4",
"type": "Maintaining Live Orders",
"definition": {
"text": "Orders at the exchange are monitored on every execution to discover the size filled, rates, and other exchange events. Also, the trading bot synchronizes Superalgos with the real transactional information handled by the exchange.",
"updated": 1610220454133
},
"paragraphs": [
{
"style": "Text",
"text": "As hinted in the Overview of the Management Issue page, there are two different paths for maintaining orders. The pages in this section describe the maintenance of real orders sent to the exchange, as opposed to simulated orders that live within Superalgos only.",
"updated": 1610220513296
},
{
"style": "Text",
"text": "The maintenance of orders involves a series of tasks that deal with three main concerns:"
},
{
"style": "List",
"text": "Checking the orders at the exchange, mainly to find out whether they have been filled or not, what size of the order was filled, and at what rate. We also need to know if the order has been arbitrarily canceled, either by the user or the exchange itself."
},
{
"style": "List",
"text": "Synchronizing the information existing in Superalgos with the actual happenings at the exchange. The original information Superalgos has about orders derive from definitions, but what happens at the exchange is what truly matters."
},
{
"style": "List",
"text": "Cancelling orders whenever the trading system’s definitions indicate so."
},
{
"style": "Success",
"text": "It is highly recommended to read these pages and compare with the simulated version of order maintenance. The comparison will greatly help you understand the differences between backtesting or paper trading and live trading sessions.",
"updated": 1610220471695
}
]
}
@@ -0,0 +1,163 @@
{
"topic": "Order Management",
"pageNumber": "5",
"type": "Checking Exchange Events",
"definition": {
"text": "The trading bot monitors exchange orders to check their status analyzing multiple possible scenarios.",
"updated": 1610220643629
},
"paragraphs": [
{
"style": "Text",
"text": "For forward testing and live trading sessions, the state of orders at the exchange is checked on every execution of the trading bot.",
"updated": 1610220673347
},
{
"style": "Text",
"text": "It’s important to note that, when an order is placed, no relevant information is obtained from the exchange other than a confirmation that the order was received. The trading bot must ask the exchange for the status of the order some time after placing it."
},
{
"style": "Note",
"text": "The trading bot places the order during the second execution cycle and asks the exchange about the order in the next run of the bot, during the first execution cycle. This means that the order is checked one unit of the trading session’s time frame after the order is placed. For example, if the session is running on the 01-min time frame, the order is checked roughly one minute after it is placed.",
"updated": 1610220684415
},
{
"style": "Text",
"text": "When the trading bot fetches an order from the exchange, it gets the order information in a text message. What does the trading bot obtain from the exchange?"
},
{
"style": "Text",
"text": "This is an important question, as the answer conditions what the trading bot may or may not do with each order, and how it may keep a reliable internal accounting system."
},
{
"style": "Title",
"text": "Orders According to the Exchange",
"updated": 1610220706175
},
{
"style": "Text",
"text": "What follows are several examples including a market sell order, a market buy order, a limit sell order, and a limit buy order, all of them in the BTC/USDT market in Binance."
},
{
"style": "Note",
"text": "Notice that the body section is provided by the CCXT library, and is the same for all exchanges; the info section is provided by the exchange itself, and may vary across exchanges.",
"updated": 1610220717780
},
{
"style": "Subtitle",
"text": "Market sell order for 0.1 BTC",
"updated": 1610220735916
},
{
"style": "Json",
"text": "Body: \naverage:12930.92\nclientOrderId:\"eLAkNrEoMw3erEp8AeaiTT\"\ncost:1293.24717104\ndatetime:\"2020-10-24T08:47:43.104Z\"\nfee:undefined\nfilled:0.100012\nid:\"3420506109\"\nlastTradeTimestamp:undefined\nprice:12930.92\nremaining:0\nside:\"sell\"\nstatus:\"closed\"\nsymbol:\"BTC/USDT\"\ntimestamp:1603529263104\ntrades:undefined\ntype:\"market\"\n\nInfo: \norderId:3420506109\norderListId:-1\norigQty:\"0.10001200\"\norigQuoteOrderQty:\"1293.25000000\"\nprice:\"0.00000000\"\nside:\"SELL\"\nstatus:\"FILLED\"\nstopPrice:\"0.00000000\"\nsymbol:\"BTCUSDT\"\ntime:1603529263104\ntimeInForce:\"GTC\"\ntype:\"MARKET\"\nupdateTime:1603529263104",
"updated": 1610220759201
},
{
"style": "Subtitle",
"text": "Limit sell order for 0.1 BTC",
"updated": 1610220791496
},
{
"style": "Json",
"text": "Body: \namount:0.1\naverage:12976.74\nclientOrderId:\"iZbiUF9W1WiKmtMfhA8hIr\"\ncost:1297.674\ndatetime:\"2020-10-24T10:43:47.944Z\"\nfee:undefined\nfilled:0.1\nid:\"3420762036\"\nlastTradeTimestamp:undefined\nprice:12969.83\nremaining:0\nside:\"sell\"\nstatus:\"closed\"\nsymbol:\"BTC/USDT\"\ntimestamp:1603536227944\ntrades:undefined\ntype:\"limit\"\n\nInfo: \nexecutedQty:\"0.10000000\"\nicebergQty:\"0.00000000\"\nisWorking:true\norderId:3420762036\norderListId:-1\norigQty:\"0.10000000\"\norigQuoteOrderQty:\"0.00000000\"\nprice:\"12969.83000000\"\nside:\"SELL\"\nstatus:\"FILLED\"\nstopPrice:\"0.00000000\"\nsymbol:\"BTCUSDT\"\ntime:1603536227944\ntimeInForce:\"GTC\"\ntype:\"LIMIT\"\nupdateTime:1603536227944",
"updated": 1610220811097
},
{
"style": "Title",
"text": "Status checks",
"updated": 1610220854490
},
{
"style": "Text",
"text": "Once the status of the order is received as in one of the above examples, the trading bot performs multiple checks, each leading to particular actions. The following are the particular cases analyzed and the actions taken."
},
{
"style": "Subtitle",
"text": "Filled and closed"
},
{
"style": "Text",
"text": "If the order is filled and closed, the corresponding data structures in the trading engine are updated to indicate so."
},
{
"style": "Javascript",
"text": "tradingEngineOrder.status.value = 'Closed'\ntradingEngineOrder.exitType.value = 'Filled'",
"updated": 1610220873457
},
{
"style": "Text",
"text": "But, most importantly, the details in the order are processed to synchronize the information in the trading engine—at this point consisting mostly of information derived from the definitions in the trading system—with the information obtained from the exchange."
},
{
"style": "Text",
"text": "The data structures to be updated are mostly those related to the actual rate at which the order was filled, the actual size that was filled, the actual fees that were charged, and how those variables affect balances and the overall accounts in various contexts (order, stage, position, episode, etc.)."
},
{
"style": "Note",
"text": "Notice that definitions in the trading system are—in a way—just a plan. Your definitions tell the trading bot what to do, but there is no certainty on the outcome. That is the reason why the first set of accounts recorded with information derived from the trading system needs to be synchronized in every execution cycle with what actually happened at the exchange until the order is closed.",
"updated": 1610220886259
},
{
"style": "Text",
"text": "The calculations involved in the synchronization process are covered in Syncing With the Exchange.",
"updated": 1610221145905
},
{
"style": "Subtitle",
"text": "Partially filled and closed"
},
{
"style": "Text",
"text": "If the order is partially filled and closed, the corresponding data structures in the trading engine are updated to indicate so."
},
{
"style": "Javascript",
"text": "tradingEngineOrder.status.value = 'Closed'\ntradingEngineOrder.exitType.value = 'Closed at the Exchange'",
"updated": 1610220905601
},
{
"style": "Text",
"text": "For a limit order to be closed while partially filled, it must be closed manually by the user directly at the exchange, or forcefully closed by the exchange itself, for whatever reason. The system handles such occurrences so that they do not disrupt the trading session or the accounts at Superalgos."
},
{
"style": "Text",
"text": "The first thing to do with such an order is to update the size placed on the stage so that the stage accounts for the amount that was filled only, instead of the original size of the order (see Accounting)."
},
{
"style": "Text",
"text": "And then, the same synchronization process described earlier must be applied as well (see Syncing With the Exchange).",
"updated": 1610221158590
},
{
"style": "Subtitle",
"text": "Cancelled"
},
{
"style": "Text",
"text": "These are limit orders canceled by the trading bot upon the triggering of the cancel order event. In such cases, the exit type is set as follows:"
},
{
"style": "Javascript",
"text": "tradingEngineOrder.exitType.value = 'Cancelled at the Exchange'"
},
{
"style": "Text",
"text": "Canceled orders go through the same processes of synchronization (see Syncing With the Exchange) and the recalculation of the size of the stage (see Accounting).",
"updated": 1610221173299
},
{
"style": "Subtitle",
"text": "All other instances"
},
{
"style": "Text",
"text": "The cases described above refer to orders with particular characteristics. Orders that do not match any of the above criteria trigger the synchronization process described earlier (see Syncing With the Exchange).",
"updated": 1610221181661
},
{
"style": "Text",
"text": ""
}
]
}
@@ -0,0 +1,303 @@
{
"topic": "Order Management",
"pageNumber": "6",
"type": "Syncing With the Exchange",
"definition": {
"text": "Syncing with the exchange involves calculating the actual size, the actual rate, the percentage filled, the fees paid, and the size filled, to update the trading engine data structure so that it matches with the actual situation of the order at the exchange.",
"updated": 1610221056957
},
"paragraphs": [
{
"style": "Text",
"text": "The process of synchronizing the data in the trading engine with what actually happens at the exchange is crucial to monitoring and controlling a live trading operation from within Superalgos. It is this process that allows users to access the information at the exchange throughout the life cycle of each order, on the fly.",
"updated": 1610221245028
},
{
"style": "Text",
"text": "This is when all calculations involving the actual size, actual rate, actual fees, and so on are made. We will closely look into each of the calculations."
},
{
"style": "Text",
"text": "Once the synchronization is done, the bot does the accounting (see Accounting), to keep the rest of the variables—like balances and the stage size—up to date with the reality of orders."
},
{
"style": "Title",
"text": "Actual Size Calculation"
},
{
"style": "Text",
"text": "While users may define the target size of the stage in either the base asset or the quoted asset, the size of orders is always denominated in the base asset, as per the CCXT Library API, and—likely—most exchange’s APIs."
},
{
"style": "Note",
"text": "It is a common occurrence that exchanges change the size slightly, for whatever reason, including issues with the precision of decimal places, for example. This is why the size of the order as defined by the user may need to be updated, synchronizing it with the actual size determined by the exchange.",
"updated": 1610221270715
},
{
"style": "Text",
"text": "When the actual size of the order as reported by the exchange is different than the size defined by the user, the trading bot makes the adjustments described below."
},
{
"style": "Subtitle",
"text": "Recalculate Actual Size"
},
{
"style": "Text",
"text": "The actual size of the base asset is updated with the size reported by the exchange:"
},
{
"style": "Javascript",
"text": "tradingEngineOrder.orderBaseAsset.actualSize.value = order.amount"
},
{
"style": "Text",
"text": "Then it’s time to calculate the actual size in the quoted asset. At this stage, the actual rate of the order hasn’t been established yet, so the existing rate is used temporarily."
},
{
"style": "Javascript",
"text": "tradingEngineOrder.orderQuotedAsset.actualSize.value =\ntradingEngineOrder.orderBaseAsset.actualSize.value *\ntradingEngineOrder.rate.value",
"updated": 1610221293179
},
{
"style": "Subtitle",
"text": "Recalculate Size Placed"
},
{
"style": "Text",
"text": "The open stage and close stage sections of the trading engine hierarchy keep track of the accumulated size of the orders that have been placed so that the stage size may be compared to the target size defined in the trading system."
},
{
"style": "Note",
"text": "Remember that the target size defined acts as a size cap, thus, the system must not place orders in excess of the defined target size.",
"updated": 1610221313060
},
{
"style": "Text",
"text": "If the size of the order as determined by the exchange is different from the original size of the order, the current stage size must be recalculated."
},
{
"style": "Text",
"text": "What the trading bot does in this case is subtracting the original size from the stage size placed, and then add the actual size, as obtained from the exchange. As usual, this is done both for the base asset and the quoted asset."
},
{
"style": "Text",
"text": "For clarity, each operation is done in two steps."
},
{
"style": "Javascript",
"text": "tradingEngineStage.stageBaseAsset.sizePlaced.value =\ntradingEngineStage.stageBaseAsset.sizePlaced.value -\ntradingEngineOrder.orderBaseAsset.size.value\n\ntradingEngineStage.stageBaseAsset.sizePlaced.value =\ntradingEngineStage.stageBaseAsset.sizePlaced.value +\ntradingEngineOrder.orderBaseAsset.actualSize.value\n\ntradingEngineStage.stageQuotedAsset.sizePlaced.value =\ntradingEngineStage.stageQuotedAsset.sizePlaced.value -\ntradingEngineOrder.orderQuotedAsset.size.value\n\ntradingEngineStage.stageQuotedAsset.sizePlaced.value =\ntradingEngineStage.stageQuotedAsset.sizePlaced.value +\ntradingEngineOrder.orderQuotedAsset.actualSize.value",
"updated": 1610221350195
},
{
"style": "Title",
"text": "Actual Rate Calculation"
},
{
"style": "Text",
"text": "Market orders are placed without a definition in terms of the rate they will be executed at, as, by definition, a market rate is filled at whatever rate the order book allows.",
"updated": 1610221400343
},
{
"style": "Text",
"text": "In the case of limit orders—although the user defines a rate—the exchange may change it slightly, for multiple reasons. For example, due to issues related to decimals precision, or because the order may match existing orders in the order book with a better rate."
},
{
"style": "Text",
"text": "For those reasons, the trading bot gets the actual rate from the exchange and —in case it differs from the defined rate—makes the updates described below."
},
{
"style": "Text",
"text": "First of all, the actual rate under the order statistics node is updated with the actual rate provided by the exchange:"
},
{
"style": "Javascript",
"text": "tradingEngineOrder.orderStatistics.actualRate.value = order.price"
},
{
"style": "Text",
"text": "If the actual rate is the same as the rate of the order as originally defined, then that’s all. Otherwise, the bot goes back and recalculates the size of the order for the quoted asset and the size placed in the quoted asset for the corresponding stage—again."
},
{
"style": "Callout",
"text": "Let’s do a little recap in case the above is not crystal clear. When the order size in the quoted asset was calculated earlier, the calculation was made by multiplying the actual size in the base asset as reported by the exchange, by the rate as was originally defined. However, if the rate used earlier is not the actual rate at which the order was filled at the exchange, the trading bot needs to go back and calculate the size in the quoted asset again. The same goes for the size placed in the quoted asset."
},
{
"style": "Text",
"text": "Both calculations are virtually the same as described earlier, so we are not going to go over the details again. Suffice to say that the only difference is that the actual rate is used instead of the original rate as defined in the trading system."
},
{
"style": "Text",
"text": "And remember, the size in the base asset does not need to be recalculated, as it is not affected by the differences in rates."
},
{
"style": "Title",
"text": "Percentage Filled Calculation"
},
{
"style": "Text",
"text": "This is a simple calculation to determine what percentage of the order has been filled, which is relevant later on to calculate fees and balances:"
},
{
"style": "Javascript",
"text": "tradingEngineOrder.orderStatistics.percentageFilled.value = \norder.filled * 100 / \ntradingEngineOrder.orderBaseAsset.actualSize.value",
"updated": 1610221437484
},
{
"style": "Note",
"text": "As you can see, the actual size in the base asset is used, as the size is always denominated in the base asset according to the exchange.",
"updated": 1610221445535
},
{
"style": "Title",
"text": "Fees Paid Calculation"
},
{
"style": "Text",
"text": "Exchange fees are a crucial aspect of trading, as they may greatly affect the profitability of strategies."
},
{
"style": "Callout",
"text": "Surprisingly, the exchange does not explicitly report how much is charged in fees on each order. This apparent contradiction must be resolved by Superalgos, so let’s dive into the details."
},
{
"style": "Text",
"text": "There are a few fundamental workings that affect the calculations:"
},
{
"style": "Text",
"text": "The fees are not explicitly reported by the exchange, hence the need to calculate them."
},
{
"style": "Important",
"text": "To calculate fees, the user bears the ultimate responsibility in supplying the trading bot with the correct parameters defined in the fee structure session parameters. It is these values of maker and taker fees that the system uses to calculate fees. If the parameters are wrong, the calculated fees will be wrong as well.",
"updated": 1610221483105
},
{
"style": "Text",
"text": "The taker fee parameter is used to calculate the fees on market orders, while the maker fee parameter is used to calculate fees for limit orders."
},
{
"style": "Text",
"text": "The exchange charges fees denominated in the asset that the user is acquiring in the transaction. For example, in the BTC/USDT market, a sell order exchanges BTC for USDT, and the exchange charges fees in USDT, because that is the asset you are acquiring. On the contrary, a buy order in the BTC/USDT market exchanges USDT for BTC, thus fees are charged in BTC."
},
{
"style": "Callout",
"text": "Properly calculating fees is crucial to keeping an accurate accounting system, as they directly affect balances. This is why: The actual size reported by the exchange is not representative of the actual amount of the asset acquired in the transaction. This is because the exchange fills the order, determines the size filled, and then subtracts the fees from the size filled. That is, the size filled reported by the exchange is greater than the amount you receive. In fact, the amount you receive is the actual size filled minus the fees. That calculation is the one used to estimate the balances for both assets in Superalgos so that they match the balances at the exchange."
},
{
"style": "Text",
"text": "Because orders (in particular limit orders) may be partially filled, the system uses the percentage filled calculated earlier to determine the fees to be paid for the portion filled, as the exchange charges fees for the amount filled only."
},
{
"style": "Text",
"text": "All of the above considerations are captured in the following calculations."
},
{
"style": "Subtitle",
"text": "Market buy orders"
},
{
"style": "Text",
"text": "Because you are acquiring the base asset, fees paid are calculated using the base asset actual size. Because it’s a market order, the taker fees parameter is used."
},
{
"style": "Javascript",
"text": "tradingEngineOrder.orderBaseAsset.feesPaid.value =\ntradingEngineOrder.orderBaseAsset.actualSize.value *\nsessionParameters.feeStructure.config.taker / 100 *\ntradingEngineOrder.orderStatistics.percentageFilled.value / 100",
"updated": 1610221512567
},
{
"style": "Subtitle",
"text": "Limit buy orders"
},
{
"style": "Text",
"text": "Like with market buy orders, because you are acquiring the base asset, fees paid are calculated using the base asset actual size. Because it’s a limit order, the maker fees parameter is used."
},
{
"style": "Javascript",
"text": "tradingEngineOrder.orderBaseAsset.feesPaid.value =\ntradingEngineOrder.orderBaseAsset.actualSize.value *\nsessionParameters.feeStructure.config.maker / 100 *\ntradingEngineOrder.orderStatistics.percentageFilled.value / 100",
"updated": 1610221532644
},
{
"style": "Subtitle",
"text": "Market sell orders"
},
{
"style": "Text",
"text": "Because you are acquiring the quoted asset, fees paid are calculated using the base asset actual size. Because it’s a market order, the taker fees parameter is used."
},
{
"style": "Javascript",
"text": "tradingEngineOrder.orderQuotedAsset.feesPaid.value =\ntradingEngineOrder.orderQuotedAsset.actualSize.value *\nsessionParameters.feeStructure.config.taker / 100 *\ntradingEngineOrder.orderStatistics.percentageFilled.value / 100",
"updated": 1610221581263
},
{
"style": "Subtitle",
"text": "Limit sell orders"
},
{
"style": "Text",
"text": "Like with market sell orders, because you are acquiring the quoted asset, fees paid are calculated using the quoted asset actual size. Because it’s a limit order, the maker fees parameter is used."
},
{
"style": "Javascript",
"text": "tradingEngineOrder.orderQuotedAsset.feesPaid.value =\ntradingEngineOrder.orderQuotedAsset.actualSize.value *\nsessionParameters.feeStructure.config.maker / 100 *\ntradingEngineOrder.orderStatistics.percentageFilled.value / 100",
"updated": 1610221607990
},
{
"style": "Title",
"text": "Size Filled Calculation"
},
{
"style": "Text",
"text": "As mentioned earlier, and as may be inferred from the example orders presented earlier, the size filled is always reported by the exchange denominated in the base asset. That is:"
},
{
"style": "Javascript",
"text": "tradingEngineOrder.orderBaseAsset.sizeFilled.value = order.filled"
},
{
"style": "Text",
"text": "Therefore, the trading bot needs to calculate the size filled in the quoted asset:"
},
{
"style": "Javascript",
"text": "tradingEngineOrder.orderQuotedAsset.sizeFilled.value =\ntradingEngineOrder.orderQuotedAsset.actualSize.value *\ntradingEngineOrder.orderStatistics.percentageFilled.value / 100",
"updated": 1610221632885
},
{
"style": "Title",
"text": "Amount Received Calculation"
},
{
"style": "Text",
"text": "The amount received is a simple calculation to facilitate the comprehension of the trade, given that the exchange does not provide that basic information. Remember that only the size filled is reported and that fees are subtracted from the size filled."
},
{
"style": "Subtitle",
"text": "Market and limit buy orders"
},
{
"style": "Text",
"text": "In these cases, the user receives the amount in the base asset."
},
{
"style": "Javascript",
"text": "tradingEngineOrder.orderBaseAsset.amountReceived.value =\ntradingEngineOrder.orderBaseAsset.sizeFilled.value -\ntradingEngineOrder.orderBaseAsset.feesPaid.value",
"updated": 1610221660430
},
{
"style": "Subtitle",
"text": "Market and limit sell orders"
},
{
"style": "Text",
"text": "In these cases, the user receives the amount in the quoted asset."
},
{
"style": "Javascript",
"text": "tradingEngineOrder.orderQuotedAsset.amountReceived.value =\ntradingEngineOrder.orderQuotedAsset.sizeFilled.value -\ntradingEngineOrder.orderQuotedAsset.feesPaid.value",
"updated": 1610221674345
}
]
}
@@ -0,0 +1,74 @@
{
"topic": "Order Management",
"pageNumber": "7",
"type": "Canceling Orders",
"definition": {
"text": "After running a few checks, if the Cancel Order Event is triggered, the order is canceled, the synchronization is run, and accounts are updated.",
"updated": 1610221990441
},
"paragraphs": [
{
"style": "Title",
"text": "Check Cancel Order Event",
"updated": 1610222003919
},
{
"style": "Text",
"text": "Before evaluating the cancel order event, a few checks are in order."
},
{
"style": "List",
"text": "Orders are not canceled if the stage is closing."
},
{
"style": "Javascript",
"text": "(tradingEngineStage.status.value === 'Closing')"
},
{
"style": "List",
"text": "Orders may only be canceled if the status is Open."
},
{
"style": "Javascript",
"text": "(tradingEngineOrder.status.value === 'Open')"
},
{
"style": "Text",
"text": "If both checks pass, then the cancel order event is evaluated. If a situation in the event is true, then the following actions take place:",
"updated": 1610222066264
},
{
"style": "List",
"text": "If it’s a backtesting or paper trading session, the order cancelation must be simulated (see Simulating Order Cancelation).",
"updated": 1610222051378
},
{
"style": "List",
"text": "If it’s a forward testing or live trading session, the order must be canceled at the exchange."
},
{
"style": "Title",
"text": "Canceling Orders"
},
{
"style": "Text",
"text": "When the cancel order event as defined in the trading system is triggered, the trading bot sends the cancel order request to the exchange, and waits for an answer. No further action is taken until the exchange confirms the order has been closed."
},
{
"style": "Text",
"text": "Once the confirmation is in, a new request to check the order is sent, so as to determine if the size filled for the order changed between the last time it was checked and the moment of the cancellation."
},
{
"style": "Text",
"text": "Once the trading bot gets the order details, it runs the synchronization (see Syncing with the exchange) and the recalculation of the stage size again (see Accounting), to make up and account for any differences that may exist compared to the last known state of the order"
},
{
"style": "Text",
"text": "The order is not closed until the order details are received from the exchange."
},
{
"style": "Javascript",
"text": "tradingEngineOrder.status.value = 'Closed'"
}
]
}
@@ -0,0 +1,41 @@
{
"topic": "Order Management",
"pageNumber": "8",
"type": "Maintaining Simulated Orders",
"definition": {
"text": "The maintenance of simulated orders follows the same kind of logic as the maintenance of real orders, using definitions in the trading session parameters and in the trading system to complete the required assumption",
"updated": 1610222218174
},
"paragraphs": [
{
"style": "Text",
"text": "The pages in this section describe how the trading bot simulates the maintenance of orders in the case of backtesting and paper trading sessions.",
"updated": 1610222228462
},
{
"style": "Success",
"text": "It is highly recommended that you read the Maintaining Live Orders section first, as the explanations on what is calculated and why are more extensive and detailed there.",
"updated": 1610222251113
},
{
"style": "Text",
"text": "When on backtesting or paper trading sessions, there is no exchange involved as orders are not actually placed, but live within the simulation only."
},
{
"style": "Text",
"text": "However, to make simulations as realistic and as accurate as possible, the system goes through a similar process as when it’s interacting with an exchange, performs similar checks, does similar calculations, and keeps similar accounts—while simulating the response from the exchange according to the definitions in the trading system."
},
{
"style": "Text",
"text": "The definitions that affect simulations directly are:"
},
{
"style": "List",
"text": "The slippage and fee structure parameters at the level of the trading session."
},
{
"style": "List",
"text": "The simulated exchange events at the level of the trading system, where a simulated partial fill, a simulated actual rate, and a simulated fees paid may be defined."
}
]
}
@@ -0,0 +1,34 @@
{
"topic": "Order Management",
"pageNumber": "9",
"type": "Simulating Check of Events",
"definition": {
"text": "Instead of checking what happened with the order at the exchange, the bot launches the synchronization simulation and updates the trading engine with the results of the calculations.",
"updated": 1610222347712
},
"paragraphs": [
{
"style": "Text",
"text": "The process is the same for all orders and involves a simulated synchronization with the exchange (see Simulating Sync With the Exchange), which performs all the checks and calculations, and updates the associated nodes in the trading engine hierarchy.",
"updated": 1610222491422
},
{
"style": "Text",
"text": "Once the simulated synchronization is done, the bot checks if the order was completely filled during the simulation... ",
"updated": 1610222413583
},
{
"style": "Javascript",
"text": "tradingEngineOrder.orderStatistics.percentageFilled.value === 100"
},
{
"style": "Text",
"text": "... and updates the corresponding trading engine nodes accordingly:"
},
{
"style": "Javascript",
"text": "tradingEngineOrder.status.value = 'Closed'\ntradingEngineOrder.exitType.value = 'Filled'",
"updated": 1610222428232
}
]
}
@@ -0,0 +1,431 @@
{
"topic": "Order Management",
"pageNumber": "10",
"type": "Simulating Sync With the Exchange",
"definition": {
"text": "The simulated synchronization with the exchange resembles the real synchronization in that it follows the same logic. The difference lies in that the data involved in calculations originates in user definitions instead of real-life orders.",
"updated": 1610222523595
},
"paragraphs": [
{
"style": "Text",
"text": "The simulation of the synchronization with the exchange looks to reproduce the logic of live trading for backtesting and paper trading sessions so that simulations follow similar mechanisms, and thus, maximize their capacity to predict what live trading with any given trading system may look like.",
"updated": 1610222800319
},
{
"style": "Text",
"text": "The obvious difference is that there is no exchange involved in the process, that is, no real-life data about the variables affecting orders such as the actual fill rates, or if orders are filled at all. Instead, all information is taken from user definitions (both from the trading system and session parameters) and market information."
},
{
"style": "Text",
"text": "There are two main levels of definitions that affect how orders are simulated."
},
{
"style": "Text",
"text": "The one level that takes precedence in all cases is the definitions made through the simulated exchange events section under each order defined in the trading system. These definitions affect each order, providing granular control over how each order should be simulated."
},
{
"style": "Text",
"text": "The second level of definitions affecting how simulations work is that of parameters at the level of the trading session. These parameters are used for all orders that do not have a specific definition in the form of simulated exchange events."
},
{
"style": "Text",
"text": "Like with the real synchronization process, once all calculations are done, the trading bot does the bookkeeping (see Accounting)."
},
{
"style": "Title",
"text": "Actual Size Simulation"
},
{
"style": "Text",
"text": "Minimal variations in the size of orders that may occur during live trading sessions are irrelevant to the production of proper simulations, thus, there is no need to simulate such things. Instead, the trading bot takes the defined sizes as valid and uses those as the actual size of the order."
},
{
"style": "Javascript",
"text": "tradingEngineOrder.orderBaseAsset.actualSize.value = \ntradingEngineOrder.orderBaseAsset.size.value\ntradingEngineOrder.orderQuotedAsset.actualSize.value = \ntradingEngineOrder.orderQuotedAsset.size.value",
"updated": 1610222816044
},
{
"style": "Title",
"text": "Actual Rate Simulation",
"updated": 1610222855123
},
{
"style": "Text",
"text": "The initial value for the rate of orders is the close of the last candle for market orders, that is, the last known market rate, and the value defined for the rate node in case of limit orders."
},
{
"style": "Javascript",
"text": "tradingEngineOrder.orderStatistics.actualRate.value = tradingEngineOrder.rate.value"
},
{
"style": "Text",
"text": "However, in real live trading situations, there are many factors out of the users’ control that may affect the actual rate of an order, especially for market orders. Properly simulating such issues is conducive to more realistic projections on the potential performance of strategies, thus, simulations should take such issues into account."
},
{
"style": "Text",
"text": "There are three steps involved in the simulation of the actual rate, and shall be analyzed separately:"
},
{
"style": "List",
"text": "Slippage simulation when there are definitions at the level of the trading system, that is, at the level of the simulated exchange events node (see Based On Trading System below)."
},
{
"style": "List",
"text": "Slippage simulation when there are no definitions at the level of the trading system; session parameters are used instead (see Based On Session Parameters below)."
},
{
"style": "List",
"text": "The last case has to do with verifying if the simulated actual rate defined in either of the two earlier steps makes sense in the context of the market (see Consider Best Match With Order Book below)."
},
{
"style": "Subtitle",
"text": "Based On Trading System"
},
{
"style": "Text",
"text": "If an actual rate is properly defined under simulated exchange events for the order in question, the value resulting from the formula is used as the actual rate."
},
{
"style": "Javascript",
"text": "tradingEngineOrder.orderStatistics.actualRate.value ===\ntradingEngineOrder.orderStatistics.actualRate.config.initialValue",
"updated": 1610222897750
},
{
"style": "Note",
"text": "Although limit orders tend to have little or no slippage, notice that the above is valid both for market orders and limit orders.",
"updated": 1610222907606
},
{
"style": "Subtitle",
"text": "Based On Session Parameters"
},
{
"style": "Text",
"text": "If a limit order does not have an actual rate defined under simulated exchange events, then the actual rate of a limit order is the defined initial rate, as the slippage session parameter does not apply to limit orders. That is, the value is left untouched."
},
{
"style": "Text",
"text": "However, if a market order does not have an actual rate defined under simulated exchange events, then the marketOrderRate parameter within the slippage session parameter is used to apply a slippage factor."
},
{
"style": "Javascript",
"text": "slippageAmount = tradingEngineOrder.rate.value *\nsessionParameters.slippage.config.marketOrderRate / 100",
"updated": 1610222939129
},
{
"style": "Important",
"text": "Slippage is applied so that it always goes against the interest of the trading system. For example, for a market sell order, the slippage amount is subtracted from the initial rate, therefore simulating that the rate is worse than ideal.",
"updated": 1610222950786
},
{
"style": "Javascript",
"text": "tradingEngineOrder.orderStatistics.actualRate.value =\ntradingEngineOrder.rate.value -\nslippageAmount",
"updated": 1610222960155
},
{
"style": "Text",
"text": "The opposite is true for market buy orders:"
},
{
"style": "Javascript",
"text": "tradingEngineOrder.orderStatistics.actualRate.value =\ntradingEngineOrder.rate.value +\nslippageAmount",
"updated": 1610222973506
},
{
"style": "Subtitle",
"text": "Consider Best Match With Order Book"
},
{
"style": "Text",
"text": "Let’s set up the context for a little piece of analysis required to understand this simulation criterion."
},
{
"style": "Text",
"text": "The exchange’s order book is populated with bids (buy orders) and asks (sell orders). In terms of rates, we could argue that buy orders sit below sell orders. When the rate of buy and sell orders converge, orders get filled."
},
{
"style": "Text",
"text": "Market buy orders are filled with the lowest rate possible sell orders in the book. Market sell orders are filled with the highest rate possible buy orders in the book."
},
{
"style": "Text",
"text": "Limit buy and sell orders have a defined rate. However, by definition, a limit order is an instruction to the exchange to fill the order at the specified price or better. The “or better” part of the instruction is the key to this analysis."
},
{
"style": "Text",
"text": "During the period of time represented in a candle, the range of rates between the maximum and minimum rates in the candle tells us that virtually all orders within those rates that were open upon the begin datetime of the candle must have been filled."
},
{
"style": "Callout",
"text": "Now, what happens if a buy order is placed at a rate higher than the maximum rate of the candle?"
},
{
"style": "Text",
"text": "In such a scenario, it is safe to make the following assumptions:"
},
{
"style": "List",
"text": "The order is filled, because there are plenty of sell orders at a cheaper rate."
},
{
"style": "List",
"text": "The order is filled at a lower rate than the one defined, for the same reasons (there are cheaper asks in the order book)."
},
{
"style": "Text",
"text": "The above is the consideration that drives this simulation criterion to estimate the actual rate of an order. However, what is not possible to pinpoint is the exact rate at which the order would be filled."
},
{
"style": "Callout",
"text": "With all this in mind, when a buy order’s actual rate—as calculated by the Based On Trading System or the Based On Session Parameters approaches—is higher than the maximum rate of the candle, the Consider Best Match With Order Book simulation corrects the actual rate and assigns it the maximum value of the candle."
},
{
"style": "Javascript",
"text": "tradingEngineOrder.orderStatistics.actualRate.value =\ntradingEngine.current.episode.candle.max.value",
"updated": 1610223027648
},
{
"style": "Text",
"text": "As a corollary, the following criteria govern this particular simulation:"
},
{
"style": "List",
"text": "On one hand, the simulation must mirror live trading as closely as possible. This is the reason for factoring in this analysis."
},
{
"style": "List",
"text": "On the other hand, when something is uncertain, the simulation must assume the worst possible scenario, so that simulations remain on the “realistic-pessimistic” type of performance outcome, as opposed to “wishful-thinking” scenarios that may be dangerous. This is the reason for using candle.max instead of any other more optimistic assumptions that—while feasible—are not necessarily more likely to happen."
},
{
"style": "Text",
"text": "The reversed scenario is considered as well: when a sell order is placed at a lower rate than the minimum rate of the candle against which the order is being simulated, the actual rate is corrected with the candle.min value."
},
{
"style": "Javascript",
"text": "tradingEngineOrder.orderStatistics.actualRate.value =\ntradingEngine.current.episode.candle.min.value",
"updated": 1610223044937
},
{
"style": "Title",
"text": "Recalculate Actual Size"
},
{
"style": "Text",
"text": "Since the actual rate may have been modified by the Actual Rate Simulation, it is necessary to recalculate the actual size in the quoted asset. The actual size in base asset remains the same, as it is not affected by the change in rate. Remember that the properties of the quoted asset always derive from the properties of the base asset."
},
{
"style": "Javascript",
"text": "tradingEngineOrder.orderQuotedAsset.actualSize.value =\ntradingEngineOrder.orderBaseAsset.actualSize.value *\ntradingEngineOrder.orderStatistics.actualRate.value",
"updated": 1610223069460
},
{
"style": "Title",
"text": "Recalculate Size Placed"
},
{
"style": "Text",
"text": "Since the actual rate may have changed, it is also necessary to calculate the stage’s size placed. Remember that the size placed node at the level of the stage keeps track of the total size of orders that have been placed so that the target size defined for the stage may be enforced as a cap."
},
{
"style": "Text",
"text": "As done during a typical exchange synchronization, the initial size of the order is subtracted from the size placed, and then the actual size is added. This is done in two steps, for clarity:"
},
{
"style": "Javascript",
"text": "tradingEngineStage.stageQuotedAsset.sizePlaced.value =\ntradingEngineStage.stageQuotedAsset.sizePlaced.value -\npreviousQuotedAssetActualSize\n\ntradingEngineStage.stageQuotedAsset.sizePlaced.value =\ntradingEngineStage.stageQuotedAsset.sizePlaced.value +\ntradingEngineOrder.orderQuotedAsset.actualSize.value",
"updated": 1610223111181
},
{
"style": "Title",
"text": "Percentage Filled Simulation"
},
{
"style": "Text",
"text": "The simulation of the filling of market orders is straightforward: they always fill. For limit orders, the trading bot runs a basic check:"
},
{
"style": "List",
"text": "For limit buy orders to fill, the minimum rate of the candle must be equal or lower than the actual rate of the order. This means that the rate of the order falls within the range of rates filled during the duration of the candle."
},
{
"style": "Javascript",
"text": "tradingEngine.current.episode.candle.min.value <=\ntradingEngineOrder.actualRate.value",
"updated": 1610223130690
},
{
"style": "List",
"text": "For limit sell orders to fill, the reverse logic applies: the maximum rate of the candle must be equal or greater than the actual rate of the order."
},
{
"style": "Javascript",
"text": "tradingEngine.current.episode.candle.max.value >=\ntradingEngineOrder.actualRate.value",
"updated": 1610223149566
},
{
"style": "Note",
"text": "If limit orders do not pass the above check, they remain unfilled.",
"updated": 1610223159959
},
{
"style": "Text",
"text": "When an order is filled, by default it is filled fully, that is, the percentage filled is 100%:"
},
{
"style": "Javascript",
"text": "tradingEngineOrder.orderStatistics.percentageFilled.value = 100"
},
{
"style": "Text",
"text": "However, the above may change if you have defined a specific fill probability for the specific order on the simulated partial fill node. If there is a valid definition to simulate the probability of the order to be filled on each execution, then this is what the trading bot does with it:"
},
{
"style": "Javascript",
"text": "percentageFilled =\ntradingSystemOrder.simulatedExchangeEvents.simulatedPartialFill.config.fillProbability * 100",
"updated": 1610223186906
},
{
"style": "Text",
"text": "That is, the fillProbability parameter is multiplied by 100, and the result is the percentage filled. If the percentage filled is lower than 100, then the order may continue filling in subsequent executions, provided it passes the above checks."
},
{
"style": "Text",
"text": "Therefore, in every execution, the following update is done on the percentage filled node of the order statistics:"
},
{
"style": "Javascript",
"text": "tradingEngineOrder.orderStatistics.percentageFilled.value =\ntradingEngineOrder.orderStatistics.percentageFilled.value +\npercentageFilled",
"updated": 1610223206637
},
{
"style": "Note",
"text": "Of course, there is also a check to make sure that the percentage filled is never greater than 100.",
"updated": 1610223219878
},
{
"style": "Title",
"text": "Fees Paid Simulation"
},
{
"style": "Text",
"text": "Like with the definitions regarding the actual rate of the order, the definition of the simulated fees paid node under simulated exchange events takes precedence in regards to the definitions in the fee structure parameter of the trading session."
},
{
"style": "Text",
"text": "In general terms, fees paid are calculated as follows:"
},
{
"style": "List",
"text": "The percentage of fees is applied to the actual size to obtain the total amount of fees to be paid when the order is 100% filled."
},
{
"style": "List",
"text": "Then, the percentage filled is applied to obtain the fees paid for the portion of the order that actually filled."
},
{
"style": "Subtitle",
"text": "Trading system definitions"
},
{
"style": "Text",
"text": "For buy orders, fees are calculated in the base asset, as that is the asset being acquired:"
},
{
"style": "Javascript",
"text": "feesPaid =\ntradingEngineOrder.orderBaseAsset.actualSize.value *\ntradingSystemOrder.simulatedExchangeEvents.simulatedFeesPaid.config.percentage / 100 *\ntradingEngineOrder.orderStatistics.percentageFilled.value / 100",
"updated": 1610223256887
},
{
"style": "Text",
"text": "For sell orders, fees are calculated in the quoted asset:"
},
{
"style": "Javascript",
"text": "feesPaid =\ntradingEngineOrder.orderQuotedAsset.actualSize.value *\ntradingSystemOrder.simulatedExchangeEvents.simulatedFeesPaid.config.percentage / 100 *\ntradingEngineOrder.orderStatistics.percentageFilled.value / 100",
"updated": 1610223271791
},
{
"style": "Subtitle",
"text": "Session parameters definitions"
},
{
"style": "Text",
"text": "When producing the simulation based on the fees structure parameter of the trading session, the maker setting is applied to limit orders and the taker setting is applied to market orders."
},
{
"style": "Text",
"text": "For market buy orders:"
},
{
"style": "Javascript",
"text": "feesPaid =\ntradingEngineOrder.orderBaseAsset.actualSize.value *\nsessionParameters.feeStructure.config.taker / 100 *\ntradingEngineOrder.orderStatistics.percentageFilled.value / 100",
"updated": 1610223296764
},
{
"style": "Text",
"text": "For market sell orders:"
},
{
"style": "Javascript",
"text": "feesPaid =\ntradingEngineOrder.orderQuotedAsset.actualSize.value *\nsessionParameters.feeStructure.config.taker / 100 *\ntradingEngineOrder.orderStatistics.percentageFilled.value / 100",
"updated": 1610223315630
},
{
"style": "Text",
"text": "For limit buy orders:"
},
{
"style": "Javascript",
"text": "feesPaid =\ntradingEngineOrder.orderBaseAsset.actualSize.value *\nsessionParameters.feeStructure.config.maker / 100 *\ntradingEngineOrder.orderStatistics.percentageFilled.value / 100",
"updated": 1610223336052
},
{
"style": "Text",
"text": "For limit sell orders:"
},
{
"style": "Javascript",
"text": "feesPaid =\ntradingEngineOrder.orderQuotedAsset.actualSize.value *\nsessionParameters.feeStructure.config.maker / 100 *\ntradingEngineOrder.orderStatistics.percentageFilled.value / 100",
"updated": 1610223351171
},
{
"style": "Title",
"text": "Size Filled Simulation"
},
{
"style": "Text",
"text": "Calculating the size filled is straightforward considering we have already established the percentage of the size that has been filled. Bear in mind the property needs to be calculated for both assets."
},
{
"style": "Javascript",
"text": "tradingEngineOrder.orderBaseAsset.sizeFilled.value =\ntradingEngineOrder.orderBaseAsset.actualSize.value *\ntradingEngineOrder.orderStatistics.percentageFilled.value / 100\ntradingEngineOrder.orderQuotedAsset.sizeFilled.value =\ntradingEngineOrder.orderQuotedAsset.actualSize.value *\ntradingEngineOrder.orderStatistics.percentageFilled.value / 100",
"updated": 1610223373798
},
{
"style": "Title",
"text": "Amount Received Simulation"
},
{
"style": "Text",
"text": "This is a simple calculation to explicitly determine how much of the asset was acquired in the transaction. It is calculated by subtracting the fees from the actual size."
},
{
"style": "Text",
"text": "Buy orders acquire the base asset, thus, the amount is denominated in the base asset:"
},
{
"style": "Javascript",
"text": "tradingEngineOrder.orderBaseAsset.amountReceived.value =\ntradingEngineOrder.orderBaseAsset.sizeFilled.value -\ntradingEngineOrder.orderBaseAsset.feesPaid.value",
"updated": 1610223399677
},
{
"style": "Text",
"text": "Sell orders acquire the quoted asset, thus, the amount is denominated in the quoted asset:"
},
{
"style": "Javascript",
"text": "tradingEngineOrder.orderQuotedAsset.amountReceived.value =\ntradingEngineOrder.orderQuotedAsset.sizeFilled.value -\ntradingEngineOrder.orderQuotedAsset.feesPaid.value",
"updated": 1610223419660
}
]
}
@@ -0,0 +1,28 @@
{
"topic": "Order Management",
"pageNumber": "11",
"type": "Simulating Order Cancellations",
"definition": {
"text": "The simulation of the cancellation of an order is quite straightforward, as the trading bot has all the information required to proceed.",
"updated": 1610223512005
},
"paragraphs": [
{
"style": "Text",
"text": "Simulating the cancelation of an order is almost trivial. Of course, the process applies to backtesting and paper trading sessions only.",
"updated": 1610223521328
},
{
"style": "Text",
"text": "The order is closed seamlessly as the bot has full control over the order’s details."
},
{
"style": "Javascript",
"text": "tradingEngineOrder.status.value = 'Closed'"
},
{
"style": "Text",
"text": "Once the order is closed, the bot runs the calculations to adjusts the stage size (see Accounting)."
}
]
}
@@ -0,0 +1,211 @@
{
"topic": "Order Management",
"pageNumber": "12",
"type": "Accounting",
"definition": {
"text": "The accounting process involves keeping balances synchronized with the happenings at the exchange (or the simulated events) and keeping track of the size placed and size filled of the stage.",
"updated": 1610223863701
},
"paragraphs": [
{
"style": "Text",
"text": "Once the synchronization is done, either with a real exchange or in a simulation, and with all relevant details about the order gathered and in place, it is time to do some bookkeeping.",
"updated": 1610223883776
},
{
"style": "Text",
"text": "Both the real and simulated synchronization processes save the previous values for the size filled and fees paid in both assets before performing the calculations to update those values."
},
{
"style": "Text",
"text": "These previous values are then used to undo the previous accounts to redo them with the latest synchronized data."
},
{
"style": "Title",
"text": "Update Stage Assets"
},
{
"style": "Text",
"text": "Stage base aset, undoing the previous accounting:"
},
{
"style": "Javascript",
"text": "tradingEngineStage.stageBaseAsset.sizeFilled.value =\ntradingEngineStage.stageBaseAsset.sizeFilled.value -\npreviousBaseAssetSizeFilled\n\ntradingEngineStage.stageBaseAsset.feesPaid.value =\ntradingEngineStage.stageBaseAsset.feesPaid.value -\npreviousBaseAssetFeesPaid",
"updated": 1610223906627
},
{
"style": "Text",
"text": "Stage base asset, accounting for the current filling and fees:",
"updated": 1610223935259
},
{
"style": "Javascript",
"text": "tradingEngineStage.stageBaseAsset.sizeFilled.value =\ntradingEngineStage.stageBaseAsset.sizeFilled.value +\ntradingEngineOrder.orderBaseAsset.sizeFilled.value\n\ntradingEngineStage.stageBaseAsset.feesPaid.value =\ntradingEngineStage.stageBaseAsset.feesPaid.value +\ntradingEngineOrder.orderBaseAsset.feesPaid.value",
"updated": 1610223957139
},
{
"style": "Text",
"text": "Stage quoted asset, undoing the previous accounting:",
"updated": 1610223973902
},
{
"style": "Javascript",
"text": "tradingEngineStage.stageQuotedAsset.sizeFilled.value =\ntradingEngineStage.stageQuotedAsset.sizeFilled.value -\npreviousQuotedAssetSizeFilled\n\ntradingEngineStage.stageQuotedAsset.feesPaid.value =\ntradingEngineStage.stageQuotedAsset.feesPaid.value -\npreviousQuotedAssetFeesPaid",
"updated": 1610223983436
},
{
"style": "Text",
"text": "Stage quote asset, accounting for the current filling and fees:",
"updated": 1610223987080
},
{
"style": "Javascript",
"text": "tradingEngineStage.stageQuotedAsset.sizeFilled.value =\ntradingEngineStage.stageQuotedAsset.sizeFilled.value +\ntradingEngineOrder.orderQuotedAsset.sizeFilled.value\n\ntradingEngineStage.stageQuotedAsset.feesPaid.value =\ntradingEngineStage.stageQuotedAsset.feesPaid.value +\ntradingEngineOrder.orderQuotedAsset.feesPaid.value",
"updated": 1610223999042
},
{
"style": "Title",
"text": "Update Balances",
"updated": 1610224010466
},
{
"style": "Text",
"text": "The updating of balances must take one crucial aspect into account: for sell orders, fees are paid in the quoted asset, while for buy orders, fees are paid in the base asset."
},
{
"style": "Subtitle",
"text": "Sell orders"
},
{
"style": "Text",
"text": "Balance base asset, undoing the previous accounting:"
},
{
"style": "Javascript",
"text": "tradingEngine.current.episode.episodeBaseAsset.balance.value =\ntradingEngine.current.episode.episodeBaseAsset.balance.value +\npreviousBaseAssetSizeFilled",
"updated": 1610224035951
},
{
"style": "Text",
"text": "Balance base asset, accounting for the current filling and fees:",
"updated": 1610224064051
},
{
"style": "Javascript",
"text": "tradingEngine.current.episode.episodeBaseAsset.balance.value =\ntradingEngine.current.episode.episodeBaseAsset.balance.value -\ntradingEngineOrder.orderBaseAsset.sizeFilled.value",
"updated": 1610224081072
},
{
"style": "Text",
"text": "Balance quoted asset, undoing the previous accounting:",
"updated": 1610224090601
},
{
"style": "Javascript",
"text": "tradingEngine.current.episode.episodeQuotedAsset.balance.value =\ntradingEngine.current.episode.episodeQuotedAsset.balance.value -\npreviousQuotedAssetSizeFilled +\npreviousQuotedAssetFeesPaid",
"updated": 1610224107848
},
{
"style": "Text",
"text": "Balance quoted asset, account for the current filling and fees:",
"updated": 1610224138020
},
{
"style": "Javascript",
"text": "tradingEngine.current.episode.episodeQuotedAsset.balance.value =\ntradingEngine.current.episode.episodeQuotedAsset.balance.value +\ntradingEngineOrder.orderQuotedAsset.sizeFilled.value -\ntradingEngineOrder.orderQuotedAsset.feesPaid.value",
"updated": 1610224148958
},
{
"style": "Subtitle",
"text": "Buy orders",
"updated": 1610224169177
},
{
"style": "Text",
"text": "Balance base asset, undoing the previous accounting:"
},
{
"style": "Javascript",
"text": "tradingEngine.current.episode.episodeBaseAsset.balance.value =\ntradingEngine.current.episode.episodeBaseAsset.balance.value -\npreviousBaseAssetSizeFilled +\npreviousBaseAssetFeesPaid",
"updated": 1610224182969
},
{
"style": "Text",
"text": "Balance base asset, accounting for the current filling and fees:",
"updated": 1610224192900
},
{
"style": "Javascript",
"text": "tradingEngine.current.episode.episodeBaseAsset.balance.value =\ntradingEngine.current.episode.episodeBaseAsset.balance.value +\ntradingEngineOrder.orderBaseAsset.sizeFilled.value -\ntradingEngineOrder.orderBaseAsset.feesPaid.value",
"updated": 1610224202075
},
{
"style": "Text",
"text": "Balance quoted asset, undoing the previous accounting:",
"updated": 1610224209182
},
{
"style": "Javascript",
"text": "tradingEngine.current.episode.episodeQuotedAsset.balance.value =\ntradingEngine.current.episode.episodeQuotedAsset.balance.value +\npreviousQuotedAssetSizeFilled",
"updated": 1610224219415
},
{
"style": "Text",
"text": "Balance quoted asset, accounting for the current filling and fees:",
"updated": 1610224228103
},
{
"style": "Javascript",
"text": "tradingEngine.current.episode.episodeQuotedAsset.balance.value =\ntradingEngine.current.episode.episodeQuotedAsset.balance.value -\ntradingEngineOrder.orderQuotedAsset.sizeFilled.value",
"updated": 1610224237924
},
{
"style": "Title",
"text": "Recalculate Stage Size",
"updated": 1610224257004
},
{
"style": "Text",
"text": "The stage keeps track of the accumulated size of orders placed for two reasons:"
},
{
"style": "List",
"text": "The trading bot must enforce the cap embodied in the definition of the target size. That is, the bot must not place orders for an amount higher than the size defined."
},
{
"style": "List",
"text": "The bot must close the stage once the target size has been filled."
},
{
"style": "Text",
"text": "That is why keeping track of the size placed at the level of the stage is important."
},
{
"style": "Text",
"text": "The process is similar to what other accounting operations we’ve covered so far: first, the obsolete account is undone; then the new account is made."
},
{
"style": "Text",
"text": "Undoing the old accounts for base and quoted asset:"
},
{
"style": "Text",
"text": ""
},
{
"style": "Javascript",
"text": "tradingEngineStage.stageBaseAsset.sizePlaced.value =\ntradingEngineStage.stageBaseAsset.sizePlaced.value -\ntradingEngineOrder.orderBaseAsset.actualSize.value\n\ntradingEngineStage.stageQuotedAsset.sizePlaced.value =\ntradingEngineStage.stageQuotedAsset.sizePlaced.value -\ntradingEngineOrder.orderQuotedAsset.actualSize.value",
"updated": 1610224328128
},
{
"style": "Text",
"text": "Redoing the new accounts for base and quoted asset:",
"updated": 1610224337735
},
{
"style": "Javascript",
"text": "tradingEngineStage.stageBaseAsset.sizePlaced.value =\ntradingEngineStage.stageBaseAsset.sizePlaced.value +\ntradingEngineOrder.orderBaseAsset.sizeFilled.value\n\ntradingEngineStage.stageQuotedAsset.sizePlaced.value =\ntradingEngineStage.stageQuotedAsset.sizePlaced.value +\ntradingEngineOrder.orderQuotedAsset.sizeFilled.value",
"updated": 1610224348969
}
]
}
@@ -0,0 +1,61 @@
{
"topic": "Trading Logic",
"pageNumber": "1",
"type": "Situations, Conditions, and Formulas",
"definition": {
"text": "The trading framework implemented in Trading Systems and Trading Strategies carries some low-level trading logic in and of itself. However, the bulk of the logic specific to each strategy derives from the way you describe market situations, and how you define the actions the Trading Bot must take.",
"updated": 1610211518547
},
"paragraphs": [
{
"style": "Title",
"text": "Situation",
"updated": 1610211543537
},
{
"style": "Include",
"text": "Superalgos->Node->Situation->Definition",
"updated": 1610211550330
},
{
"style": "Include",
"text": "Superalgos->Node->Situation->Content",
"updated": 1610211554482
},
{
"style": "Title",
"text": "Condition",
"updated": 1610211561606
},
{
"style": "Include",
"text": "Superalgos->Node->Condition->Definition",
"updated": 1610211581358
},
{
"style": "Include",
"text": "Superalgos->Node->Condition->Content",
"updated": 1610211584280
},
{
"style": "Title",
"text": "Formula",
"updated": 1610211589034
},
{
"style": "Include",
"text": "Superalgos->Node->Formula->Definition",
"updated": 1610211600331
},
{
"style": "Include",
"text": "Superalgos->Node->Formula->Content",
"updated": 1610211603147
},
{
"style": "Include",
"text": "Superalgos->Node->Formula->Examples",
"updated": 1610211711972
}
]
}
@@ -0,0 +1,266 @@
{
"topic": "Trading Logic",
"pageNumber": "2",
"type": "Syntax Overview",
"definition": {
"text": "The syntax for writing conditions and formulas combine references to the data product name, the name of the property, and the time frame.",
"updated": 1610214683129
},
"paragraphs": [
{
"style": "Title",
"text": "Introduction",
"updated": 1610214707473
},
{
"style": "Text",
"text": "Different bots running within the system produce data products that others may consume. These products are available for you to use within your strategies."
},
{
"style": "Text",
"text": "Datasets are stored as a collection of sequential records and you may access any of the properties (fields) of each record."
},
{
"style": "Text",
"text": "To do that, you will use the following syntax: ",
"updated": 1610214730077
},
{
"style": "Javascript",
"text": ".productName + .propertyName."
},
{
"style": "Text",
"text": "The above syntax returns the value of the property of the declared product at the latest closed candle. This is common throughout all available datasets."
},
{
"style": "Success",
"text": "Each Indicator Bot outputs one or more data products, each with a set of properties. Find the details of the products and properties available in the documentation of each indicator.",
"updated": 1610216390888
},
{
"style": "Text",
"text": ""
},
{
"style": "Text",
"text": ""
},
{
"style": "Title",
"text": "Specifying the Time Frame"
},
{
"style": "Text",
"text": "When building conditions and formulas, you may want to use analysis concerning different time frames. This is perfectly possible."
},
{
"style": "Text",
"text": "The variables explained further down this section, written as described for each indicator, are not valid unless they are preceeded by the declaration of the time frame they refer to."
},
{
"style": "Text",
"text": "To do that, you need to preceed the above syntax with the following:"
},
{
"style": "Javascript",
"text": "chart.at + time frame"
},
{
"style": "Text",
"text": "Therefore, the complete syntax to build a valid statement is:"
},
{
"style": "Javascript",
"text": "chart.at + time frame + .productName + .propertyName"
},
{
"style": "Text",
"text": "For example:"
},
{
"style": "Javascript",
"text": "chart.at04hs.candle.close > chart.at04hs.candle.previous.close"
},
{
"style": "Text",
"text": "The above statement compares the current 4 hours candle to the previous 4 hours candle."
},
{
"style": "Text",
"text": "The complete list of time frames available is:"
},
{
"style": "Table",
"text": "| Time Frame | Syntax |\n| 1 min | chart.at01min |\n| 2 min | chart.at02min |\n| 3 min | chart.at03min |\n| 4 min | chart.at04min |\n| 5 min | chart.at05min |\n| 10 min | chart.at10min |\n| 15 min | chart.at15min |\n| 20 min | chart.at20min |\n| 30 min | chart.at30min |\n| 40 min | chart.at40min |\n| 45 min | chart.at45min |\n| 1 h | chart.at01hs |\n| 2 hs | chart.at02hs |\n| 3 hs | chart.at03hs |\n| 4 hs | chart.at04hs |\n| 6 hs | chart.at06hs |\n| 8 hs | chart.at08hs |\n| 12 hs | chart.at12hs |\n| 24 hs | chart.at24hs |",
"updated": 1610214935448
},
{
"style": "Text",
"text": "The previous property is a property common to all products that allows you to retrieve the value of the candle that closed previous to the last one."
},
{
"style": "Text",
"text": "The property is used with the following syntax: ",
"updated": 1610215018833
},
{
"style": "Javascript",
"text": "chart.at + time frame + .productName + .previous + .propertyName. "
},
{
"style": "Text",
"text": "You may use the property on any of the indicators in a similar way."
},
{
"style": "Text",
"text": "In addition, you may use the previous property more than once, to retrieve values further in the past: ",
"updated": 1610215040020
},
{
"style": "Javascript",
"text": "chart.at + time frame + .productName + .previous.previous... ...previous + .propertyName"
},
{
"style": "Text",
"text": "For example:",
"updated": 1610215089118
},
{
"style": "Javascript",
"text": "chart.at01hs.candle.previous.previous.max"
},
{
"style": "Text",
"text": "The above returns the maximum value of two candles before the last closed candle at the 1-hour chart.",
"updated": 1610215099927
},
{
"style": "Title",
"text": "Alternative to the Previous Property"
},
{
"style": "Text",
"text": "There is a cool alternative to the previous property, that you can use to fetch the value of a property beyond the last closed candle."
},
{
"style": "Text",
"text": "The syntax is:",
"updated": 1610215130206
},
{
"style": "Javascript",
"text": "productName.[currentCandleIndex-n].propertyName"
},
{
"style": "Text",
"text": "... where currentCandleIndex represents the last closed candle and n may be replaced by any integer number."
},
{
"style": "Text",
"text": "For example:",
"updated": 1610215164809
},
{
"style": "Javascript",
"text": "chart.at01hs.candle.[currentCandleIndex-5].max"
},
{
"style": "Text",
"text": "... retrieves the maximum value of the fifth candle previous to the last closed candle at the 1-hour chart."
},
{
"style": "Note",
"text": "There is a technical limitation by which you may retrieve the value of a property up to a maximum of 24 hours in the past, whatever number of periods that may represent, depending on the time frame you may be working on. For instance, if you are working on the 1 hour time frame, you may fetch up to 23 candles before the last one. If you are working on the 1 minute time frame, you may retrieve 1439 candles. If you need to retrieve information further in the past, then you should consider building an indicator that makes the data available to your strategies.",
"updated": 1610215195223
},
{
"style": "Title",
"text": "Comparison and Logical Operators"
},
{
"style": "Text",
"text": "To define conditions you will use statements using the syntax described above. You will use the properties of indicators that will be introduced later on. The data behind those indicators describe what is happening with the market."
},
{
"style": "Text",
"text": "Remember, conditions need to evaluate either true or false."
},
{
"style": "Text",
"text": "To create such statements you will use comparison and logical operators:"
},
{
"style": "Table",
"text": "| Operator | Description |\n| === | equal value and equal type |\n| != | not equal |\n| > | greater than |\n| < | less than |\n| >= | greater than or equal to |\n| <= | less than or equal to |\n| && | and |\n| ∣∣ | or |",
"updated": 1610215345573
},
{
"style": "Text",
"text": "For example:",
"updated": 1610215388469
},
{
"style": "Subtitle",
"text": "Situation 1"
},
{
"style": "List",
"text": "Condition A: The latest candle at the 1 hour chart closed above the Bollinger Bands moving average.",
"updated": 1610215456837
},
{
"style": "Javascript",
"text": "chart.at01hs.candle.close > chart.at01hs.bollingerBand.MovingAverage"
},
{
"style": "List",
"text": "Condition B: The maximum value of the candle before the last one, was higher than the Bollinger Bands moving average.",
"updated": 1610215484498
},
{
"style": "Javascript",
"text": "chart.at01hs.candle.previous.max > chart.at01hs.bollingerBand.previous.MovingAverage"
},
{
"style": "Text",
"text": "In the example above, conditions A and B are comparison statements that may evaluate either true or false. In the case both would evaluate true then Situation 1 would be true as well."
},
{
"style": "Subtitle",
"text": "Situation 2"
},
{
"style": "List",
"text": "Condition C: The entire candle at the 4 hours chart fits within the price range between 9000 and 10000.",
"updated": 1610215565978
},
{
"style": "Javascript",
"text": "chart.at04hs.candle.max <= 10000 && chart.at04hs.candle.min >= 9000"
},
{
"style": "Text",
"text": "In the example above, condition C would be true if the whole 4-hour candle falls within the range between 9000 and 10000. If this is true, then situation 2 is true as well, as there is only one condition to check."
},
{
"style": "Title",
"text": "JaveScript Code"
},
{
"style": "Text",
"text": "You may use any valid piece of JavaScript code for your conditions and formulas. The system imposses no contraints whatsoever. The code on conditions and formulas is run through the eval() function, as follows:",
"updated": 1610215780497
},
{
"style": "Javascript",
"text": "try {\n let code = node.code\n value = eval(code);\n addCodeToSnapshot(code)\n}",
"updated": 1610215800115
},
{
"style": "Success",
"text": "Remember that all conditions must evaluate to true or false and that formulas must evaluate to a number. If you are having issues with your code, learn how to debug a task.",
"updated": 1610215814504
}
]
}
@@ -0,0 +1,74 @@
{
"topic": "Trading Logic",
"pageNumber": "3",
"type": "Accessing Runtime Data",
"definition": {
"text": "The Trading Bot makes every piece of information processed available to Trading Systems in the data structure of the Trading Engine hierarchy.",
"updated": 1610216690404
},
"paragraphs": [
{
"style": "Text",
"text": "To access the value of any of the nodes in the Trading Engine from within conditions and formulas, the syntax follows the ramifications of the data structure, exactly as seen in the visual representation of the hierarchy on the Design Space.",
"updated": 1610216724389
},
{
"style": "Text",
"text": "For example, let’s say you wish to access the value of the Begin node under Strategy Open Stage. The path to that node, as denoted by the structure of the hierachy below, is:",
"updated": 1610216746961
},
{
"style": "Javascript",
"text": "tradingEngine.current.strategyOpenStage.begin.value"
},
{
"style": "Text",
"text": "If you wish to go one step lower and access the value of the Target Size under the Stage Quoted Asset, then the path is:",
"updated": 1610216775084
},
{
"style": "Javascript",
"text": "tradingEngine.current.strategyOpenStage.stageQuotedAsset.targetSize.value"
},
{
"style": "Note",
"text": "As usual, make sure you follow the JavaScript camel case notation by which the first word is in lower case and the rest in uppercase.",
"updated": 1610216790819
},
{
"style": "Title",
"text": "Copy Node Path"
},
{
"style": "Text",
"text": "For ease of use, you may copy the path of any node that holds a valid value directly from within the node’s menu. Simply use the Copy Node Path button."
},
{
"style": "Title",
"text": "Formula Example"
},
{
"style": "Text",
"text": "Let’s say you wish to set a take profit 3% above the initial target rate you defined in the open stage of your strategy."
},
{
"style": "Text",
"text": "That value is stored in the Entry Target Rate node under the Current Position.",
"updated": 1610216903247
},
{
"style": "Text",
"text": "So, the formula for the take profit phase is:"
},
{
"style": "Javascript",
"text": "tradingEngine.current.position.entryTargetRate.value * 1.03",
"updated": 1610216926922
},
{
"style": "Success",
"text": "All of this will become clear when you study the Trading Engine hierarchy!",
"updated": 1610216962576
}
]
}
@@ -0,0 +1,70 @@
{
"topic": "Trading Logic",
"pageNumber": "4",
"type": "Accessing Trading System Definitions and Session Parameters",
"definition": {
"text": "The Trading System may access it's own definitions as well as Session Parameters from any Formula or Condition.",
"updated": 1610217064031
},
"paragraphs": [
{
"style": "Text",
"text": "Trading System definitions and Trading Session Parameters are accessible from within conditions and formulas, pretty much like conditions and formulas may access the values of indicators, or the Trading Engine hierarchy.",
"updated": 1610217113377
},
{
"style": "Note",
"text": "This is a technical feature mostly oriented to developers. Practical use cases are few for less technically oriented individuals.",
"updated": 1610217120684
},
{
"style": "Title",
"text": "Syntax"
},
{
"style": "Text",
"text": "To access a trading system definition, follow the path given by the trading system structure. For example, to access a condition in the take position event, use:",
"updated": 1610217151294
},
{
"style": "Javascript",
"text": "tradingSystem.tradingStrategies[i].triggerStage.takePositionEvent.situations[n].conditions[m].code"
},
{
"style": "Text",
"text": "To access a trading session parameter, use the syntax starting with sessionParameters followed by the name of the parameter, and the name of the specific parameter in the configuration. For example, to access the taker parameter in the fee structure, use:",
"updated": 1610217182677
},
{
"style": "Javascript",
"text": "sessionParameters.feeStructure.config.taker",
"updated": 1610217195909
},
{
"style": "Title",
"text": "Example"
},
{
"style": "Text",
"text": "Such a feature may be useful, for instance, to include such definitions or parameters on Telegram accouncement messages, as in:"
},
{
"style": "Javascript",
"text": "\"The condition with the following code: \" + \ntradingSystem.tradingStrategies[tradingEngine.current.strategy.index.value].triggerStage.takePositionEvent.situations[0].conditions[0].code +\n\" triggered the take position event.\"",
"updated": 1610217276846
},
{
"style": "Text",
"text": "Notice that...",
"updated": 1610217314692
},
{
"style": "Javascript",
"text": "[tradingEngine.current.strategy.index.value]"
},
{
"style": "Text",
"text": "... corresponds to the syntax deriving from the trading engine hierarchy."
}
]
}
@@ -0,0 +1,20 @@
{
"topic": "Trading Systems",
"pageNumber": "1",
"type": "Trading System Hierarchy",
"definition": {
"text": "A Trading System carries the trading logic implemented by the Trading Bot during a trading session.",
"updated": 1610138743003
},
"paragraphs": [
{
"style": "Include",
"text": "Superalgos->Node->Trading System->Definition",
"updated": 1610138679068
},
{
"style": "Include",
"text": "Superalgos->Node->Trading System->Content"
}
]
}
@@ -0,0 +1,21 @@
{
"topic": "Trading Systems",
"pageNumber": "2",
"type": "Trading Strategies",
"definition": {
"text": "Trading strategies encompass the logic to trigger a strategy among the many that may exist in the Trading System, take a position, manage it, and close a position.",
"updated": 1610199807593
},
"paragraphs": [
{
"style": "Include",
"text": "Superalgos->Node->Trading Strategy->Definition",
"updated": 1610138825934
},
{
"style": "Include",
"text": "Superalgos->Node->Trading Strategy->Content",
"updated": 1610138829122
}
]
}
@@ -0,0 +1,79 @@
{
"topic": "Trading Systems",
"pageNumber": "3",
"type": "The Trigger Stage",
"definition": {
"text": "The trigger stage features the definitions of the Trigger-On Event, Trigger-Off Event, and Take Position Event.",
"updated": 1610139390213
},
"paragraphs": [
{
"style": "Include",
"text": "Superalgos->Node->Trigger Stage->Definition",
"updated": 1610139409395
},
{
"style": "Include",
"text": "Superalgos->Node->Trigger Stage->Content",
"updated": 1610139413791
},
{
"style": "Include",
"text": "Superalgos->Concept->Reusable Snippets->Note for Hierarchy Tables"
},
{
"style": "Hierarchy",
"text": "Superalgos->Trigger Stage->2",
"updated": 1610139448080
},
{
"style": "Note",
"text": "Announcements is a feature external to Trading Systems and shall be addressed elsewhere.",
"updated": 1610139662103
},
{
"style": "Title",
"text": "Trigger On Event"
},
{
"style": "Include",
"text": "Superalgos->Node->Trigger On Event->Definition",
"updated": 1610139524793
},
{
"style": "Include",
"text": "Superalgos->Node->Trigger On Event->Content",
"updated": 1610139534038
},
{
"style": "Title",
"text": "Trigger Off Event",
"updated": 1610139540955
},
{
"style": "Include",
"text": "Superalgos->Node->Trigger Off Event->Definition",
"updated": 1610139544555
},
{
"style": "Include",
"text": "Superalgos->Node->Trigger Off Event->Content",
"updated": 1610139548323
},
{
"style": "Title",
"text": "Take Position Event",
"updated": 1610139565779
},
{
"style": "Include",
"text": "Superalgos->Node->Take Position Event->Definition",
"updated": 1610139569040
},
{
"style": "Include",
"text": "Superalgos->Node->Take Position Event->Content",
"updated": 1610139572696
}
]
}
@@ -0,0 +1,104 @@
{
"topic": "Trading Systems",
"pageNumber": "4",
"type": "Open Stage Initial Targets",
"definition": {
"text": "The initial targets section features the first few definitions required to open a position: the definition of target rate and the target size.",
"updated": 1610185761943
},
"paragraphs": [
{
"style": "Title",
"text": "Open Stage",
"updated": 1610185795249
},
{
"style": "Include",
"text": "Superalgos->Node->Open Stage->Definition",
"updated": 1610185816513
},
{
"style": "Include",
"text": "Superalgos->Node->Open Stage->Content",
"updated": 1610185811108
},
{
"style": "Hierarchy",
"text": "Superalgos->Open Stage->2",
"updated": 1610185891458
},
{
"style": "Text",
"text": ""
},
{
"style": "Callout",
"text": "In this page, we will cover the Initial Targets definitions.",
"updated": 1610185946482
},
{
"style": "Title",
"text": "Initial Targets",
"updated": 1610185978859
},
{
"style": "Include",
"text": "Superalgos->Node->Initial Targets->Definition",
"updated": 1610185989025
},
{
"style": "Include",
"text": "Superalgos->Concept->Reusable Snippets->Note for Hierarchy Tables"
},
{
"style": "Hierarchy",
"text": "Superalgos->Initial Targets->2",
"updated": 1610186094999
},
{
"style": "Title",
"text": "Target Rate",
"updated": 1610186138633
},
{
"style": "Include",
"text": "Superalgos->Node->Target Rate->Definition",
"updated": 1610186142640
},
{
"style": "Include",
"text": "Superalgos->Node->Target Rate->Content",
"updated": 1610186146771
},
{
"style": "Title",
"text": "Target Size In Base Asset",
"updated": 1610186357107
},
{
"style": "Include",
"text": "Superalgos->Node->Target Size In Base Asset->Definition",
"updated": 1610186350579
},
{
"style": "Include",
"text": "Superalgos->Node->Target Size In Base Asset->Content",
"updated": 1610186365816
},
{
"style": "Title",
"text": "Target Size In Quoted Asset",
"updated": 1610186383350
},
{
"style": "Include",
"text": "Superalgos->Node->Target Size In Quoted Asset->Definition",
"updated": 1610186394276
},
{
"style": "Include",
"text": "Superalgos->Node->Target Size In Quoted Asset->Content",
"updated": 1610186405759
}
]
}
@@ -0,0 +1,114 @@
{
"topic": "Trading Systems",
"pageNumber": "5",
"type": "Open Stage Execution",
"definition": {
"text": "This section of the Open Stage handles the logic and orders used to enter a Position.",
"updated": 1610187656657
},
"paragraphs": [
{
"style": "Title",
"text": "Open Execution",
"updated": 1610187698287
},
{
"style": "Include",
"text": "Superalgos->Node->Open Execution->Definition",
"updated": 1610187702278
},
{
"style": "Include",
"text": "Superalgos->Node->Open Execution->Content",
"updated": 1610187706054
},
{
"style": "Include",
"text": "Superalgos->Concept->Reusable Snippets->Note for Hierarchy Tables"
},
{
"style": "Hierarchy",
"text": "Superalgos->Open Execution->3",
"updated": 1610187711323
},
{
"style": "Title",
"text": "Execution Algorithm",
"updated": 1610187940008
},
{
"style": "Include",
"text": "Superalgos->Node->Execution Algorithm->Definition",
"updated": 1610187949950
},
{
"style": "Include",
"text": "Superalgos->Node->Execution Algorithm->Content",
"updated": 1610187955512
},
{
"style": "Title",
"text": "Market Buy Order",
"updated": 1610187970840
},
{
"style": "Include",
"text": "Superalgos->Node->Market Buy Order->Definition",
"updated": 1610187974574
},
{
"style": "Include",
"text": "Superalgos->Node->Market Buy Order->Content",
"updated": 1610187977959
},
{
"style": "Title",
"text": "Market Sell Order",
"updated": 1610187985806
},
{
"style": "Include",
"text": "Superalgos->Node->Market Sell Order->Definition",
"updated": 1610187989119
},
{
"style": "Include",
"text": "Superalgos->Node->Market Sell Order->Content",
"updated": 1610187993001
},
{
"style": "Title",
"text": "Limit Buy Order",
"updated": 1610188013160
},
{
"style": "Include",
"text": "Superalgos->Node->Limit Buy Order->Definition",
"updated": 1610188017480
},
{
"style": "Include",
"text": "Superalgos->Node->Limit Buy Order->Content",
"updated": 1610188020558
},
{
"style": "Title",
"text": "Limit Sell Order",
"updated": 1610188029692
},
{
"style": "Include",
"text": "Superalgos->Node->Limit Sell Order->Definition",
"updated": 1610188033186
},
{
"style": "Include",
"text": "Superalgos->Node->Limit Sell Order->Content",
"updated": 1610188036350
},
{
"style": "Text",
"text": ""
}
]
}
@@ -0,0 +1,126 @@
{
"topic": "Trading Systems",
"pageNumber": "6",
"type": "Order Definitions",
"definition": {
"text": "All types of orders have similar definitions. The one difference between market and limit orders is that market orders do no hace an Order Rate definition.",
"updated": 1610197366077
},
"paragraphs": [
{
"style": "Include",
"text": "Superalgos->Concept->Reusable Snippets->Note for Hierarchy Tables",
"updated": 1610196847887
},
{
"style": "Hierarchy",
"text": "Superalgos->Limit Buy Order->2",
"updated": 1610197390955
},
{
"style": "Title",
"text": "Order Rate",
"updated": 1610197404420
},
{
"style": "Include",
"text": "Superalgos->Node->Order Rate->Definition",
"updated": 1610197408556
},
{
"style": "Include",
"text": "Superalgos->Node->Order Rate->Content",
"updated": 1610197412802
},
{
"style": "Title",
"text": "Create Order Event",
"updated": 1610197420979
},
{
"style": "Include",
"text": "Superalgos->Node->Create Order Event->Definition",
"updated": 1610197428592
},
{
"style": "Include",
"text": "Superalgos->Node->Create Order Event->Content",
"updated": 1610197431668
},
{
"style": "Title",
"text": "Cancel Order Event",
"updated": 1610197449295
},
{
"style": "Include",
"text": "Superalgos->Node->Cancel Order Event->Definition",
"updated": 1610197456707
},
{
"style": "Include",
"text": "Superalgos->Node->Cancel Order Event->Content",
"updated": 1610197460196
},
{
"style": "Title",
"text": "Simulated Exchange Events",
"updated": 1610197475143
},
{
"style": "Include",
"text": "Superalgos->Node->Simulated Exchange Events->Definition",
"updated": 1610197481087
},
{
"style": "Include",
"text": "Superalgos->Node->Simulated Exchange Events->Content",
"updated": 1610197485556
},
{
"style": "Subtitle",
"text": "Simulated Partial Fill",
"updated": 1610197512649
},
{
"style": "Include",
"text": "Superalgos->Node->Simulated Partial Fill->Definition",
"updated": 1610197521350
},
{
"style": "Include",
"text": "Superalgos->Node->Simulated Partial Fill->Content",
"updated": 1610197525227
},
{
"style": "Subtitle",
"text": "Simulated Actual Rate",
"updated": 1610197534951
},
{
"style": "Include",
"text": "Superalgos->Node->Simulated Actual Rate->Definition",
"updated": 1610197538992
},
{
"style": "Include",
"text": "Superalgos->Node->Simulated Actual Rate->Content",
"updated": 1610197541958
},
{
"style": "Subtitle",
"text": "Simulated Fees Paid",
"updated": 1610197551998
},
{
"style": "Include",
"text": "Superalgos->Node->Simulated Fees Paid->Definition",
"updated": 1610197559999
},
{
"style": "Include",
"text": "Superalgos->Node->Simulated Fees Paid->Content",
"updated": 1610197563054
}
]
}
@@ -0,0 +1,64 @@
{
"topic": "Trading Systems",
"pageNumber": "7",
"type": "The Manage Stage",
"definition": {
"text": "The Manage Stage is where you define how positions are managed, from the moment the decision to take the position is made, until the moment the decision to exit the position is made.",
"updated": 1610199688355
},
"paragraphs": [
{
"style": "Include",
"text": "Superalgos->Node->Manage Stage->Definition",
"updated": 1610198924545
},
{
"style": "Include",
"text": "Superalgos->Node->Manage Stage->Content",
"updated": 1610198927824
},
{
"style": "Include",
"text": "Superalgos->Concept->Reusable Snippets->Note for Hierarchy Tables"
},
{
"style": "Hierarchy",
"text": "Superalgos->Manage Stage->2",
"updated": 1610199384375
},
{
"style": "Text",
"text": ""
},
{
"style": "Title",
"text": "Managed Stop Loss",
"updated": 1610199422482
},
{
"style": "Include",
"text": "Superalgos->Node->Managed Stop Loss->Definition",
"updated": 1610199431689
},
{
"style": "Include",
"text": "Superalgos->Node->Managed Stop Loss->Content",
"updated": 1610199434764
},
{
"style": "Title",
"text": "Managed Take Profit",
"updated": 1610199457335
},
{
"style": "Include",
"text": "Superalgos->Node->Managed Take Profit->Definition",
"updated": 1610199483083
},
{
"style": "Include",
"text": "Superalgos->Node->Managed Take Profit->Content",
"updated": 1610199486279
}
]
}
@@ -0,0 +1,64 @@
{
"topic": "Trading Systems",
"pageNumber": "8",
"type": "Position Management Phases",
"definition": {
"text": "You may manage a position using dynammic stop loss and take profit targets. Targets are dynamic in the sense that they are defined by formulas, which may change depending on defined market situations.",
"updated": 1610207512419
},
"paragraphs": [
{
"style": "Include",
"text": "Superalgos->Node->Phase->Definition"
},
{
"style": "Include",
"text": "Superalgos->Node->Phase->Content",
"updated": 1610205689779
},
{
"style": "Include",
"text": "Superalgos->Concept->Reusable Snippets->Note for Hierarchy Tables"
},
{
"style": "Hierarchy",
"text": "Superalgos->Phase->2",
"updated": 1610205876120
},
{
"style": "Callout",
"text": "We will discuss formulas later on, together with situations and conditions.",
"updated": 1610206194016
},
{
"style": "Title",
"text": "Next Phase Event",
"updated": 1610206213863
},
{
"style": "Include",
"text": "Superalgos->Node->Next Phase Event->Definition",
"updated": 1610206224515
},
{
"style": "Include",
"text": "Superalgos->Node->Next Phase Event->Content",
"updated": 1610206227962
},
{
"style": "Title",
"text": "Move To Phase Event",
"updated": 1610206257700
},
{
"style": "Include",
"text": "Superalgos->Node->Move To Phase Event->Definition",
"updated": 1610206283751
},
{
"style": "Include",
"text": "Superalgos->Node->Move To Phase Event->Content",
"updated": 1610206292181
}
]
}
@@ -0,0 +1,31 @@
{
"topic": "Trading Systems",
"pageNumber": "9",
"type": "The Close Stage",
"definition": {
"text": "The close stage is a mirror of the open stage, with definitions concerning the closing of the position, including the close execution.",
"updated": 1610206979676
},
"paragraphs": [
{
"style": "Include",
"text": "Superalgos->Node->Close Stage->Definition",
"updated": 1610207033911
},
{
"style": "Include",
"text": "Superalgos->Node->Close Stage->Content",
"updated": 1610207037298
},
{
"style": "Hierarchy",
"text": "Superalgos->Close Stage->2",
"updated": 1610207264945
},
{
"style": "Success",
"text": "If the data structure depicted in the table above looks familiar, it is because it is a mirror of the Open Stage. Refer to those definitions in case you need a refresher.",
"updated": 1610207351033
}
]
}