forked from askmike/gekko
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'backtesting' into develop
Conflicts: core/util.js gekko.js sample-config.js
- Loading branch information
Showing
17 changed files
with
307 additions
and
199 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
var _ = require('lodash'); | ||
var util = require('./util'); | ||
var config = util.getConfig(); | ||
var dirs = util.dirs(); | ||
var log = require('./log'); | ||
var moment = require('moment'); | ||
|
||
var Reader = require(dirs.gekko + config.adapter.path); | ||
|
||
var daterange = config.backtest.daterange; | ||
|
||
var Market = function() { | ||
_.bindAll(this); | ||
|
||
this.pushing = false; | ||
this.ended = false; | ||
|
||
Readable.call(this, {objectMode: true}); | ||
|
||
console.log(''); | ||
log.info('\tWARNING: BACKTESTING FEATURE NEEDS PROPER TESTING'); | ||
log.info('\tWARNING: ACT ON THESE NUMBERS AT YOUR OWN RISK!'); | ||
console.log(''); | ||
|
||
this.reader = new Reader(); | ||
this.batchSize = config.backtest.batchSize; | ||
this.iterator = { | ||
from: daterange.from, | ||
to: daterange.from.clone().add(this.batchSize, 'm').subtract(1, 's') | ||
} | ||
} | ||
|
||
var Readable = require('stream').Readable; | ||
Market.prototype = Object.create(Readable.prototype, { | ||
constructor: { value: Market } | ||
}); | ||
|
||
Market.prototype._read = function noop() { | ||
if(this.pushing) | ||
return; | ||
|
||
this.get(); | ||
} | ||
|
||
// Market.prototype.start = function() { | ||
// return this; | ||
// } | ||
|
||
Market.prototype.get = function() { | ||
if(this.iterator.to >= daterange.to) { | ||
this.iterator.to = daterange.to; | ||
this.ended = true; | ||
} | ||
|
||
this.reader.get( | ||
this.iterator.from.unix(), | ||
this.iterator.to.unix(), | ||
this.processCandles | ||
) | ||
} | ||
|
||
Market.prototype.processCandles = function(candles) { | ||
this.pushing = true; | ||
var amount = _.size(candles); | ||
_.each(candles, function(c, i) { | ||
c.start = moment.unix(c.start); | ||
|
||
if(++i === amount) { | ||
// last one candle from batch | ||
if(!this.ended) | ||
this.pushing = false; | ||
else { | ||
_.defer(function() { | ||
this.reader.close(); | ||
this.emit('end'); | ||
}.bind(this)); | ||
} | ||
} | ||
|
||
this.push(c); | ||
|
||
}, this); | ||
|
||
this.iterator = { | ||
from: this.iterator.from.clone().add(this.batchSize, 'm'), | ||
to: this.iterator.from.clone().add(this.batchSize * 2, 'm').subtract(1, 's') | ||
} | ||
} | ||
|
||
module.exports = Market; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
var _ = require('lodash'); | ||
|
||
var util = require('./util'); | ||
var dirs = util.dirs(); | ||
|
||
var config = util.getConfig(); | ||
|
||
var exchanges = require(dirs.gekko + 'exchanges'); | ||
var exchange = _.find(exchanges, function(e) { | ||
return e.slug === config.watch.exchange.toLowerCase(); | ||
}); | ||
|
||
if(!exchange) | ||
util.die(`Unsupported exchange: ${config.watch.exchange.toLowerCase()}`) | ||
|
||
var exchangeChecker = require(util.dirs().core + 'exchangeChecker'); | ||
|
||
var error = exchangeChecker.cantMonitor(config.watch); | ||
if(error) | ||
util.die(error, true); | ||
|
||
module.exports = require(dirs.budfox + 'budfox'); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,52 +1,22 @@ | ||
**These are old docs referrring to the old stable master branch on Gekko. The backtester is broken in this branch** | ||
|
||
# Backtesting with Gekko | ||
|
||
**Note that this functionality should only be used for testing purposes at this moment as it's in early development stage** | ||
|
||
After you configured and run the backtester Gekko will output the results like so: | ||
|
||
2013-06-30 13:25:30 (INFO): (PROFIT REPORT) start time: 2013-04-24 07:00:00 | ||
2013-06-30 13:25:30 (INFO): (PROFIT REPORT) end time: 2013-05-23 16:00:00 | ||
2013-06-30 13:25:30 (INFO): (PROFIT REPORT) timespan: 29 days | ||
|
||
2013-06-30 13:25:30 (INFO): (PROFIT REPORT) start price: 121.6 | ||
2013-06-30 13:25:30 (INFO): (PROFIT REPORT) end price: 125.44 | ||
2013-06-30 13:25:30 (INFO): (PROFIT REPORT) Buy and Hold profit: 3.158% | ||
|
||
2013-06-30 13:25:30 (INFO): (PROFIT REPORT) amount of trades: 15 | ||
2013-06-30 13:25:30 (INFO): (PROFIT REPORT) original simulated balance: 245.404 USD | ||
2013-06-30 13:25:30 (INFO): (PROFIT REPORT) current simulated balance: 281.819 USD | ||
2013-06-30 13:25:30 (INFO): (PROFIT REPORT) simulated profit: 36.415 USD (14.839%) | ||
2013-06-30 13:25:30 (INFO): (PROFIT REPORT) simulated yearly profit: 447.030 USD (182.161%) | ||
|
||
## Preparing Gekko | ||
|
||
You can configure Gekko to test the current EMA strategy on historical data. To do this you need candle data in CSV format. On [this webpage](https://bitcointalk.org/index.php?topic=239815.0) you can downloaded precalculated candles from Mt. Gox or you can calculate your own using the script provided in the link. Alternatively you can supply your own candles, the only requirement is that the csv file has candles ordered like this: `timestamp,open,high,low,close`. | ||
|
||
## Configuring Gekko | ||
Gekko is able to backtest strategies against historical data. | ||
|
||
Once you have the csv file with candles you can configure Gekko for backtesting: in [config.js](https://github.com/askmike/gekko/blob/master/config.js) in the advanced zone you need to the backtesting part like so: | ||
## Setup | ||
|
||
config.backtest = { | ||
candleFile: 'candles.csv', // the candles file | ||
from: 0, // optional start timestamp | ||
to: 0 // optional end timestamp | ||
} | ||
For backtesting you should enable and configure the following plugins: | ||
|
||
Once configured Gekko will run the backtest instead of watching the live market. It wil use the following configuration items: | ||
- trading advisor (to run your strategy) | ||
- profit simulator (to calculate how succesfull the strategy would have been) | ||
|
||
* Everything under `backtest`. | ||
* Everything under `profitCalculator`. | ||
* Everything under `EMA` with the exception of interval, as this will be determined by the candles file. | ||
## Historical data | ||
|
||
## Running the backtester | ||
Gekko requires historical data to backtest strategies against. The easiest way to get this is to run Gekko on real markets with the plugin sqliteWriter enabled (this will cause Gekko to store realtime data on disk). | ||
|
||
Instead of running the paper / live trading Gekko using `node gekko`, you can start the backtester by running: | ||
## Configure | ||
|
||
node gekko-backtest | ||
In your config set the `backtest.daterange` properties. | ||
|
||
## Notes | ||
## Run | ||
|
||
* Use the backtesting feature only for testing until the code is stable. | ||
* When there are missing candles Gekko will act as if the whole duration of the missing candle never happened. | ||
node gekko --backtest |
Oops, something went wrong.