Something that has been on my mind lately is trading Bitcoin using the various REST-APIs integral to most exchanges.

Building an automated system to trade a handful of times per day based on market ebbs and flows is my plan for now. None of the exchanges are setup (as far as I can tell) to allow ultra-high frequency trading, but that’s probably a good thing for all involved. You can read about some of the controversy from Mark Cuban; the gist is that some think it almost gaurantees profits for those investing billions to do it, but at the expense of individuals, mutual funds, and pretty much everyone else. Bottom line; it would discourage trading in a fledgling market.

First, I’ll go for very few bitcoins and low daily trade volumes, and later I’ll build in some forecasting to account for price shifts during larger trades. Since the commissions are percentage based, I stand to make money even on small buys. Eventually I would like to port some of this logic for working with NYSE, FOREX, or the like, but it will be a while before I can invest that much (>$30k for HFT).

Forecast Model

The models that I have found for HFT range from middle school math to Ph.D. in lambda calculus, but I tend to think simple works better in a system that isn’t largely forecastable. To this end, I’m taking the opportunity to learn enough C++ and CUDA to map out effectiveness of a ton of “magic numbers” in base algorithms and compare what their historical performance would have been. I’ll take some of the winners and apply them to incoming data, and eventually give one of them real dollars and bitcoins to play with.

Free code sample!

I won’t divulge too much about how I’m planning to do it, but I will throw in some code for monitoring an exchange. You’ll notice there are some bits that aren’t really needed or used, but thrown in there for the sake of future extensibility. It seems like it would be worth it to tie in multiple exchanges, and at some point build models for multiple currencies like Litecoin and whatever else. This is written for use with Node.js, so you’ll have to do the whole npm install thing with each dependency. Also make sure you’re not running Node.js 0.12, it doesn’t like the Request.js library.



// requirements
// -----------------------------------------

var cli = require('cli');
var request = require('request');
var async = require('async');
var fs = require('fs');


// structure
// -----------------------------------------

var main = {};
main.baseUrl = 'https://api.bitfinex.com/v1';
main.btcPriceUrl = main.baseUrl + '/pubticker/btcusd';
main.lastTimestamp = 0;
main.openConnections = 0;
main.serialDelay = 1020;
main.logPrices = true;
main.contPull = true;
main.outputDir = './price_logs/';

// make folder for the output
if (!fs.existsSync(main.outputDir)){
    fs.mkdirSync(main.outputDir);
}

main.wStream = fs.createWriteStream(main.outputDir + 'BTC-price-' + Date.now() + '.log');



// moving parts
// -----------------------------------------

getBtcPrice(main.logPrices, main.contPull);

// this function recursively calls itself indefinitely, unless interrupted in terminal
function getBtcPrice(logPrices, contPull) {

  // add to the active connection counter, in case of async stuff later on
  main.openConnections++;

  request(main.btcPriceUrl, function(err, res, body) { 
    if ( !err && res.statusCode == 200 ) {

      var btc = JSON.parse(body);

      // sometimes BFX returns JSON that is out of date
      if (btc.timestamp > main.lastTimestamp) {

        main.lastTimestamp = btc.timestamp;

        // parse -> print to screen && log to file
        console.log( 
          '\nBitFinix@' + btc.timestamp
          + '\n////////////////////////////////////////////////\n\n'
          + 'Last -> ' + btc.last_price 
          + '\nBid/Ask -> ' + btc.ask + '/' + btc.bid 
          + '\nMid/Spread: ' + btc.mid + '/' + Math.round((btc.ask - btc.bid) * 100) / 100
          + '\nHigh/Low -> ' + btc.high + '/' + btc.low
          + '\n\n////////////////////////////////////////////////\n\n'
        );
        main.wStream.write(body);
        main.openConnections--;

      }

      // start the process over, after delay
      if ( main.contPull === true ) {
        setTimeout(function() {
          getBtcPrice(logPrices, contPull);
        }, main.serialDelay);
      }

    } else {
      console.log( 'BitFinix failed... \n\nResponse: \n' 
        + JSON.stringify(res) 
        + '\n\n Body: \n' 
        + JSON.stringify(body) );
    }
  });
}