Welcome, Guest
You have to register before you can post on our site.

Username
  

Password
  





Search Forums



(Advanced Search)

Forum Statistics
» Members: 20,566
» Latest member: AdultAd
» Forum threads: 1,541
» Forum posts: 7,724

Full Statistics

Online Users
There are currently 211 online users.
» 1 Member(s) | 210 Guest(s)
Destinydudge

Latest Threads
Gekko development status ...
Forum: Announcements
Last Post: ameliezilber
2 hours ago
» Replies: 805
» Views: 523,666
Gekko with malware spotte...
Forum: Announcements
Last Post: ladyjames6600
04-12-2024, 03:23 AM
» Replies: 129
» Views: 89,977
An official Gekko service...
Forum: Announcements
Last Post: Henery
04-08-2024, 10:56 AM
» Replies: 83
» Views: 138,714
New Gekko UI in the works
Forum: Announcements
Last Post: pmkisanstatuscheckaadharcard
03-28-2024, 10:19 AM
» Replies: 133
» Views: 153,872
Gekko 0.6 released
Forum: Announcements
Last Post: sabinaholt
03-27-2024, 12:10 PM
» Replies: 104
» Views: 213,483
How to Soft Reset or Hard...
Forum: General Discussion
Last Post: lucifar
10-07-2021, 07:18 PM
» Replies: 22
» Views: 39,007
How to add Binance Future...
Forum: Technical Support
Last Post: Xavier32
10-07-2021, 02:20 PM
» Replies: 47
» Views: 81,040
Bittrex Configuration hel...
Forum: Bittrex
Last Post: yirzolusto
10-07-2021, 07:39 AM
» Replies: 6
» Views: 15,053
[Question] Why does gekko...
Forum: General Discussion
Last Post: cryptocurrency0
10-06-2021, 01:16 PM
» Replies: 16
» Views: 34,308
a couple of technical Que...
Forum: Technical Support
Last Post: mtom78632
10-06-2021, 11:08 AM
» Replies: 25
» Views: 45,293

 
  StochRSI K&D Value
Posted by: sartux - 04-05-2018, 02:42 PM - Forum: Strategy Development - No Replies

I would like to create a simple strategy to buy and sell at the intersection of the K and D curves of the StochRSI (a simple difference between the values and then to attach an IF)

But I can not find where to get these values from gekko, can someone help me?


  Do gekko support bitstamp import on not?
Posted by: xFFFFF - 04-05-2018, 02:13 PM - Forum: Bitstamp - Replies (1)

By this page: https://gekko.wizb.it/docs/introduction/...anges.html
Gekko is supporting import for bitstamp. But havent file in gekko/importers and import via Gekko dont working.


  [BOUNTY] strategy on 4ema
Posted by: lucag74 - 04-05-2018, 08:26 AM - Forum: Strategy Development - Replies (4)

Hi, 
my first post here, i'm a newbie in gekko strategy.
What i need , also paying it's a people help me to develop my strategy,

First signal to buy :
Name: 4ema
We analyze 4 Ema, 

for example

Blue Ema : 8 (very short)
Green Ema : 13 (short)
Yellow EMA : 20 (medium)
Red EMA : 30 (long)

Of course the time of for ema must can  be set as parameters.

Buy signal : upward trend
Blue Ema > Green Ema > Yellow Ema > Red Ema

Sell signal :
When there is no more buy signal

You can see the indicator on tradingview is called 4ema.

This strategy must be implemented in future with other indicator like RSI.

And last question, gekko can be make short sell ? I intend short sell , selling borrowed crypto to buy back then.

Thank's


  Kraken import error: (getTrades) returned an irrecoverable error
Posted by: xFFFFF - 04-05-2018, 08:20 AM - Forum: Technical Support - No Replies

In debug all is fine, candles are imported but in terminal I have error like this:

Code:
2018-04-05 10:16:53 (ERROR):    [kraken.js] (getTrades) returned an irrecoverable error: Cannot read property 'date' of undefined
2018-04-05 10:16:53 (ERROR):    There was an error importing from Kraken [kraken.js] Cannot read property 'date' of undefined

