Permalink
Browse files

initial development of the cli trader

The cli trader is a simple command line app to do basic trading.
  • Loading branch information...
1 parent d0fbb28 commit bb806cbef540bbc58b9c43b5fca16b34c846efce @defunctzombie defunctzombie committed Sep 9, 2011
Showing with 209 additions and 0 deletions.
  1. +1 −0 .gitignore
  2. +187 −0 bin/cli_trader.js
  3. +6 −0 config.json
  4. +15 −0 package.json
View
@@ -0,0 +1 @@
+node_modules
View
@@ -0,0 +1,187 @@
+#!/usr/bin/env node
+
+// builtin
+var http = require('http');
+var querystring = require('querystring');
+var crypto = require('crypto');
+var readline = require('readline');
+
+var colors = require('colors');
+
+// trader setup
+var config = require('../config.json');
+
+// the hmac which will sign our requests
+var api_key = config.api_key;
+var sec_key = config.sec_key;
+
+var host = config.host;
+var port = config.port;
+
+/// send payload to url
+/// nonce will be added
+/// callback(response)
+function send(url, payload, cb) {
+ payload.nonce = Date.now();
+ var body = querystring.stringify(payload);
+
+ var hmac = crypto.createHmac('sha512', sec_key);
+ hmac.update(body);
+ var sign = hmac.digest('base64');
+
+ var options = {
+ host: host,
+ port: port,
+ path: url,
+ method: 'POST',
+ headers: {
+ 'bitfloor-key': api_key,
+ 'bitfloor-sign': sign,
+ 'Content-Type': 'application/x-www-form-urlencoded',
+ 'Content-Length': body.length
+ }
+ };
+
+ var req = http.request(options, function(res) {
+ var buff = '';
+ res.setEncoding('utf8');
+ res.on('data', function(data) {
+ buff += data;
+ });
+
+ res.on('end', function() {
+ var msg = JSON.parse(buff);
+ cb(msg);
+ });
+
+ });
+
+ // write the payload out to the request
+ req.write(body);
+ req.end();
+}
+
+function order_new(product, price, size, side, cb) {
+ var out = {
+ price: price,
+ size: size,
+ product: product,
+ side: side,
+ };
+
+ send('/order/new', out, function(response) {
+ if (response.reject_reason) {
+ console.log('[rejected] %s'.red, response.reject_reason);
+ } else if (response.order_id) {
+ console.log('[placed] order id: %s'.green, response.order_id);
+ } else {
+ console.log('unknown response: %j'.red, response);
+ }
+
+ cb();
+ });
+}
+
+function order_cancel(product, order_id, cb) {
+ var out = {
+ product: product,
+ order_id: order_id
+ };
+
+ send('/order/cancel', out, function(response) {
+ if (response.reject_reason) {
+ console.log('[rejected] %s'.red, response.reject_reason);
+ } else if (response.status === 'cancelled') {
+ console.log('[cancelled] %s'.green, response.order_id);
+ } else {
+ console.log('unknown response: %j'.red, response);
+ }
+
+ cb();
+ });
+}
+
+function orders(cb) {
+ send('/orders', {}, function(response) {
+ response.forEach(function(order) {
+ var side = 'buy';
+ if (order.side === 1) {
+ side = 'sell'
+ }
+ console.log('id: %s product: %s %s %d @ %d'.yellow,
+ order.id, order.product_id, side, order.size, order.price);
+ });
+
+ cb();
+ });
+}
+
+var rl = readline.createInterface(process.stdin, process.stdout);
+
+rl.prompt();
+
+// handle commands from readline
+var handlers = {
+ 'buy': function(params, cb) {
+ if (params.length != 3) {
+ console.log('buy <product_id> <size> <price>');
+ return cb();
+ }
+
+ var product = params.shift();
+ var size = params.shift();
+ var price = params.shift();
+
+ // send new order
+ order_new(product, price, size, 'buy', cb);
+ },
+ 'sell': function(params, cb) {
+ if (params.length != 3) {
+ console.log('sell <product_id> <size> <price>');
+ return cb();
+ }
+
+ var product = params.shift();
+ var size = params.shift();
+ var price = params.shift();
+
+ // send new order
+ order_new(product, price, size, 'sell', cb);
+ },
+ 'orders': function(params, cb) {
+ orders(cb);
+ },
+ 'cancel': function(params, cb) {
+ if (params.length != 2) {
+ console.log('cancel <product_id> <order_id>');
+ return cb();
+ }
+
+ var product = params.shift();
+ var order_id = params.shift();
+
+ order_cancel(product, order_id, cb);
+ },
+ 'exit': function() {
+ rl.close();
+ process.stdin.destroy();
+ }
+}
+
+
+rl.on('line', function(line) {
+ var args = line.split(' ');
+ var cmd = args.shift();
+ var handler = handlers[cmd];
+ if (!handler) {
+ console.log('not a valid command: ' + cmd);
+ rl.prompt();
+ return;
+ }
+
+ // redisplay the prompt after the callback has printed
+ handler(args, function() {
+ rl.prompt();
+ });
+});
+
View
@@ -0,0 +1,6 @@
+{
+ "api_key": "your-api-key-here",
+ "sec_key": "your-secret-key-here",
+ "host": "rapi.testnet.bitfloor.com",
+ "port": 80
+}
View
@@ -0,0 +1,15 @@
+{
+ "author": "bitfloor <support@bitfloor.com>",
+ "name": "bitfloor_trader",
+ "description": "Sample trader for bitfloor",
+ "version": "0.0.0",
+ "homepage": "bitfloor.com",
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/bitfloor/trader.nodejs.git"
+ },
+ "dependencies": {
+ "colors":"*"
+ },
+ "devDependencies": {}
+}

0 comments on commit bb806cb

Please sign in to comment.