# -*- coding: utf-8 -*- import json import logging import threading import ConfigParser from ib.ext.Contract import Contract from ib.ext.Order import Order from ib.ext.ExecutionFilter import ExecutionFilter class BaseHelper(): @staticmethod def object2kvstring(o): return json.dumps(o.__dict__) @staticmethod def kvstring2object(kvstring, object): return BaseHelper.kv2object(json.loads(kvstring), object) @staticmethod def kv2object(kv, Object): o = Object() map(lambda x: o.__setattr__(x, kv[x].encode('ascii') if type(kv[x]) == unicode else kv[x]), kv.keys()) return o class OrderHelper(BaseHelper): pass # @staticmethod # def object2kvstring(contract): # return json.dumps(contract.__dict__) # # @staticmethod # def kvstring2object(sm_order): # return OrderHelper.kv2object(json.loads(sm_order)) # # # @staticmethod # def kv2object(m_order): # newOrder = Order() # map(lambda x: newOrder.__setattr__(x, m_order[x].encode('ascii') if type(m_order[x]) == unicode else m_order[x]), m_order.keys()) # return newOrder class ExecutionFilterHelper(BaseHelper): @staticmethod def makeExeuction(executionTuple): ''' String m_acctNumber The customer account number. double m_avgPrice Average price. Used in regular trades, combo trades and legs of the combo. Does not include commissions. int m_clientId "The id of the client that placed the order. Note: TWS orders have a fixed client id of ""0.""" int m_cumQty Cumulative quantity. Used in regular trades, combo trades and legs of the combo. String m_exchange Exchange that executed the order. String m_execId Unique order execution id. int m_liquidation Identifies the position as one to be liquidated last should the need arise. int m_orderId "The order id. Note:  TWS orders have a fixed order id of ""0.""" int m_permId The TWS id used to identify orders, remains the same over TWS sessions. double m_price The order execution price, not including commissions. int m_shares The number of shares filled. String m_side "Specifies if the transaction was a sale or a purchase. Valid values are: BOT SLD" String m_time The order execution time. ''' pass @staticmethod def makeExeuctionFilter(executionFilterTuple): ''' String m_acctCode Filter the results of the reqExecutions() method based on an account code. Note: this is only relevant for Financial Advisor (FA) accounts. int m_clientId Filter the results of the reqExecutions() method based on the clientId. String m_exchange Filter the results of the reqExecutions() method based on theorder exchange. String m_secType "Filter the results of the reqExecutions() method based on the order security type. Note: Refer to the Contract struct for the list of valid security types." String m_side "Filter the results of the reqExecutions() method based on the order action. Note: Refer to the Order class for the list of valid order actions." String m_symbol Filter the results of the reqExecutions() method based on the order symbol. String m_time "Filter the results of the reqExecutions() method based on execution reports received after the specified time. The format for timeFilter is ""yyyymmdd-hh:mm:ss""" ''' new_filter = ExecutionFilter() new_filter.m_acctCode = executionFilterTuple[0] new_filter.m_clientId = executionFilterTuple[1] new_filter.m_exchange = executionFilterTuple[2] new_filter.m_secType = executionFilterTuple[3] new_filter.m_side = executionFilterTuple[4] new_filter.m_symbol = executionFilterTuple[5] new_filter.m_time = executionFilterTuple[6] return new_filter class ContractHelper(BaseHelper): def __init__(self, contractTuple): self.makeContract(contractTuple) @staticmethod def makeContract(contractTuple): newContract = Contract() newContract.m_symbol = contractTuple[0] newContract.m_secType = contractTuple[1] newContract.m_exchange = contractTuple[2] newContract.m_currency = contractTuple[3] newContract.m_expiry = contractTuple[4] newContract.m_strike = contractTuple[5] newContract.m_right = contractTuple[6] logging.debug( 'Contract Values:%s,%s,%s,%s,%s,%s,%s:' % contractTuple) return newContract @staticmethod def convert2Tuple(newContract): newContractTuple = (newContract.m_symbol,\ newContract.m_secType,\ newContract.m_exchange,\ newContract.m_currency,\ newContract.m_expiry,\ newContract.m_strike,\ newContract.m_right, newContract.m_conId) logging.debug( 'Contract Values:%s,%s,%s,%s,%s,%s,%s %s:' % newContractTuple) return newContractTuple @staticmethod def contract2kvstring(contract): return json.dumps(contract.__dict__) @staticmethod def kvstring2contract(sm_contract): return ContractHelper.kv2contract(json.loads(sm_contract)) @staticmethod def kv2contract(m_contract): newContract = Contract() map(lambda x: newContract.__setattr__(x, m_contract[x].encode('ascii') if type(m_contract[x]) == unicode else m_contract[x]), m_contract.keys()) return newContract @staticmethod def printContract(contract): s = '[%s-%s-%s-%s-%s-%s-%s-%s]' % (contract.m_symbol, contract.m_secType, contract.m_exchange, contract.m_currency, contract.m_expiry, contract.m_strike, contract.m_right, contract.m_conId) #logging.info(s) return s @staticmethod def makeRedisKey(contract): #print "makerediskey %s" % ContractHelper.printContract(contract) #20150904 contract.m_strike = int(contract.m_strike) #contract.m_strike = contract.m_strike if contract.m_secType == 'OPT': s = '%s-%s-%s-%s' % (contract.m_symbol, contract.m_expiry, contract.m_strike, contract.m_right) else: s = '%s-%s-%s-%s' % (contract.m_symbol, contract.m_expiry, contract.m_secType, '') return s @staticmethod def makeRedisKeyEx(contract, old=False): # this routine is to circumvent a problem in makeRedisKey with # the key in position 3 having different meanings under different conditions. # # # to differentiate the keys generated by the old and new functions, # contract keys created using this routine have their last slot # hard coded a magic number 102 if (old): return ContractHelper.makeRedisKey(contract) #contract.m_strike = int(contract.m_strike) #contract.m_strike = contract.m_strike # amend 10/22 # add exchange to the key # s = '%s-%s-%s-%s-%s-%s-%s-%d' % (contract.m_symbol, # contract.m_expiry, # contract.m_strike, # contract.m_right, # contract.m_secType, # contract.m_currency, # # contract.m_exchange, # # 102) # amend 12/1 #change strike format to 2 dp s = '%s-%s-%.2f-%s-%s-%s-%s-%d' % (contract.m_symbol, contract.m_expiry, float(contract.m_strike), contract.m_right, contract.m_secType, contract.m_currency, contract.m_exchange, 102) return s @staticmethod def is_equal(c1, c2): return ContractHelper.makeRedisKeyEx(c1) == ContractHelper.makeRedisKeyEx(c2) @staticmethod def makeContractfromRedisKeyEx(key): def utf2asc(x): return x.encode('ascii') if isinstance(x, unicode) else x #return map(lambda x: (x[0], ContractHelper.kvstring2contract(utf2asc(x[1]))), id_contracts) toks = utf2asc(key).split('-') c = Contract() c.m_symbol = toks[0] c.m_expiry = toks[1] c.m_strike = float(toks[2]) c.m_right = toks[3] c.m_secType = toks[4] c.m_currency = toks[5] c.m_exchange = toks[6] return c # def str2dict(s): # return ast.literal_eval(s) def dict2str(dict): # enclose strings in double quotes return '{' + ', '.join('"%s" : %s' % (k, '"%s"' % v if type(v) == str else v) for k, v in dict.iteritems()) + '}' class HelperFunctions(): @staticmethod def utf2asc(x): return x.encode('ascii') if isinstance(x, unicode) else x class ConfigMap(): def kwargs_from_file(self, path): cfg = ConfigParser.ConfigParser() if len(cfg.read(path)) == 0: raise ValueError, "Failed to open config file [%s]" % path kwargs = {} for section in cfg.sections(): optval_list = map(lambda o: (o, cfg.get(section, o)), cfg.options(section)) for ov in optval_list: try: kwargs[ov[0]] = eval(ov[1]) except: continue #logging.debug('ConfigMap: %s' % kwargs) return kwargs