This is already what i do with e.g. my own performance measurement that measures how long it takes to run a strategy.
But i also currently use the end() function to output
custom strategy statistics e.g. min/max for an indicator.
This in order to simply debug the run or see if there's some values that indicate that the strategy params should be changed in a certain direction.
In that way the end() -function is great and works just as expected.
If you try the
RSI BULL/BEAR that i have shared on these forums and set
this.debug = true (custom debug) at init() you'll see that there
are statistics about min/max RSI for two different types of periods (bull/bear) and that you get the total run time
for how long it took to backtest the strategy etc.
All that stuff rely on the end() function since one wouldn't want to output all those messages on each candle.
It also would seem that you initially was talking about the
finish() function? If i try to modify that the strategy crashes no
matter what one write. It would seem that finish() is the one responsible for doing cleanup and end-type of processing.
It would therefor seem that you have done this:
end: Something that occurs when a backtest ends and that a user can customize
finish: general cleanup that occurs when everything is completed
So... you already do what i would want, but with the major difference being that one cannot output stuff to the UI
or modify performance analyzer to include custom data (since perfAnalyzer is 'hidden' as you say).
---
What i translate all the other stuff to is:
"
Hi, here's my strategy.
Download strategy.js
put in /gekko/strategies
npm install bloated_library
npm install awful_library
download strategy.helpers.js, put in plugins folder (this makes use of function a, b, y from bloated_library and q, d, e from awful_library)
run and if you have port 58833 open it migh work, else npm install security_hell and try again
"
..instead of:
"
Hi, here's my strategy.
download strategy.js
put in /gekko/strategies
run
"
What i'm basically talking about is commonly called
dependency hell.
(yes, this was harsh... but uneccessary npm installs and over 10x dependencies isn't uncommon)
---
I even think that the TOML-files for strategies is unneeded since these files could just get auto-created on first strategy init (and changed if the strategy settings changes).
I would rather just see all that stuff be defined iniline within the strategy. That way the strategies becomes even simpler.
// pseudo code, doing this.settings.STUFF = 10 already does work though
init: function(){
// settings "A" for strategy; basically would equals toml [section a]
this.settings.section_a.HELLO = 10;
this.settings.section_a.WORLD = 20;
// settings "B" for strategy... which would equal [section b]
this.settings.section_b.HELLO = 10;
this.settings.section_b.WORLD = 20;
}
// somewhere else (pseudo code)
// create toml-file if not exist or modify if exist but strategy params has changed
if( this.strategy.toml || this.strategy.toml.settings !== this.strategy.settings )
writeTOML( this.strategy.settings );
---
It's important to note that I do NOT want your strat to have code that will be run in the UI automatically, for a number of reasons:
- There might not be an UI, or the UI might not be running when the event happens.
- There might be multiple UIs running looking at the same strat.
- It's a big security risk, strats now have the opportunity to run a browser context (of a potentially different machine).
- Some people are working on a native mobile Gekko App, these might not be able to execute client side javascript (or if they can it's another security risk).
1. Yes, but performance analyzer seems to have already solved this? It outputs to terminal if not running UI and outputs to UI if running ui. There's even a "if(ui.connected)" if i remember correctly. I think you're thinking LIVE while i'm thinking BACKTEST, these two differ quite a lot.
2. This already seems to work though; again -- the performance analyzer outputs stuff and it doesn't matter if i got 10x tabs with 10x gekkos? The perf analyzer will still output unique results on a per-browser level so it already seems to be solved?
3. Yes, but having people download custom plugins that may have a lot of dependecies and stuff is an even greater security concern? More code does not increase security since it increases the attack surface. I do not understand the rationale behind more code/dependecies = increased security.
4. The UI already works great on anything that has a browser?
---
I do understand why you don't want 10x hooks to the UI though.
The simpler solution would just be this:
1. Allow user to customize the performance analyzer object e.g:
end: function(){
// get (object?)
let pa = this.performanceAnalyzer;
// modify
pa.result.custom.Stuff = 'Some stuff';
pa.result.custom.Other_stuff = 'Some other stuff';
// write changes
this.performanceAnalyzer = pa;
}
2. Implement 'messages' as a 1st class citizen within Gekko (no plugins...):
msg.alert('hello world')
msg.log('hello world')
msg.speak('hello world')
...etc...
// somewhere else....
msg: {
alert: function( str ){
if( ui.connected ) alert(str)
else log.debug(str)
},
confirm: function( str ){
if( confirm(str) ) return true;
else return false;
},
log: function( str ){
if( ui.connected ) console.log(str); // log to browser console
else log.debug(str); // log to terminal
},
// yeah, this is more for fun; but could be used e.g.
// msg.speak('Backtest finished in 2 minutes and 4 seconds')
speak: function( str ){
if( ui.connected ){
// check support
if( 'speechSynthesis' in window ){
let utterance = new SpeechSynthesisUtterance( str );
utterance.lang = 'en-US';
speechSynthesis.speak(utterance);
}
else { this.alert( str ); }
}
else { log.debug(str); } // no ui -- just log it
}
}
--
I've tried hacking around without modifying the core Gekko files but haven't been successful yet. :-)