my config
Code:
var config = {};
config.debug = true;
config.watch = {
  exchange: 'kraken',
  currency: 'USD',
  asset: 'DASH',
}
config.tradingAdvisor = {
  enabled: false,
  method: 'BBRSI',
  candleSize: 1,
  historySize: 2,
}
config.paperTrader = {
  enabled: false,
  reportInCurrency: true,
  simulationBalance: {
    asset: 0,
    currency: 4,
  },
  feeMaker: 0.05,
  feeTaker: 0.05,
  feeUsing: 'maker',
  slippage: 0.5,
}
config.performanceAnalyzer = {
  enabled: false,
  riskFreeReturn: 5
}
config.trader = {
  enabled: false,
  key: '',
  secret: '',
  username: '',
  passphrase: '',
  orderUpdateDelay: 1,
}
config.adviceLogger = {
  enabled: false,
  muteSoft: true
}
config.candleWriter = {
  enabled: true
}
config.adviceWriter = {
  enabled: false,
  muteSoft: true,
}
config.adapter = 'sqlite';
config.sqlite = {
  path: 'plugins/sqlite',
  dataDirectory: 'history',
  version: 0.1,
  dependencies: []
}
config.backtest = {
  daterange:  'scan',
  batchSize: 50
}
config.importer = {
  daterange: {
    from: "2018-03-28 00:00",
    to: "2018-04-05 08:16:16"
  }
}

config['I understand that Gekko only automates MY OWN trading strategies'] = true;
module.exports = config;


  Can incrase signature chars limit?
Posted by: xFFFFF - 04-05-2018, 08:04 AM - Forum: General Discussion - No Replies

I would add links to my repos but lenght is too high...

Quote:Please correct the following errors before continuing:

  • You cannot update your signature because it is too long. The maximum length for signatures is 100 characters.

  • Please remove 122 characters and try again.


  Fix Increase efficiency and shorten order filling time
Posted by: xFFFFF - 04-05-2018, 07:59 AM - Forum: Guides - No Replies

I found this solution at Gekkos Issues. It bounce last bid/ask price down/up by 0,04% while making order at Binance. Its cheaper solution than market order type. Im lame in Gekkos functions and overall javascript, so it propablly bounce price two times.

Code:
const moment = require('moment');
const _ = require('lodash');

const util = require('../core/util');
const Errors = require('../core/error');
const log = require('../core/log');
const marketData = require('./binance-markets.json');

const Binance = require('binance');

var Trader = function(config) {
  _.bindAll(this);

  if (_.isObject(config)) {
    this.key = config.key;
    this.secret = config.secret;
    this.currency = config.currency.toUpperCase();
    this.asset = config.asset.toUpperCase();
  }

  this.pair = this.asset + this.currency;
  this.name = 'binance';

  this.market = _.find(Trader.getCapabilities().markets, (market) => {
    return market.pair[0] === this.currency && market.pair[1] === this.asset
  });

  this.binance = new Binance.BinanceRest({
    key: this.key,
    secret: this.secret,
    timeout: 15000,
    recvWindow: 60000, // suggested by binance
    disableBeautification: false,
    handleDrift: true,
  });
};

var retryCritical = {
  retries: 10,
  factor: 1.2,
  minTimeout: 1 * 1000,
  maxTimeout: 30 * 1000
};

var retryForever = {
  forever: false,
  factor: 1.2,
  minTimeout: 10 * 1000,
  maxTimeout: 30 * 1000
};

var recoverableErrors = new RegExp(/(SOCKETTIMEDOUT|TIMEDOUT|CONNRESET|CONNREFUSED|NOTFOUND|Error -1021|Response code 429|Response code 5)/);

Trader.prototype.processError = function(funcName, error) {
  if (!error) return undefined;

  if (!error.message || !error.message.match(recoverableErrors)) {
    log.error(`[binance.js] (${funcName}) returned an irrecoverable error: ${error}`);
    return new Errors.AbortError('[binance.js] ' + error.message || error);
  }

  log.debug(`[binance.js] (${funcName}) returned an error, retrying: ${error}`);
  return new Errors.RetryError('[binance.js] ' + error.message || error);
};

