first commit

This commit is contained in:
Francois Klieber committed 2021-06-06 20:25:14 +02:00
commit aa7869eb33
386 files changed
+69375

No files matched your search

+26
View File
@@ -0,0 +1,26 @@
const cache = require('../state/cache');
const manager = cache.get('apiKeyManager');
module.exports = {
get: function *() {
this.body = manager.get();
},
add: function *() {
const content = this.request.body;
manager.add(content.exchange, content.values);
this.body = {
status: 'ok'
};
},
remove: function *() {
const exchange = this.request.body.exchange;
manager.remove(exchange);
this.body = {
status: 'ok'
};
}
}
+31
View File
@@ -0,0 +1,31 @@
// simple POST request that returns the backtest result
const _ = require('lodash');
const promisify = require('tiny-promisify');
const pipelineRunner = promisify(require('../../core/workers/pipeline/parent'));
// starts a backtest
// requires a post body like:
//
// {
// gekkoConfig: {watch: {exchange: "poloniex", currency: "USDT", asset: "BTC"},…},…}
// data: {
// candleProps: ["close", "start"],
// indicatorResults: true,
// report: true,
// roundtrips: true
// }
// }
module.exports = function *() {
var mode = 'backtest';
var config = {};
var base = require('./baseConfig');
var req = this.request.body;
_.merge(config, base, req);
this.body = yield pipelineRunner(mode, config);
}
+104
View File
@@ -0,0 +1,104 @@
var UIconfig = require('../vue/dist/UIconfig');
var config = {};
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// GENERAL SETTINGS
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
config.silent = false;
config.debug = true;
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// CONFIGURING TRADING ADVICE
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
config.tradingAdvisor = {
}
config.candleWriter = {
enabled: false
}
config.backtestResultExporter = {
enabled: false,
writeToDisk: false,
data: {
stratUpdates: false,
roundtrips: true,
stratCandles: true,
trades: true
}
}
config.childToParent = {
enabled: false,
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// CONFIGURING ADAPTER
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// configurable in the UIconfig
config.adapter = UIconfig.adapter;
config.sqlite = {
path: 'plugins/sqlite',
version: 0.1,
dataDirectory: 'history',
journalMode: require('../isWindows.js') ? 'PERSIST' : 'WAL',
dependencies: [{
module: 'sqlite3',
version: '3.1.4'
}]
}
// Postgres adapter example config (please note: requires postgres >= 9.5):
config.postgresql = {
path: 'plugins/postgresql',
version: 0.1,
connectionString: 'postgres://user:pass@localhost:5432', // if default port
database: null, // if set, we'll put all tables into a single database.
schema: 'public',
dependencies: [{
module: 'pg',
version: '7.4.3'
}]
}
// Mongodb adapter, requires mongodb >= 3.3 (no version earlier tested)
config.mongodb = {
path: 'plugins/mongodb',
version: 0.1,
connectionString: 'mongodb://mongodb/gekko', // connection to mongodb server
dependencies: [{
module: 'mongojs',
version: '2.4.0'
}]
}
config.adviceWriter = {
enabled: false,
muteSoft: true,
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// CONFIGURING BACKTESTING
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Note that these settings are only used in backtesting mode, see here:
// @link: https://github.com/askmike/gekko/blob/stable/docs/Backtesting.md
config.backtest = {
daterange: 'scan',
batchSize: 50
}
config.importer = {
daterange: {
// NOTE: these dates are in UTC
from: "2016-06-01 12:00:00"
}
}
module.exports = config;
+20
View File
@@ -0,0 +1,20 @@
const _ = require('lodash');
const fs = require('co-fs');
const parts = {
paperTrader: 'config/plugins/paperTrader',
candleWriter: 'config/plugins/candleWriter',
performanceAnalyzer: 'config/plugins/performanceAnalyzer'
}
const gekkoRoot = __dirname + '/../../';
module.exports = function *() {
if(!_.has(parts, this.params.part))
return this.body = 'error :(';
const fileName = gekkoRoot + '/' + parts[this.params.part] + '.toml';
this.body = {
part: yield fs.readFile(fileName, 'utf8')
}
}
+22
View File
@@ -0,0 +1,22 @@
const cache = require('../state/cache');
const gekkoManager = cache.get('gekkos');
// Deletes a gekko
// requires a post body with an id
module.exports = function *() {
let id = this.request.body.id;
if(!id) {
this.body = { status: 'not ok' }
return;
}
try {
gekkoManager.delete(id);
} catch(e) {
this.body = { status: e.message }
}
this.body = { status: 'ok' };
}
+39
View File
@@ -0,0 +1,39 @@
const _ = require('lodash');
const fs = require('co-fs');
const gekkoRoot = __dirname + '/../../';
var util = require(__dirname + '/../../core/util');
var config = {};
config.debug = false;
config.silent = false;
util.setConfig(config);
module.exports = function *() {
const exchangesDir = yield fs.readdir(gekkoRoot + 'exchange/wrappers/');
const exchanges = exchangesDir
.filter(f => _.last(f, 3).join('') === '.js')
.map(f => f.slice(0, -3));
let allCapabilities = [];
exchanges.forEach(function (exchange) {
let Trader = null;
try {
Trader = require(gekkoRoot + 'exchange/wrappers/' + exchange);
} catch (e) {
return;
}
if (!Trader || !Trader.getCapabilities) {
return;
}
allCapabilities.push(Trader.getCapabilities());
});
this.body = allCapabilities;
}
+40
View File
@@ -0,0 +1,40 @@
// simple POST request that returns the candles requested
// expects a config like:
// let config = {
// watch: {
// exchange: 'poloniex',
// currency: 'USDT',
// asset: 'BTC'
// },
// daterange: {
// from: '2016-05-22 11:22',
// to: '2016-06-03 19:56'
// },
// adapter: 'sqlite',
// sqlite: {
// path: 'plugins/sqlite',
// dataDirectory: 'history',
// version: 0.1,
// dependencies: [{
// module: 'sqlite3',
// version: '3.1.4'
// }]
// },
// candleSize: 100
// }
const _ = require('lodash');
const promisify = require('tiny-promisify');
const candleLoader = promisify(require('../../core/workers/loadCandles/parent'));
const base = require('./baseConfig');
module.exports = function *() {
config = {};
_.merge(config, base, this.request.body);
this.body = yield candleLoader(config);
}
+75
View File
@@ -0,0 +1,75 @@
const _ = require('lodash');
const promisify = require('tiny-promisify');
const pipelineRunner = promisify(require('../../core/workers/pipeline/parent'));
const cache = require('../state/cache');
const broadcast = cache.get('broadcast');
const importManager = cache.get('imports');
const base = require('./baseConfig');
// starts an import
// requires a post body with a config object
module.exports = function *() {
let mode = 'importer';
let config = {}
_.merge(config, base, this.request.body);
let importId = (Math.random() + '').slice(3);
let errored = false;
console.log('Import', importId, 'started');
pipelineRunner(mode, config, (err, event) => {
if(errored)
return;
if(err) {
errored = true;
console.error('RECEIVED ERROR IN IMPORT', importId);
console.error(err);
importManager.delete(importId);
return broadcast({
type: 'import_error',
import_id: importId,
error: err
});
}
if(!event)
return;
// update local cache
importManager.update(importId, {
latest: event.latest,
done: event.done
});
// emit update over ws
let wsEvent = {
type: 'import_update',
import_id: importId,
updates: {
latest: event.latest,
done: event.done
}
}
broadcast(wsEvent);
});
let daterange = this.request.body.importer.daterange;
const _import = {
watch: config.watch,
id: importId,
latest: '',
from: daterange.from,
to: daterange.to
}
importManager.add(_import);
this.body = _import;
}
+8
View File
@@ -0,0 +1,8 @@
const p = require('../../package.json');
// Retrieves API information
module.exports = function *() {
this.body = {
version: p.version
}
}
+7
View File
@@ -0,0 +1,7 @@
const cache = require('../state/cache');
module.exports = function(name) {
return function *() {
this.body = cache.get(name).list();
}
}
+19
View File
@@ -0,0 +1,19 @@
const _ = require('lodash');
const promisify = require('promisify-node');
const scan = promisify(require('../../core/workers/datasetScan/parent'));
// starts a scan
// requires a post body with configuration of:
//
// - config.watch
const route = function *() {
var config = require('./baseConfig');
_.merge(config, this.request.body);
this.body = yield scan(config);
};
module.exports = route;
+19
View File
@@ -0,0 +1,19 @@
const _ = require('lodash');
const promisify = require('promisify-node');
const scan = promisify(require('../../core/workers/dateRangeScan/parent'));
// starts a scan
// requires a post body with configuration of:
//
// - config.watch
const route = function *() {
var config = require('./baseConfig');
_.merge(config, this.request.body);
this.body = yield scan(config);
};
module.exports = route;
+38
View File
@@ -0,0 +1,38 @@
const _ = require('lodash');
const cache = require('../state/cache');
const Logger = require('../state/logger');
const apiKeyManager= cache.get('apiKeyManager');
const gekkoManager = cache.get('gekkos');
const base = require('./baseConfig');
// starts an import
// requires a post body with a config object
module.exports = function *() {
const mode = this.request.body.mode;
let config = {};
_.merge(config, base, this.request.body);
// Attach API keys
if(config.trader && config.trader.enabled && !config.trader.key) {
const keys = apiKeyManager._getApiKeyPair(config.watch.exchange);
if(!keys) {
this.body = 'No API keys found for this exchange.';
return;
}
_.merge(
config.trader,
keys
);
}
const state = gekkoManager.add({config, mode});
this.body = state;
}
+23
View File
@@ -0,0 +1,23 @@
const cache = require('../state/cache');
const gekkoManager = cache.get('gekkos');
// stops a Gekko
// requires a post body with an id
module.exports = function *() {
let id = this.request.body.id;
if(!id) {
this.body = { status: 'not ok' }
return;
}
let stopped = gekkoManager.stop(id);
if(!stopped) {
this.body = { status: 'not ok' }
return;
}
this.body = { status: 'ok' };
}
+27
View File
@@ -0,0 +1,27 @@
const _ = require('lodash');
const fs = require('co-fs');
const gekkoRoot = __dirname + '/../../';
module.exports = function *() {
const strategyDir = yield fs.readdir(gekkoRoot + 'strategies');
const strats = strategyDir
.filter(f => _.last(f, 3).join('') === '.js')
.map(f => {
return { name: f.slice(0, -3) }
});
// for every strat, check if there is a config file and add it
const stratConfigPath = gekkoRoot + 'config/strategies';
const strategyParamsDir = yield fs.readdir(stratConfigPath);
for(let i = 0; i < strats.length; i++) {
let strat = strats[i];
if(strategyParamsDir.indexOf(strat.name + '.toml') !== -1)
strat.params = yield fs.readFile(stratConfigPath + '/' + strat.name + '.toml', 'utf8')
else
strat.params = '';
}
this.body = strats;
}