"Last of the typos"
This commit is contained in:
1 parent
c203040f3a
commit
785e10fa16
176 files changed
+449
-449
No files matched your search
+9
-9
@@ -1,6 +1,6 @@
|
||||
exports.newAlgorithmicTradingBotModulesOrdersCalculations = function (processIndex) {
|
||||
/*
|
||||
When we are live trading, we need to syncronize with the exchange.
|
||||
When we are live trading, we need to synchronize with the exchange.
|
||||
*/
|
||||
|
||||
let thisObject = {
|
||||
@@ -48,7 +48,7 @@ exports.newAlgorithmicTradingBotModulesOrdersCalculations = function (processInd
|
||||
|
||||
If it happens that the size accepted (Actual Size) is different than the
|
||||
size requested (Size), we need to make several adjustments so that the
|
||||
accounting syncronizes with reality.
|
||||
accounting synchronizes with reality.
|
||||
*/
|
||||
|
||||
/* This calculation needs to happen only once, the first time the order is checked. */
|
||||
@@ -65,8 +65,8 @@ exports.newAlgorithmicTradingBotModulesOrdersCalculations = function (processInd
|
||||
function recalculateActualSize() {
|
||||
/*
|
||||
We will recalculate the Quoted Asset Actual Size. This will also give to it an initial value.
|
||||
In the next formula, we are unsing the rate of the order because we dont know yet the Actual Rate.
|
||||
This rate might be replaced afteerwards for the Actual Rate when this is calculated again once
|
||||
In the next formula, we are using the rate of the order because we dont know yet the Actual Rate.
|
||||
This rate might be replaced afterwards for the Actual Rate when this is calculated again once
|
||||
the Actual Rate is known.
|
||||
*/
|
||||
tradingEngineOrder.orderQuotedAsset.actualSize.value = tradingEngineOrder.orderBaseAsset.actualSize.value * tradingEngineOrder.rate.value
|
||||
@@ -133,7 +133,7 @@ exports.newAlgorithmicTradingBotModulesOrdersCalculations = function (processInd
|
||||
tradingEngineOrder.orderStatistics.actualRate.value = TS.projects.foundations.utilities.miscellaneousFunctions.truncateToThisPrecision(tradingEngineOrder.orderStatistics.actualRate.value, 10)
|
||||
|
||||
/*
|
||||
If the Actual Rate happens to be exctly the same than the order rate, then there is
|
||||
If the Actual Rate happens to be exactly the same than the order rate, then there is
|
||||
nothing else to do here. Otherwise there are adjustments to be made.
|
||||
*/
|
||||
if (tradingEngineOrder.orderStatistics.actualRate.value === tradingEngineOrder.rate.value) { return }
|
||||
@@ -146,12 +146,12 @@ exports.newAlgorithmicTradingBotModulesOrdersCalculations = function (processInd
|
||||
function recalculateActualSize() {
|
||||
/*
|
||||
Now we know the Actual Rate at which the order was filled. Since the actual rate
|
||||
is not the same as the Rate we defined for the order, we need to syncronize
|
||||
is not the same as the Rate we defined for the order, we need to synchronize
|
||||
the Actual Order Size for Quoted Asset since it was calculated with the Order Size that we
|
||||
now know it is not the one really used at the exchange. We will recalculate the
|
||||
Actual Size in Quoted Asset and not in Base Asset, since the Actual Size in Base Asset
|
||||
is the one we accepted by the exchange, so that is fixed, regardless of how we initially
|
||||
got the Order Size in Base Asset, either from direct imput from the user or calculated
|
||||
got the Order Size in Base Asset, either from direct input from the user or calculated
|
||||
from the Order Size in Quoted Asset input it by the user. So here we go.
|
||||
*/
|
||||
previousQuotedAssetActualSize = tradingEngineOrder.orderQuotedAsset.actualSize.value
|
||||
@@ -270,7 +270,7 @@ exports.newAlgorithmicTradingBotModulesOrdersCalculations = function (processInd
|
||||
async function feesPaidCalculation(tradingEngineStage, tradingSystemOrder, tradingEngineOrder, order, applyFeePercentage) {
|
||||
/*
|
||||
Within the order information received from the exchange we can not see the fees paid so we need to
|
||||
calculate them ourselves. Knwowing the Fees Paid is critical to later update the balances correctly,
|
||||
calculate them ourselves. Knowing the Fees Paid is critical to later update the balances correctly,
|
||||
since at every trade we will receive less than just the Actual Size. In fact we will receive the Actual
|
||||
Size minus the Fees Paid.
|
||||
|
||||
@@ -324,7 +324,7 @@ exports.newAlgorithmicTradingBotModulesOrdersCalculations = function (processInd
|
||||
/*
|
||||
This calculation is for informational purposes, so that users do not have to calculate
|
||||
it by themselves. The Amount Received out of the trade depends if we are Buying or Selling
|
||||
the Base Asset. If we are Buying, then the Amount Receiced will be in Base Asset. If we
|
||||
the Base Asset. If we are Buying, then the Amount Received will be in Base Asset. If we
|
||||
are selling then it will be in Quoted Asset.
|
||||
*/
|
||||
|
||||
|
||||
+6
-6
@@ -36,7 +36,7 @@ exports.newAlgorithmicTradingBotModulesOrdersSimulations = function (processInde
|
||||
async function actualSizeSimulation(tradingEngineStage, tradingSystemOrder, tradingEngineOrder, applyFeePercentage) {
|
||||
/*
|
||||
The Actual Size is the size the exchange accepts for the order,
|
||||
regarless of the size sent in the request to the exchange.
|
||||
regardless of the size sent in the request to the exchange.
|
||||
|
||||
While backtesting and paper trading, we do not really need to
|
||||
simulate an Actual Size. We will just copy to that field the
|
||||
@@ -81,7 +81,7 @@ exports.newAlgorithmicTradingBotModulesOrdersSimulations = function (processInde
|
||||
switch (tradingEngineOrder.type) {
|
||||
case 'Market Order': {
|
||||
|
||||
/* Actual Rate is simulated based on the Session Paremeters */
|
||||
/* Actual Rate is simulated based on the Session Parameters */
|
||||
let slippageAmount = tradingEngineOrder.rate.value * sessionParameters.slippage.config.marketOrderRate / 100
|
||||
if (slippageAmount !== 0) {
|
||||
switch (tradingSystemOrder.type) {
|
||||
@@ -197,7 +197,7 @@ exports.newAlgorithmicTradingBotModulesOrdersSimulations = function (processInde
|
||||
Until here we have got the Actual Rate based on the formula definition or based on session parameters slippage.
|
||||
The last check is about watching what happened in the market. Let's remember that the exchange will
|
||||
fill the order with the best possible matches at it's order book. That means that if the rate
|
||||
we set for the order was too low (for a sale order) or too hight (for a buy order), the actual rate
|
||||
we set for the order was too low (for a sale order) or too height (for a buy order), the actual rate
|
||||
should be better than expected.
|
||||
|
||||
We don't know what it is at the order book, but whe know that the last candle includes trades that bounced between
|
||||
@@ -303,7 +303,7 @@ exports.newAlgorithmicTradingBotModulesOrdersSimulations = function (processInde
|
||||
if (tradingEngineOrder.orderStatistics.actualRate.value === tradingEngineOrder.rate.value) { return }
|
||||
/*
|
||||
Since the Actual Rate might have changed, we need to recalculate the Size Placed, where we accumulate all the Size Placed of
|
||||
all orders of a Stage. For Base Asset there is nothing to do, since the Actual Rate does not have an inpact on it.
|
||||
all orders of a Stage. For Base Asset there is nothing to do, since the Actual Rate does not have an impact on it.
|
||||
|
||||
For Quoted Asset, we need to first unaccount what this same orded added before to Size Placed (with the precious Actual Size) and
|
||||
account with the new Actual Size.
|
||||
@@ -462,7 +462,7 @@ exports.newAlgorithmicTradingBotModulesOrdersSimulations = function (processInde
|
||||
}
|
||||
|
||||
/*
|
||||
Another way to simulate the Fees Paid is by using the Session Paremeters configuration for Fees.
|
||||
Another way to simulate the Fees Paid is by using the Session Parameters configuration for Fees.
|
||||
*/
|
||||
switch (tradingEngineOrder.type) {
|
||||
case 'Market Order': {
|
||||
@@ -510,7 +510,7 @@ exports.newAlgorithmicTradingBotModulesOrdersSimulations = function (processInde
|
||||
/*
|
||||
This simulation is for informational purposes, so that users do not have to calculate
|
||||
it by themselves. The Amount Received out of the trade depends if we are Buying or Selling
|
||||
the Base Asset. If we are Buying, then the Amount Receiced will be in Base Asset. If we
|
||||
the Base Asset. If we are Buying, then the Amount Received will be in Base Asset. If we
|
||||
are selling then it will be in Quoted Asset.
|
||||
*/
|
||||
|
||||
|
||||
+4
-4
@@ -135,7 +135,7 @@ exports.newAlgorithmicTradingBotModulesSnapshots = function(processIndex) {
|
||||
function evalNode(node) {
|
||||
if (node === undefined) { return }
|
||||
|
||||
/* Here we check if there is a codition to be evaluated */
|
||||
/* Here we check if there is a condition to be evaluated */
|
||||
if (node.type === 'Condition') {
|
||||
/* We will eval this condition */
|
||||
evalCondition(node)
|
||||
@@ -154,7 +154,7 @@ exports.newAlgorithmicTradingBotModulesSnapshots = function(processIndex) {
|
||||
if (schemaDocument === undefined) { return }
|
||||
|
||||
if (schemaDocument.childrenNodesProperties !== undefined) {
|
||||
let previousPropertyName // Since there are cases where there are many properties with the same name,because they can hold nodes of different types but only one at the time, we have to avoind counting each property of those as individual children.
|
||||
let previousPropertyName // Since there are cases where there are many properties with the same name,because they can hold nodes of different types but only one at the time, we have to avoid counting each property of those as individual children.
|
||||
for (let i = 0; i < schemaDocument.childrenNodesProperties.length; i++) {
|
||||
let property = schemaDocument.childrenNodesProperties[i]
|
||||
|
||||
@@ -398,7 +398,7 @@ exports.newAlgorithmicTradingBotModulesSnapshots = function(processIndex) {
|
||||
if (record[record.length - 1] === undefined && contentArray.length > 0) {
|
||||
|
||||
let rowToMutateArray = contentArray[contentArray.length - 1].split(',')
|
||||
// check if are for sure on the same tradenumber and merge the data and remove previous line incl separator
|
||||
// check if are for sure on the same trade number and merge the data and remove previous line incl separator
|
||||
if (rowToMutateArray[0] == record[0]) {
|
||||
record.pop()
|
||||
rowToMutateArray.splice(0, record.length)
|
||||
@@ -451,7 +451,7 @@ exports.newAlgorithmicTradingBotModulesSnapshots = function(processIndex) {
|
||||
function onFileReceived(err, text) {
|
||||
if (err.result === TS.projects.foundations.globals.standardResponses.DEFAULT_OK_RESPONSE.result) {
|
||||
try {
|
||||
// remove the last linebreak and seperator which is introduced extra during save
|
||||
// remove the last linebreak and separator which is introduced extra during save
|
||||
text = text.replace(/\n$/, '')
|
||||
text = text.replace(/\r\n$/, '')
|
||||
writeOutput(text)
|
||||
|
||||
+5
-5
@@ -1,6 +1,6 @@
|
||||
exports.newAlgorithmicTradingBotModulesTradingEngine = function (processIndex) {
|
||||
/*
|
||||
We call the Trading Engine to the data structure that is needed in order to exevute the
|
||||
We call the Trading Engine to the data structure that is needed in order to execute the
|
||||
trading protocol with the specific rules defined at the Trading System.
|
||||
*/
|
||||
|
||||
@@ -31,7 +31,7 @@ exports.newAlgorithmicTradingBotModulesTradingEngine = function (processIndex) {
|
||||
|
||||
if (TS.projects.foundations.globals.processVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).IS_SESSION_FIRST_LOOP === true) {
|
||||
/*
|
||||
Here we will go through all the nodes in the Trading Engine hiriarchy and
|
||||
Here we will go through all the nodes in the Trading Engine hierarchy and
|
||||
apply the initial value to the value property when needed
|
||||
*/
|
||||
initializeNode(tradingEngine)
|
||||
@@ -116,7 +116,7 @@ exports.newAlgorithmicTradingBotModulesTradingEngine = function (processIndex) {
|
||||
if (schemaDocument === undefined) { return }
|
||||
|
||||
if (schemaDocument.childrenNodesProperties !== undefined) {
|
||||
let previousPropertyName // Since there are cases where there are many properties with the same name,because they can hold nodes of different types but only one at the time, we have to avoind counting each property of those as individual children.
|
||||
let previousPropertyName // Since there are cases where there are many properties with the same name,because they can hold nodes of different types but only one at the time, we have to avoid counting each property of those as individual children.
|
||||
for (let i = 0; i < schemaDocument.childrenNodesProperties.length; i++) {
|
||||
let property = schemaDocument.childrenNodesProperties[i]
|
||||
|
||||
@@ -155,7 +155,7 @@ exports.newAlgorithmicTradingBotModulesTradingEngine = function (processIndex) {
|
||||
if (schemaDocument === undefined) { return }
|
||||
|
||||
if (schemaDocument.childrenNodesProperties !== undefined) {
|
||||
let previousPropertyName // Since there are cases where there are many properties with the same name,because they can hold nodes of different types but only one at the time, we have to avoind counting each property of those as individual children.
|
||||
let previousPropertyName // Since there are cases where there are many properties with the same name,because they can hold nodes of different types but only one at the time, we have to avoid counting each property of those as individual children.
|
||||
for (let i = 0; i < schemaDocument.childrenNodesProperties.length; i++) {
|
||||
let property = schemaDocument.childrenNodesProperties[i]
|
||||
|
||||
@@ -198,7 +198,7 @@ exports.newAlgorithmicTradingBotModulesTradingEngine = function (processIndex) {
|
||||
if (schemaDocument === undefined) { return }
|
||||
|
||||
if (schemaDocument.childrenNodesProperties !== undefined) {
|
||||
let previousPropertyName // Since there are cases where there are many properties with the same name,because they can hold nodes of different types but only one at the time, we have to avoind counting each property of those as individual children.
|
||||
let previousPropertyName // Since there are cases where there are many properties with the same name,because they can hold nodes of different types but only one at the time, we have to avoid counting each property of those as individual children.
|
||||
for (let i = 0; i < schemaDocument.childrenNodesProperties.length; i++) {
|
||||
let property = schemaDocument.childrenNodesProperties[i]
|
||||
|
||||
|
||||
+2
-2
@@ -108,7 +108,7 @@ exports.newAlgorithmicTradingBotModulesTradingEpisode = function (processIndex)
|
||||
|
||||
function updateStatistics() {
|
||||
|
||||
/* Daus Calculation */
|
||||
/* Days Calculation */
|
||||
tradingEngine.tradingCurrent.tradingEpisode.tradingEpisodeStatistics.days.value =
|
||||
tradingEngine.tradingCurrent.tradingEpisode.tradingEpisodeCounters.periods.value *
|
||||
sessionParameters.timeFrame.config.value /
|
||||
@@ -261,7 +261,7 @@ exports.newAlgorithmicTradingBotModulesTradingEpisode = function (processIndex)
|
||||
}
|
||||
|
||||
function updateDistanceToTradingEventsCounters() {
|
||||
/* Keeping Distance Counters Up-to-date while avoinding counting before the first event happens. */
|
||||
/* Keeping Distance Counters Up-to-date while avoiding counting before the first event happens. */
|
||||
if (
|
||||
tradingEngine.tradingCurrent.tradingEpisode.distanceToTradingEvent.triggerOn.value > 0
|
||||
) {
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
exports.newAlgorithmicTradingBotModulesTradingExecution = function (processIndex) {
|
||||
/*
|
||||
The Trading Execution modules manages the execution nodes and execution algoritms.
|
||||
The Trading Execution modules manages the execution nodes and execution algorithms.
|
||||
*/
|
||||
const MODULE_NAME = 'Trading Execution'
|
||||
|
||||
|
||||
+10
-10
@@ -226,7 +226,7 @@ exports.newAlgorithmicTradingBotModulesTradingOrders = function (processIndex) {
|
||||
let situationName = await checkOrderEvent(tradingSystemOrder.cancelOrderEvent, tradingSystemOrder, executionAlgorithm, executionNode)
|
||||
if (situationName !== undefined) {
|
||||
|
||||
/* Simulate Order Cancelation, if needed. */
|
||||
/* Simulate Order Cancellation, if needed. */
|
||||
simulateCancelOrder(tradingEngineStage, tradingSystemOrder, tradingEngineOrder, 'Cancel Event')
|
||||
|
||||
/* Cancel the order at the Exchange, if needed. */
|
||||
@@ -731,8 +731,8 @@ exports.newAlgorithmicTradingBotModulesTradingOrders = function (processIndex) {
|
||||
/* Close this Order */
|
||||
tradingEngineOrder.status.value = 'Closed'
|
||||
/*
|
||||
We must be carefull here not to overide an already defined exitType. It can happen
|
||||
for instance that the order was cancellerd from the but veryfing the cancellation
|
||||
We must be carefully here not to override an already defined exitType. It can happen
|
||||
for instance that the order was cancelled from the but verifying the cancellation
|
||||
was not possible because of a connection to the exchange problem. In that case
|
||||
the exit type was defined but the order was kept open until the verification could be done.
|
||||
*/
|
||||
@@ -764,7 +764,7 @@ exports.newAlgorithmicTradingBotModulesTradingOrders = function (processIndex) {
|
||||
}
|
||||
|
||||
/*
|
||||
If the order happens to be at least partially filled, there is a syncronization work
|
||||
If the order happens to be at least partially filled, there is a synchronization work
|
||||
we need to do, that includes discovering which is the Actual Rate the order is being filled,
|
||||
the Fees Paid and many other thing we need to account for.
|
||||
*/
|
||||
@@ -1118,7 +1118,7 @@ exports.newAlgorithmicTradingBotModulesTradingOrders = function (processIndex) {
|
||||
if (order.status === 'NotFound') {
|
||||
/*
|
||||
Some exchanges, like Coinbase Pro, deletes orders after being cancelled, and when we request information
|
||||
about them, it returns null. We will interprate this as ORDER NOT FOUND.
|
||||
about them, it returns null. We will interpret this as ORDER NOT FOUND.
|
||||
*/
|
||||
const message = 'Order Not Found at the Exchange'
|
||||
let docs = {
|
||||
@@ -1136,8 +1136,8 @@ exports.newAlgorithmicTradingBotModulesTradingOrders = function (processIndex) {
|
||||
]
|
||||
)
|
||||
/*
|
||||
We must be carefull here not to overide an already defined exitType. It can happen
|
||||
for instance that the order was cancellerd from the but veryfing the cancellation
|
||||
We must be carefully here not to overide an already defined exitType. It can happen
|
||||
for instance that the order was cancelled from the but verifying the cancellation
|
||||
was not possible because of a connection to the exchange problem. In that case
|
||||
the exit type was defined but the order was kept open until the verification could be done.
|
||||
*/
|
||||
@@ -1148,7 +1148,7 @@ exports.newAlgorithmicTradingBotModulesTradingOrders = function (processIndex) {
|
||||
|
||||
/*
|
||||
Close this Order. Note that we are not closing the order until we have the exchange
|
||||
response with the order details that we can use to syncronize with our accoounting.
|
||||
response with the order details that we can use to synchronize with our accounting.
|
||||
Otherwise if the connection to the exchange fails, we would have a closed order not
|
||||
accounted in any way.
|
||||
*/
|
||||
@@ -1182,8 +1182,8 @@ exports.newAlgorithmicTradingBotModulesTradingOrders = function (processIndex) {
|
||||
async function recalculateStageSize(tradingEngineStage, tradingEngineOrder) {
|
||||
/*
|
||||
Since the order is Cancelled, we need to adjust the stage sizePlaced. Remember that the Stage
|
||||
Size Placed accumulates for each asset, the order size placed at the exchange. A cancelation means that
|
||||
only the part filled can be considered placed, so we need to substract from the stage size
|
||||
Size Placed accumulates for each asset, the order size placed at the exchange. A cancellation means that
|
||||
only the part filled can be considered placed, so we need to subtract from the stage size
|
||||
the remainder. To achieve this with the information we currently have, we are going first
|
||||
to unaccount the order actual size, and the account only the sizeFilled + the feesPaid.
|
||||
*/
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
exports.newAlgorithmicTradingBotModulesTradingOutput = function (processIndex) {
|
||||
/*
|
||||
This module will load if necesary all the data outputs so that they can be appended with new
|
||||
This module will load if necessary all the data outputs so that they can be appended with new
|
||||
records if needed. After running the simulation, it will save all the data outputs.
|
||||
*/
|
||||
const MODULE_NAME = 'Trading Output'
|
||||
|
||||
+1
-1
@@ -71,7 +71,7 @@ exports.newAlgorithmicTradingBotModulesTradingPosition = function (processIndex)
|
||||
/* Updating Episode Counters */
|
||||
tradingEngine.tradingCurrent.tradingEpisode.tradingEpisodeCounters.positions.value++
|
||||
|
||||
/* Inicializing this counter */
|
||||
/* Initializing this counter */
|
||||
tradingEngine.tradingCurrent.tradingEpisode.distanceToTradingEvent.takePosition.value = 1
|
||||
|
||||
/* Remember the balance we had before taking the position to later calculate profit or loss */
|
||||
|
||||
+2
-2
@@ -65,7 +65,7 @@
|
||||
This is the Date that is going to be used across the execution of this Trading Process.
|
||||
We need this because it has a different life cycle than the processData stored at the
|
||||
Trading Engine data structure. This date has to remain the same during the whole execution
|
||||
of the Trading Process until the end, inclusind the writing of Data Ranges and Status Reports.
|
||||
of the Trading Process until the end, including the writing of Data Ranges and Status Reports.
|
||||
The processDate of the Trading Engine data structure on the other hand can be changed during
|
||||
the simulation loop, once we discover that all candles from a certain date have benn processed.
|
||||
Here is the point where we sync one and the other.
|
||||
@@ -108,7 +108,7 @@
|
||||
Here we check if we need to get Daily Files or not. As an optimization, when
|
||||
we are running on a Time Frame of 1hs or above, we are not going to load
|
||||
dependencies on Daily Files. The way we recognize that is by checking if
|
||||
we alreaady set a value to currentTimeFrame.value. We are also not going to loop
|
||||
we already set a value to currentTimeFrame.value. We are also not going to loop
|
||||
through days if we are processing market files.
|
||||
*/
|
||||
if (currentTimeFrame.value) {
|
||||
|
||||
+10
-10
@@ -95,14 +95,14 @@ exports.newAlgorithmicTradingBotModulesTradingRecords = function (processIndex)
|
||||
*/
|
||||
for (let index = 0; index < productRoot.length; index++) {
|
||||
/*
|
||||
The Product Root Node is the root of the node hiriarchy from where we are going to extract the record values.
|
||||
The Product Root Node is the root of the node hierarchy from where we are going to extract the record values.
|
||||
*/
|
||||
let productRootNode = productRoot[index]
|
||||
let record = scanRecordDefinition(product, productRootNode, index)
|
||||
if (record !== undefined) {
|
||||
/*
|
||||
We will add the index value to the record itself, so that the plotter can know to which
|
||||
brach of the trading engine data structure it belongs.
|
||||
branch of the trading engine data structure it belongs.
|
||||
*/
|
||||
record.push(index)
|
||||
persistIndividualRecord(record, product, outputDatasetArray)
|
||||
@@ -114,7 +114,7 @@ exports.newAlgorithmicTradingBotModulesTradingRecords = function (processIndex)
|
||||
the record to be saved at the output file.
|
||||
*/
|
||||
/*
|
||||
The Product Root Node is the root of the node hiriarchy from where we are going to extract the record values.
|
||||
The Product Root Node is the root of the node hierarchy from where we are going to extract the record values.
|
||||
*/
|
||||
let productRootNode = productRoot
|
||||
let record = scanRecordDefinition(product, productRootNode)
|
||||
@@ -131,7 +131,7 @@ exports.newAlgorithmicTradingBotModulesTradingRecords = function (processIndex)
|
||||
for (let j = 0; j < product.record.properties.length; j++) {
|
||||
let recordProperty = product.record.properties[j]
|
||||
/*
|
||||
The Property Root Node is the Root of the Hiriarchy branch we must find in order
|
||||
The Property Root Node is the Root of the Hierarchy branch we must find in order
|
||||
to get the node where we are going to extract the value. Initially
|
||||
we point it to the Product Root Node, because that is the default in case
|
||||
a property does not have at its configuration a different nodePath configured
|
||||
@@ -150,7 +150,7 @@ exports.newAlgorithmicTradingBotModulesTradingRecords = function (processIndex)
|
||||
}
|
||||
}
|
||||
/*
|
||||
The Target Node is the node from where we are going to exctract the value.
|
||||
The Target Node is the node from where we are going to extract the value.
|
||||
We will use the codeName of the Record Property to match it with
|
||||
any of the properties of the Root Node to get the Target Node.
|
||||
*/
|
||||
@@ -170,7 +170,7 @@ exports.newAlgorithmicTradingBotModulesTradingRecords = function (processIndex)
|
||||
targetNode = propertyRootNode[recordProperty.config.childProperty]
|
||||
}
|
||||
/*
|
||||
It can happen that intead of having a Node in targetNode what we have is an
|
||||
It can happen that instead of having a Node in targetNode what we have is an
|
||||
array of nodes. We need to pick one of the elements of the array and for that
|
||||
we use the Index value we find at the configuration of the Record Property.
|
||||
*/
|
||||
@@ -187,7 +187,7 @@ exports.newAlgorithmicTradingBotModulesTradingRecords = function (processIndex)
|
||||
of Nodes defined in the Record Properties but not all of them exist at the Root Node.
|
||||
We filter out those cases by not extracting the value from the value property.
|
||||
*/
|
||||
let value = 0 // This is a default value, since we do not want null in files because it breakes JSON format.
|
||||
let value = 0 // This is a default value, since we do not want null in files because it brakes JSON format.
|
||||
if (targetNode !== undefined) {
|
||||
if (targetNode.type !== undefined) {
|
||||
/*
|
||||
@@ -251,14 +251,14 @@ exports.newAlgorithmicTradingBotModulesTradingRecords = function (processIndex)
|
||||
/*
|
||||
When dealing with Daily Files, we need to avoid to write an open object at the last 'candle' of the day,
|
||||
since the object will be duplicated on the next day. How do we know we are positioned at the last candle
|
||||
of the day? Easy: the end of the candle must be 1 millisecod before the next day. That happens at any
|
||||
of the day? Easy: the end of the candle must be 1 millisecond before the next day. That happens at any
|
||||
time frame.
|
||||
*/
|
||||
let currentDay = new Date(tradingEngine.tradingCurrent.tradingEpisode.candle.end.value)
|
||||
let nextDay = new Date(tradingEngine.tradingCurrent.tradingEpisode.candle.end.value + 1)
|
||||
if (currentDay.getUTCDate() !== nextDay.getUTCDate()) {
|
||||
/*
|
||||
We will save the object only if it is closed, becasuse we are at the last candle of the day.
|
||||
We will save the object only if it is closed, because we are at the last candle of the day.
|
||||
*/
|
||||
if (propertyValue === product.config.propertyValueThatClosesObject) {
|
||||
outputDatasetArray.push(record)
|
||||
@@ -275,7 +275,7 @@ exports.newAlgorithmicTradingBotModulesTradingRecords = function (processIndex)
|
||||
}
|
||||
else {
|
||||
/*
|
||||
For Market Files we will add a record everytime that proeprty value does not match this
|
||||
For Market Files we will add a record everytime that property value does not match this
|
||||
*/
|
||||
if (propertyValue !== product.config.propertyValueThatPreventsSavingObject) {
|
||||
outputDatasetArray.push(record)
|
||||
|
||||
+10
-10
@@ -1,6 +1,6 @@
|
||||
exports.newAlgorithmicTradingBotModulesTradingSimulation = function (processIndex) {
|
||||
/*
|
||||
This Module represents the trading simulacion. Escentially a loop through a set of candles and
|
||||
This Module represents the trading simulation. Essentially a loop through a set of candles and
|
||||
the execution at each loop cycle of the Trading System Protocol.
|
||||
*/
|
||||
const MODULE_NAME = 'Trading Simulation -> ' + TS.projects.foundations.globals.taskConstants.TASK_NODE.bot.processes[processIndex].session.name
|
||||
@@ -134,7 +134,7 @@ exports.newAlgorithmicTradingBotModulesTradingSimulation = function (processInde
|
||||
|
||||
TS.projects.foundations.globals.processModuleObjects.MODULE_OBJECTS_BY_PROCESS_INDEX_MAP.get(processIndex).TRADING_ENGINE_MODULE_OBJECT.setCurrentCandle(candle) // We move the current candle we are standing at, to the trading engine data structure to make it available to anyone, including conditions and formulas.
|
||||
|
||||
/* We emit a heart beat so that the UI can now where we are at the overal process.*/
|
||||
/* We emit a heart beat so that the UI can now where we are at the overall process.*/
|
||||
heartBeat()
|
||||
|
||||
/* Opening the Episode, if needed. */
|
||||
@@ -157,7 +157,7 @@ exports.newAlgorithmicTradingBotModulesTradingSimulation = function (processInde
|
||||
|
||||
/*
|
||||
Do the stuff needed previous to the run like
|
||||
Episode Counters and Statistics update. Mantaince is done
|
||||
Episode Counters and Statistics update. Maintenance is done
|
||||
once per simulation candle.
|
||||
*/
|
||||
tradingSystemModuleObject.mantain()
|
||||
@@ -176,7 +176,7 @@ exports.newAlgorithmicTradingBotModulesTradingSimulation = function (processInde
|
||||
|
||||
/*
|
||||
We check if we need to stop before appending the records so that the stop
|
||||
reason is also propery recorded. Note also that we check this after the first
|
||||
reason is also properly recorded. Note also that we check this after the first
|
||||
cycle, where orders have not been submitted to the exchange yet, but we
|
||||
had the chance to check for the status of placed orders or even cancel
|
||||
the ones that needed cancellation.
|
||||
@@ -312,7 +312,7 @@ exports.newAlgorithmicTradingBotModulesTradingSimulation = function (processInde
|
||||
let currentDate = new Date(heartBeatDate)
|
||||
let percentage = TS.projects.foundations.utilities.dateTimeFunctions.getPercentage(fromDate, currentDate, lastDate)
|
||||
/*
|
||||
Theere are a few tasks that we need to do only when the date changes,
|
||||
There are a few tasks that we need to do only when the date changes,
|
||||
otherwise it would be suboptimal.
|
||||
*/
|
||||
if (heartBeatDate.valueOf() !== previousHeartBeatDate) {
|
||||
@@ -328,7 +328,7 @@ exports.newAlgorithmicTradingBotModulesTradingSimulation = function (processInde
|
||||
TS.projects.foundations.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.newInternalLoop(currentDate, percentage)
|
||||
}
|
||||
|
||||
/* Date only hearbeat */
|
||||
/* Date only heartbeat */
|
||||
if (sessionParameters.heartbeats.config.date === true && sessionParameters.heartbeats.config.candleIndex === false) {
|
||||
hartbeatText = hartbeatText + currentDateString
|
||||
TS.projects.foundations.functionLibraries.processFunctions.processHeartBeat(processIndex, hartbeatText, percentage)
|
||||
@@ -337,7 +337,7 @@ exports.newAlgorithmicTradingBotModulesTradingSimulation = function (processInde
|
||||
}
|
||||
|
||||
/*
|
||||
When the Candle Index nees to be shown, then we can not send the hearbet
|
||||
When the Candle Index needs to be shown, then we can not send the heartbeat
|
||||
only when the dates changes, we have to send it for every candle.
|
||||
It might also contain the date information.
|
||||
*/
|
||||
@@ -354,7 +354,7 @@ exports.newAlgorithmicTradingBotModulesTradingSimulation = function (processInde
|
||||
|
||||
function positionDataStructuresAtCurrentCandle() {
|
||||
/*
|
||||
In conditions and Formulas, we want users to have an easy sintax to refer to indicators. In order to achieve that, we need the user to have
|
||||
In conditions and Formulas, we want users to have an easy syntax to refer to indicators. In order to achieve that, we need the user to have
|
||||
easy access to the current candle for instance, or the current bollinger band, meaning the one the Simulation is currently standing at.
|
||||
For that reason we do the following processing, to have at the chart data structure the current objects of each indicator / time frame.
|
||||
*/
|
||||
@@ -483,7 +483,7 @@ exports.newAlgorithmicTradingBotModulesTradingSimulation = function (processInde
|
||||
Note: for Daily Files, this means that the last candle of each day will never be processed.
|
||||
|
||||
The first +1 is because array indexes are based on 0.
|
||||
The second +1 is because we need to compare the next candle (remember that the loops allways avoid the
|
||||
The second +1 is because we need to compare the next candle (remember that the loops always avoid the
|
||||
last candle of the dataset available.)
|
||||
*/
|
||||
if (tradingEngine.tradingCurrent.tradingEpisode.candle.index.value + 1 + 1 === candles.length) {
|
||||
@@ -550,7 +550,7 @@ exports.newAlgorithmicTradingBotModulesTradingSimulation = function (processInde
|
||||
}
|
||||
|
||||
function checkMinimunAndMaximunBalance() {
|
||||
/* Checks for Minimun and Maximun Balance. We do the check while not inside any strategy only. */
|
||||
/* Checks for Minimum and Maximum Balance. We do the check while not inside any strategy only. */
|
||||
if (
|
||||
tradingEngine.tradingCurrent.strategy.index.value === tradingEngine.tradingCurrent.strategy.index.config.initialValue
|
||||
) {
|
||||
|
||||
+9
-9
@@ -422,7 +422,7 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) {
|
||||
|
||||
/*
|
||||
The system allows the user not to define a Manage Stage, because the Manage Stage is optional.
|
||||
Here we are going to see if that is the case and if it is, we will inmidiatelly consider
|
||||
Here we are going to see if that is the case and if it is, we will immediately consider
|
||||
the Manage Stage as closed.
|
||||
*/
|
||||
if (manageStage === undefined) {
|
||||
@@ -820,7 +820,7 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) {
|
||||
if (tradingEngine.tradingCurrent.strategyCloseStage.status.value === 'Opening') {
|
||||
/*
|
||||
The system allows the user not to define a close stage, because the close stage is optional.
|
||||
Here we are goint to see if that is the case and if it is, we will inmidiatelly consider
|
||||
Here we are going to see if that is the case and if it is, we will immediately consider
|
||||
the close stage as closed.
|
||||
*/
|
||||
if (tradingSystem.tradingStrategies[tradingEngine.tradingCurrent.strategy.index.value].closeStage === undefined) {
|
||||
@@ -1024,7 +1024,7 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) {
|
||||
The Target Size is defined by the end user either in Base Asset or Quoted Asset.
|
||||
Whatever the user chooses defines also the way we check if the Target was met.
|
||||
Why? Because the counterparty target is estimated with the Target Rate and it
|
||||
is not syncronized with the reality we later learn when the exchange tell us the
|
||||
is not synchronized with the reality we later learn when the exchange tell us the
|
||||
actual rate each of the orders where executed at.
|
||||
|
||||
For the same reason that the user does not know exactly which is the rate the orders
|
||||
@@ -1041,7 +1041,7 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) {
|
||||
}
|
||||
/*
|
||||
We will also implement a mechanism to allow users declare an absolute value to add
|
||||
to the Size Filled before checking it againt the Stage Target Size.
|
||||
to the Size Filled before checking it against the Stage Target Size.
|
||||
*/
|
||||
let ABSOLUTE_DUST_IN_BASE_ASSET = 0
|
||||
if (tradingSystemStage.config.absoluteDustInBaseAsset !== undefined) {
|
||||
@@ -1151,13 +1151,13 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) {
|
||||
}
|
||||
|
||||
/*
|
||||
The way the begining and end of the Stages object works is as follows:
|
||||
This object begins with the last cycle, that is the current cycle diplaced
|
||||
The way the beginning and end of the Stages object works is as follows:
|
||||
This object begins with the last cycle, that is the current cycle displayed
|
||||
backwards to the current candle. And it ends at the end of the last cycle.
|
||||
During mantainance, we add the time frame of the candle, since we assume it
|
||||
During maintenance, we add the time frame of the candle, since we assume it
|
||||
will survive the 2 cycles without the end being updated. If it closes,
|
||||
then we update the end to the end of the last cycle, overrinding the
|
||||
mantainance if needed. If we assume that in the same cycle there will be
|
||||
then we update the end to the end of the last cycle, overriding the
|
||||
maintenance if needed. If we assume that in the same cycle there will be
|
||||
no closing and opening of the same type of object, then there can be no
|
||||
overlap.
|
||||
*/
|
||||
|
||||
+4
-4
@@ -221,7 +221,7 @@ exports.newAlgorithmicTradingBotModulesTradingSystem = function (processIndex) {
|
||||
|
||||
} catch (err) {
|
||||
/*
|
||||
If an error ocurred during execution, it was alreeady logged and
|
||||
If an error occurred during execution, it was already logged and
|
||||
included at the errors array. That means we need to do nothing here,
|
||||
just prevent the execution to be halted for not handling exceptions.
|
||||
*/
|
||||
@@ -237,14 +237,14 @@ exports.newAlgorithmicTradingBotModulesTradingSystem = function (processIndex) {
|
||||
function evalNode(node, evaluating, descendentOfNodeType, isDescendent) {
|
||||
if (node === undefined) { return }
|
||||
|
||||
/* Verify if this node is decendent of the specified node type */
|
||||
/* Verify if this node is descendent of the specified node type */
|
||||
if (isDescendent !== true) {
|
||||
if (node.type === descendentOfNodeType) {
|
||||
isDescendent = true
|
||||
}
|
||||
}
|
||||
|
||||
/* Here we check if there is a codition to be evaluated */
|
||||
/* Here we check if there is a condition to be evaluated */
|
||||
if (node.type === 'Condition' && evaluating === 'Conditions') {
|
||||
/* We will eval this condition */
|
||||
if (isDescendent === true) {
|
||||
@@ -276,7 +276,7 @@ exports.newAlgorithmicTradingBotModulesTradingSystem = function (processIndex) {
|
||||
if (schemaDocument === undefined) { return }
|
||||
|
||||
if (schemaDocument.childrenNodesProperties !== undefined) {
|
||||
let previousPropertyName // Since there are cases where there are many properties with the same name,because they can hold nodes of different types but only one at the time, we have to avoind counting each property of those as individual children.
|
||||
let previousPropertyName // Since there are cases where there are many properties with the same name,because they can hold nodes of different types but only one at the time, we have to avoid counting each property of those as individual children.
|
||||
for (let i = 0; i < schemaDocument.childrenNodesProperties.length; i++) {
|
||||
let property = schemaDocument.childrenNodesProperties[i]
|
||||
|
||||
|
||||
@@ -63,8 +63,8 @@
|
||||
/* We tell the UI that we are running. */
|
||||
TS.projects.foundations.functionLibraries.processFunctions.processHeartBeat(processIndex, undefined, undefined, "Running...")
|
||||
|
||||
/* We define the datetime for the process that we are running now. This will be the official processing time for both the infraestructure and the bot. */
|
||||
TS.projects.foundations.globals.processVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).PROCESS_DATETIME = new Date(); // This will be considered the process date and time, so as to have it consistenly all over the execution.
|
||||
/* We define the datetime for the process that we are running now. This will be the official processing time for both the infrastructure and the bot. */
|
||||
TS.projects.foundations.globals.processVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).PROCESS_DATETIME = new Date(); // This will be considered the process date and time, so as to have it consistently all over the execution.
|
||||
|
||||
/* Main Loop Console Logging */
|
||||
TS.projects.foundations.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.newMainLoop()
|
||||
@@ -95,7 +95,7 @@
|
||||
return
|
||||
}
|
||||
|
||||
/* We will prepare first the infraestructure needed for the bot to run. There are 3 modules we need to sucessfullly initialize first. */
|
||||
/* We will prepare first the infrastructure needed for the bot to run. There are 3 modules we need to sucessfullly initialize first. */
|
||||
|
||||
let processExecutionEvents
|
||||
let userBot;
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
return;
|
||||
}
|
||||
/*
|
||||
We will store here the session key, which we will need everytine
|
||||
We will store here the session key, which we will need everytime
|
||||
we need to emit an event related to the session itself.
|
||||
*/
|
||||
let VARIABLES_BY_PROCESS_INDEX = TS.projects.foundations.globals.processVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex)
|
||||
@@ -109,7 +109,7 @@
|
||||
return
|
||||
}
|
||||
|
||||
/* We are going to initialize here these constants whose values are comming at the event. */
|
||||
/* We are going to initialize here these constants whose values are coming at the event. */
|
||||
TS.projects.foundations.globals.processConstants.CONSTANTS_BY_PROCESS_INDEX_MAP.get(processIndex).TRADING_SYSTEM_NODE = JSON.parse(message.event.tradingSystem)
|
||||
TS.projects.foundations.globals.processConstants.CONSTANTS_BY_PROCESS_INDEX_MAP.get(processIndex).TRADING_ENGINE_NODE = JSON.parse(message.event.tradingEngine)
|
||||
TS.projects.foundations.globals.processConstants.CONSTANTS_BY_PROCESS_INDEX_MAP.get(processIndex).SESSION_NODE = JSON.parse(message.event.session)
|
||||
|
||||
Reference in new issue
Block a user