{ "metadata": { "name": "" }, "nbformat": 3, "nbformat_minor": 0, "worksheets": [ { "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "Audubon Technologies" ] }, { "cell_type": "heading", "level": 1, "metadata": {}, "source": [ "Tribute to the greatest and best" ] }, { "cell_type": "heading", "level": 1, "metadata": {}, "source": [ "Simple tutorial on using IB's API with python" ] }, { "cell_type": "raw", "metadata": {}, "source": [ "import necessary libraries" ] }, { "cell_type": "code", "collapsed": false, "input": [ "from ib.ext.Contract import Contract\n", "from ib.ext.Order import Order\n", "from ib.ext.EWrapper import EWrapper\n", "from ib.ext.EClientSocket import EClientSocket\n", "from ib.ext.ExecutionFilter import ExecutionFilter\n" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 2 }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": [ "create some functions and a wrapper class" ] }, { "cell_type": "code", "collapsed": false, "input": [ "def showmessage(message, mapping):\n", " try:\n", " del(mapping['self'])\n", " except (KeyError, ):\n", " pass\n", " items = mapping.items()\n", " items.sort()\n", " print '### %s' % (message, )\n", " for k, v in items:\n", " print ' %s:%s' % (k, v)\n" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 3 }, { "cell_type": "code", "collapsed": false, "input": [ "import logging as logger\n", "import types\n", "\n", "class Observable(object):\n", " \"\"\"\n", " Sender -> dispatches messages to interested callables\n", " \"\"\"\n", " def __init__(self):\n", " self.listeners = {}\n", " self.logger = logger.getLogger()\n", "\n", "\n", " def register(self,listener,events=None):\n", " \"\"\"\n", " register a listener function\n", "\n", " Parameters\n", " -----------\n", " listener : external listener function\n", " events : tuple or list of relevant events (default=None)\n", " \"\"\"\n", " if events is not None and type(events) not in (types.TupleType,types.ListType):\n", " events = (events,)\n", "\n", " self.listeners[listener] = events\n", "\n", " def dispatch(self,event=None, msg=None):\n", " \"\"\"notify listeners \"\"\"\n", " for listener,events in self.listeners.items():\n", " if events is None or event is None or event in events:\n", " try:\n", " listener(self,event,msg)\n", " except (Exception,):\n", " self.unregister(listener)\n", " errmsg = \"Exception in message dispatch: Handler '{0}' unregistered for event '{1}' \".format(listener.func_name,event)\n", " self.logger.exception(errmsg)\n", "\n", " def unregister(self,listener):\n", " \"\"\" unregister listener function \"\"\"\n", " del self.listeners[listener]\n" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 5 }, { "cell_type": "code", "collapsed": false, "input": [ "class ReferenceWrapper(EWrapper,Observable):\n", " def __init__ (self,subs={}):\n", " super(ReferenceWrapper, self).__init__()\n", " self.orderID = None\n", " self.subscriptions = subs\n", "\n", " def setSubscriptions (self,subs):\n", " self.subscriptions = subs\n", "\n", " def tickGeneric(self, tickerId, field, price):\n", " pass\n", "\n", " def tickPrice(self, tickerId, field, price, canAutoExecute):\n", " showmessage('tickPrice', vars())\n", "\n", " def tickSize(self, tickerId, field, size):\n", " showmessage('tickSize', vars())\n", "\n", "\n", " def tickString(self, tickerId, tickType, value):\n", " #showmessage('tickString', vars())\n", " pass\n", "\n", " def tickOptionComputation(self, tickerId, field, impliedVolatility, delta,x,c,q,w,e,r):\n", " #showmessage('tickOptionComputation', vars())\n", " pass\n", "\n", " def openOrderEnd(self):\n", " pass\n", "\n", " def orderStatus(self, orderId, status, filled, remaining, avgFillPrice, permId, parentId, lastFillPrice, clientId, whyHeId):\n", " if filled:\n", " self.dispatch(event='execution',msg=[1,2,3])\n", " showmessage('orderStatus', vars())\n", "\n", " def openOrder(self, orderId, contract, order, state):\n", " showmessage('openOrder', vars())\n", "\n", " def connectionClosed(self):\n", " showmessage('connectionClosed', {})\n", "\n", " def updateAccountValue(self, key, value, currency, accountName):\n", " showmessage('updateAccountValue', vars())\n", "\n", " def updatePortfolio(self, contract, position, marketPrice, marketValue, averageCost, unrealizedPNL, realizedPNL, accountName):\n", " showmessage('updatePortfolio', vars())\n", "\n", " def updateAccountTime(self, timeStamp):\n", " showmessage('updateAccountTime', vars())\n", "\n", " def nextValidId(self, orderId):\n", " self.orderID = orderId\n", " showmessage('nextValidId', vars())\n", "\n", " def contractDetails(self, contractDetails):\n", " showmessage('contractDetails', vars())\n", "\n", " def bondContractDetails(self, contractDetails):\n", " showmessage('bondContractDetails', vars())\n", "\n", " def execDetails(self, orderId, contract, execution):\n", " showmessage('execDetails', vars())\n", "\n", " def error(self, id=None, errorCode=None, errorMsg=None):\n", " showmessage('error', vars())\n", "\n", " def updateMktDepth(self, tickerId, position, operation, side, price, size):\n", " showmessage('updateMktDepth', vars())\n", "\n", " def updateMktDepthL2(self, tickerId, position, marketMaker, operation, side, price, size):\n", " showmessage('updateMktDepthL2', vars())\n", "\n", " def updateNewsBulletin(self, msgId, msgType, message, origExchange):\n", " showmessage('updateNewsBulletin', vars())\n", "\n", " def managedAccounts(self, accountsList):\n", " showmessage('managedAccounts', vars())\n", "\n", " def receiveFA(self, faDataType, xml):\n", " showmessage('receiveFA', vars())\n", "\n", " def historicalData(self, reqId, date, open, high, low, close, volume, count, WAP, hasGaps):\n", " showmessage('historicalData', vars())\n", "\n", " def scannerParameters(self, xml):\n", " showmessage('scannerParameters', vars())\n", "\n", " def scannerData(self, reqId, rank, contractDetails, distance, benchmark, projection):\n", " showmessage('scannerData', vars())\n", "\n" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 6 }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": [ "Create a Base application to work off" ] }, { "cell_type": "code", "collapsed": false, "input": [ "allMethods = []\n", "def ref(method):\n", " allMethods.append(method.__name__)\n", " return method\n", "\n", "class Listener(object):\n", " def __init__(self,name=None):\n", " self.name = name\n", "\n", " def method(self,sender,event,msg=None):\n", " print \"[{0}] got event {1} with message {2}\".format(self.name,event,msg)\n" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 7 }, { "cell_type": "code", "collapsed": false, "input": [ "import random\n", "\n", "class BaseApp(Listener):\n", " def __init__(self, host='localhost', port=7496, clientId=random.randint(0,1000),name=None,**kwargs):\n", " self.host = host\n", " self.port = port\n", " self.clientId = clientId\n", " self.subscriptions = {}\n", " if kwargs.has_key('wrapper'):\n", " self.wrapper = kwargs['wrapper']\n", " self.wrapper.setSubscriptions(self.subscriptions)\n", " else:\n", " self.wrapper = ReferenceWrapper(self.subscriptions)\n", " self.connection = EClientSocket(self.wrapper)\n", " self.oms= OrderManager()\n", " self.conid = 1\n", " self.name = name\n", " self.wrapper.register(self.method,events='execution') # listen to execution\n", "\n", " def method(self,sender,event,msg=None):\n", " print \"[{0}] got event {1} with message {2}\".format(self.name,event,msg)\n", " #self.cancelAll()\n", "\n", " @ref\n", " def eConnect(self):\n", " self.connection.eConnect(self.host, self.port, self.clientId)\n", "\n", " @ref\n", " def reqAccountUpdates(self):\n", " self.connection.reqAccountUpdates(1, '')\n", "\n", " @ref\n", " def reqOpenOrders(self):\n", " self.connection.reqOpenOrders()\n", "\n", " @ref\n", " def reqContractDetails(self,instrument):\n", " self.connection.reqContractDetails(instrument.id, instrument.contract)\n", "\n", " @ref\n", " def reqExecutions(self):\n", " filt = ExecutionFilter()\n", " self.connection.reqExecutions(filt)\n", "\n", " @ref\n", " def reqIds(self):\n", " self.connection.reqIds(10)\n", "\n", " @ref\n", " def reqNewsBulletins(self):\n", " self.connection.reqNewsBulletins(1)\n", "\n", " @ref\n", " def cancelNewsBulletins(self):\n", " self.connection.cancelNewsBulletins()\n", "\n", " @ref\n", " def setServerLogLevel(self):\n", " self.connection.setServerLogLevel(3)\n", "\n", " @ref\n", " def reqAutoOpenOrders(self):\n", " self.connection.reqAutoOpenOrders(1)\n", "\n", " @ref\n", " def reqAllOpenOrders(self):\n", " self.connection.reqAllOpenOrders()\n", "\n", " @ref\n", " def reqManagedAccts(self):\n", " self.connection.reqManagedAccts()\n", "\n", " @ref\n", " def requestFA(self):\n", " self.connection.requestFA(1)\n", "\n", " @ref\n", " def reqMktData(self,contract):\n", " self.connection.reqMktData(1, contract, '', False)\n", "\n", " def nextOrderID(self):\n", " self.wrapper.orderID += 1\n", " return self.wrapper.orderID\n", "\n", " def nextConID(self):\n", " self.conid += 1\n", " return self.conid\n", "\n", "\n", " @ref\n", " def reqHistoricalData(self,contract):\n", " endtime = strftime('%Y%m%d %H:%M:%S')\n", " self.connection.reqHistoricalData(\n", " tickerId=1,\n", " contract=contract,\n", " endDateTime=endtime,\n", " durationStr='1 D',\n", " barSizeSetting='1 min',\n", " whatToShow='TRADES',\n", " useRTH=0,\n", " formatDate=1)\n", "\n", " def placeOrder (self,soid, optContractX, optOrderS):\n", " self.oms.add(optOrderS)\n", " self.connection.placeOrder(soid, optContractX, optOrderS)\n", "\n", " def cancelOrder (self,soid):\n", " self.oms.remove(soid)\n", " self.connection.cancelOrder(soid)\n", "\n", " def cancelAll(self):\n", " for oid in self.oms.getOpenOrderIds():\n", " self.cancelOrder(oid)\n", " \n", " @ref\n", " def eDisconnect(self):\n", " sleep(5)\n", " self.connection.eDisconnect()\n" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 9 }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": [ "Create some classes for building contracts and orders" ] }, { "cell_type": "code", "collapsed": false, "input": [ "class BagBuilder(object):\n", " def __init__(self):\n", " self.addAllLegs = []\n", "\n", " def addLeg (self,cid,ratio,side,exchange):\n", " leg = ComboLeg()\n", " #print \"conid in bag %s\" % (cid)\n", " leg.m_conId = cid\n", " leg.m_ratio = ratio\n", " leg.m_action = side\n", " leg.m_exchange = exchange\n", " leg.m_openClose = 0\n", " leg.m_shortSaleSlot = 0\n", " leg.m_designatedLocation = \"\"\n", " self.addAllLegs.append(leg)\n", "\n", " def create(self,symbol):\n", " contract = Contract()\n", " contract.m_symbol = \"USD\" # For combo order use ?USD? as the symbol value all the time\n", " contract.m_secType = \"BAG\" # BAG is the security type for COMBO order\n", " contract.m_exchange = self.addAllLegs[0].m_exchange\n", " contract.m_currency = \"USD\"\n", " contract.m_comboLegs = self.addAllLegs #including combo order in contract object\n", " contract.m_symbol = symbol\n", " return contract\n" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 10 }, { "cell_type": "code", "collapsed": false, "input": [ "class Side(object):\n", " def __init__(self,s):\n", " self.sides=['dummy','BUY','SELL']\n", " self.s = self.sides[s]\n", "\n", " def side(self):\n", " return self.s\n", "\n", " def flip(self):\n", " return self.sides[2] if self.s == 'BUY' else self.side[1]\n", "\n", " @staticmethod\n", " def flipside(s):\n", " if s.lower() == 'sell':\n", " return 'BUY'\n", " else:\n", " return 'SELL'\n", "\n", "\n", "class Utils(object):\n", " months=['','F','G','H','J','K','M','N','Q','U','V','X','Z']\n", " @staticmethod\n", " def makeContract(sym, exchange,sectype,exp=None):\n", " newContract = Contract()\n", " newContract.m_symbol = sym\n", " newContract.m_secType = sectype\n", " newContract.m_expiry = exp\n", " newContract.m_exchange = exchange\n", " newContract.m_currency = 'USD'\n", " return newContract\n", "\n", " @staticmethod\n", " def makeOptOrder(action, oID, tif, orderType,price,qty):\n", " newOptOrder = Order()\n", " newOptOrder.m_orderId = oID\n", " newOptOrder.m_clientId = 0\n", " newOptOrder.m_permid = 0\n", " newOptOrder.m_action = action\n", " newOptOrder.m_lmtPrice = price\n", " newOptOrder.m_auxPrice = 0\n", " newOptOrder.m_tif = tif\n", " newOptOrder.m_transmit = True\n", " newOptOrder.m_orderType = orderType\n", " newOptOrder.m_totalQuantity = qty\n", " return newOptOrder\n", "\n", " @staticmethod\n", " def createBracketOrder(origOrder, oID, tif, orderType,price): \n", " bracketoptOrder = Utils.makeOptOrder( Side.flipside(origOrder.m_action), oID, tif, orderType,price,origOrder.m_totalQuantity)\n", " bracketoptOrder.m_parentId = origOrder.m_orderId\n", " return bracketoptOrder\n", " " ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 11 }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": [ "keep track of your orders" ] }, { "cell_type": "code", "collapsed": false, "input": [ "class OrderManager(object):\n", " def __init__(self):\n", " self.orders = {}\n", "\n", " def add(self,order):\n", " self.orders[order.m_orderId] = order\n", "\n", " def remove(self,oid):\n", " try:\n", " del self.orders[oid]\n", " except:\n", " pass\n", "\n", " def get(self,order_id):\n", " return self.orders[order_id]\n", "\n", " def status(self,order_id):\n", " return self.orders[order_id].status\n", "\n", " def onFill(self,order_id,fillqty):\n", " self.orders[order_id].m_quantity -= fillqty\n", "\n", " def getOpenOrderIds(self):\n", " return self.orders.keys()" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 12 }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": [ "Add magic and make money" ] }, { "cell_type": "code", "collapsed": false, "input": [], "language": "python", "metadata": {}, "outputs": [] } ], "metadata": {} } ] }