diff --git a/BottomSpace/PlayStopButton.js b/BottomSpace/PlayStopButton.js
index a287ac6d7..bdc545994 100644
--- a/BottomSpace/PlayStopButton.js
+++ b/BottomSpace/PlayStopButton.js
@@ -1,4 +1,4 @@
-
+
function newPlayStopButton () {
var thisObject = {
container: undefined,
@@ -56,7 +56,7 @@ function newPlayStopButton () {
}
function resize () {
- container.frame.position.x = viewPort.visibleArea.topLeft.x + 150 * 4
+ container.frame.position.x = viewPort.visibleArea.topLeft.x + 150 * 5
container.frame.position.y = viewPort.visibleArea.bottomLeft.y
}
diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md
index c71b685b4..4b37b0e16 100644
--- a/CODE_OF_CONDUCT.md
+++ b/CODE_OF_CONDUCT.md
@@ -34,7 +34,7 @@ This Code of Conduct applies both within project spaces and in public spaces whe
## Enforcement
-Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at feedback at advancedalgos dot org. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
+Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team using the online form in the contacts page of the superalgos.org website. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 1b0e7b3d8..c67e8d115 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,51 +1,45 @@
-# Contributing
+# Contributing
-We are thrilled you are interested in contributing to the CanvasApp. Your help may be essential to the project's success and we want you in!
+We are thrilled you are interested in contributing to this repository. Your help may be essential to the project's success and we want you in!
-Advanced Algos is a startup, currently at a very early stage. Although CanvasApp is not open source software yet, we do welcome contributions from the community.
+Superalgos is a collective project, currently at a very early stage. Although this repository is not open source software yet, we do welcome contributions from the community.
-Contributions are deemed _work for hire_ and --as such-- are compensated on a case by case basis, with ALGO tokens. Contributors agree to provide an express grant of patent rights for their contributions. Our Balanced Contributor Intellectual Property Agreement is a direct implementation of GitHub's [Balanced Employee Intellectual Property Agreement 1.0.1](https://github.com/github/balanced-employee-ip-agreement/blob/master/Balanced_Employee_IP_Agreement.md).
+Contributions are deemed _voluntary work_. There might be incentives in place for certain kinds of contributions. Contact us for more information in this regard.
+
+In any case, contributors agree to provide an express grant of patent rights for their contributions. Submitting Pull Requests to this repository represents an express agreement with the terms of our Balanced Contributor Intellectual Property Agreement. This agreement is a direct implementation of GitHub's [Balanced Employee Intellectual Property Agreement 1.0.1](https://github.com/github/balanced-employee-ip-agreement/blob/master/Balanced_Employee_IP_Agreement.md).
# Balanced Contributor Intellectual Property Agreement 1.0.1
-This BALANCED CONTRIBUTOR INTELLECTUAL PROPERTY AGREEMENT is between person named below and Advanced Algos ("Company").
+This BALANCED CONTRIBUTOR INTELLECTUAL PROPERTY AGREEMENT is between person or team submitting Pull Requests to this repository and Superalgos.org ("Project").
-**What is this?** This is the Company's Intellectual Property Agreement ("Agreement"). If you've worked in the technology space before, there's a good chance that you've run across one or more of these in the past. This document is the official, entire and exclusive agreement on what intellectual property ("IP") is yours, and what belongs to the Company.
+**What is this?** This is the Project's Intellectual Property Agreement ("Agreement"). If you've worked in the technology space before, there's a good chance that you've run across one or more of these in the past. This document is the official, entire and exclusive agreement on what intellectual property ("IP") is yours, and what belongs to the Project.
-**Why is this?** The Company needs to be clear on what IP it owns and has rights to. Its customers, contributors, and investors depend on the Company having the legal rights to the products and services it is providing so that the Company can continue operating and doing business.
+**Why is this?** The Project needs to be clear on what IP it owns and has rights to. Its customers, contributors, and investors depend on the Project having the legal rights to the products and services it is providing so that the Project can continue operating and doing business.
-The Company also believes that it's important to be clear on what it doesn't own. The Company doesn't want you looking over your shoulder every time you work on something personal or worrying that the Company will someday seize your open source non-lethal mousetrap simulation software. In other words, the Company isn't interested in appropriating your personal projects.
+The Project also believes that it's important to be clear on what it doesn't own. The Project doesn't want you looking over your shoulder every time you work on something personal or worrying that the Project will someday seize your open source non-lethal mousetrap simulation software. In other words, the Project isn't interested in appropriating your personal projects.
-**Read this.** Please read this document and be sure you understand it before you sign it. Due to legal risk and corporate obligations, the Company cannot, by and large, negotiate its terms. If you feel you have a particular circumstance that keeps you from signing, please let the Company's legal department ("Legal") know. And, of course, you're always free and encouraged to get your own legal counsel to explain anything you're not clear on.
+**Read this.** Please read this document and be sure you understand it before you submit any Pull Requests. Due to legal risk and corporate obligations, the Project cannot, by and large, negotiate its terms. If you feel you have a particular circumstance that keeps you from signing, please let the Project's legal department ("Legal") know. And, of course, you're always free and encouraged to get your own legal counsel to explain anything you're not clear on.
-Cool? Then, by signing this Agreement, and as a condition of your contribution, you agree to the following:
+Cool? Then, by submitting your first Pull Request, and as a condition of your contribution, you agree to the following:
-1. **What the Company owns.** The Company owns any IP ("Company IP") that you create, or help create _as its contributor or contractor_, but only if it meets one or more of these additional conditions: The IP was (i) related to an existing or prospective Company product or service at the time you developed, invented, or created it, (ii) developed for use by the Company, or (iii) developed or promoted with existing Company IP or with the Company's endorsement. You hereby grant and assign, and will grant and assign, to the Company all rights and interests in all Company IP.
+1. **What the Project owns.** The Project owns any IP ("Project IP") that you create, or help create _as its contributor_, but only if it meets one or more of these additional conditions: The IP was (i) related to an existing or prospective Project product or service at the time you developed, invented, or created it, (ii) developed for use by the Project, or (iii) developed or promoted with existing Project IP or with the Project's endorsement. You hereby grant and assign, and will grant and assign, to the Project all rights and interests in all Project IP.
- "Company IP" includes concepts, designs, developments, discoveries, ideas, improvements, inventions, trade secrets, trademarks, and works of authorship.
+ "Project IP" includes concepts, designs, developments, discoveries, ideas, improvements, inventions, trade secrets, trademarks, and works of authorship.
-2. **What the Company doesn't own.** If you create IP that doesn't fit into one of the categories listed above, the Company doesn't own it. In other words, the Company doesn't own concepts, designs, developments, discoveries, ideas, improvements, inventions, trade secrets, trademarks, or works of authorship that you develop, invent, or create that do not meet any of the conditions in Section 1. This is true regardless of the computer you use to develop your IP, including the one furnished to you by the Company.
+2. **What the Project doesn't own.** If you create IP that doesn't fit into one of the categories listed above, the Project doesn't own it. In other words, the Project doesn't own concepts, designs, developments, discoveries, ideas, improvements, inventions, trade secrets, trademarks, or works of authorship that you develop, invent, or create that do not meet any of the conditions in Section 1.
-3. **Contribution of your IP to Company projects.** If you include your own IP – such as IP you created prior to working for the Company – into a Company product or service, it's still yours, of course, but you grant the Company a non-exclusive, irrevocable, fully paid-up, royalty-free, perpetual, sublicensable, transferable, worldwide license to use it without restriction in any way or implementation, in modified form, or as is, by itself, or incorporated into another product or service ("License"). If you include your name in any project over which the Company would have rights under this Agreement, such as in a copyright notice or a comment in code or documentation, then the License covers the rights associated with that use of your name as well.
+3. **Contribution of your IP to Project projects.** If you include your own IP – such as IP you created prior to working for the Project – into a Project product or service, it's still yours, of course, but you grant the Project a non-exclusive, irrevocable, fully paid-up, royalty-free, perpetual, sublicensable, transferable, worldwide license to use it without restriction in any way or implementation, in modified form, or as is, by itself, or incorporated into another product or service ("License"). If you include your name in any project over which the Project would have rights under this Agreement, such as in a copyright notice or a comment in code or documentation, then the License covers the rights associated with that use of your name as well.
-4. **Your contributions to non-Company projects.** The Company recognizes that you may be engaged in work that requires you to submit IP to entities other than the Company, such as open source projects used by the Company. Please make sure that Legal is aware of what you're working on so that Legal can help with any licensing issues. If any project asks you to sign a contribution agreement, you should check with Legal before doing so. These agreements may be legally binding on the Company and so should be run through Legal first.
+4. **Your contributions to non-Project projects.** The Project recognizes that you may be engaged in work that requires you to submit IP to entities other than the Project, such as open source projects used by the Project. Please make sure that Legal is aware of what you're working on so that Legal can help with any licensing issues. If any project asks you to sign a contribution agreement, you should check with Legal before doing so. These agreements may be legally binding on the Project and so should be run through Legal first.
-5. **Works made for hire.** All Company IP that you are involved with or create as part of your work for the Company is [work made for hire](http://www.copyright.gov/circs/circ09.pdf) under copyright law and compensated by your regular salary or pay.
+5. **Voluntary Works** All Project IP that you are involved with or create as part of your work for the Project is voluntary work which does not require compensation. There might be incentives in place for certain kinds of contributions. Feel free to contact the Project to learn more.
6. **No conflicts.** You agree that you don't have any outstanding agreements or obligations that conflict with those in this Agreement, and that you won't enter into conflicting agreements in the future.
-7. **IP protection.** The Company might someday need to show the work that went into the development of IP that it uses or has used, or to make government filings to establish that it owns the IP or has rights over it. To help in those situations, you agree not to destroy any records you maintain relating to the development of any Company IP or IP under License (together, "All IP"), and, if the Company asks, to provide those records to the Company. You agree to help the Company secure and defend its rights in All IP, including after you leave the Company. For your help the Company will compensate you at a reasonable rate. If the Company is unable to secure your help, you authorize the Company to act on your behalf (as your agent and attorney-in-fact) in securing all rights related to All IP.
+7. **IP protection.** The Project might someday need to show the work that went into the development of IP that it uses or has used, or to make government filings to establish that it owns the IP or has rights over it. To help in those situations, you agree not to destroy any records you maintain relating to the development of any Project IP or IP under License (together, "All IP"), and, if the Project asks, to provide those records to the Project. You agree to help the Project secure and defend its rights in All IP. For your help the Project will compensate you at a reasonable rate. If the Project is unable to secure your help, you authorize the Project to act on your behalf (as your agent and attorney-in-fact) in securing all rights related to All IP.
-8. **Confidentiality.** As an contributor or contractor of the Company, you will have access to sensitive confidential information that is important to the Company's business. You are responsible for keeping this information confidential, including after you end your work for the Company.
+8. **Confidentiality.** As an contributor or contractor of the Project, you will have access to sensitive confidential information that is important to the Project's business. You are responsible for keeping this information confidential, including after you end your work for the Project.
- "Confidential Information" includes non-public technical details about our products or services, financial information, business strategies and forecasts, customer data, or any other information, data or know-how that is valuable to the Company because it is not publicly known.
-
- The Company's Confidential Information is sensitive and we expect that you'll treat it as such. You agree to only use the Company's Confidential Information for the purpose of performing your job and for the benefit of the Company. You will do your best to keep Confidential Information secret. If you are not sure if something is Confidential Information, you should assume that it is, until you can confirm otherwise.
-
-
-Print Name: _____________
-
-Sign: ________________
-
-Date: ________________
+ "Confidential Information" includes non-public technical details about our products or services, financial information, business strategies and forecasts, customer data, or any other information, data or know-how that is valuable to the Project because it is not publicly known.
+ The Project's Confidential Information is sensitive and we expect that you'll treat it as such. You agree to only use the Project's Confidential Information for the purpose of performing your contribution and for the benefit of the Project. You will do your best to keep Confidential Information secret. If you are not sure if something is Confidential Information, you should assume that it is, until you can confirm otherwise.
\ No newline at end of file
diff --git a/CompetitionStorage.js b/CompetitionStorage.js
index 9b4ce6c23..2e4a12500 100644
--- a/CompetitionStorage.js
+++ b/CompetitionStorage.js
@@ -1,4 +1,4 @@
-
+
function newCompetitionStorage (pName) {
const MODULE_NAME = 'Competition Storage'
const INFO_LOG = false
@@ -37,6 +37,7 @@ function newCompetitionStorage (pName) {
for (let j = 0; j < pCompetition.participants.length; j++) {
let devTeam = ecosystem.getTeam(pCompetition.participants[j].devTeam)
let bot = ecosystem.getBot(devTeam, pCompetition.participants[j].bot)
+ let pOperationsId = pCompetition.participants[j].pOperationsId
let product = ecosystem.getProduct(bot, 'Competition Trading History')
if (INFO_LOG === true) { logger.write('[INFO] initialize -> key = ' + devTeam.codeName + '-' + bot.codeName + '-' + product.codeName) }
@@ -49,7 +50,7 @@ function newCompetitionStorage (pName) {
if (INFO_LOG === true) { logger.write('[INFO] initialize -> File Sequence -> key = ' + pHost.codeName + '-' + pCompetition.codeName + '-' + devTeam.codeName + '-' + bot.codeName + '-' + product.codeName) }
let fileSequence = newFileSequence()
- fileSequence.initialize(devTeam, bot, product, thisSet, pExchange, pMarket, onFileSequenceReady)
+ fileSequence.initialize(devTeam, bot, product, thisSet, pExchange, pMarket, onFileSequenceReady, pOperationsId)
fileSequences.push(fileSequence)
dataSetsToLoad++
}
@@ -133,4 +134,3 @@ function newCompetitionStorage (pName) {
}
}
}
-
diff --git a/Exchange/ExchangeAPI.js b/Exchange/ExchangeAPI.js
index 31dc911f4..ae881079d 100644
--- a/Exchange/ExchangeAPI.js
+++ b/Exchange/ExchangeAPI.js
@@ -28,9 +28,8 @@
function getTicker (pMarket, callBackFunction) {
let authToken = window.localStorage.getItem('access_token')
- let path = SERVER_URL
- + CURRENT_BOT_CODE_NAME + '/'
- + 'getTicker' + '/'
+ let path = SERVER_URL
+ + "getTicker" + "/"
+ authToken
callServer(undefined, path + '/NO-LOG', onServerResponse)
@@ -48,31 +47,54 @@
function getOpenPositions (pMarket, callBackFunction) {
let authToken = window.localStorage.getItem('access_token')
- let path = SERVER_URL
- + CURRENT_BOT_CODE_NAME + '/'
- + 'getOpenPositions' + '/'
+ let authToken = window.localStorage.getItem('access_token');
+
+ let path = SERVER_URL
+ + "getOpenPositions" + "/"
+ authToken
- callServer(undefined, path + '/NO-LOG', onServerResponse)
+ function onServerResponse(pServerResponse) {
+ let response = JSON.parse(pServerResponse);
+ if (response.result === window.DEFAULT_FAIL_RESPONSE.result)
+ callBackFunction(window.DEFAULT_FAIL_RESPONSE);
+ else
+ callBackFunction(window.DEFAULT_OK_RESPONSE, response);
+ }
+ }
- function onServerResponse (pServerResponse) {
- let response = JSON.parse(pServerResponse)
- if (response.result === window.DEFAULT_FAIL_RESPONSE.result) {
- callBackFunction(window.DEFAULT_FAIL_RESPONSE)
- } else {
- callBackFunction(window.DEFAULT_OK_RESPONSE, response)
- }
- }
- }
+ function getExecutedTrades(pPositionId, callBackFunction) {
- function getExecutedTrades (pPositionId, callBackFunction) {
- let authToken = window.localStorage.getItem('access_token')
+ let authToken = window.localStorage.getItem('access_token');
- let path = SERVER_URL
- + CURRENT_BOT_CODE_NAME + '/'
- + 'getExecutedTrades' + '/'
- + authToken + '/'
+ let path = SERVER_URL
+ + "getExecutedTrades" + "/"
+ + authToken + "/"
+ pPositionId
+ ;
+
+ callServer(undefined, path + "/NO-LOG", onServerResponse);
+
+ function onServerResponse(pServerResponse) {
+ let response = JSON.parse(pServerResponse);
+ if (response.result === window.DEFAULT_FAIL_RESPONSE.result)
+ callBackFunction(window.DEFAULT_FAIL_RESPONSE);
+ else
+ callBackFunction(window.DEFAULT_OK_RESPONSE, response);
+ }
+ }
+
+ function putPosition(pMarket, pType, pRate, pAmountA, pAmountB, callBackFunction) {
+
+ let authToken = window.localStorage.getItem('access_token');
+
+ let path = SERVER_URL
+ + "putPosition" + "/"
+ + authToken + "/"
+ + pType + "/"
+ + pRate + "/"
+ + pAmountA + "/"
+ + pAmountB
+ ;
callServer(undefined, path + '/NO-LOG', onServerResponse)
@@ -98,27 +120,11 @@
+ pAmountA + '/'
+ pAmountB
- callServer(undefined, path + '/NO-LOG', onServerResponse)
-
- function onServerResponse (pServerResponse) {
- let response = JSON.parse(pServerResponse)
- if (response.result === window.DEFAULT_FAIL_RESPONSE.result) {
- callBackFunction(window.DEFAULT_FAIL_RESPONSE)
- } else {
- callBackFunction(window.DEFAULT_OK_RESPONSE, response)
- }
- }
- }
-
- function movePosition (pPositionId, pNewRate, pPositionAmountB, callBackFunction) {
- let authToken = window.localStorage.getItem('access_token')
-
- let path = SERVER_URL
- + CURRENT_BOT_CODE_NAME + '/'
- + 'movePosition' + '/'
- + authToken + '/'
- + pPositionId + '/'
- + pNewRate + '/'
+ let path = SERVER_URL
+ + "movePosition" + "/"
+ + authToken + "/"
+ + pPositionId + "/"
+ + pNewRate + "/"
+ pPositionAmountB
callServer(undefined, path + '/NO-LOG', onServerResponse)
@@ -145,11 +151,21 @@
callServer(undefined, path + '/NO-LOG', onServerResponse)
- function onServerResponse (pServerResponse) {
- let response = JSON.parse(pServerResponse)
- if (response.result === window.DEFAULT_FAIL_RESPONSE.result) {
- callBackFunction(window.DEFAULT_FAIL_RESPONSE)
- } else { callBackFunction(window.DEFAULT_OK_RESPONSE, response) }
- }
- }
- }
+ let path = SERVER_URL
+ + "getPublicTradeHistory" + "/"
+ + authToken + "/"
+ + startTime + "/"
+ + endTime
+ ;
+
+ callServer(undefined, path + "/NO-LOG", onServerResponse);
+
+ function onServerResponse(pServerResponse) {
+ let response = JSON.parse(pServerResponse);
+ if (response.result === window.DEFAULT_FAIL_RESPONSE.result)
+ callBackFunction(window.DEFAULT_FAIL_RESPONSE);
+ else
+ callBackFunction(window.DEFAULT_OK_RESPONSE, response);
+ }
+ }
+}
diff --git a/Files/FileCloud.js b/Files/FileCloud.js
index 8d0964413..49e5002c7 100644
--- a/Files/FileCloud.js
+++ b/Files/FileCloud.js
@@ -1,4 +1,4 @@
-
+
function newFileCloud () {
const MODULE_NAME = 'File Cloud'
const INFO_LOG = false
@@ -33,15 +33,19 @@ function newFileCloud () {
}
}
- function getFile (pDevTeam, pBot, pSet, pExchange, pMarket, pPeriodName, pDatetime, pSequence, pDataRange, callBackFunction) {
+ function getFile (pDevTeam, pBot, pSet, pExchange, pMarket, pPeriodName, pDatetime, pSequence, pDataRange, callBackFunction, pOperationsId) {
try {
if (INFO_LOG === true) { logger.write('[INFO] getFile -> Entering function.') }
const MAX_RETRIES = 3
- getFileRecursively(0, pDevTeam, pBot, pSet, pExchange, pMarket, pPeriodName, pDatetime, pSequence, pDataRange, callBackFunction)
+ if (pOperationsId !== undefined) {
+ getFileRecursively(0, pDevTeam, pBot, pSet, pExchange, pMarket, pPeriodName, pDatetime, pSequence, pDataRange, callBackFunction, pOperationsId)
+ } else {
+ getFileRecursively(0, pDevTeam, pBot, pSet, pExchange, pMarket, pPeriodName, pDatetime, pSequence, pDataRange, callBackFunction)
+ }
- function getFileRecursively (pRetryCounter, pDevTeam, pBot, pSet, pExchange, pMarket, pPeriodName, pDatetime, pSequence, pDataRange, callBackFunction) {
+ function getFileRecursively (pRetryCounter, pDevTeam, pBot, pSet, pExchange, pMarket, pPeriodName, pDatetime, pSequence, pDataRange, callBackFunction, pOperationsId) {
try {
if (INFO_LOG === true) { logger.write('[INFO] getFile -> getFileRecursively -> Entering function.') }
if (INFO_LOG === true) { logger.write('[INFO] getFile -> getFileRecursively -> key = ' + pDevTeam.codeName + '-' + pBot.codeName + '-' + pSet.filePath + '-' + pSet.fileName) }
@@ -92,7 +96,11 @@ function newFileCloud () {
}
if (pBot !== undefined) {
- filePath = filePath.replace('@Bot', pBot.codeName)
+ if (pOperationsId !== undefined) {
+ filePath = filePath.replace('@Bot', pBot.codeName + '-' + pOperationsId)
+ } else {
+ filePath = filePath.replace('@Bot', pBot.codeName)
+ }
}
if (pExchange !== undefined) {
@@ -153,7 +161,6 @@ function newFileCloud () {
if (err.message === 'XHR error') {
if (pRetryCounter < MAX_RETRIES) {
-
if (ERROR_LOG === true) { logger.write('[ERROR] getFile -> getFileRecursively -> onFileReceived -> Retrying to get this file. ') }
if (ERROR_LOG === true) { logger.write('[ERROR] getFile -> getFileRecursively -> onFileReceived -> MAX_RETRIES = ' + MAX_RETRIES) }
if (ERROR_LOG === true) { logger.write('[ERROR] getFile -> getFileRecursively -> onFileReceived -> pRetryCounter = ' + pRetryCounter) }
@@ -161,7 +168,6 @@ function newFileCloud () {
getFileRecursively(pRetryCounter + 1, pDevTeam, pBot, pSet, pExchange, pMarket, pPeriodName, pDatetime, pSequence, pDataRange, callBackFunction)
return
} else {
-
if (ERROR_LOG === true) { logger.write('[ERROR] getFile -> getFileRecursively -> onFileReceived -> Could not get this file from storage. ') }
if (ERROR_LOG === true) { logger.write('[ERROR] getFile -> getFileRecursively -> onFileReceived -> MAX_RETRIES = ' + MAX_RETRIES) }
if (ERROR_LOG === true) { logger.write('[ERROR] getFile -> getFileRecursively -> onFileReceived -> pRetryCounter = ' + pRetryCounter) }
diff --git a/Files/FileSequence.js b/Files/FileSequence.js
index 55fca7746..330af1e55 100644
--- a/Files/FileSequence.js
+++ b/Files/FileSequence.js
@@ -1,4 +1,4 @@
-
+
function newFileSequence () {
const MODULE_NAME = 'File Sequence'
const INFO_LOG = false
@@ -50,7 +50,7 @@ function newFileSequence () {
}
}
- function initialize (pDevTeam, pBot, pProduct, pSet, pExchange, pMarket, callBackFunction) {
+ function initialize (pDevTeam, pBot, pProduct, pSet, pExchange, pMarket, callBackFunction, pOperationsId) {
try {
if (INFO_LOG === true) { logger.write('[INFO] initialize -> Entering function.') }
if (INFO_LOG === true) { logger.write('[INFO] initialize -> key = ' + pDevTeam.codeName + '-' + pBot.codeName + '-' + pProduct.codeName) }
@@ -76,7 +76,11 @@ function newFileSequence () {
/* First we will get the sequence max number */
- fileCloud.getFile(devTeam, bot, thisSet, exchange, market, undefined, undefined, 'Sequence', undefined, onSequenceFileReceived)
+ if (pOperationsId !== undefined) {
+ fileCloud.getFile(devTeam, bot, thisSet, exchange, market, undefined, undefined, 'Sequence', undefined, onSequenceFileReceived, pOperationsId)
+ } else {
+ fileCloud.getFile(devTeam, bot, thisSet, exchange, market, undefined, undefined, 'Sequence', undefined, onSequenceFileReceived)
+ }
function onSequenceFileReceived (err, file) {
try {
@@ -125,26 +129,27 @@ function newFileSequence () {
/* Now we will get the sequence of files */
for (let i = 0; i <= maxSequence; i++) {
- fileCloud.getFile(devTeam, bot, thisSet, exchange, market, undefined, undefined, i, undefined, onFileReceived)
+ if (pOperationsId !== undefined) {
+ fileCloud.getFile(devTeam, bot, thisSet, exchange, market, undefined, undefined, i, undefined, onFileReceived, pOperationsId)
+ } else {
+ fileCloud.getFile(devTeam, bot, thisSet, exchange, market, undefined, undefined, i, undefined, onFileReceived)
+ }
function onFileReceived (err, file) {
try {
switch (err.result) {
case GLOBAL.DEFAULT_OK_RESPONSE.result: {
-
if (INFO_LOG === true) { logger.write('[INFO] initialize -> onSequenceFileReceived -> onFileReceived -> Received OK Response.') }
break
}
case GLOBAL.DEFAULT_FAIL_RESPONSE.result: {
-
if (INFO_LOG === true) { logger.write('[INFO] initialize -> onSequenceFileReceived -> onFileReceived -> Received FAIL Response.') }
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE)
return
}
case GLOBAL.CUSTOM_FAIL_RESPONSE.result: {
-
if (INFO_LOG === true) { logger.write('[INFO] initialize -> onSequenceFileReceived -> onFileReceived -> Received CUSTOM FAIL Response.') }
if (INFO_LOG === true) { logger.write('[INFO] initialize -> onSequenceFileReceived -> onFileReceived -> err.message = ' + err.message) }
@@ -153,7 +158,6 @@ function newFileSequence () {
}
default: {
-
if (INFO_LOG === true) { logger.write('[INFO] initialize -> onSequenceFileReceived -> onFileReceived -> Received Unexpected Response.') }
callBackFunction(err)
return
@@ -207,7 +211,11 @@ function newFileSequence () {
if (INFO_LOG === true) { logger.write('[INFO] updateFiles -> bot = ' + bot.codeName) }
if (INFO_LOG === true) { logger.write('[INFO] updateFiles -> thisSet = ' + thisSet.codeName) }
- fileCloud.getFile(devTeam, bot, thisSet, exchange, market, undefined, undefined, 'Sequence', undefined, onSequenceFileReceived)
+ if (pOperationsId !== undefined) {
+ fileCloud.getFile(devTeam, bot, thisSet, exchange, market, undefined, undefined, 'Sequence', undefined, onSequenceFileReceived, pOperationsId)
+ } else {
+ fileCloud.getFile(devTeam, bot, thisSet, exchange, market, undefined, undefined, 'Sequence', undefined, onSequenceFileReceived)
+ }
function onSequenceFileReceived (err, file) {
try {
@@ -252,32 +260,32 @@ function newFileSequence () {
for (let i = currentMaxSequence; i <= maxSequence; i++) {
if (INFO_LOG === true) { logger.write('[INFO] updateFiles -> onSequenceFileReceived -> i = ' + i) }
- fileCloud.getFile(devTeam, bot, thisSet, exchange, market, undefined, undefined, i, undefined, onFileReceived)
+ if (pOperationsId !== undefined) {
+ fileCloud.getFile(devTeam, bot, thisSet, exchange, market, undefined, undefined, i, undefined, onFileReceived, pOperationsId)
+ } else {
+ fileCloud.getFile(devTeam, bot, thisSet, exchange, market, undefined, undefined, i, undefined, onFileReceived)
+ }
function onFileReceived (err, file) {
try {
switch (err.result) {
case GLOBAL.DEFAULT_OK_RESPONSE.result: {
-
if (INFO_LOG === true) { logger.write('[INFO] updateFiles -> onSequenceFileReceived -> onFileReceived -> Received OK Response.') }
break
}
case GLOBAL.DEFAULT_FAIL_RESPONSE.result: {
-
if (INFO_LOG === true) { logger.write('[INFO] updateFiles -> onSequenceFileReceived -> onFileReceived -> Received FAIL Response.') }
return
}
case GLOBAL.CUSTOM_FAIL_RESPONSE.result: {
-
if (INFO_LOG === true) { logger.write('[INFO] updateFiles -> onSequenceFileReceived -> onFileReceived -> Received CUSTOM FAIL Response.') }
if (INFO_LOG === true) { logger.write('[INFO] updateFiles -> onSequenceFileReceived -> onFileReceived -> err.message = ' + err.message) }
return
}
default: {
-
if (INFO_LOG === true) { logger.write('[INFO] updateFiles -> onSequenceFileReceived -> onFileReceived -> Received Unexpected Response.') }
return
}
diff --git a/LICENSE b/LICENSE
index 908876ec9..2fe09f449 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,48 +1,39 @@
COPYRIGHT NOTICE
-© Copyright 2018 Advanced Algos
+© Copyright 2018 Superalgos.org
LICENSE NOTICE
-Advanced Algos is a startup, currently at a very early stage. Because certain aspects of
-the business are still not clearly defined, we have chosen to --temporarily-- grant a
-restrictive license for the use of CanvasApp, until those business aspects are clarified
-and a proper open source license can be granted.
+Superalgos is a collaborative project currently at a very early stage. Because certain aspects of
+the project are still not clearly defined, we have chosen to --temporarily-- grant a restrictive
+license for the use of this repository, until those aspects are clarified and a proper open source
+license can be granted.
-Advanced Algos is publishing the code of this software for several reasons. However,
-it shall not be considered free software yet. Advanced Algos is a for-profit company
-in the crypto space and CanvasApp is still proprietary software.
+Superalgos.org is publishing the code of this software for several reasons. However, it shall not be considered free software yet. Superalgos is a collaborative project in the crypto space and this
+software is still proprietary software.
-The reasons for opening up the code of CanvasApp at this stage are the following:
+The reasons for opening up the code of this software at this stage are the following:
- * We believe that transparency is paramount to achieving our goals, so we want everyone
- to be able to understand what CanvasApp does and how. Opening up the code of CanvasApp allows
- anyone to take a close look.
+ * We believe that transparency is paramount to achieving our goals, so we want everyone to
+ be able to understand what this software does and how. Opening up the code of this software
+ allows anyone to take a close look.
- * We welcome contributions from the community. Contributions are compensated on a case
- by case basis with ALGO tokens. Contributions are deemed _work for hire_ and contributors
- agree to provide an express grant of patent rights for their contributions.
-
- * We wish the community to be able to create their own bots and watch their activity in CanvasApp, thus we grant
- a development and testing license so that developers can test their bots in their local
- environment.
+ * We welcome contributions from the community. Contributions are regarded as voluntary work.
+ There may be incentives in place for certain kinds of contributions. Contact us to learn more.
+ Contributors agree to provide an express grant of patent rights for their contributions.
LICENSE WORDING
-Advanced Algos grants a limited license for the following uses:
+Superalgos.org grants a limited license for the following uses:
-1. CODE REVIEW AND AUDITS. You are granted permission to clone the CanvasApp repository to analyze,
+1. CODE REVIEW AND AUDITS. You are granted permission to clone this repository to analyze,
review or audit the code.
-2. COLLABORATING WITH ADVANCED ALGOS. You are granted permission to fork the CanvasApp repository
+2. COLLABORATING WITH Superalgos.org. You are granted permission to fork this repository
with the sole purpose of correcting bugs and developing functionality in agreement with
- Advanced Algos. Before your contributions are merged into our repository, you will be requested
- to sign a Contributors Work for Hire Agreement.
-
-3. DEVELOPMENT AND TESTING OF TRADING BOTS. You are granted permission to clone the CanvasApp
- repository and use the software in your local environment to develop and test trading bots.
-
-
+ Superalgos.org. By contributing to this repository you explicitely agree to the terms
+ detailed in CONTRIBUTING.MD.
+PLEASE SEE CONTRIBUTING.MD FOR MORE DETAILS ON THE IMPLICATIONS SURROUNDING YOUR CONTRIBUTIONS TO THIS REPOSITORY.
\ No newline at end of file
diff --git a/Project.njsproj b/Project.njsproj
index df482b062..4634a91ad 100644
--- a/Project.njsproj
+++ b/Project.njsproj
@@ -47,7 +47,6 @@
Code
-
Code
@@ -104,6 +103,9 @@
Code
+
+ Code
+
Code
@@ -172,7 +174,6 @@
-
@@ -223,4 +224,4 @@
-
\ No newline at end of file
+
diff --git a/Spaces/TopSpace.js b/Spaces/TopSpace.js
index 71dd40717..04ac158b9 100644
--- a/Spaces/TopSpace.js
+++ b/Spaces/TopSpace.js
@@ -1,4 +1,4 @@
-
+
function newTopSpace () {
var thisObject = {
container: undefined,
@@ -10,6 +10,7 @@ function newTopSpace () {
currentBot: undefined,
currentProcess: undefined,
currentStartMode: undefined,
+ currentEvent: undefined,
login: undefined,
initialize: initialize
}
@@ -27,6 +28,7 @@ function newTopSpace () {
function initialize () {
let sharedStatus = {
currentDevTeamIndex: 0,
+ currentEventIndex: 0,
currentUserBotIndex: 0,
currentProcessIndex: 0,
currentBotType: '',
@@ -34,13 +36,14 @@ function newTopSpace () {
}
thisObject.login = newLogin()
- thisObject.login.initialize(onLoginInitialized)
+ thisObject.login.initialize(sharedStatus, onLoginInitialized)
thisObject.companyLogo = newCompanyLogo()
thisObject.endUser = newEndUser()
thisObject.currentBot = newCurrentBot()
thisObject.currentProcess = newCurrentProcess()
thisObject.currentStartMode = newCurrentStartMode()
+ thisObject.currentEvent = newCurrentEvent()
thisObject.devTeam = newDevTeam()
window.canvasApp.eventHandler.listenToEvent('Browser Resized', resize)
@@ -51,6 +54,7 @@ function newTopSpace () {
thisObject.currentBot.initialize(sharedStatus)
thisObject.currentProcess.initialize(sharedStatus)
thisObject.currentStartMode.initialize(sharedStatus)
+ thisObject.currentEvent.initialize(sharedStatus)
thisObject.devTeam.initialize(sharedStatus)
}
}
@@ -84,6 +88,9 @@ function newTopSpace () {
container = thisObject.currentStartMode.getContainer(point)
if (container !== undefined) { return container }
+ container = thisObject.currentEvent.getContainer(point)
+ if (container !== undefined) { return container }
+
container = thisObject.login.getContainer(point)
if (container !== undefined) { return container }
@@ -102,6 +109,7 @@ function newTopSpace () {
thisObject.currentBot.draw()
thisObject.currentProcess.draw()
thisObject.currentStartMode.draw()
+ thisObject.currentEvent.draw()
thisObject.login.draw()
}
diff --git a/TopSpace/CurrentBot.js b/TopSpace/CurrentBot.js
index 34bb64339..46185d12b 100644
--- a/TopSpace/CurrentBot.js
+++ b/TopSpace/CurrentBot.js
@@ -1,4 +1,4 @@
-
+
function newCurrentBot () {
let thisObject = {
container: undefined,
diff --git a/TopSpace/CurrentEvent.js b/TopSpace/CurrentEvent.js
new file mode 100644
index 000000000..df3aae840
--- /dev/null
+++ b/TopSpace/CurrentEvent.js
@@ -0,0 +1,198 @@
+function newCurrentEvent () {
+ let thisObject = {
+ container: undefined,
+ draw: draw,
+ getContainer: getContainer,
+ initialize: initialize
+ }
+
+ const ecosystemBase =
+ [{
+ 'codeName': 'AAArena',
+ 'displayName': 'AA Arena',
+ 'competitions': [{
+ 'codeName': 'Weekend-Deathmatch',
+ 'description': 'First AA Internal Competition. Bots will be trading during 3 days at the USDT/BTC market of Poloniex to see who can make the gratest return over investment (ROI).',
+ 'displayName': 'AA Internal Challenge',
+ 'startDatetime': '2019-03-05T16:00:00.000Z',
+ 'finishDatetime': '2019-02-07T16:59:59.999Z',
+ 'formula': 'ROI',
+ 'plotter': {
+ 'codeName': 'PlottersROI',
+ 'host': 'AAArena',
+ 'repo': 'Plotters-ROI',
+ 'moduleName': 'CombinedProfits'
+ },
+ 'participants': [
+ ],
+ 'repo': 'Weekend-Deathmatch',
+ 'configFile': 'this.competition.config.json'
+ }],
+ 'plotters': [{
+ 'displayName': 'Plotters ROI',
+ 'codeName': 'PlottersROI',
+ 'devTeam': 'AAMasters',
+ 'modules': [{
+ 'codeName': 'CombinedProfits',
+ 'moduleName': 'CombinedProfits',
+ 'description': 'Plots participants of a competition by the ROI each one had over time.',
+ 'panels': []
+ }],
+ 'repo': 'Plotters-ROI',
+ 'configFile': 'this.plotter.config.json'
+ }]
+ }]
+
+ function buildEcosystemEventsHack (reload) {
+ let hackedEcosystem = ecosystemBase
+
+ let ecosysTemp = window.localStorage.getItem('currentEventObject')
+ if (!(ecosysTemp === null || ecosysTemp === '[]' || ecosysTemp === '')) {
+ let parsedEcosysTemp = JSON.parse(ecosysTemp)
+ hackedEcosystem[0].competitions[0].startDatetime = new Date(parsedEcosysTemp.startDatetime * 1000).toISOString()
+ hackedEcosystem[0].competitions[0].finishDatetime = new Date(parsedEcosysTemp.endDatetime * 1000).toISOString()
+ parsedEcosysTemp.participants.forEach(function (participant) {
+ hackedEcosystem[0].competitions[0].participants.push({
+ devTeam: participant.clone.team.slug,
+ bot: participant.clone.bot.slug,
+ pOperationsId: participant.clone.id,
+ release: '1.0.0'
+ })
+ })
+ }
+
+ window.localStorage.setItem('ecosystemEventsHack', JSON.stringify(hackedEcosystem))
+ ecosystem.setEvent(hackedEcosystem)
+ if (reload) {
+ dashboard.start()
+ }
+ }
+
+ let container = newContainer()
+ container.initialize()
+ thisObject.container = container
+
+ thisObject.container.frame.width = 150
+ thisObject.container.frame.height = BOTTOM_SPACE_HEIGHT
+
+ resize()
+
+ container.isDraggeable = false
+ container.isClickeable = true
+
+ const NOT_FOUND = 'Event NOT FOUND'
+
+ let sharedStatus
+ let storedEvents
+ let label = 'Event -'
+
+ return thisObject
+
+ function initialize (pSharedStatus) {
+ let sessionToken = window.localStorage.getItem('sessionToken')
+
+ if (sessionToken === null || sessionToken === '') {
+ /* not logged in */
+ return
+ }
+
+ sharedStatus = pSharedStatus
+
+ storedEvents = window.localStorage.getItem('currentEvents')
+ if (storedEvents === null || storedEvents === '[]' || storedEvents === '') {
+ window.EVENTS = ''
+ window.CURRENT_EVENT_TITLE = ''
+ label = NOT_FOUND
+ } else if (sharedStatus.currentEventIndex === -1) {
+ storedEvents = JSON.parse(storedEvents)
+ window.EVENTS = storedEvents
+ window.CURRENT_EVENT_TITLE = ''
+ label = 'Select an event'
+ } else {
+ storedEvents = JSON.parse(storedEvents)
+ window.EVENTS = storedEvents
+ window.CURRENT_EVENT_TITLE = storedEvents[sharedStatus.currentEventIndex].title
+ label = 'Event - ' + storedEvents[sharedStatus.currentEventIndex].title
+ window.localStorage.setItem('currentEventObject', JSON.stringify(storedEvents[sharedStatus.currentEventIndex]))
+ buildEcosystemEventsHack(false)
+ sharedStatus.eventHandler.raiseEvent('Event Changed')
+ }
+
+ thisObject.container.eventHandler.listenToEvent('onMouseClick', onClick)
+
+ window.canvasApp.eventHandler.listenToEvent('Browser Resized', resize)
+ }
+
+ function resize () {
+ container.frame.position.x = viewPort.visibleArea.topLeft.x + thisObject.container.frame.width * 2
+ container.frame.position.y = viewPort.visibleArea.bottomLeft.y
+ }
+
+ function onClick () {
+ let sessionToken = window.localStorage.getItem('sessionToken')
+
+ if (sessionToken === null || sessionToken === '') {
+ /* not logged in */
+ return
+ }
+
+ if (sharedStatus.currentEventIndex + 1 === window.EVENTS.length) {
+ sharedStatus.currentEventIndex = 0
+ window.CURRENT_EVENT_TITLE = storedEvents[sharedStatus.currentEventIndex].title
+ label = 'Event - ' + storedEvents[sharedStatus.currentEventIndex].title
+ window.localStorage.setItem('currentEventObject', JSON.stringify(storedEvents[sharedStatus.currentEventIndex]))
+ buildEcosystemEventsHack(true)
+ sharedStatus.eventHandler.raiseEvent('Event Changed')
+ return
+ }
+
+ if (sharedStatus.currentEventIndex + 1 < window.EVENTS.length) {
+ sharedStatus.currentEventIndex++
+ window.CURRENT_EVENT_TITLE = storedEvents[sharedStatus.currentEventIndex].title
+ label = 'Event - ' + storedEvents[sharedStatus.currentEventIndex].title
+ window.localStorage.setItem('currentEventObject', JSON.stringify(storedEvents[sharedStatus.currentEventIndex]))
+ buildEcosystemEventsHack(true)
+ sharedStatus.eventHandler.raiseEvent('Event Changed')
+ return
+ }
+ }
+
+ function getContainer (point) {
+ let container
+
+ /* First we check if this point is inside this object UI. */
+
+ if (thisObject.container.frame.isThisPointHere(point, true) === true) {
+ return this.container
+ } else {
+ /* This point does not belong to this space. */
+
+ return undefined
+ }
+ }
+
+ function draw () {
+ let sessionToken = window.localStorage.getItem('sessionToken')
+
+ if (sessionToken === null || sessionToken === '') {
+ /* not logged in */
+ return
+ }
+
+ thisObject.container.frame.draw(false, false)
+
+ let breakpointsHeight = 14
+ let fontSize = 12
+
+ let point = {
+ x: thisObject.container.frame.width / 2 - label.length / 2 * fontSize / 3,
+ y: thisObject.container.frame.height / 2 + fontSize / 2 + breakpointsHeight
+ }
+
+ point = thisObject.container.frame.frameThisPoint(point)
+
+ browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY
+ browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', 1)'
+ browserCanvasContext.fillText(label, point.x, point.y)
+ }
+}
diff --git a/TopSpace/CurrentProcess.js b/TopSpace/CurrentProcess.js
index 23ad46466..f9c08ad7c 100644
--- a/TopSpace/CurrentProcess.js
+++ b/TopSpace/CurrentProcess.js
@@ -1,4 +1,4 @@
-
+
function newCurrentProcess () {
let thisObject = {
container: undefined,
@@ -49,7 +49,7 @@ function newCurrentProcess () {
}
function resize () {
- container.frame.position.x = viewPort.visibleArea.topLeft.x + thisObject.container.frame.width * 2
+ container.frame.position.x = viewPort.visibleArea.topLeft.x + thisObject.container.frame.width * 3
container.frame.position.y = viewPort.visibleArea.bottomLeft.y
}
diff --git a/TopSpace/CurrentStartMode.js b/TopSpace/CurrentStartMode.js
index e0b75b3f8..e6ca9eb09 100644
--- a/TopSpace/CurrentStartMode.js
+++ b/TopSpace/CurrentStartMode.js
@@ -1,4 +1,4 @@
-
+
function newCurrentStartMode () {
var thisObject = {
container: undefined,
@@ -34,7 +34,7 @@ function newCurrentStartMode () {
}
function resize () {
- container.frame.position.x = viewPort.visibleArea.topLeft.x + thisObject.container.frame.width * 3
+ container.frame.position.x = viewPort.visibleArea.topLeft.x + thisObject.container.frame.width * 4
container.frame.position.y = viewPort.visibleArea.bottomLeft.y
}
diff --git a/TopSpace/DevTeam.js b/TopSpace/DevTeam.js
index d6ae96865..5f17d67be 100644
--- a/TopSpace/DevTeam.js
+++ b/TopSpace/DevTeam.js
@@ -1,4 +1,3 @@
-
function newDevTeam () {
let thisObject = {
container: undefined,
diff --git a/TopSpace/Login.js b/TopSpace/Login.js
index d4753ecc1..8de07fd84 100644
--- a/TopSpace/Login.js
+++ b/TopSpace/Login.js
@@ -1,4 +1,4 @@
-
+
function newLogin () {
let thisObject = {
container: undefined,
@@ -26,10 +26,12 @@ function newLogin () {
return thisObject
- function initialize (callBackFunction) {
+ function initialize (pSharedStatus, callBackFunction) {
const accessToken = window.localStorage.getItem('access_token')
let user = window.localStorage.getItem('user')
+ sharedStatus = pSharedStatus
+
if (user === null) {
// if there is no user that means that we are logged off, which means it is time to clean the local storage of things from the last log in.
@@ -165,10 +167,73 @@ function newLogin () {
})
}
+ // Gettings events
+
+ const networkInterfaceEvents = Apollo.lib.createNetworkInterface({
+ uri: window.canvasApp.graphQL.masterAppApiUrl
+ })
+
+ const apolloClientEvents = new Apollo.lib.ApolloClient({
+ networkInterface: networkInterfaceEvents,
+ connectToDevTools: true,
+ addTypename: false
+ })
+
+ const EVENTS = Apollo.gql`
+ query events($maxStartDate: Int, $minEndDate: Int){
+ events_Events(maxStartDate: $maxStartDate, minEndDate: $minEndDate){
+ id
+ title
+ startDatetime
+ endDatetime
+ participants{
+ clone{
+ id
+ team{
+ slug
+ }
+ bot{
+ slug
+ }
+ }
+ }
+ }
+ }
+ `
+
+ const getCurrentEvents = () => {
+ var d = new Date()
+ var nowSeconds = Math.round(d.getTime() / 1000)
+ var twoWeeksAgoSeconds = nowSeconds - 1209600
+ return new Promise((resolve, reject) => {
+ apolloClientEvents.query({
+ query: EVENTS,
+ variables: { maxStartDate: nowSeconds, minEndDate: twoWeeksAgoSeconds }
+ })
+ .then(response => {
+ window.localStorage.setItem('currentEvents', JSON.stringify(response.data.events_Events))
+ currentEvent = window.localStorage.getItem('currentEventObject')
+ if (currentEvent === null || currentEvent === '[]' || currentEvent === '') {
+ sharedStatus.currentEventIndex = -1
+ } else {
+ currentEvent = JSON.parse(currentEvent)
+ sharedStatus.currentEventIndex = response.data.events_Events.findIndex(function (element) {
+ return element.id == currentEvent.id
+ })
+ }
+ resolve({ currentEvents: response.data.events_Events})
+ })
+ .catch(error => {
+ console.log('apolloClient error getting current events', error)
+ reject(error)
+ })
+ })
+ }
+
// To avoid race conditions, add asynchronous fetches to array
let fetchDataPromises = []
- fetchDataPromises.push(getUser(), getTeamByOwner())
+ fetchDataPromises.push(getUser(), getTeamByOwner(), getCurrentEvents())
// When all asynchronous fetches resolve, authenticate user or throw error.
Promise.all(fetchDataPromises).then(result => {