Trader.prototype.handleResponse = function(funcName, callback) {
  return (error, body) => {
    if (body && !_.isEmpty(body.code)) {
      error = new Error(`Error ${body.code}: ${body.msg}`);
    }

    return callback(this.processError(funcName, error), body);
  }
};

Trader.prototype.getTrades = function(since, callback, descending) {
  var processResults = function(err, data) {
    if (err) return callback(err);

    var parsedTrades = [];
    _.each(
      data,
      function(trade) {
        parsedTrades.push({
          tid: trade.aggTradeId,
          date: moment(trade.timestamp).unix(),
          price: parseFloat(trade.price),
          amount: parseFloat(trade.quantity),
        });
      },
      this
    );

    if (descending) callback(null, parsedTrades.reverse());
    else callback(undefined, parsedTrades);
  };

  var reqData = {
    symbol: this.pair,
  };

  if (since) {
    var endTs = moment(since)
      .add(1, 'h')
      .valueOf();
    var nowTs = moment().valueOf();

    reqData.startTime = moment(since).valueOf();
    reqData.endTime = endTs > nowTs ? nowTs : endTs;
  }

  let handler = (cb) => this.binance.aggTrades(reqData, this.handleResponse('getTrades', cb));
  util.retryCustom(retryForever, _.bind(handler, this), _.bind(processResults, this));
};

Trader.prototype.getPortfolio = function(callback) {
  var setBalance = function(err, data) {
    log.debug(`[binance.js] entering "setBalance" callback after api call, err: ${err} data: ${JSON.stringify(data)}`)
    if (err) return callback(err);

    var findAsset = function(item) {
      return item.asset === this.asset;
    }
    var assetAmount = parseFloat(_.find(data.balances, _.bind(findAsset, this)).free);

    var findCurrency = function(item) {
      return item.asset === this.currency;
    }
    var currencyAmount = parseFloat(_.find(data.balances, _.bind(findCurrency, this)).free);

    if (!_.isNumber(assetAmount) || _.isNaN(assetAmount)) {
      log.error(
        `Binance did not return portfolio for ${this.asset}, assuming 0.`
      );
      assetAmount = 0;
    }

    if (!_.isNumber(currencyAmount) || _.isNaN(currencyAmount)) {
      log.error(
        `Binance did not return portfolio for ${this.currency}, assuming 0.`
      );
      currencyAmount = 0;
    }

    var portfolio = [
      { name: this.asset, amount: assetAmount },
      { name: this.currency, amount: currencyAmount },
    ];

    return callback(undefined, portfolio);
  };

  let handler = (cb) => this.binance.account({}, this.handleResponse('getPortfolio', cb));
  util.retryCustom(retryForever, _.bind(handler, this), _.bind(setBalance, this));
};

// This uses the base maker fee (0.1%), and does not account for BNB discounts
Trader.prototype.getFee = function(callback) {
  var makerFee = 0.05;
  callback(undefined, makerFee / 100);
};

Trader.prototype.getTicker = function(callback) {
  var setTicker = function(err, data) {
    log.debug(`[binance.js] entering "getTicker" callback after api call, err: ${err} data: ${(data || []).length} symbols`);
    if (err) return callback(err);

    var findSymbol = function(ticker) {
      return ticker.symbol === this.pair;
    }
    var result = _.find(data, _.bind(findSymbol, this));

    var ticker = {
      ask: parseFloat(result.askPrice),
      bid: parseFloat(result.bidPrice),
    };

    callback(undefined, ticker);
  };

  let handler = (cb) => this.binance._makeRequest({}, this.handleResponse('getTicker', cb), 'api/v1/ticker/allBookTickers');
  util.retryCustom(retryForever, _.bind(handler, this), _.bind(setTicker, this));
};

// Effectively counts the number of decimal places, so 0.001 or 0.234 results in 3
Trader.prototype.getPrecision = function(tickSize) {
  if (!isFinite(tickSize)) return 0;
  var e = 1, p = 0;
  while (Math.round(tickSize * e) / e !== tickSize) { e *= 10; p++; }
  return p;
};

