Skip to content

Commit

Permalink
Merge github.com:kuzetsa/gekko into anti-conflicts
Browse files Browse the repository at this point in the history
  • Loading branch information
Sarah White committed Nov 19, 2014
2 parents fa9fb05 + c27b57b commit 796a84f
Show file tree
Hide file tree
Showing 17 changed files with 1,761 additions and 25 deletions.
661 changes: 661 additions & 0 deletions LICENSE.md

Large diffs are not rendered by default.

25 changes: 0 additions & 25 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,32 +34,7 @@ Gekko also has a plugin system that can do certain things whenever something hap
- Profit Simulator (paper trader): Hold a fake portfolio and simulate trades based on advice.
- Redis Beacon: Broadcast events propagating through Gekko on [Redis pub/sub](http://redis.io/topics/pubsub).

<<<<<<< HEAD
### Installing Gekko
||||||| merged common ancestors
## Supported exchanges

Gekko works on the following exchanges:

- Mt. Gox
- Bitstamp
- CEX.io
- Kraken
- BTC-e
- ~~Cryptsy~~ (In the [pipeline](https://github.com/askmike/gekko/pull/200))
=======
## Supported exchanges

Gekko works on the following exchanges:

- Mt. Gox
- Bitstamp
- CEX.io
- Kraken
- BTC-e
- Bitfinex
- ~~Cryptsy~~ (In the [pipeline](https://github.com/askmike/gekko/pull/200))
>>>>>>> 50ed5e840d7a355932bd8ed01410605c35d682ee

Windows user? Here is a [step-by-step guide](https://github.com/kuzetsa/gekko/blob/master/docs/installing_gekko_on_windows.md) on how to get Gekko running on Windows.

Expand Down
283 changes: 283 additions & 0 deletions exchanges/cryptsy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,283 @@
var cryptsy = require("cryptsy-api");
moment = require('moment'),
async = require('async'),
_ = require('lodash'),
util = require('../core/util'),
log = require('../core/log');


var Trader = function(config) {
this.key = config.key;
this.secret = config.secret;
this.currency = config.currency;
this.asset = config.asset;
this.pair = config.asset.toUpperCase() + config.currency.toUpperCase();

if( config.market_id )
this.market_id = config.market_id;

this.name = 'Cryptsy';

this.cryptsy = new cryptsy(
this.key,
this.secret
);

this.market = this.pair;

_.bindAll(this);
}


Trader.prototype.return_trades = function(market, callback) {

var m_id;
var main_trades;
var client = this.cryptsy;

//log.debug('client is ', client);
client.getmarketid(market, function(market_id) {
//log.debug('id is', market_id);
// Display user's trades in that market
client.markettrades(market_id, function(trades) {
m_id = market_id;
//log.debug("Grabbing trades for id ", market_id);
if(trades.length) {
//log.debug("There are ", trades.length, 'trades');
var full_array = [];
//trades = trades.reverse();
trades.forEach( function(trade) {
// convert to int
trade.amount = Number(trade.quantity);
trade.price = Number(trade.tradeprice);
trade.tid = Number(trade.tradeid);
// ISSUE: this assumes that the local machine is in PDT
trade.date = moment(Date.parse(trade.datetime)).utc().unix();
full_array.push(trade);
});

callback(null, full_array);
}
});
});
//this.market_id = m_id;
}


Trader.prototype.get_bid_ask = function(market, callback) {

var m_id;
var main_trades;
var client = this.cryptsy;

//log.debug('client is ', client);
client.getmarketid(market, function(market_id) {
//log.debug('id is', market_id);
// Display user's trades in that market
client.markettrades(market_id, function(trades) {
//log.debug("Grabbing trades for id ", market_id);
if(trades.length) {
var data_output = { };
trades = trades.reverse();
trades.forEach( function(trade) {
// convert to int
if(trade.initiate_ordertype.toLowerCase() == 'sell') {
//log.debug("Sell with initiate_ordertype", trade.initiate_ordertype, 'so using the price as the ask');
data_output.bid = Number(trade.tradeprice);
} else {
//log.debug("Buy with initiate_ordertype", trade.initiate_ordertype, 'so using the price as the bid');
data_output.ask = Number(trade.tradeprice);
}
data_output.datetime = trade.datetime;
});

callback(null, data_output);
}
});
});
//this.market_id = m_id;
}

Trader.prototype.return_mkt_id = function(market, callback) {

var client = this.cryptsy;

//log.debug('client is ', client);
client.getmarketid(market, function(market_id) {
callback(null, market_id);
});
//this.market_id = m_id;
}


Trader.prototype.getTrades = function(since, callback, descending) {
var args = _.toArray(arguments);
var mkt_id = this.market;

var process = function(err, trades) {
//log.debug("Err is ", err, 'and length of trades is', trades);
if(err || !trades || trades.length === 0)
return this.retry(this.getTrades, args, err);

var f = parseFloat;

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

this.return_trades(mkt_id, _.bind(process, this));

}



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

var mkt_name = this.market;
// [MM]: Something about cryptsy's orders seems to be behind the actual market, which causes orders to go unfilled.
// Make the amount slightly on the upside of the actual price.
price = price * 1.003;

log.debug('BUY', amount, this.asset, ' @', price, this.currency);
this.place_order(mkt_name, 'buy', amount, price, _.bind(callback, this));
}


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

var mkt_name = this.market;
// [MM]: Something about cryptsy's orders seems to be behind the actual market, which causes orders to go unfilled.
// Make the amount slightly on the downside of the actual price.
price = price * 0.997;

log.debug('SELL', amount, this.asset, ' @', price, this.currency);
this.place_order(mkt_name, 'sell', amount, price, _.bind(callback, this));
}


Trader.prototype.place_order = function(market_name, trans_type, amount, price, callback) {

var client = this.cryptsy;

//log.debug(trans_type, 'order placed for ', amount, this.asset, ' @', price, this.currency);

//log.debug('client is ', client);
client.getmarketid(market_name, function(market_id) {
//log.debug('id is', market_id);
client.createorder(market_id, trans_type, amount, price, function(orderid) {
callback(null, orderid);

});
});
}


Trader.prototype.retry = function(method, args, err) {
var wait = +moment.duration(10, 'seconds');
log.debug(this.name, 'returned an error in method', method.name, ', retrying..', err, 'waiting for', wait, 'ms');

if (!_.isFunction(method)) {
log.error(this.name, 'failed to retry, no method supplied.');
return;
}

var self = this;

// make sure the callback (and any other fn)
// is bound to Trader
_.each(args, function(arg, i) {
if(_.isFunction(arg))
args[i] = _.bind(arg, self);
});

// run the failed method again with the same
// arguments after wait
setTimeout(
function() { method.apply(self, args) },
wait
);
}

Trader.prototype.getPortfolio = function(callback) {
var args = _.toArray(arguments);
var curr_balance, asst_balance;
var curr = this.currency;
var asst = this.asset;

var calculate = function(data) {
if(!data)
return this.retry(this.getPortfolio, args, null);
balances = data.balances_available;
holds = data.balances_hold;

curr_balance = parseFloat(balances[curr])
asst_balance = parseFloat(balances[asst]);
/*
if(holds) {
if(parseFloat(holds[curr])){
curr_balance -= parseFloat(holds[curr])
}
if( parseFloat(holds[asst])){
asst_balance -= parseFloat(holds[asst]);
}
}
*/
var portfolio = [];
portfolio.push({name: curr, amount: curr_balance});
portfolio.push({name: asst, amount: asst_balance});
callback(null, portfolio);
}

this.cryptsy.getinfo(_.bind(calculate, this));
}

Trader.prototype.getTicker = function(callback) {

var mkt_name = this.market;
var set = function(err, data) {
log.debug('Timestamp is', data.datetime, 'with bid ', data.bid, 'and ask ', data.ask);
var ticker = {
ask: data.ask,
bid: data.bid
};
callback(err, ticker);
}
this.get_bid_ask(mkt_name, _.bind(set, this));
}

Trader.prototype.getFee = function(callback) {
callback(false, 0.0025);
}

Trader.prototype.checkOrder = function(order, callback) {
var check = function(err, result) {

if(err)
callback(false, true);

var exists = false;
_.forEach(result, function(entry) {
if(entry.orderid === order) {
exists = true; return;
}
});
callback(err, !exists);
};

this.cryptsy.allmyorders(_.bind(check, this));
}

Trader.prototype.cancelOrder = function(order) {
var check= function(err, result) {
if(err)
log.error('cancel order failed:', err);
if(typeof(result) !== 'undefined' && result.error)
log.error('cancel order failed:', result.error);
}
this.cryptsy.cancelorder(order, check);
}

module.exports = Trader;
16 changes: 16 additions & 0 deletions launcher
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#!/bin/bash
# kuzetsa's gekko [re]launcher

while true; do
echo [`date +%Y.%m.%d/@%H%M.%S/%Z`] attempting to \(re\)start gekko...
sleep 5
echo [`date +%Y.%m.%d/@%H%M.%S/%Z`] launching node.js gekko bot NOW
echo -e '\n'
node gekko
echo -e '\n'
echo [`date +%Y.%m.%d/@%H%M.%S/%Z`] gekko seems to have stopped, waiting 30 seconds before restarting
sleep 5
echo [`date +%Y.%m.%d/@%H%M.%S/%Z`] Press Ctrl + C now if you REALLY want to stop gekko
sleep 20
echo loop starts 5 delay
done
3 changes: 3 additions & 0 deletions lizard
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/bin/bash
# kuzetsa's gekko lizard wrapper
./launcher | tee -i lizard.log
Loading

0 comments on commit 796a84f

Please sign in to comment.