first commit
This commit is contained in:
commit
aa7869eb33
386 files changed
+69375
No files matched your search
@@ -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'
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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;
|
||||
@@ -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')
|
||||
}
|
||||
}
|
||||
@@ -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' };
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
const p = require('../../package.json');
|
||||
|
||||
// Retrieves API information
|
||||
module.exports = function *() {
|
||||
this.body = {
|
||||
version: p.version
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
const cache = require('../state/cache');
|
||||
|
||||
module.exports = function(name) {
|
||||
return function *() {
|
||||
this.body = cache.get(name).list();
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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' };
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
Reference in new issue
Block a user