Trader.prototype.roundAmount = function(amount, tickSize) {
  var precision = 100000000;
  var t = this.getPrecision(tickSize);

  if(Number.isInteger(t))
    precision = Math.pow(10, t);

  amount *= precision;
  amount = Math.floor(amount);
  amount /= precision;
  return amount;
};

Trader.prototype.getLotSize = function(tradeType, amount, price, callback) {
log.debug(price);

  log.debug(price);
  amount = this.roundAmount(amount, this.market.minimalOrder.amount);
  if (amount < this.market.minimalOrder.amount)
    return callback(undefined, { amount: 0, price: 0 });
log.debug(price);
  price = this.roundAmount(price, this.market.minimalOrder.price)
  price += (tradeType === 'buy') ? (price * .004) : -(price * .004);
  price = Math.max(this.roundAmount(price, 0.00001), 0.00001);



  if (price < this.market.minimalOrder.price)
    return callback(undefined, { amount: 0, price: 0 });

  if (amount * price < this.market.minimalOrder.order)
    return callback(undefined, { amount: 0, price: 0});

  callback(undefined, { amount: amount, price: price });
}


Trader.prototype.addOrder = function(tradeType, amount, price, callback) {
  log.debug(`[binance.js] (addOrder) ${tradeType.toUpperCase()} ${amount} ${this.asset} @${price} ${this.currency}`);
log.debug(price);
price += (tradeType === 'buy') ? (price * .004) : -(price * .004);
  price = Math.max(this.roundAmount(price, 0.00001), 0.00001);
log.debug(price);
  var setOrder = function(err, data) {
    log.debug(`[binance.js] entering "setOrder" callback after api call, err: ${err} data: ${JSON.stringify(data)}`);
    if (err) return callback(err);

    var txid = data.orderId;
    log.debug(`[binance.js] added order with txid: ${txid}`);

    callback(undefined, txid);
  };

  let reqData = {
    symbol: this.pair,
    side: tradeType.toUpperCase(),
    type: 'LIMIT',
    timeInForce: 'GTC', // Good to cancel (I think, not really covered in docs, but is default)
    quantity: amount,
    price: price,
    timestamp: new Date().getTime()
  };

  let handler = (cb) => this.binance.newOrder(reqData, this.handleResponse('addOrder', cb));
  util.retryCustom(retryCritical, _.bind(handler, this), _.bind(setOrder, this));
    log.debug(price);
    

   log.debug(price);
};

Trader.prototype.getOrder = function(order, callback) {
  var get = function(err, data) {
    log.debug(`[binance.js] entering "getOrder" callback after api call, err ${err} data: ${JSON.stringify(data)}`);
    if (err) return callback(err);
log.debug(price);
    var price = parseFloat(data.price);
log.debug(price);
    var amount = parseFloat(data.executedQty);
    // Data.time is a 13 digit millisecon unix time stamp.
    // https://momentjs.com/docs/#/parsing/unix-timestamp-milliseconds/ 
    var date = moment(data.time);

    callback(undefined, { price, amount, date });
  }.bind(this);

  let reqData = {
    symbol: this.pair,
    orderId: order,
  };

  let handler = (cb) => this.binance.queryOrder(reqData, this.handleResponse('getOrder', cb));
  util.retryCustom(retryCritical, _.bind(handler, this), _.bind(get, this));
};

Trader.prototype.buy = function(amount, price, callback) {
log.debug(price);

  this.addOrder('buy', amount, price, callback);
      price += price * .004;
};

Trader.prototype.sell = function(amount, price, callback) {
log.debug(price);

log.debug(price);
  this.addOrder('sell', amount, price, callback);
      price += - price * .004;
};

Trader.prototype.checkOrder = function(order, callback) {
  var check = function(err, data) {
    log.debug(`[binance.js] entering "checkOrder" callback after api call, err ${err} data: ${JSON.stringify(data)}`);
    if (err) return callback(err);

    var stillThere = data.status === 'NEW' || data.status === 'PARTIALLY_FILLED';
    var canceledManually = data.status === 'CANCELED' || data.status === 'REJECTED' || data.status === 'EXPIRED';
    callback(undefined, !stillThere && !canceledManually);
  };

  let reqData = {
    symbol: this.pair,
    orderId: order,
  };

  let handler = (cb) => this.binance.queryOrder(reqData, this.handleResponse('checkOrder', cb));
  util.retryCustom(retryCritical, _.bind(handler, this), _.bind(check, this));
};

Trader.prototype.cancelOrder = function(order, callback) {
  // callback for cancelOrder should be true if the order was already filled, otherwise false
  var cancel = function(err, data) {
    log.debug(`[binance.js] entering "cancelOrder" callback after api call, err ${err} data: ${JSON.stringify(data)}`);
    if (err) {
      if(data && data.msg === 'UNKNOWN_ORDER') {  // this seems to be the response we get when an order was filled
        return callback(true); // tell the thing the order was already filled
      }
      return callback(err);
    }
    callback(undefined);
  };

  let reqData = {
    symbol: this.pair,
    orderId: order,
  };

  let handler = (cb) => this.binance.cancelOrder(reqData, this.handleResponse('cancelOrder', cb));
  util.retryCustom(retryForever, _.bind(handler, this), _.bind(cancel, this));
};

Trader.prototype.initMarkets = function(callback) {

}

Trader.getCapabilities = function() {
  return {
    name: 'Binance',
    slug: 'binance',
    currencies: marketData.currencies,
    assets: marketData.assets,
    markets: marketData.markets,
    requires: ['key', 'secret'],
    providesHistory: 'date',
    providesFullHistory: true,
    tid: 'tid',
    tradable: true,
  };
};

module.exports = Trader;
Only lines 215-216, 223-224, 292 and 300 was changed. This same way You can implement fix on all exchanges. 

UPDATE - BITFINEX EXAMPLE
You must add one line to Trader.prototype.buy and Trader.prototype.sell in bitfinex.js
Example:
Code:
Trader.prototype.buy = function(amount, price, callback) {
  this.submit_order('buy', amount, price, callback);
  price += price * .004;
}

Trader.prototype.sell = function(amount, price, callback) {
  this.submit_order('sell', amount, price, callback);
  price += - price * .004;
}

It plus 0,4% of price to ask/bid price on making order to exchange. So incrase/decrase price a bit. Full changed file:
Code:
const Bitfinex = require("bitfinex-api-node");
const _ = require('lodash');
const moment = require('moment');

const util = require('../core/util');
const Errors = require('../core/error');
const log = require('../core/log');

const marketData = require('./bitfinex-markets.json');

var Trader = function(config) {
  _.bindAll(this);
  if(_.isObject(config)) {
    this.key = config.key;
    this.secret = config.secret;
  }
  this.name = 'Bitfinex';
  this.balance;
  this.price;
  this.asset = config.asset;
  this.currency = config.currency;
  this.pair = this.asset + this.currency;
  this.bitfinex = new Bitfinex(this.key, this.secret, { version: 1 }).rest;
}

var retryCritical = {
  retries: 10,
  factor: 1.2,
  minTimeout: 10 * 1000,
  maxTimeout: 60 * 1000
};

var retryForever = {
  forever: true,
  factor: 1.2,
  minTimeout: 10 * 1000,
  maxTimeout: 300 * 1000
};

// Probably we need to update these string
var recoverableErrors = new RegExp(/(SOCKETTIMEDOUT|TIMEDOUT|CONNRESET|CONNREFUSED|NOTFOUND|429|443|5\d\d)/g);

Trader.prototype.processError = function(funcName, error) {
  if (!error) return undefined;

  if (!error.message.match(recoverableErrors)) {
    log.error(`[bitfinex.js] (${funcName}) returned an irrecoverable error: ${error.message}`);
    return new Errors.AbortError('[bitfinex.js] ' + error.message);
  }

  log.debug(`[bitfinex.js] (${funcName}) returned an error, retrying: ${error.message}`);
  return new Errors.RetryError('[bitfinex.js] ' + error.message);
};

Trader.prototype.handleResponse = function(funcName, callback) {
  return (error, data, body) => {
    return callback(this.processError(funcName, error), data);
  }
};

Trader.prototype.getPortfolio = function(callback) {
  let process = (err, data) => {
    if (err) return callback(err);

    // We are only interested in funds in the "exchange" wallet
    data = data.filter(c => c.type === 'exchange');

    const asset = _.find(data, c => c.currency.toUpperCase() === this.asset);
    const currency = _.find(data, c => c.currency.toUpperCase() === this.currency);

    let assetAmount, currencyAmount;

    if(_.isObject(asset) && _.isNumber(+asset.available) && !_.isNaN(+asset.available))
      assetAmount = +asset.available;
    else {
      log.error(`Bitfinex did not provide ${this.asset} amount, assuming 0`);
      assetAmount = 0;
    }

    if(_.isObject(currency) && _.isNumber(+currency.available) && !_.isNaN(+currency.available))
      currencyAmount = +currency.available;
    else {
      log.error(`Bitfinex did not provide ${this.currency} amount, assuming 0`);
      currencyAmount = 0;
    }

    const portfolio = [
      { name: this.asset, amount: assetAmount },
      { name: this.currency, amount: currencyAmount },
    ];

    callback(undefined, portfolio);
  };

  let handler = (cb) => this.bitfinex.wallet_balances(this.handleResponse('getPortfolio', cb));
  util.retryCustom(retryForever, _.bind(handler, this), _.bind(process, this));
}

Trader.prototype.getTicker = function(callback) {
  let process = (err, data) => {
    if (err) return callback(err);

    // whenever we reach this point we have valid
    // data, the callback is still the same since
    // we are inside the same javascript scope.
    callback(undefined, {bid: +data.bid, ask: +data.ask})
  };
  
  let handler = (cb) => this.bitfinex.ticker(this.pair, this.handleResponse('getTicker', cb));
  util.retryCustom(retryForever, _.bind(handler, this), _.bind(process, this));
}

// This assumes that only limit orders are being placed, so fees are the
// "maker fee" of 0.1%.  It does not take into account volume discounts.
Trader.prototype.getFee = function(callback) {
    var makerFee = 0.1;
    callback(undefined, makerFee / 100);
}

Trader.prototype.submit_order = function(type, amount, price, callback) {
  let process = (err, data) => {
    if (err) return callback(err);

    callback(err, data.order_id);
  }

  amount = Math.floor(amount*100000000)/100000000;
  let handler = (cb) => this.bitfinex.new_order(this.pair,
    amount + '',
    price + '',
    this.name.toLowerCase(),
    type,
    'exchange limit',
    this.handleResponse('submitOrder', cb)
  );

  util.retryCustom(retryCritical, _.bind(handler, this), _.bind(process, this));
}

Trader.prototype.buy = function(amount, price, callback) {
  this.submit_order('buy', amount, price, callback);
  price += price * .004;
}

Trader.prototype.sell = function(amount, price, callback) {
  this.submit_order('sell', amount, price, callback);
  price += - price * .004;
}

Trader.prototype.checkOrder = function(order_id, callback) {
  let process = (err, data) => {
    if (err) return callback(err);

    callback(undefined, !data.is_live);
  }

  let handler = (cb) => this.bitfinex.order_status(order_id, this.handleResponse('checkOrder', cb));
  util.retryCustom(retryCritical, _.bind(handler, this), _.bind(process, this));
}


Trader.prototype.getOrder = function(order_id, callback) {
  let process = (err, data) => {
    if (err) return callback(err);

    var price = parseFloat(data.avg_execution_price);
    var amount = parseFloat(data.executed_amount);
    var date = moment.unix(data.timestamp);

    callback(undefined, {price, amount, date});
  };

  let handler = (cb) => this.bitfinex.order_status(order_id, this.handleResponse('getOrder', cb));
  util.retryCustom(retryCritical, _.bind(handler, this), _.bind(process, this));
}


Trader.prototype.cancelOrder = function(order_id, callback) {
  let process = (err, data) => {
    if (err) return callback(err);

    return callback(undefined);
  }

  let handler = (cb) => this.bitfinex.cancel_order(order_id, this.handleResponse('cancelOrder', cb));
  util.retryCustom(retryForever, _.bind(handler, this), _.bind(process, this));
}

Trader.prototype.getTrades = function(since, callback, descending) {
  let process = (err, data) => {  
    if (err) return callback(err);

    var trades = _.map(data, function(trade) {
      return {
        tid: trade.tid,
        date:  trade.timestamp,
        price: +trade.price,
        amount: +trade.amount
      }
    });

    callback(undefined, descending ? trades : trades.reverse());
  };

  var path = this.pair;
  if(since)
    path += '?limit_trades=2000';

  let handler = (cb) => this.bitfinex.trades(path, this.handleResponse('getTrades', cb));
  util.retryCustom(retryForever, _.bind(handler, this), _.bind(process, this));
}

Trader.getCapabilities = function () {
  return {
    name: 'Bitfinex',
    slug: 'bitfinex',
    currencies: marketData.currencies,
    assets: marketData.assets,
    markets: marketData.markets,
    requires: ['key', 'secret'],
    tid: 'tid',
    providesFullHistory: true,
    providesHistory: 'date',
    tradable: true,
    forceReorderDelay: true
  };
}

module.exports = Trader;


My subjective feelings are that it speeds up filling orders a bit. The more value you put in place .004 the faster theoretically it should be order filled. Im using tickrate 2 sec and orderdelay 15 sec. If someone will compare the method with the traditional one in live mode, please let me know.

This idea can be used to delevop a more intelligent solution that would raise the price until the order is filled. I would be grateful if someone did it Smile


  Complete Gekko's datasets - ready files to download and use
Posted by: xFFFFF - 04-04-2018, 10:14 PM - Forum: General Discussion - Replies (22)

Ready to use Gekko's SQLite dumps files. Without importing via Gekko import and exchange APIs.
Just copy the file to the history directory and you have: full history of Binance Exchange for example. The files are updated daily after 23:15 GMT.

Included
- Binance - FULL history
- Poloniex - all pairs - in progress
- Kraken - all pairs - in progress

Download
Links and all acctually information are on Github: https://github.com/xFFFFF/Gekko-Datasets

Soon
- Kraken all pairs
- Bitfinex all pairs
- Poloniex all pairs
- Gdax all pairs

How to import pairs from Coinfalcon, BTCC and Bitstamp? Smile


  Ability to long/short multiple shares
Posted by: rcleaves - 04-04-2018, 06:15 PM - Forum: Feature Requests - No Replies

It would be great to be able to specify the number of shares to be traded either as a number and/or percentage of total held.


Thumbs Up How to run Rsi-Bull-bear with command line (cli)
Posted by: ankasem - 04-04-2018, 04:55 PM - Forum: Automated Trading - Replies (7)

hi all

- Rsi-Bull-bear command line (cli) mod how to operate with


  Config.jsRsi-Bull-bear )how to write strategy


thank you

-------------------------------------------------- ----------------------------
     sample config.js
     https://github.com/xFFFFF

     


  Add multi-threaded backtesting
Posted by: tommiehansen - 04-04-2018, 01:23 PM - Forum: Technical Discussion - Replies (1)

Why?
Because a single backtest does not really say that much, often we want to test a broad range of different parameters but doing this takes a lot of bloody time.
Imagine that one of these tests take 5 minutes and now imagine that you want to try at least 10 different variations. It quickly becomes so tedious so that one basically needs to create 3rd party software in order to do this.

How?
1. Make sure Gekko caches repeating calculations (basically -- just cache last X requests so that repeating queries for the same data is cached or 'pre-compiled')
2. Add options for the above (i might run 3x strategies against 3x different asset/currencies so i might need more caching)
3. Invent a new pseudo-TOML format to allow dynamic parameters
4. Add timeouts
5. Add option for number of threads
6. Let user specify timeout @ web/vue/UIconfig.js (this file is btw terrible since it dictates timeouts for the backtesting ... should be a user.conf value and easily change:able via the api e.g. { timeout: 30000 }
7. Add option for multi-server mode (run the backtests against an array of servers instead of just 'localhost')
8. Use localStorage to automatically save stuff (not fun to have to input the same stuff again... again.. and again)

There are loads of things to write here, basically -- check out my "GAB" tool:
https://forum.gekko.wizb.it/thread-56589.html

And basically clone the functionality and core ideas.