├── ArtemisIBWrapper.py ├── ArtemisIBWrapperSilent.py ├── DataDownloadIBWrapper.py ├── DataDownloadIBWrapperSilent.py ├── IPynb ├── ATS test.ipynb ├── BrownianMotion.ipynb ├── MachineLearning.ipynb ├── PricingDownload.ipynb ├── Untitled0.ipynb ├── Untitled1.ipynb ├── Untitled2.ipynb ├── consensus_quant.ipynb ├── earnings_analysis.ipynb ├── earnings_analysis_event_trade_atsametime.ipynb ├── earnings_analysis_short.ipynb ├── earnings_analysis_short_pt2.ipynb ├── earnings_analysisv2.ipynb ├── earnings_analysisv2_pt2.ipynb ├── earnings_analysisv3.ipynb └── num earnings.ipynb ├── NewsScrape └── flyonthewall.py ├── README.md ├── Trading ├── ATS.py ├── fowscanner.py ├── strategy.py └── tws_reconnect_test.py ├── example.py ├── example2.py ├── example3.py ├── example4.py └── example_historicaldata.py /ArtemisIBWrapper.py: -------------------------------------------------------------------------------- 1 | from datetime import datetime 2 | import time, sys 3 | import pdb 4 | 5 | sys.path.append('/home/mchan/git/Artemis/util') 6 | import dbutil 7 | 8 | from swigibpy import EWrapper, Contract, ContractDetails 9 | 10 | ### 11 | 12 | tickTypeHash = {0:"bid size", 1:"bid price", 2:"ask price", 3:"ask size", 4:"last price", \ 13 | 5:"last size", 6:"high", 7:"low", 8:"volume", 9:"close price", 10:"bid option computation", \ 14 | 11:"ask option computation", 12:"last option computation", 13:"model option computation", \ 15 | 14:"open tick", 15:"low 13 week", 16:"high 13 week", 17:"low 26 week", 18:"high 26 week", \ 16 | 19:"low 52 week", 20:"high 52 week", 21:"avg volume", 22:"open interest", \ 17 | 23:"option historical vol", 24:"option implied vol", 25:"option bid exch", \ 18 | 26:"option ask exch", 27:"option call open interest", 28:"option put open interest", \ 19 | 29:"option call volume", 30:"option put volume", 31:"index future premium", \ 20 | 32:"bid exch", 33:"ask exch", 37:"mark price", 45:"last timestamp", \ 21 | 46:"shortable", 47:"fundamental ratios", 48:"rt volume", 49:"halted", \ 22 | 53:"cust option computation", 54:"trade count", 55:"trade rate", \ 23 | 56:"volume rate"} 24 | 25 | wrapper_db = dbutil.db(h='127.0.0.1', schema='mchan') 26 | class ArtemisIBWrapper(EWrapper): 27 | '''Callback object passed to TWS, these functions will be called directly 28 | by TWS. 29 | 30 | ''' 31 | def deltaNeutralValidation(self, reqId, underComp): 32 | pass 33 | 34 | def marketDataType(self, reqid, marketDataType): 35 | print "Market Data Type: ", reqId, " ", marketDataType 36 | 37 | def winError(self, mesg, errorCode): 38 | print "Win error message: ", mesg, " ", errorCode 39 | 40 | def error(self, orderId, errorCode, errorString): 41 | print orderId, " ", errorCode, " ", errorString 42 | 43 | def nextValidId(self, orderId): 44 | '''Always called by TWS but not relevant for our example''' 45 | self.myNextValidId = orderId 46 | print "Next Valid Id: ", orderId 47 | 48 | def openOrderEnd(self): 49 | '''Always called by TWS but not relevant for our example''' 50 | print "Open Order end:" 51 | 52 | def tickEFP(self, tickerId, tickType, basisPoints, formattedBasisPoints, totalDividends, holdDays, futureExpiry, dividendImpact, dividendsToExpiry): 53 | pass 54 | 55 | def openOrder(self, orderId, contract, order, orderState): 56 | print "Open Order status: Order Id: ", orderId, " Order State: ", orderState.status 57 | 58 | def managedAccounts(self, openOrderEnd): 59 | '''Called by TWS but not relevant for our example''' 60 | pass 61 | 62 | def historicalData(self, reqId, date, open, high, 63 | low, close, volume, 64 | barCount, WAP, hasGaps): 65 | 66 | if date[:8] == 'finished': 67 | self.histClose = self.lastClose 68 | print "History request complete" 69 | else: 70 | try: 71 | date = datetime.strptime(date, "%Y%m%d").strftime("%d %b %Y") 72 | except: 73 | date = datetime.strptime(date, "%Y%m%d %H:%M:%S").strftime("%d %b %Y %H:%M:%S") 74 | self.lastClose = close 75 | print ( "History %s - Open: %s, High: %s, Low: %s, Close: " + 76 | "%s, Volume: %d" ) % (date, open, high, low, close, volume) 77 | 78 | def tickOptionComputation(self, reqId, tickType, impliedVol, delta, 79 | optPrice, pvDiv, gamma, vega, theta, undPrice): 80 | tickTypeStr = tickTypeHash[tickType] 81 | print ("Option Data -Request ID: %s -TickType: %s -Implied Vol: %f" + 82 | " -Delta: %f -Option Price: %f -PV Dividend: %f -Gamma: %f -Vega: %f -Theta: %f" + 83 | " -Underlying Price: %f") % (reqId, tickTypeStr, impliedVol, delta, optPrice, pvDiv, gamma, vega, theta, undPrice) 84 | 85 | def tickPrice(self, reqId, tickType, price, canAutoExecute): 86 | tickTypeStr = tickTypeHash[tickType] 87 | if tickType == 2: 88 | self.askPrice = price 89 | elif tickType == 4: 90 | self.lastPrice = price 91 | elif tickType == 9: 92 | self.closePrice = price 93 | print ("Pricing Data -Request ID: %s -TickType: %s -Price: %s -CanAutoExecute: %s") % (reqId, tickTypeStr, price, canAutoExecute) 94 | 95 | def tickGeneric(self, reqId, tickType, value): 96 | tickTypeStr = tickTypeHash[tickType] 97 | print ("TickGeneric Data -Request ID: %s -TickType: %s -Value: %s") % (reqId, tickTypeStr, value) 98 | 99 | def tickSize(self, reqId, field, size): 100 | fieldStr = tickTypeHash[field] 101 | print ("TickSize Data -Request ID: %s -TickType: %s -Size: %s") % (reqId, fieldStr, size) 102 | 103 | def tickSnapshotEnd(self, reqId): 104 | self.tickDataEnd = True 105 | print "Tick Data end" 106 | 107 | def tickString(self, reqId, tickType, value): 108 | tickTypeStr = tickTypeHash[tickType] 109 | print ("TickString Data -Request ID: %s -TickType: %s -Value: %s") % (reqId, tickTypeStr, value) 110 | 111 | def contractDetails(self, reqId, conDetails): 112 | print ("Contract Details Recieved") 113 | print "Options Summary: ContractID: ", conDetails.summary.conId, " Exchange: ", conDetails.summary.exchange, " Trading Hours: ",\ 114 | conDetails.tradingHours, " Strike: ", conDetails.summary.strike, " Multiplier: ", conDetails.summary.multiplier, \ 115 | " Expiry: ", conDetails.summary.expiry, " Right: " , conDetails.summary.right, " Currency: ", conDetails.summary.currency 116 | self.contractDetailsData = conDetails 117 | self.conId = conDetails.summary.conId 118 | self.exchange = conDetails.summary.exchange 119 | self.tradingHours = conDetails.tradingHours 120 | self.strike = conDetails.summary.strike 121 | self.Strikes.append(conDetails.summary.strike) 122 | self.StrikesHash[conDetails.summary.strike] = (conDetails.summary.conId, conDetails.summary.multiplier) 123 | self.multiplier = conDetails.summary.multiplier 124 | self.expiry = conDetails.summary.expiry 125 | self.right = conDetails.summary.right 126 | self.currency = conDetails.summary.currency 127 | 128 | def contractDetailsEnd(self, reqId): 129 | self.contractDataEnd = True 130 | print ("Contract Details End") 131 | 132 | def updateAccountValue(self, key, value, currency, account): 133 | if key == "BuyingPower": 134 | self.buyingPower = value 135 | # INITIALIZE 136 | self.portfolioData = [] 137 | elif key == "TotalCashBalance": 138 | self.totalCashBalance = value 139 | elif key == "NetLiquidation": 140 | self.netLiquidation = value 141 | #if key in ["BuyingPower", "AccountType", "CashBalance", "TotalCashBalance", "TotalCashValue"]: 142 | # print key, " ", value 143 | print key, " ", value 144 | 145 | def updateAccountTime(self, timestmp): 146 | print timestmp 147 | 148 | def accountDownloadEnd(self, account): 149 | self.accountEnd = True 150 | print "Account Download End ", account 151 | 152 | def updatePortfolio(self, contract, position, marketPrice, marketValue, averageCost, unrealizedPNL, realizedPNL, accountName): 153 | self.portfolioContractSymbol = contract.symbol 154 | self.portfolioContractSecType = contract.secType 155 | self.portfolioContractRight = contract.right 156 | self.portfolioContractExpiry = contract.expiry 157 | self.portfolioContractStrike = contract.strike 158 | self.portfolioContractConId = contract.conId 159 | self.portfolioSecMarketValue = marketValue 160 | self.portfolioPosition = position 161 | self.portfolioContract = contract 162 | print "Contract: ", contract.symbol, " ", contract.secType, " Position: ", position, " Market Value: ", marketValue, \ 163 | " Market Price: ", marketPrice, " averageCost: ", averageCost, " Unrealized PnL: ", unrealizedPNL, \ 164 | " Realized PnL: ", realizedPNL, " Account Name: ", accountName 165 | try: 166 | self.portfolioData.append({'symbol':contract.symbol, 'secType':contract.secType, 'right':contract.right, 'expiry':contract.expiry, \ 167 | 'strike':contract.strike, 'conId':contract.conId, 'marketValue':marketValue, 'Position':position}) 168 | except: 169 | pass 170 | 171 | def connectionClosed(self): 172 | print "TWS Connection closed at: ", str(datetime.now()) 173 | 174 | def orderStatus(self, orderId, status, filled, remaining, avgFillPrice, permId, parentId, lastFillPrice, clientId, whyHeld): 175 | myNow = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) 176 | wrapper_db.execute('''INSERT INTO mchan.twsOrderStatus VALUES (%i, "%s", %i, %i, %i, %f, "%s");''' % (orderId, status, clientId, filled, remaining, avgFillPrice, myNow)) 177 | wrapper_db.commit() 178 | print "Order Status Alert, STATUS: ", status, " Filled: ", filled, " Remaining: ", remaining, " Avg Fill Price: ", avgFillPrice, \ 179 | " PermId: ", permId, " ParentId: ", parentId, " Last fill Price: ", lastFillPrice, " Client Id: ", clientId, " Why Held: ", whyHeld 180 | self.orderState = status 181 | 182 | def execDetails(self, orderId, contract, execution): 183 | pass 184 | 185 | def execDetailsEnd(self, requestId): 186 | pass 187 | 188 | def updateMktDepth(self, tickerId, position, operation, side, price, size): 189 | print "Market Depth" 190 | print "Ticker ID: ", tickerId, " Position: ", position, " Operation: ", operation, " Side: ", side, " Price: ", price, " Size: ", size 191 | 192 | def updateMktDepthL2(self, tickerId, position, marketMaker, operation, side, price, size): 193 | print "L2 Market Depth" 194 | print "Ticker ID: ", tickerId, " Market Maker: ", marketMaker," Position: ", position, " Operation: ", operation, " Side: ", side, " Price: ", price, " Size: ", size 195 | 196 | def updateNewsBulletin(self, msgId, msgType, message, origExchange): 197 | print "Message ID:", str(msgId), " Message type:", str(msgType), " Message: ", message, " Originating Exchange:", origExchange 198 | pass 199 | 200 | def receiveFA(self, faDataType, XML): 201 | pass 202 | 203 | def bondContractDetails(self, reqId, contractDetails): 204 | pass 205 | 206 | def scannerParameters(self, xml): 207 | pass 208 | 209 | def scannerData(self, reqId, rank, contractDetails, distance, benchmark, projection): 210 | pass 211 | 212 | def scannerDataEnd(self, reqId): 213 | pass 214 | 215 | def realtimeBar(self, reqId, time, open, high, low, close, volume, wap, count): 216 | pass 217 | 218 | def currentTime(self, time): 219 | pass 220 | 221 | def fundamentalData(self, reqId, data): 222 | pass 223 | 224 | def commissionReport(self, commission_rpt): 225 | print "Commision from trade: ", commission_rpt.commission 226 | 227 | -------------------------------------------------------------------------------- /ArtemisIBWrapperSilent.py: -------------------------------------------------------------------------------- 1 | from datetime import datetime 2 | import time, sys 3 | import pdb 4 | 5 | sys.path.append('/home/mchan/git/Artemis/util') 6 | import dbutil 7 | 8 | from swigibpy import EWrapper, Contract, ContractDetails 9 | 10 | ### 11 | 12 | tickTypeHash = {0:"bid size", 1:"bid price", 2:"ask price", 3:"ask size", 4:"last price", \ 13 | 5:"last size", 6:"high", 7:"low", 8:"volume", 9:"close price", 10:"bid option computation", \ 14 | 11:"ask option computation", 12:"last option computation", 13:"model option computation", \ 15 | 14:"open tick", 15:"low 13 week", 16:"high 13 week", 17:"low 26 week", 18:"high 26 week", \ 16 | 19:"low 52 week", 20:"high 52 week", 21:"avg volume", 22:"open interest", \ 17 | 23:"option historical vol", 24:"option implied vol", 25:"option bid exch", \ 18 | 26:"option ask exch", 27:"option call open interest", 28:"option put open interest", \ 19 | 29:"option call volume", 30:"option put volume", 31:"index future premium", \ 20 | 32:"bid exch", 33:"ask exch", 37:"mark price", 45:"last timestamp", \ 21 | 46:"shortable", 47:"fundamental ratios", 48:"rt volume", 49:"halted", \ 22 | 53:"cust option computation", 54:"trade count", 55:"trade rate", \ 23 | 56:"volume rate"} 24 | 25 | wrapper_db = dbutil.db(h='127.0.0.1', schema='mchan') 26 | class ArtemisIBWrapper(EWrapper): 27 | '''Callback object passed to TWS, these functions will be called directly 28 | by TWS. 29 | 30 | ''' 31 | def deltaNeutralValidation(self, reqId, underComp): 32 | pass 33 | 34 | def marketDataType(self, reqid, marketDataType): 35 | print "Market Data Type: ", reqId, " ", marketDataType 36 | 37 | def winError(self, mesg, errorCode): 38 | print "Win error message: ", mesg, " ", errorCode 39 | 40 | def error(self, orderId, errorCode, errorString): 41 | print orderId, " ", errorCode, " ", errorString 42 | 43 | def nextValidId(self, orderId): 44 | '''Always called by TWS but not relevant for our example''' 45 | self.myNextValidId = orderId 46 | print "Next Valid Id: ", orderId 47 | 48 | def openOrderEnd(self): 49 | '''Always called by TWS but not relevant for our example''' 50 | print "Open Order end:" 51 | 52 | def tickEFP(self, tickerId, tickType, basisPoints, formattedBasisPoints, totalDividends, holdDays, futureExpiry, dividendImpact, dividendsToExpiry): 53 | pass 54 | 55 | def openOrder(self, orderId, contract, order, orderState): 56 | print "Open Order status: Order Id: ", orderId, " Order State: ", orderState.status 57 | 58 | def managedAccounts(self, openOrderEnd): 59 | '''Called by TWS but not relevant for our example''' 60 | pass 61 | 62 | def historicalData(self, reqId, date, open, high, 63 | low, close, volume, 64 | barCount, WAP, hasGaps): 65 | 66 | if date[:8] == 'finished': 67 | self.histClose = self.lastClose 68 | print "History request complete" 69 | else: 70 | try: 71 | date = datetime.strptime(date, "%Y%m%d").strftime("%d %b %Y") 72 | except: 73 | date = datetime.strptime(date, "%Y%m%d %H:%M:%S").strftime("%d %b %Y %H:%M:%S") 74 | self.lastClose = close 75 | print ( "History %s - Open: %s, High: %s, Low: %s, Close: " + 76 | "%s, Volume: %d" ) % (date, open, high, low, close, volume) 77 | 78 | def tickOptionComputation(self, reqId, tickType, impliedVol, delta, 79 | optPrice, pvDiv, gamma, vega, theta, undPrice): 80 | tickTypeStr = tickTypeHash[tickType] 81 | print ("Option Data -Request ID: %s -TickType: %s -Implied Vol: %f" + 82 | " -Delta: %f -Option Price: %f -PV Dividend: %f -Gamma: %f -Vega: %f -Theta: %f" + 83 | " -Underlying Price: %f") % (reqId, tickTypeStr, impliedVol, delta, optPrice, pvDiv, gamma, vega, theta, undPrice) 84 | 85 | def tickPrice(self, reqId, tickType, price, canAutoExecute): 86 | tickTypeStr = tickTypeHash[tickType] 87 | if tickType == 2: 88 | self.askPrice = price 89 | elif tickType == 4: 90 | self.lastPrice = price 91 | elif tickType == 9: 92 | self.closePrice = price 93 | print ("Pricing Data -Request ID: %s -TickType: %s -Price: %s -CanAutoExecute: %s") % (reqId, tickTypeStr, price, canAutoExecute) 94 | 95 | def tickGeneric(self, reqId, tickType, value): 96 | tickTypeStr = tickTypeHash[tickType] 97 | print ("TickGeneric Data -Request ID: %s -TickType: %s -Value: %s") % (reqId, tickTypeStr, value) 98 | 99 | def tickSize(self, reqId, field, size): 100 | fieldStr = tickTypeHash[field] 101 | print ("TickSize Data -Request ID: %s -TickType: %s -Size: %s") % (reqId, fieldStr, size) 102 | 103 | def tickSnapshotEnd(self, reqId): 104 | self.tickDataEnd = True 105 | print "Tick Data end" 106 | 107 | def tickString(self, reqId, tickType, value): 108 | tickTypeStr = tickTypeHash[tickType] 109 | print ("TickString Data -Request ID: %s -TickType: %s -Value: %s") % (reqId, tickTypeStr, value) 110 | 111 | def contractDetails(self, reqId, conDetails): 112 | # print ("Contract Details Recieved") 113 | # print "Options Summary: ContractID: ", conDetails.summary.conId, " Exchange: ", conDetails.summary.exchange, " Trading Hours: ",\ 114 | # conDetails.tradingHours, " Strike: ", conDetails.summary.strike, " Multiplier: ", conDetails.summary.multiplier, \ 115 | # " Expiry: ", conDetails.summary.expiry, " Right: " , conDetails.summary.right, " Currency: ", conDetails.summary.currency 116 | self.contractDetailsData = conDetails 117 | self.conId = conDetails.summary.conId 118 | self.exchange = conDetails.summary.exchange 119 | self.tradingHours = conDetails.tradingHours 120 | self.strike = conDetails.summary.strike 121 | self.Strikes.append(conDetails.summary.strike) 122 | self.StrikesHash[conDetails.summary.strike] = (conDetails.summary.conId, conDetails.summary.multiplier) 123 | self.multiplier = conDetails.summary.multiplier 124 | self.expiry = conDetails.summary.expiry 125 | self.right = conDetails.summary.right 126 | self.currency = conDetails.summary.currency 127 | 128 | def contractDetailsEnd(self, reqId): 129 | self.contractDataEnd = True 130 | print ("Contract Details End") 131 | 132 | def updateAccountValue(self, key, value, currency, account): 133 | if key == "BuyingPower": 134 | self.buyingPower = value 135 | # INITIALIZE 136 | self.portfolioData = [] 137 | elif key == "TotalCashBalance": 138 | self.totalCashBalance = value 139 | elif key == "NetLiquidation": 140 | self.netLiquidation = value 141 | if key in ["BuyingPower", "AccountType", "NetLiquidation", "CashBalance", "TotalCashBalance", "TotalCashValue"]: 142 | print key, " ", value 143 | #print key, " ", value 144 | 145 | def updateAccountTime(self, timestmp): 146 | print timestmp 147 | 148 | def accountDownloadEnd(self, account): 149 | self.accountEnd = True 150 | print "Account Download End ", account 151 | 152 | def updatePortfolio(self, contract, position, marketPrice, marketValue, averageCost, unrealizedPNL, realizedPNL, accountName): 153 | self.portfolioContractSymbol = contract.symbol 154 | self.portfolioContractSecType = contract.secType 155 | self.portfolioContractRight = contract.right 156 | self.portfolioContractExpiry = contract.expiry 157 | self.portfolioContractStrike = contract.strike 158 | self.portfolioContractConId = contract.conId 159 | self.portfolioSecMarketValue = marketValue 160 | self.portfolioPosition = position 161 | self.portfolioContract = contract 162 | print "Contract: ", contract.symbol, " ", contract.secType, " Position: ", position, " Market Value: ", marketValue, \ 163 | " Market Price: ", marketPrice, " averageCost: ", averageCost, " Unrealized PnL: ", unrealizedPNL, \ 164 | " Realized PnL: ", realizedPNL, " Account Name: ", accountName 165 | try: 166 | self.portfolioData.append({'symbol':contract.symbol, 'secType':contract.secType, 'right':contract.right, 'expiry':contract.expiry, \ 167 | 'strike':contract.strike, 'conId':contract.conId, 'marketValue':marketValue, 'Position':position}) 168 | except: 169 | pass 170 | 171 | def connectionClosed(self): 172 | print "TWS Connection closed at: ", str(datetime.now()) 173 | 174 | def orderStatus(self, orderId, status, filled, remaining, avgFillPrice, permId, parentId, lastFillPrice, clientId, whyHeld): 175 | myNow = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) 176 | wrapper_db.execute('''INSERT INTO mchan.twsOrderStatus VALUES (%i, "%s", %i, %i, %i, %f, "%s");''' % (orderId, status, clientId, filled, remaining, avgFillPrice, myNow)) 177 | wrapper_db.commit() 178 | print "Order Status Alert, STATUS: ", status, " Filled: ", filled, " Remaining: ", remaining, " Avg Fill Price: ", avgFillPrice, \ 179 | " PermId: ", permId, " ParentId: ", parentId, " Last fill Price: ", lastFillPrice, " Client Id: ", clientId, " Why Held: ", whyHeld 180 | self.orderState = status 181 | 182 | def execDetails(self, orderId, contract, execution): 183 | pass 184 | 185 | def execDetailsEnd(self, requestId): 186 | pass 187 | 188 | def updateMktDepth(self, tickerId, position, operation, side, price, size): 189 | print "Market Depth" 190 | print "Ticker ID: ", tickerId, " Position: ", position, " Operation: ", operation, " Side: ", side, " Price: ", price, " Size: ", size 191 | 192 | def updateMktDepthL2(self, tickerId, position, marketMaker, operation, side, price, size): 193 | print "L2 Market Depth" 194 | print "Ticker ID: ", tickerId, " Market Maker: ", marketMaker," Position: ", position, " Operation: ", operation, " Side: ", side, " Price: ", price, " Size: ", size 195 | 196 | def updateNewsBulletin(self, msgId, msgType, message, origExchange): 197 | pass 198 | 199 | def receiveFA(self, faDataType, XML): 200 | pass 201 | 202 | def bondContractDetails(self, reqId, contractDetails): 203 | pass 204 | 205 | def scannerParameters(self, xml): 206 | pass 207 | 208 | def scannerData(self, reqId, rank, contractDetails, distance, benchmark, projection): 209 | pass 210 | 211 | def scannerDataEnd(self, reqId): 212 | pass 213 | 214 | def realtimeBar(self, reqId, time, open, high, low, close, volume, wap, count): 215 | pass 216 | 217 | def currentTime(self, time): 218 | pass 219 | 220 | def fundamentalData(self, reqId, data): 221 | pass 222 | 223 | def commissionReport(self, commission_rpt): 224 | print "Commision from trade: ", commission_rpt.commission 225 | 226 | 227 | -------------------------------------------------------------------------------- /DataDownloadIBWrapper.py: -------------------------------------------------------------------------------- 1 | from datetime import datetime, timedelta 2 | import time, sys 3 | import pdb 4 | 5 | sys.path.append('/home/mchan/git/Artemis/util') 6 | import dbutil 7 | 8 | from swigibpy import EWrapper, Contract, ContractDetails 9 | 10 | ### 11 | 12 | tickTypeHash = {0:"bid size", 1:"bid price", 2:"ask price", 3:"ask size", 4:"last price", \ 13 | 5:"last size", 6:"high", 7:"low", 8:"volume", 9:"close price", 10:"bid option computation", \ 14 | 11:"ask option computation", 12:"last option computation", 13:"model option computation", \ 15 | 14:"open tick", 15:"low 13 week", 16:"high 13 week", 17:"low 26 week", 18:"high 26 week", \ 16 | 19:"low 52 week", 20:"high 52 week", 21:"avg volume", 22:"open interest", \ 17 | 23:"option historical vol", 24:"option implied vol", 25:"option bid exch", \ 18 | 26:"option ask exch", 27:"option call open interest", 28:"option put open interest", \ 19 | 29:"option call volume", 30:"option put volume", 31:"index future premium", \ 20 | 32:"bid exch", 33:"ask exch", 37:"mark price", 45:"last timestamp", \ 21 | 46:"shortable", 47:"fundamental ratios", 48:"rt volume", 49:"halted", \ 22 | 53:"cust option computation", 54:"trade count", 55:"trade rate", \ 23 | 56:"volume rate"} 24 | 25 | wrapper_db = dbutil.db(h='127.0.0.1', schema='mchan') 26 | wrapper_db.execute('SET autocommit=0;') 27 | class ArtemisIBWrapper(EWrapper): 28 | '''Callback object passed to TWS, these functions will be called directly 29 | by TWS. 30 | 31 | ''' 32 | def deltaNeutralValidation(self, reqId, underComp): 33 | pass 34 | 35 | def marketDataType(self, reqid, marketDataType): 36 | print "Market Data Type: ", reqId, " ", marketDataType 37 | 38 | def winError(self, mesg, errorCode): 39 | print "Win error message: ", mesg, " ", errorCode 40 | 41 | def error(self, orderId, errorCode, errorString): 42 | print orderId, " ", errorCode, " ", errorString 43 | 44 | def nextValidId(self, orderId): 45 | '''Always called by TWS but not relevant for our example''' 46 | self.myNextValidId = orderId 47 | print "Next Valid Id: ", orderId 48 | 49 | def openOrderEnd(self): 50 | '''Always called by TWS but not relevant for our example''' 51 | print "Open Order end:" 52 | 53 | def tickEFP(self, tickerId, tickType, basisPoints, formattedBasisPoints, totalDividends, holdDays, futureExpiry, dividendImpact, dividendsToExpiry): 54 | pass 55 | 56 | def openOrder(self, orderId, contract, order, orderState): 57 | print "Open Order status: Order Id: ", orderId, " Order State: ", orderState.status 58 | 59 | def managedAccounts(self, openOrderEnd): 60 | '''Called by TWS but not relevant for our example''' 61 | pass 62 | 63 | def historicalData(self, reqId, date, open, high, 64 | low, close, volume, 65 | barCount, WAP, hasGaps): 66 | 67 | if date[:8] == 'finished': 68 | wrapper_db.commit() 69 | wrapper_db.execute("COMMIT;") 70 | wrapper_db.execute('SET autocommit=0;') 71 | self.histTickerID = None 72 | print "History request complete" 73 | else: 74 | try: 75 | date_str = datetime.strptime(date, "%Y%m%d").strftime("%d %b %Y") 76 | except: 77 | date_str = (datetime.strptime(date, "%Y%m%d %H:%M:%S") + timedelta(hours=3)).strftime("%d %b %Y %H:%M:%S") 78 | date = datetime.strptime(date, "%Y%m%d %H:%M:%S") + timedelta(hours=3) 79 | 80 | wrapper_db.execute('''INSERT IGNORE INTO mchan.pricing1Min VALUES ("%s", "%s", "%s", %i, %f, %i);''' % (self.histTickerID, date.date().isoformat(),\ 81 | date.time().isoformat(), 0, close, volume)) 82 | print ( "%s %s - Open: %s, High: %s, Low: %s, Close: " + 83 | "%s, Volume: %d" ) % (self.histTickerID, date_str, open, high, low, close, volume) 84 | 85 | def tickOptionComputation(self, reqId, tickType, impliedVol, delta, 86 | optPrice, pvDiv, gamma, vega, theta, undPrice): 87 | tickTypeStr = tickTypeHash[tickType] 88 | print ("Option Data -Request ID: %s -TickType: %s -Implied Vol: %f" + 89 | " -Delta: %f -Option Price: %f -PV Dividend: %f -Gamma: %f -Vega: %f -Theta: %f" + 90 | " -Underlying Price: %f") % (reqId, tickTypeStr, impliedVol, delta, optPrice, pvDiv, gamma, vega, theta, undPrice) 91 | 92 | def tickPrice(self, reqId, tickType, price, canAutoExecute): 93 | tickTypeStr = tickTypeHash[tickType] 94 | if tickType == 2: 95 | self.askPrice = price 96 | elif tickType == 4: 97 | self.lastPrice = price 98 | elif tickType == 9: 99 | self.closePrice = price 100 | print ("Pricing Data -Request ID: %s -TickType: %s -Price: %s -CanAutoExecute: %s") % (reqId, tickTypeStr, price, canAutoExecute) 101 | 102 | def tickGeneric(self, reqId, tickType, value): 103 | tickTypeStr = tickTypeHash[tickType] 104 | print ("TickGeneric Data -Request ID: %s -TickType: %s -Value: %s") % (reqId, tickTypeStr, value) 105 | 106 | def tickSize(self, reqId, field, size): 107 | fieldStr = tickTypeHash[field] 108 | print ("TickSize Data -Request ID: %s -TickType: %s -Size: %s") % (reqId, fieldStr, size) 109 | 110 | def tickSnapshotEnd(self, reqId): 111 | self.tickDataEnd = True 112 | print "Tick Data end" 113 | 114 | def tickString(self, reqId, tickType, value): 115 | tickTypeStr = tickTypeHash[tickType] 116 | print ("TickString Data -Request ID: %s -TickType: %s -Value: %s") % (reqId, tickTypeStr, value) 117 | 118 | def contractDetails(self, reqId, conDetails): 119 | print ("Contract Details Recieved") 120 | print "Options Summary: ContractID: ", conDetails.summary.conId, " Exchange: ", conDetails.summary.exchange, " Trading Hours: ",\ 121 | conDetails.tradingHours, " Strike: ", conDetails.summary.strike, " Multiplier: ", conDetails.summary.multiplier, \ 122 | " Expiry: ", conDetails.summary.expiry, " Right: " , conDetails.summary.right, " Currency: ", conDetails.summary.currency 123 | self.contractDetailsData = conDetails 124 | self.conId = conDetails.summary.conId 125 | self.exchange = conDetails.summary.exchange 126 | self.tradingHours = conDetails.tradingHours 127 | self.strike = conDetails.summary.strike 128 | self.Strikes.append(conDetails.summary.strike) 129 | self.StrikesHash[conDetails.summary.strike] = (conDetails.summary.conId, conDetails.summary.multiplier) 130 | self.multiplier = conDetails.summary.multiplier 131 | self.expiry = conDetails.summary.expiry 132 | self.right = conDetails.summary.right 133 | self.currency = conDetails.summary.currency 134 | 135 | def contractDetailsEnd(self, reqId): 136 | self.contractDataEnd = True 137 | print ("Contract Details End") 138 | 139 | def updateAccountValue(self, key, value, currency, account): 140 | if key == "BuyingPower": 141 | self.buyingPower = value 142 | # INITIALIZE 143 | self.portfolioData = [] 144 | #if key in ["BuyingPower", "AccountType", "CashBalance", "TotalCashBalance", "TotalCashValue"]: 145 | # print key, " ", value 146 | print key, " ", value 147 | 148 | def updateAccountTime(self, timestmp): 149 | print timestmp 150 | 151 | def accountDownloadEnd(self, account): 152 | self.accountEnd = True 153 | print "Account Download End ", account 154 | 155 | def updatePortfolio(self, contract, position, marketPrice, marketValue, averageCost, unrealizedPNL, realizedPNL, accountName): 156 | self.portfolioContractSymbol = contract.symbol 157 | self.portfolioContractSecType = contract.secType 158 | self.portfolioContractRight = contract.right 159 | self.portfolioContractExpiry = contract.expiry 160 | self.portfolioContractStrike = contract.strike 161 | self.portfolioContractConId = contract.conId 162 | self.portfolioSecMarketValue = marketValue 163 | self.portfolioPosition = position 164 | self.portfolioContract = contract 165 | print "Contract: ", contract.symbol, " ", contract.secType, " Position: ", position, " Market Value: ", marketValue, \ 166 | " Market Price: ", marketPrice, " averageCost: ", averageCost, " Unrealized PnL: ", unrealizedPNL, \ 167 | " Realized PnL: ", realizedPNL, " Account Name: ", accountName 168 | try: 169 | self.portfolioData.append({'symbol':contract.symbol, 'secType':contract.secType, 'right':contract.right, 'expiry':contract.expiry, \ 170 | 'strike':contract.strike, 'conId':contract.conId, 'marketValue':marketValue, 'Position':position}) 171 | except: 172 | pass 173 | 174 | def connectionClosed(self): 175 | print "TWS Connection closed at: ", str(datetime.now()) 176 | 177 | def orderStatus(self, orderId, status, filled, remaining, avgFillPrice, permId, parentId, lastFillPrice, clientId, whyHeld): 178 | #myNow = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) 179 | #wrapper_db.execute('''INSERT INTO mchan.twsOrderStatus VALUES (%i, "%s", %i, %i, %i, %f, "%s");''' % (orderId, status, clientId, filled, remaining, avgFillPrice, myNow)) 180 | #wrapper_db.commit() 181 | print "Order Status Alert, STATUS: ", status, " Filled: ", filled, " Remaining: ", remaining, " Avg Fill Price: ", avgFillPrice, \ 182 | " PermId: ", permId, " ParentId: ", parentId, " Last fill Price: ", lastFillPrice, " Client Id: ", clientId, " Why Held: ", whyHeld 183 | self.orderState = status 184 | 185 | def execDetails(self, orderId, contract, execution): 186 | pass 187 | 188 | def execDetailsEnd(self, requestId): 189 | pass 190 | 191 | def updateMktDepth(self, tickerId, position, operation, side, price, size): 192 | print "Market Depth" 193 | print "Ticker ID: ", tickerId, " Position: ", position, " Operation: ", operation, " Side: ", side, " Price: ", price, " Size: ", size 194 | 195 | def updateMktDepthL2(self, tickerId, position, marketMaker, operation, side, price, size): 196 | print "L2 Market Depth" 197 | print "Ticker ID: ", tickerId, " Market Maker: ", marketMaker," Position: ", position, " Operation: ", operation, " Side: ", side, " Price: ", price, " Size: ", size 198 | 199 | def updateNewsBulletin(self, msgId, msgType, message, origExchange): 200 | pass 201 | 202 | def receiveFA(self, faDataType, XML): 203 | pass 204 | 205 | def bondContractDetails(self, reqId, contractDetails): 206 | pass 207 | 208 | def scannerParameters(self, xml): 209 | pass 210 | 211 | def scannerData(self, reqId, rank, contractDetails, distance, benchmark, projection): 212 | pass 213 | 214 | def scannerDataEnd(self, reqId): 215 | pass 216 | 217 | def realtimeBar(self, reqId, time, open, high, low, close, volume, wap, count): 218 | pass 219 | 220 | def currentTime(self, time): 221 | pass 222 | 223 | def fundamentalData(self, reqId, data): 224 | pass 225 | 226 | 227 | -------------------------------------------------------------------------------- /DataDownloadIBWrapperSilent.py: -------------------------------------------------------------------------------- 1 | from datetime import datetime, timedelta 2 | import time, sys 3 | import pdb 4 | 5 | sys.path.append('/home/mchan/git/Artemis/util') 6 | import dbutil 7 | 8 | from swigibpy import EWrapper, Contract, ContractDetails 9 | 10 | ### 11 | 12 | tickTypeHash = {0:"bid size", 1:"bid price", 2:"ask price", 3:"ask size", 4:"last price", \ 13 | 5:"last size", 6:"high", 7:"low", 8:"volume", 9:"close price", 10:"bid option computation", \ 14 | 11:"ask option computation", 12:"last option computation", 13:"model option computation", \ 15 | 14:"open tick", 15:"low 13 week", 16:"high 13 week", 17:"low 26 week", 18:"high 26 week", \ 16 | 19:"low 52 week", 20:"high 52 week", 21:"avg volume", 22:"open interest", \ 17 | 23:"option historical vol", 24:"option implied vol", 25:"option bid exch", \ 18 | 26:"option ask exch", 27:"option call open interest", 28:"option put open interest", \ 19 | 29:"option call volume", 30:"option put volume", 31:"index future premium", \ 20 | 32:"bid exch", 33:"ask exch", 37:"mark price", 45:"last timestamp", \ 21 | 46:"shortable", 47:"fundamental ratios", 48:"rt volume", 49:"halted", \ 22 | 53:"cust option computation", 54:"trade count", 55:"trade rate", \ 23 | 56:"volume rate"} 24 | 25 | wrapper_db = dbutil.db(h='127.0.0.1', schema='mchan') 26 | wrapper_db.execute('SET autocommit=0;') 27 | class ArtemisIBWrapper(EWrapper): 28 | '''Callback object passed to TWS, these functions will be called directly 29 | by TWS. 30 | 31 | ''' 32 | def deltaNeutralValidation(self, reqId, underComp): 33 | pass 34 | 35 | def marketDataType(self, reqid, marketDataType): 36 | print "Market Data Type: ", reqId, " ", marketDataType 37 | 38 | def winError(self, mesg, errorCode): 39 | print "Win error message: ", mesg, " ", errorCode 40 | 41 | def error(self, orderId, errorCode, errorString): 42 | print orderId, " ", errorCode, " ", errorString 43 | 44 | def nextValidId(self, orderId): 45 | '''Always called by TWS but not relevant for our example''' 46 | self.myNextValidId = orderId 47 | print "Next Valid Id: ", orderId 48 | 49 | def openOrderEnd(self): 50 | '''Always called by TWS but not relevant for our example''' 51 | print "Open Order end:" 52 | 53 | def tickEFP(self, tickerId, tickType, basisPoints, formattedBasisPoints, totalDividends, holdDays, futureExpiry, dividendImpact, dividendsToExpiry): 54 | pass 55 | 56 | def openOrder(self, orderId, contract, order, orderState): 57 | print "Open Order status: Order Id: ", orderId, " Order State: ", orderState.status 58 | 59 | def managedAccounts(self, openOrderEnd): 60 | '''Called by TWS but not relevant for our example''' 61 | pass 62 | 63 | def historicalData(self, reqId, date, open, high, 64 | low, close, volume, 65 | barCount, WAP, hasGaps): 66 | 67 | if date[:8] == 'finished': 68 | wrapper_db.commit() 69 | wrapper_db.execute("COMMIT;") 70 | wrapper_db.execute('SET autocommit=0;') 71 | print "History request complete: ", self.histTickerID 72 | self.histTickerID = None 73 | else: 74 | try: 75 | date_str = datetime.strptime(date, "%Y%m%d").strftime("%d %b %Y") 76 | except: 77 | date_str = (datetime.strptime(date, "%Y%m%d %H:%M:%S") + timedelta(hours=3)).strftime("%d %b %Y %H:%M:%S") 78 | date = datetime.strptime(date, "%Y%m%d %H:%M:%S") + timedelta(hours=3) 79 | 80 | wrapper_db.execute('''INSERT IGNORE INTO mchan.pricing1Min VALUES ("%s", "%s", "%s", %i, %f, %i);''' % (self.histTickerID, date.date().isoformat(),\ 81 | date.time().isoformat(), 0, close, volume)) 82 | #print ( "%s %s - Open: %s, High: %s, Low: %s, Close: " + 83 | # "%s, Volume: %d" ) % (self.histTickerID, date_str, open, high, low, close, volume) 84 | 85 | def tickOptionComputation(self, reqId, tickType, impliedVol, delta, 86 | optPrice, pvDiv, gamma, vega, theta, undPrice): 87 | tickTypeStr = tickTypeHash[tickType] 88 | print ("Option Data -Request ID: %s -TickType: %s -Implied Vol: %f" + 89 | " -Delta: %f -Option Price: %f -PV Dividend: %f -Gamma: %f -Vega: %f -Theta: %f" + 90 | " -Underlying Price: %f") % (reqId, tickTypeStr, impliedVol, delta, optPrice, pvDiv, gamma, vega, theta, undPrice) 91 | 92 | def tickPrice(self, reqId, tickType, price, canAutoExecute): 93 | tickTypeStr = tickTypeHash[tickType] 94 | if tickType == 2: 95 | self.askPrice = price 96 | elif tickType == 4: 97 | self.lastPrice = price 98 | elif tickType == 9: 99 | self.closePrice = price 100 | print ("Pricing Data -Request ID: %s -TickType: %s -Price: %s -CanAutoExecute: %s") % (reqId, tickTypeStr, price, canAutoExecute) 101 | 102 | def tickGeneric(self, reqId, tickType, value): 103 | tickTypeStr = tickTypeHash[tickType] 104 | print ("TickGeneric Data -Request ID: %s -TickType: %s -Value: %s") % (reqId, tickTypeStr, value) 105 | 106 | def tickSize(self, reqId, field, size): 107 | fieldStr = tickTypeHash[field] 108 | print ("TickSize Data -Request ID: %s -TickType: %s -Size: %s") % (reqId, fieldStr, size) 109 | 110 | def tickSnapshotEnd(self, reqId): 111 | self.tickDataEnd = True 112 | print "Tick Data end" 113 | 114 | def tickString(self, reqId, tickType, value): 115 | tickTypeStr = tickTypeHash[tickType] 116 | print ("TickString Data -Request ID: %s -TickType: %s -Value: %s") % (reqId, tickTypeStr, value) 117 | 118 | def contractDetails(self, reqId, conDetails): 119 | print ("Contract Details Recieved") 120 | print "Options Summary: ContractID: ", conDetails.summary.conId, " Exchange: ", conDetails.summary.exchange, " Trading Hours: ",\ 121 | conDetails.tradingHours, " Strike: ", conDetails.summary.strike, " Multiplier: ", conDetails.summary.multiplier, \ 122 | " Expiry: ", conDetails.summary.expiry, " Right: " , conDetails.summary.right, " Currency: ", conDetails.summary.currency 123 | self.contractDetailsData = conDetails 124 | self.conId = conDetails.summary.conId 125 | self.exchange = conDetails.summary.exchange 126 | self.tradingHours = conDetails.tradingHours 127 | self.strike = conDetails.summary.strike 128 | self.Strikes.append(conDetails.summary.strike) 129 | self.StrikesHash[conDetails.summary.strike] = (conDetails.summary.conId, conDetails.summary.multiplier) 130 | self.multiplier = conDetails.summary.multiplier 131 | self.expiry = conDetails.summary.expiry 132 | self.right = conDetails.summary.right 133 | self.currency = conDetails.summary.currency 134 | 135 | def contractDetailsEnd(self, reqId): 136 | self.contractDataEnd = True 137 | print ("Contract Details End") 138 | 139 | def updateAccountValue(self, key, value, currency, account): 140 | if key == "BuyingPower": 141 | self.buyingPower = value 142 | # INITIALIZE 143 | self.portfolioData = [] 144 | #if key in ["BuyingPower", "AccountType", "CashBalance", "TotalCashBalance", "TotalCashValue"]: 145 | # print key, " ", value 146 | print key, " ", value 147 | 148 | def updateAccountTime(self, timestmp): 149 | print timestmp 150 | 151 | def accountDownloadEnd(self, account): 152 | self.accountEnd = True 153 | print "Account Download End ", account 154 | 155 | def updatePortfolio(self, contract, position, marketPrice, marketValue, averageCost, unrealizedPNL, realizedPNL, accountName): 156 | self.portfolioContractSymbol = contract.symbol 157 | self.portfolioContractSecType = contract.secType 158 | self.portfolioContractRight = contract.right 159 | self.portfolioContractExpiry = contract.expiry 160 | self.portfolioContractStrike = contract.strike 161 | self.portfolioContractConId = contract.conId 162 | self.portfolioSecMarketValue = marketValue 163 | self.portfolioPosition = position 164 | self.portfolioContract = contract 165 | print "Contract: ", contract.symbol, " ", contract.secType, " Position: ", position, " Market Value: ", marketValue, \ 166 | " Market Price: ", marketPrice, " averageCost: ", averageCost, " Unrealized PnL: ", unrealizedPNL, \ 167 | " Realized PnL: ", realizedPNL, " Account Name: ", accountName 168 | try: 169 | self.portfolioData.append({'symbol':contract.symbol, 'secType':contract.secType, 'right':contract.right, 'expiry':contract.expiry, \ 170 | 'strike':contract.strike, 'conId':contract.conId, 'marketValue':marketValue, 'Position':position}) 171 | except: 172 | pass 173 | 174 | def connectionClosed(self): 175 | print "TWS Connection closed at: ", str(datetime.now()) 176 | 177 | def orderStatus(self, orderId, status, filled, remaining, avgFillPrice, permId, parentId, lastFillPrice, clientId, whyHeld): 178 | #myNow = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) 179 | #wrapper_db.execute('''INSERT INTO mchan.twsOrderStatus VALUES (%i, "%s", %i, %i, %i, %f, "%s");''' % (orderId, status, clientId, filled, remaining, avgFillPrice, myNow)) 180 | #wrapper_db.commit() 181 | print "Order Status Alert, STATUS: ", status, " Filled: ", filled, " Remaining: ", remaining, " Avg Fill Price: ", avgFillPrice, \ 182 | " PermId: ", permId, " ParentId: ", parentId, " Last fill Price: ", lastFillPrice, " Client Id: ", clientId, " Why Held: ", whyHeld 183 | self.orderState = status 184 | 185 | def execDetails(self, orderId, contract, execution): 186 | pass 187 | 188 | def execDetailsEnd(self, requestId): 189 | pass 190 | 191 | def updateMktDepth(self, tickerId, position, operation, side, price, size): 192 | print "Market Depth" 193 | print "Ticker ID: ", tickerId, " Position: ", position, " Operation: ", operation, " Side: ", side, " Price: ", price, " Size: ", size 194 | 195 | def updateMktDepthL2(self, tickerId, position, marketMaker, operation, side, price, size): 196 | print "L2 Market Depth" 197 | print "Ticker ID: ", tickerId, " Market Maker: ", marketMaker," Position: ", position, " Operation: ", operation, " Side: ", side, " Price: ", price, " Size: ", size 198 | 199 | def updateNewsBulletin(self, msgId, msgType, message, origExchange): 200 | pass 201 | 202 | def receiveFA(self, faDataType, XML): 203 | pass 204 | 205 | def bondContractDetails(self, reqId, contractDetails): 206 | pass 207 | 208 | def scannerParameters(self, xml): 209 | pass 210 | 211 | def scannerData(self, reqId, rank, contractDetails, distance, benchmark, projection): 212 | pass 213 | 214 | def scannerDataEnd(self, reqId): 215 | pass 216 | 217 | def realtimeBar(self, reqId, time, open, high, low, close, volume, wap, count): 218 | pass 219 | 220 | def currentTime(self, time): 221 | pass 222 | 223 | def fundamentalData(self, reqId, data): 224 | pass 225 | 226 | 227 | -------------------------------------------------------------------------------- /IPynb/PricingDownload.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "metadata": { 3 | "name": "PricingDownload" 4 | }, 5 | "nbformat": 2, 6 | "worksheets": [ 7 | { 8 | "cells": [ 9 | { 10 | "cell_type": "code", 11 | "collapsed": true, 12 | "input": [ 13 | "import yaml", 14 | "import sys", 15 | "sys.path.append('/home/mchan/git/Artemis/brotchie-pytrth-381894a/trth/')", 16 | "sys.path.append('/home/mchan/git/Artemis/util/')", 17 | "import dbutil", 18 | "import multiprocessing", 19 | "import logging", 20 | "log = logging.getLogger(__name__)", 21 | "#logging.getLogger('suds.client').setLevel(logging.CRITICAL)", 22 | "import pytz, datetime", 23 | "import time", 24 | "", 25 | "# Package from brotchie-pytrth", 26 | "import api, request", 27 | "", 28 | "# For decoding function", 29 | "from cStringIO import StringIO", 30 | "from base64 import b64decode", 31 | "from gzip import GzipFile" 32 | ], 33 | "language": "python", 34 | "outputs": [], 35 | "prompt_number": 1 36 | }, 37 | { 38 | "cell_type": "code", 39 | "collapsed": false, 40 | "input": [ 41 | "run DownloadData.py" 42 | ], 43 | "language": "python", 44 | "outputs": [ 45 | { 46 | "output_type": "stream", 47 | "stream": "stdout", 48 | "text": [ 49 | "{u'A': A.N, u'C': C.N, u'IBM': IBM.N, u'INTC': INTC.O, u'MDRX': MDRX.O, u'ZNGA': ZNGA.O, u'FB': FB.O, u'CCI': CCI.N, u'NVDA': NVDA.O}" 50 | ] 51 | } 52 | ], 53 | "prompt_number": 66 54 | }, 55 | { 56 | "cell_type": "code", 57 | "collapsed": false, 58 | "input": [ 59 | "ricResult" 60 | ], 61 | "language": "python", 62 | "outputs": [ 63 | { 64 | "output_type": "pyout", 65 | "prompt_number": 67, 66 | "text": [ 67 | "{u'A': A.N,", 68 | " u'C': C.N,", 69 | " u'CCI': CCI.N,", 70 | " u'FB': FB.O,", 71 | " u'IBM': IBM.N,", 72 | " u'INTC': INTC.O,", 73 | " u'MDRX': MDRX.O,", 74 | " u'NVDA': NVDA.O,", 75 | " u'ZNGA': ZNGA.O}" 76 | ] 77 | } 78 | ], 79 | "prompt_number": 67 80 | }, 81 | { 82 | "cell_type": "code", 83 | "collapsed": false, 84 | "input": [ 85 | "ricResult['A']" 86 | ], 87 | "language": "python", 88 | "outputs": [ 89 | { 90 | "output_type": "pyout", 91 | "prompt_number": 68, 92 | "text": [ 93 | "A.N" 94 | ] 95 | } 96 | ], 97 | "prompt_number": 68 98 | }, 99 | { 100 | "cell_type": "code", 101 | "collapsed": false, 102 | "input": [ 103 | "ricList" 104 | ], 105 | "language": "python", 106 | "outputs": [ 107 | { 108 | "output_type": "pyout", 109 | "prompt_number": 49, 110 | "text": [ 111 | "[AMZN.O, QQQ.O, LSI.N, B.N, BA.N]" 112 | ] 113 | } 114 | ], 115 | "prompt_number": 49 116 | }, 117 | { 118 | "cell_type": "code", 119 | "collapsed": false, 120 | "input": [ 121 | "ricList[0].split('.')[0]" 122 | ], 123 | "language": "python", 124 | "outputs": [ 125 | { 126 | "output_type": "pyout", 127 | "prompt_number": 53, 128 | "text": [ 129 | "u'AMZN'" 130 | ] 131 | } 132 | ], 133 | "prompt_number": 53 134 | }, 135 | { 136 | "cell_type": "code", 137 | "collapsed": false, 138 | "input": [ 139 | "'xxx' in ricDict" 140 | ], 141 | "language": "python", 142 | "outputs": [ 143 | { 144 | "output_type": "pyout", 145 | "prompt_number": 59, 146 | "text": [ 147 | "False" 148 | ] 149 | } 150 | ], 151 | "prompt_number": 59 152 | }, 153 | { 154 | "cell_type": "code", 155 | "collapsed": true, 156 | "input": [ 157 | "ricDict = dict()" 158 | ], 159 | "language": "python", 160 | "outputs": [], 161 | "prompt_number": 54 162 | }, 163 | { 164 | "cell_type": "code", 165 | "collapsed": true, 166 | "input": [ 167 | "ricDict['AMZN'] = 'AMZN.O'" 168 | ], 169 | "language": "python", 170 | "outputs": [], 171 | "prompt_number": 55 172 | }, 173 | { 174 | "cell_type": "code", 175 | "collapsed": false, 176 | "input": [ 177 | "ricDict['AMZN']" 178 | ], 179 | "language": "python", 180 | "outputs": [ 181 | { 182 | "output_type": "pyout", 183 | "prompt_number": 57, 184 | "text": [ 185 | "'AMZN.O'" 186 | ] 187 | } 188 | ], 189 | "prompt_number": 57 190 | }, 191 | { 192 | "cell_type": "code", 193 | "collapsed": true, 194 | "input": [ 195 | "ricList." 196 | ], 197 | "language": "python", 198 | "outputs": [] 199 | }, 200 | { 201 | "cell_type": "code", 202 | "collapsed": false, 203 | "input": [ 204 | "dm = DownloadManager(trth)", 205 | "print dm.Tic2Ric('CCI')" 206 | ], 207 | "language": "python", 208 | "outputs": [ 209 | { 210 | "output_type": "stream", 211 | "stream": "stdout", 212 | "text": [ 213 | "CCI.N" 214 | ] 215 | } 216 | ], 217 | "prompt_number": 5 218 | }, 219 | { 220 | "cell_type": "code", 221 | "collapsed": true, 222 | "input": [ 223 | "tickerList = ['CCI.N', 'IBM.N', 'STZ.N', 'CELL.N', 'TXCC.N']", 224 | "arrayInst = dm.api.ArrayOfInstrument(instrument=[dm.api.Instrument(code=ticker) for ticker in tickerList])", 225 | "res = self.api.VerifyRICs(daterange, arrayinst, False)" 226 | ], 227 | "language": "python", 228 | "outputs": [ 229 | { 230 | "output_type": "pyout", 231 | "prompt_number": 25, 232 | "text": [ 233 | "(ArrayOfInstrument){", 234 | " instrument[] = ", 235 | " (Instrument){", 236 | " code = \"CCI.N\"", 237 | " isin = ", 238 | " (ArrayOfString){", 239 | " string[] = ", 240 | " }", 241 | " cusip = ", 242 | " (ArrayOfString){", 243 | " string[] = ", 244 | " }", 245 | " sedol = ", 246 | " (ArrayOfString){", 247 | " string[] = ", 248 | " }", 249 | " gics = ", 250 | " (ArrayOfInt){", 251 | " int[] = ", 252 | " }", 253 | " dateRange = ", 254 | " (DateRange){", 255 | " start = None", 256 | " end = None", 257 | " }", 258 | " name = ", 259 | " (ArrayOfString){", 260 | " string[] = ", 261 | " }", 262 | " status = None", 263 | " statusInfo = None", 264 | " exchange = ", 265 | " (ArrayOfString){", 266 | " string[] = ", 267 | " }", 268 | " type = ", 269 | " (ArrayOfString){", 270 | " string[] = ", 271 | " }", 272 | " expiryDate = ", 273 | " (ArrayOfDate){", 274 | " dt[] = ", 275 | " }", 276 | " strikePrice = ", 277 | " (ArrayOfString){", 278 | " string[] = ", 279 | " }", 280 | " maturityDate = ", 281 | " (ArrayOfDate){", 282 | " dt[] = ", 283 | " }", 284 | " couponRate = ", 285 | " (ArrayOfString){", 286 | " string[] = ", 287 | " }", 288 | " bondType = ", 289 | " (ArrayOfString){", 290 | " string[] = ", 291 | " }", 292 | " creditRating = ", 293 | " (ArrayOfString){", 294 | " string[] = ", 295 | " }", 296 | " currency = ", 297 | " (ArrayOfString){", 298 | " string[] = ", 299 | " }", 300 | " optionType = ", 301 | " (ArrayOfString){", 302 | " string[] = ", 303 | " }", 304 | " peCode = ", 305 | " (ArrayOfString){", 306 | " string[] = ", 307 | " }", 308 | " underlyingRIC = ", 309 | " (ArrayOfString){", 310 | " string[] = ", 311 | " }", 312 | " },", 313 | " (Instrument){", 314 | " code = \"IBM.N\"", 315 | " isin = ", 316 | " (ArrayOfString){", 317 | " string[] = ", 318 | " }", 319 | " cusip = ", 320 | " (ArrayOfString){", 321 | " string[] = ", 322 | " }", 323 | " sedol = ", 324 | " (ArrayOfString){", 325 | " string[] = ", 326 | " }", 327 | " gics = ", 328 | " (ArrayOfInt){", 329 | " int[] = ", 330 | " }", 331 | " dateRange = ", 332 | " (DateRange){", 333 | " start = None", 334 | " end = None", 335 | " }", 336 | " name = ", 337 | " (ArrayOfString){", 338 | " string[] = ", 339 | " }", 340 | " status = None", 341 | " statusInfo = None", 342 | " exchange = ", 343 | " (ArrayOfString){", 344 | " string[] = ", 345 | " }", 346 | " type = ", 347 | " (ArrayOfString){", 348 | " string[] = ", 349 | " }", 350 | " expiryDate = ", 351 | " (ArrayOfDate){", 352 | " dt[] = ", 353 | " }", 354 | " strikePrice = ", 355 | " (ArrayOfString){", 356 | " string[] = ", 357 | " }", 358 | " maturityDate = ", 359 | " (ArrayOfDate){", 360 | " dt[] = ", 361 | " }", 362 | " couponRate = ", 363 | " (ArrayOfString){", 364 | " string[] = ", 365 | " }", 366 | " bondType = ", 367 | " (ArrayOfString){", 368 | " string[] = ", 369 | " }", 370 | " creditRating = ", 371 | " (ArrayOfString){", 372 | " string[] = ", 373 | " }", 374 | " currency = ", 375 | " (ArrayOfString){", 376 | " string[] = ", 377 | " }", 378 | " optionType = ", 379 | " (ArrayOfString){", 380 | " string[] = ", 381 | " }", 382 | " peCode = ", 383 | " (ArrayOfString){", 384 | " string[] = ", 385 | " }", 386 | " underlyingRIC = ", 387 | " (ArrayOfString){", 388 | " string[] = ", 389 | " }", 390 | " },", 391 | " (Instrument){", 392 | " code = \"STZ.N\"", 393 | " isin = ", 394 | " (ArrayOfString){", 395 | " string[] = ", 396 | " }", 397 | " cusip = ", 398 | " (ArrayOfString){", 399 | " string[] = ", 400 | " }", 401 | " sedol = ", 402 | " (ArrayOfString){", 403 | " string[] = ", 404 | " }", 405 | " gics = ", 406 | " (ArrayOfInt){", 407 | " int[] = ", 408 | " }", 409 | " dateRange = ", 410 | " (DateRange){", 411 | " start = None", 412 | " end = None", 413 | " }", 414 | " name = ", 415 | " (ArrayOfString){", 416 | " string[] = ", 417 | " }", 418 | " status = None", 419 | " statusInfo = None", 420 | " exchange = ", 421 | " (ArrayOfString){", 422 | " string[] = ", 423 | " }", 424 | " type = ", 425 | " (ArrayOfString){", 426 | " string[] = ", 427 | " }", 428 | " expiryDate = ", 429 | " (ArrayOfDate){", 430 | " dt[] = ", 431 | " }", 432 | " strikePrice = ", 433 | " (ArrayOfString){", 434 | " string[] = ", 435 | " }", 436 | " maturityDate = ", 437 | " (ArrayOfDate){", 438 | " dt[] = ", 439 | " }", 440 | " couponRate = ", 441 | " (ArrayOfString){", 442 | " string[] = ", 443 | " }", 444 | " bondType = ", 445 | " (ArrayOfString){", 446 | " string[] = ", 447 | " }", 448 | " creditRating = ", 449 | " (ArrayOfString){", 450 | " string[] = ", 451 | " }", 452 | " currency = ", 453 | " (ArrayOfString){", 454 | " string[] = ", 455 | " }", 456 | " optionType = ", 457 | " (ArrayOfString){", 458 | " string[] = ", 459 | " }", 460 | " peCode = ", 461 | " (ArrayOfString){", 462 | " string[] = ", 463 | " }", 464 | " underlyingRIC = ", 465 | " (ArrayOfString){", 466 | " string[] = ", 467 | " }", 468 | " },", 469 | " (Instrument){", 470 | " code = \"CELL.N\"", 471 | " isin = ", 472 | " (ArrayOfString){", 473 | " string[] = ", 474 | " }", 475 | " cusip = ", 476 | " (ArrayOfString){", 477 | " string[] = ", 478 | " }", 479 | " sedol = ", 480 | " (ArrayOfString){", 481 | " string[] = ", 482 | " }", 483 | " gics = ", 484 | " (ArrayOfInt){", 485 | " int[] = ", 486 | " }", 487 | " dateRange = ", 488 | " (DateRange){", 489 | " start = None", 490 | " end = None", 491 | " }", 492 | " name = ", 493 | " (ArrayOfString){", 494 | " string[] = ", 495 | " }", 496 | " status = None", 497 | " statusInfo = None", 498 | " exchange = ", 499 | " (ArrayOfString){", 500 | " string[] = ", 501 | " }", 502 | " type = ", 503 | " (ArrayOfString){", 504 | " string[] = ", 505 | " }", 506 | " expiryDate = ", 507 | " (ArrayOfDate){", 508 | " dt[] = ", 509 | " }", 510 | " strikePrice = ", 511 | " (ArrayOfString){", 512 | " string[] = ", 513 | " }", 514 | " maturityDate = ", 515 | " (ArrayOfDate){", 516 | " dt[] = ", 517 | " }", 518 | " couponRate = ", 519 | " (ArrayOfString){", 520 | " string[] = ", 521 | " }", 522 | " bondType = ", 523 | " (ArrayOfString){", 524 | " string[] = ", 525 | " }", 526 | " creditRating = ", 527 | " (ArrayOfString){", 528 | " string[] = ", 529 | " }", 530 | " currency = ", 531 | " (ArrayOfString){", 532 | " string[] = ", 533 | " }", 534 | " optionType = ", 535 | " (ArrayOfString){", 536 | " string[] = ", 537 | " }", 538 | " peCode = ", 539 | " (ArrayOfString){", 540 | " string[] = ", 541 | " }", 542 | " underlyingRIC = ", 543 | " (ArrayOfString){", 544 | " string[] = ", 545 | " }", 546 | " },", 547 | " (Instrument){", 548 | " code = \"TXCC.N\"", 549 | " isin = ", 550 | " (ArrayOfString){", 551 | " string[] = ", 552 | " }", 553 | " cusip = ", 554 | " (ArrayOfString){", 555 | " string[] = ", 556 | " }", 557 | " sedol = ", 558 | " (ArrayOfString){", 559 | " string[] = ", 560 | " }", 561 | " gics = ", 562 | " (ArrayOfInt){", 563 | " int[] = ", 564 | " }", 565 | " dateRange = ", 566 | " (DateRange){", 567 | " start = None", 568 | " end = None", 569 | " }", 570 | " name = ", 571 | " (ArrayOfString){", 572 | " string[] = ", 573 | " }", 574 | " status = None", 575 | " statusInfo = None", 576 | " exchange = ", 577 | " (ArrayOfString){", 578 | " string[] = ", 579 | " }", 580 | " type = ", 581 | " (ArrayOfString){", 582 | " string[] = ", 583 | " }", 584 | " expiryDate = ", 585 | " (ArrayOfDate){", 586 | " dt[] = ", 587 | " }", 588 | " strikePrice = ", 589 | " (ArrayOfString){", 590 | " string[] = ", 591 | " }", 592 | " maturityDate = ", 593 | " (ArrayOfDate){", 594 | " dt[] = ", 595 | " }", 596 | " couponRate = ", 597 | " (ArrayOfString){", 598 | " string[] = ", 599 | " }", 600 | " bondType = ", 601 | " (ArrayOfString){", 602 | " string[] = ", 603 | " }", 604 | " creditRating = ", 605 | " (ArrayOfString){", 606 | " string[] = ", 607 | " }", 608 | " currency = ", 609 | " (ArrayOfString){", 610 | " string[] = ", 611 | " }", 612 | " optionType = ", 613 | " (ArrayOfString){", 614 | " string[] = ", 615 | " }", 616 | " peCode = ", 617 | " (ArrayOfString){", 618 | " string[] = ", 619 | " }", 620 | " underlyingRIC = ", 621 | " (ArrayOfString){", 622 | " string[] = ", 623 | " }", 624 | " },", 625 | " }" 626 | ] 627 | } 628 | ], 629 | "prompt_number": 25 630 | }, 631 | { 632 | "cell_type": "code", 633 | "collapsed": true, 634 | "input": [ 635 | "today = datetime.date.today().isoformat()", 636 | "tm1week = datetime.date.today() + datetime.timedelta(days=-7)", 637 | "daterange = trth.DateRange(start = tm1week, end = today)", 638 | "tickerList = ['CCI.N', 'IBM.N', 'STZ.N', 'CELL.N', 'TXCC.N']", 639 | "arrayinst = dm.api.ArrayOfInstrument(instrument=[dm.api.Instrument(code=ticker) for ticker in tickerList])", 640 | "res = dm.api.VerifyRICs(daterange, arrayinst, False)" 641 | ], 642 | "language": "python", 643 | "outputs": [], 644 | "prompt_number": 29 645 | }, 646 | { 647 | "cell_type": "code", 648 | "collapsed": false, 649 | "input": [ 650 | "for i in res.verifiedList.instrument:", 651 | " print i.code" 652 | ], 653 | "language": "python", 654 | "outputs": [ 655 | { 656 | "output_type": "stream", 657 | "stream": "stdout", 658 | "text": [ 659 | "CCI.N", 660 | "IBM.N", 661 | "STZ.N" 662 | ] 663 | } 664 | ], 665 | "prompt_number": 40 666 | }, 667 | { 668 | "cell_type": "code", 669 | "collapsed": true, 670 | "input": [ 671 | "print dm.api._client" 672 | ], 673 | "language": "python", 674 | "outputs": [ 675 | { 676 | "output_type": "stream", 677 | "stream": "stdout", 678 | "text": [ 679 | "", 680 | "Suds ( https://fedorahosted.org/suds/ ) version: 0.4 GA build: R699-20100913", 681 | "", 682 | "Service ( TRTHApiService ) tns=\"http://webservice.tickhistory.thomsonreuters.com\"", 683 | " Prefixes (1)", 684 | " ns0 = \"http://types.webservice.tickhistory.thomsonreuters.com\"", 685 | " Ports (1):", 686 | " (TRTHApi)", 687 | " Methods (29):", 688 | " CancelRequest(xs:string requestID, )", 689 | " CleanUp()", 690 | " ExpandChain(ns0:Instrument instrument, ns0:DateRange dateRange, ns0:TimeRange timeRange, xs:boolean requestInGMT, )", 691 | " GetAssetDomains()", 692 | " GetBondTypes()", 693 | " GetCountries()", 694 | " GetCreditRatings()", 695 | " GetCurrencies(ns0:ArrayOfData countryList, )", 696 | " GetExchanges(ns0:ArrayOfData domainList, )", 697 | " GetFuturesDeliveryMonths()", 698 | " GetInflightStatus()", 699 | " GetInstrumentTypes(ns0:ArrayOfData domainList, )", 700 | " GetMessageTypes(ns0:ArrayOfData domainList, ns0:RequestType requestType, )", 701 | " GetOptionExpiryMonths()", 702 | " GetPage(xs:string ric, xs:date requestDate, xs:string requestTime, )", 703 | " GetQuota()", 704 | " GetRICSymbology(ns0:Instrument instrument, ns0:DateRange dateRange, )", 705 | " GetRequestResult(xs:string requestID, )", 706 | " GetRestrictedPEs()", 707 | " GetSnapshotInfo()", 708 | " GetUsedInstruments(xs:int offset, xs:int length, )", 709 | " GetVersion()", 710 | " SearchPage(xs:string query, xs:int limit, )", 711 | " SearchRICs(ns0:DateRange dateRange, ns0:ArrayOfData criteria, xs:boolean refData, )", 712 | " SetFTPDetails(xs:string hostname, xs:string user, xs:string password, xs:string path, )", 713 | " SubmitFTPRequest(ns0:LargeRequestSpec request, )", 714 | " SubmitRequest(ns0:RequestSpec request, )", 715 | " TestFTP()", 716 | " VerifyRICs(ns0:DateRange dateRange, ns0:ArrayOfInstrument instrumentList, xs:boolean refData, )", 717 | " Types (32):", 718 | " ns0:ArrayOfData", 719 | " ns0:ArrayOfDate", 720 | " ns0:ArrayOfInstrument", 721 | " ns0:ArrayOfInt", 722 | " ns0:ArrayOfMessageType", 723 | " ns0:ArrayOfPage", 724 | " ns0:ArrayOfString", 725 | " ns0:CredentialsHeader", 726 | " ns0:Data", 727 | " ns0:DataType", 728 | " ns0:DateRange", 729 | " ns0:FieldType", 730 | " ns0:InflightStatus", 731 | " ns0:Instrument", 732 | " ns0:InstrumentStatus", 733 | " ns0:LargeRequestSpec", 734 | " ns0:MessageType", 735 | " ns0:Page", 736 | " ns0:Quota", 737 | " ns0:QuotaType", 738 | " ns0:RequestDateFormat", 739 | " ns0:RequestDelivery", 740 | " ns0:RequestFileFormat", 741 | " ns0:RequestResult", 742 | " ns0:RequestSortType", 743 | " ns0:RequestSpec", 744 | " ns0:RequestStatusCode", 745 | " ns0:RequestType", 746 | " ns0:TimeRange", 747 | " ns0:UsedInstruments", 748 | " ns0:VerifyRICsResult", 749 | " ns0:Version" 750 | ] 751 | } 752 | ], 753 | "prompt_number": 20 754 | }, 755 | { 756 | "cell_type": "code", 757 | "collapsed": false, 758 | "input": [ 759 | "dm.api._factory.ARRAY_MAP" 760 | ], 761 | "language": "python", 762 | "outputs": [ 763 | { 764 | "output_type": "pyout", 765 | "prompt_number": 22, 766 | "text": [ 767 | "{'Instrument': ('ArrayOfInstrument', 'instrument')}" 768 | ] 769 | } 770 | ], 771 | "prompt_number": 22 772 | }, 773 | { 774 | "cell_type": "code", 775 | "collapsed": true, 776 | "input": [ 777 | "ftpspec = dm.api._client.factory.create('ns0:LargeRequestSpec')" 778 | ], 779 | "language": "python", 780 | "outputs": [], 781 | "prompt_number": 104 782 | }, 783 | { 784 | "cell_type": "code", 785 | "collapsed": true, 786 | "input": [ 787 | "ftpspec" 788 | ], 789 | "language": "python", 790 | "outputs": [ 791 | { 792 | "output_type": "pyout", 793 | "prompt_number": 105, 794 | "text": [ 795 | "(LargeRequestSpec){", 796 | " friendlyName = None", 797 | " requestType = ", 798 | " (RequestType){", 799 | " value = None", 800 | " }", 801 | " instrumentList = ", 802 | " (ArrayOfInstrument){", 803 | " instrument[] = ", 804 | " }", 805 | " dateRange = ", 806 | " (DateRange){", 807 | " start = None", 808 | " end = None", 809 | " }", 810 | " timeRange = ", 811 | " (TimeRange){", 812 | " start = None", 813 | " end = None", 814 | " }", 815 | " messageTypeList = ", 816 | " (ArrayOfMessageType){", 817 | " messageType[] = ", 818 | " }", 819 | " requestInGMT = None", 820 | " displayInGMT = None", 821 | " marketDepth = None", 822 | " splitSize = None", 823 | " delivery = ", 824 | " (RequestDelivery){", 825 | " value = None", 826 | " }", 827 | " sortType = ", 828 | " (RequestSortType){", 829 | " value = None", 830 | " }", 831 | " fileFormat = ", 832 | " (RequestFileFormat){", 833 | " value = None", 834 | " }", 835 | " dateFormat = ", 836 | " (RequestDateFormat){", 837 | " value = None", 838 | " }", 839 | " disableDataPersistence = None", 840 | " includeCurrentRIC = None", 841 | " applyCorrections = None", 842 | " displayMicroseconds = None", 843 | " }" 844 | ] 845 | } 846 | ], 847 | "prompt_number": 105 848 | }, 849 | { 850 | "cell_type": "code", 851 | "collapsed": true, 852 | "input": [ 853 | "spec = dm.api._client.factory.create('ns0:RequestSpec')" 854 | ], 855 | "language": "python", 856 | "outputs": [], 857 | "prompt_number": 106 858 | }, 859 | { 860 | "cell_type": "code", 861 | "collapsed": true, 862 | "input": [ 863 | "spec" 864 | ], 865 | "language": "python", 866 | "outputs": [ 867 | { 868 | "output_type": "pyout", 869 | "prompt_number": 107, 870 | "text": [ 871 | "(RequestSpec){", 872 | " friendlyName = None", 873 | " requestType = ", 874 | " (RequestType){", 875 | " value = None", 876 | " }", 877 | " instrument = ", 878 | " (Instrument){", 879 | " code = None", 880 | " isin = ", 881 | " (ArrayOfString){", 882 | " string[] = ", 883 | " }", 884 | " cusip = ", 885 | " (ArrayOfString){", 886 | " string[] = ", 887 | " }", 888 | " sedol = ", 889 | " (ArrayOfString){", 890 | " string[] = ", 891 | " }", 892 | " gics = ", 893 | " (ArrayOfInt){", 894 | " int[] = ", 895 | " }", 896 | " dateRange = ", 897 | " (DateRange){", 898 | " start = None", 899 | " end = None", 900 | " }", 901 | " name = ", 902 | " (ArrayOfString){", 903 | " string[] = ", 904 | " }", 905 | " status = ", 906 | " (InstrumentStatus){", 907 | " value = None", 908 | " }", 909 | " statusInfo = None", 910 | " exchange = ", 911 | " (ArrayOfString){", 912 | " string[] = ", 913 | " }", 914 | " type = ", 915 | " (ArrayOfString){", 916 | " string[] = ", 917 | " }", 918 | " expiryDate = ", 919 | " (ArrayOfDate){", 920 | " dt[] = ", 921 | " }", 922 | " strikePrice = ", 923 | " (ArrayOfString){", 924 | " string[] = ", 925 | " }", 926 | " maturityDate = ", 927 | " (ArrayOfDate){", 928 | " dt[] = ", 929 | " }", 930 | " couponRate = ", 931 | " (ArrayOfString){", 932 | " string[] = ", 933 | " }", 934 | " bondType = ", 935 | " (ArrayOfString){", 936 | " string[] = ", 937 | " }", 938 | " creditRating = ", 939 | " (ArrayOfString){", 940 | " string[] = ", 941 | " }", 942 | " currency = ", 943 | " (ArrayOfString){", 944 | " string[] = ", 945 | " }", 946 | " optionType = ", 947 | " (ArrayOfString){", 948 | " string[] = ", 949 | " }", 950 | " peCode = ", 951 | " (ArrayOfString){", 952 | " string[] = ", 953 | " }", 954 | " underlyingRIC = ", 955 | " (ArrayOfString){", 956 | " string[] = ", 957 | " }", 958 | " }", 959 | " date = None", 960 | " timeRange = ", 961 | " (TimeRange){", 962 | " start = None", 963 | " end = None", 964 | " }", 965 | " messageTypeList = ", 966 | " (ArrayOfMessageType){", 967 | " messageType[] = ", 968 | " }", 969 | " requestInGMT = None", 970 | " displayInGMT = None", 971 | " disableHeader = None", 972 | " marketDepth = None", 973 | " dateFormat = ", 974 | " (RequestDateFormat){", 975 | " value = None", 976 | " }", 977 | " disableDataPersistence = None", 978 | " includeCurrentRIC = None", 979 | " applyCorrections = None", 980 | " displayMicroseconds = None", 981 | " }" 982 | ] 983 | } 984 | ], 985 | "prompt_number": 107 986 | }, 987 | { 988 | "cell_type": "code", 989 | "collapsed": false, 990 | "input": [ 991 | "cd trth" 992 | ], 993 | "language": "python", 994 | "outputs": [ 995 | { 996 | "output_type": "stream", 997 | "stream": "stdout", 998 | "text": [ 999 | "/home/mchan/git/Artemis/brotchie-pytrth-381894a/trth" 1000 | ] 1001 | } 1002 | ], 1003 | "prompt_number": 159 1004 | }, 1005 | { 1006 | "cell_type": "code", 1007 | "collapsed": true, 1008 | "input": [ 1009 | "import requestftp" 1010 | ], 1011 | "language": "python", 1012 | "outputs": [], 1013 | "prompt_number": 160 1014 | }, 1015 | { 1016 | "cell_type": "code", 1017 | "collapsed": true, 1018 | "input": [ 1019 | "import api", 1020 | "trth = api.TRTHApi()", 1021 | "trth.setup()", 1022 | "template = requestftp.RequestTemplate('../templates/intradayFTP.yaml')", 1023 | "request = requestftp.RequestFTP(template, 'myFTP1', ['MSFT.O', 'AMZN.O', 'LSI.N', 'B.N', 'BA.N'], ['2012-06-01', '2012-06-07'], ('0:00', '23:59:59.999'), 'msft.csv')" 1024 | ], 1025 | "language": "python", 1026 | "outputs": [], 1027 | "prompt_number": 162 1028 | }, 1029 | { 1030 | "cell_type": "code", 1031 | "collapsed": true, 1032 | "input": [ 1033 | "id1 = trth.SubmitFTPRequest(request.generateLargeRequestSpec(trth))" 1034 | ], 1035 | "language": "python", 1036 | "outputs": [], 1037 | "prompt_number": 172 1038 | }, 1039 | { 1040 | "cell_type": "code", 1041 | "collapsed": false, 1042 | "input": [ 1043 | "id1" 1044 | ], 1045 | "language": "python", 1046 | "outputs": [ 1047 | { 1048 | "output_type": "pyout", 1049 | "prompt_number": 173, 1050 | "text": [ 1051 | "StarMineQSE@thomsonreuters.com-myFTP1-N39574595" 1052 | ] 1053 | } 1054 | ], 1055 | "prompt_number": 173 1056 | }, 1057 | { 1058 | "cell_type": "code", 1059 | "collapsed": false, 1060 | "input": [ 1061 | "trth.GetRequestResult(id1)" 1062 | ], 1063 | "language": "python", 1064 | "outputs": [ 1065 | { 1066 | "output_type": "pyout", 1067 | "prompt_number": 175, 1068 | "text": [ 1069 | "(RequestResult){", 1070 | " status = \"Complete\"", 1071 | " data = None", 1072 | " queuePosition = 0", 1073 | " }" 1074 | ] 1075 | } 1076 | ], 1077 | "prompt_number": 175 1078 | }, 1079 | { 1080 | "cell_type": "code", 1081 | "collapsed": true, 1082 | "input": [ 1083 | "trth.CancelRequest(id1)" 1084 | ], 1085 | "language": "python", 1086 | "outputs": [], 1087 | "prompt_number": 167 1088 | }, 1089 | { 1090 | "cell_type": "code", 1091 | "collapsed": true, 1092 | "input": [ 1093 | "trth.SetFTPDetails(\"76.77.185.0\", \"ftpuser\", \"xjusp75hte\", \"xfer\")" 1094 | ], 1095 | "language": "python", 1096 | "outputs": [], 1097 | "prompt_number": 170 1098 | }, 1099 | { 1100 | "cell_type": "code", 1101 | "collapsed": true, 1102 | "input": [ 1103 | "trth.TestFTP()" 1104 | ], 1105 | "language": "python", 1106 | "outputs": [], 1107 | "prompt_number": 171 1108 | }, 1109 | { 1110 | "cell_type": "code", 1111 | "collapsed": false, 1112 | "input": [ 1113 | "db = dbutil.db(h='127.0.0.1', schema='mchan')", 1114 | "db.query(\"show tables;\")" 1115 | ], 1116 | "language": "python", 1117 | "outputs": [ 1118 | { 1119 | "output_type": "pyout", 1120 | "prompt_number": 259, 1121 | "text": [ 1122 | "[['consensus_quant'],", 1123 | " ['earnings'],", 1124 | " ['earnings_clean'],", 1125 | " ['earnings_clean_pt2'],", 1126 | " ['earnings_test'],", 1127 | " ['eq_daily'],", 1128 | " ['flyonthewall'],", 1129 | " ['flyonthewall2'],", 1130 | " ['mapping'],", 1131 | " ['mapping2'],", 1132 | " ['pricing1'],", 1133 | " ['pricing1Min'],", 1134 | " ['pricing1Sec'],", 1135 | " ['pricing1Sec_pt2'],", 1136 | " ['pricing_test'],", 1137 | " ['research_mapping_ds2'],", 1138 | " ['security_price'],", 1139 | " ['s_daily']]" 1140 | ] 1141 | } 1142 | ], 1143 | "prompt_number": 259 1144 | }, 1145 | { 1146 | "cell_type": "code", 1147 | "collapsed": true, 1148 | "input": [ 1149 | "tickerArray = db.query(\"\"\"SELECT DISTINCT(ticker) FROM mchan.earnings_clean_pt2 ", 1150 | " WHERE date(release_date) < '2012-08-11' ", 1151 | " AND date(release_date) > '2012-08-05'\"\"\")" 1152 | ], 1153 | "language": "python", 1154 | "outputs": [], 1155 | "prompt_number": 242 1156 | }, 1157 | { 1158 | "cell_type": "code", 1159 | "collapsed": true, 1160 | "input": [ 1161 | "tickerArray0 = db.query(\"\"\"SELECT DISTINCT(ticker) FROM mchan.earnings_clean_pt2 WHERE date(release_date) < '2012-07-28' AND date(release_date) >= '2012-07-22'\"\"\")", 1162 | "# Check for overlaps", 1163 | "#tickerArray0", 1164 | "tickerList0 = []", 1165 | "for i in tickerArray0:", 1166 | " tickerList.append(i[0])", 1167 | "for i in tickerList0:", 1168 | " if i in tickerList:", 1169 | " print i" 1170 | ], 1171 | "language": "python", 1172 | "outputs": [], 1173 | "prompt_number": 226 1174 | }, 1175 | { 1176 | "cell_type": "code", 1177 | "collapsed": true, 1178 | "input": [ 1179 | "tickerList = []", 1180 | "for i in tickerArray:", 1181 | " tickerList.append(i[0])" 1182 | ], 1183 | "language": "python", 1184 | "outputs": [], 1185 | "prompt_number": 243 1186 | }, 1187 | { 1188 | "cell_type": "code", 1189 | "collapsed": false, 1190 | "input": [ 1191 | "len(tickerList)" 1192 | ], 1193 | "language": "python", 1194 | "outputs": [ 1195 | { 1196 | "output_type": "pyout", 1197 | "prompt_number": 244, 1198 | "text": [ 1199 | "162" 1200 | ] 1201 | } 1202 | ], 1203 | "prompt_number": 244 1204 | }, 1205 | { 1206 | "cell_type": "code", 1207 | "collapsed": true, 1208 | "input": [ 1209 | "import DownloadData", 1210 | "reload(DownloadData)", 1211 | "dm = DownloadData.DownloadManager(trth)" 1212 | ], 1213 | "language": "python", 1214 | "outputs": [], 1215 | "prompt_number": 213 1216 | }, 1217 | { 1218 | "cell_type": "code", 1219 | "collapsed": true, 1220 | "input": [ 1221 | "ricList = dm.Tic2Ric(tickerList)" 1222 | ], 1223 | "language": "python", 1224 | "outputs": [], 1225 | "prompt_number": 245 1226 | }, 1227 | { 1228 | "cell_type": "code", 1229 | "collapsed": true, 1230 | "input": [ 1231 | "ricList" 1232 | ], 1233 | "language": "python", 1234 | "outputs": [ 1235 | { 1236 | "output_type": "pyout", 1237 | "prompt_number": 246, 1238 | "text": [ 1239 | "{u'AAP': 'AAP.N',", 1240 | " u'ACCO': 'ACCO.N',", 1241 | " u'AH': 'AH.N',", 1242 | " u'AIT': 'AIT.N',", 1243 | " u'AMED': 'AMED.O',", 1244 | " u'ANEN': 'ANEN.O',", 1245 | " u'APEI': 'APEI.O',", 1246 | " u'AQ': 'AQ.N',", 1247 | " u'ASYS': 'ASYS.O',", 1248 | " u'ATEC': 'ATEC.O',", 1249 | " u'AVT': 'AVT.N',", 1250 | " u'BEE': 'BEE.N',", 1251 | " u'BGG': 'BGG.N',", 1252 | " u'BIOL': 'BIOL.O',", 1253 | " u'BITA': 'BITA.N',", 1254 | " u'BKI': 'BKI.N',", 1255 | " u'BORN': 'BORN.N',", 1256 | " u'BR': 'BR.N',", 1257 | " u'BSFT': 'BSFT.O',", 1258 | " u'BXP': 'BXP.N',", 1259 | " u'CAT': 'CAT.N',", 1260 | " u'CBB': 'CBB.N',", 1261 | " u'CBOU': 'CBOU.O',", 1262 | " u'CCIX': 'CCIX.O',", 1263 | " u'CCRN': 'CCRN.O',", 1264 | " u'CFN': 'CFN.N',", 1265 | " u'CHD': 'CHD.N',", 1266 | " u'CLDT': 'CLDT.N',", 1267 | " u'CLH': 'CLH.N',", 1268 | " u'CREE': 'CREE.O',", 1269 | " u'CSC': 'CSC.N',", 1270 | " u'CSGS': 'CSGS.O',", 1271 | " u'CSII': 'CSII.O',", 1272 | " u'CTL': 'CTL.N',", 1273 | " u'CTSH': 'CTSH.O',", 1274 | " u'CVS': 'CVS.N',", 1275 | " u'CWST': 'CWST.O',", 1276 | " u'CXW': 'CXW.N',", 1277 | " u'CYOU': 'CYOU.O',", 1278 | " u'DF': 'DF.N',", 1279 | " u'DIOD': 'DIOD.O',", 1280 | " u'DMD': 'DMD.N',", 1281 | " u'DRQ': 'DRQ.N',", 1282 | " u'DTSI': 'DTSI.O',", 1283 | " u'EAT': 'EAT.N',", 1284 | " u'EDMC': 'EDMC.O',", 1285 | " u'ELON': 'ELON.O',", 1286 | " u'ELX': 'ELX.N',", 1287 | " u'EMKR': 'EMKR.O',", 1288 | " u'EMR': 'EMR.N',", 1289 | " u'ENDP': 'ENDP.O',", 1290 | " u'ENOC': 'ENOC.O',", 1291 | " u'ENPH': 'ENPH.O',", 1292 | " u'ENS': 'ENS.N',", 1293 | " u'EPOC': 'EPOC.O',", 1294 | " u'ESL': 'ESL.N',", 1295 | " u'ET': 'ET.N',", 1296 | " u'FLDM': 'FLDM.O',", 1297 | " u'FOSL': 'FOSL.O',", 1298 | " u'FSIN': 'FSIN.O',", 1299 | " u'FSYS': 'FSYS.O',", 1300 | " u'GEO': 'GEO.N',", 1301 | " u'GEOY': 'GEOY.O',", 1302 | " u'GHDX': 'GHDX.O',", 1303 | " u'GIVN': 'GIVN.O',", 1304 | " u'HCA': 'HCA.N',", 1305 | " u'HILL': 'HILL.O',", 1306 | " u'HIMX': 'HIMX.O',", 1307 | " u'HMIN': 'HMIN.O',", 1308 | " u'HSFT': 'HSFT.O',", 1309 | " u'HSH': 'HSH.N',", 1310 | " u'IL': 'IL.N',", 1311 | " u'IMPV': 'IMPV.N',", 1312 | " u'INVE': 'INVE.O',", 1313 | " u'JACK': 'JACK.O',", 1314 | " u'JDAS': 'JDAS.O',", 1315 | " u'JIVE': 'JIVE.O',", 1316 | " u'JOBS': 'JOBS.O',", 1317 | " u'JWN': 'JWN.N',", 1318 | " u'KAR': 'KAR.N',", 1319 | " u'KNXA': 'KNXA.N',", 1320 | " u'KSS': 'KSS.N',", 1321 | " u'LAMR': 'LAMR.O',", 1322 | " u'LIOX': 'LIOX.O',", 1323 | " u'LNCE': 'LNCE.O',", 1324 | " u'LOCM': 'LOCM.O',", 1325 | " u'LOPE': 'LOPE.O',", 1326 | " u'LTC': 'LTC.N',", 1327 | " u'MATR': 'MATR.O',", 1328 | " u'MFB': 'MFB.N',", 1329 | " u'MG': 'MG.N',", 1330 | " u'MKTG': 'MKTG.O',", 1331 | " u'MM': 'MM.N',", 1332 | " u'MOD': 'MOD.N',", 1333 | " u'MRC': 'MRC.N',", 1334 | " u'MRX': 'MRX.N',", 1335 | " u'NQ': 'NQ.N',", 1336 | " u'NRP': 'NRP.N',", 1337 | " u'NVDA': 'NVDA.O',", 1338 | " u'NVTL': 'NVTL.O',", 1339 | " u'NXTM': 'NXTM.O',", 1340 | " u'OSIS': 'OSIS.O',", 1341 | " u'OWW': 'OWW.N',", 1342 | " u'PCLN': 'PCLN.O',", 1343 | " u'PFPT': 'PFPT.O',", 1344 | " u'PHMD': 'PHMD.O',", 1345 | " u'PKY': 'PKY.N',", 1346 | " u'PLOW': 'PLOW.N',", 1347 | " u'PLT': 'PLT.N',", 1348 | " u'PODD': 'PODD.O',", 1349 | " u'POM': 'POM.N',", 1350 | " u'POWI': 'POWI.O',", 1351 | " u'POWL': 'POWL.O',", 1352 | " u'PRMW': 'PRMW.O',", 1353 | " u'PRXL': 'PRXL.O',", 1354 | " u'PSEM': 'PSEM.O',", 1355 | " u'PULS': 'PULS.N',", 1356 | " u'RDA': 'RDA.O',", 1357 | " u'RDEN': 'RDEN.O',", 1358 | " u'RENN': 'RENN.N',", 1359 | " u'RNDY': 'RNDY.N',", 1360 | " u'RRST': 'RRST.O',", 1361 | " u'SATC': 'SATC.O',", 1362 | " u'SEM': 'SEM.N',", 1363 | " u'SGI': 'SGI.O',", 1364 | " u'SIRI': 'SIRI.O',", 1365 | " u'SKH': 'SKH.N',", 1366 | " u'SLXP': 'SLXP.O',", 1367 | " u'SMCI': 'SMCI.O',", 1368 | " u'SMI': 'SMI.N',", 1369 | " u'SNHY': 'SNHY.O',", 1370 | " u'SNMX': 'SNMX.O',", 1371 | " u'SNTS': 'SNTS.O',", 1372 | " u'SOHU': 'SOHU.O',", 1373 | " u'SONS': 'SONS.O',", 1374 | " u'SPRD': 'SPRD.O',", 1375 | " u'SPWR': 'SPWR.O',", 1376 | " u'SRI': 'SRI.N',", 1377 | " u'SRPT': 'SRPT.O',", 1378 | " u'SSNC': 'SSNC.O',", 1379 | " u'STAN': 'STAN.O',", 1380 | " u'STEC': 'STEC.O',", 1381 | " u'STRI': 'STRI.N',", 1382 | " u'SVN': 'SVN.N',", 1383 | " u'SYKE': 'SYKE.O',", 1384 | " u'TNGO': 'TNGO.O',", 1385 | " u'TOWR': 'TOWR.N',", 1386 | " u'TRNX': 'TRNX.O',", 1387 | " u'TSN': 'TSN.N',", 1388 | " u'TTGT': 'TTGT.O',", 1389 | " u'TUMI': 'TUMI.N',", 1390 | " u'UBNT': 'UBNT.O',", 1391 | " u'UGI': 'UGI.N',", 1392 | " u'UNTK': 'UNTK.O',", 1393 | " u'VIPS': 'VIPS.N',", 1394 | " u'VIT': 'VIT.N',", 1395 | " u'VTSS': 'VTSS.O',", 1396 | " u'WIFI': 'WIFI.O',", 1397 | " u'WRC': 'WRC.N',", 1398 | " u'XIN': 'XIN.N',", 1399 | " u'YOKU': 'YOKU.N',", 1400 | " u'Z': 'Z.O'}" 1401 | ] 1402 | } 1403 | ], 1404 | "prompt_number": 246 1405 | }, 1406 | { 1407 | "cell_type": "code", 1408 | "collapsed": false, 1409 | "input": [ 1410 | "len(ricList.values())" 1411 | ], 1412 | "language": "python", 1413 | "outputs": [ 1414 | { 1415 | "output_type": "pyout", 1416 | "prompt_number": 247, 1417 | "text": [ 1418 | "162" 1419 | ] 1420 | } 1421 | ], 1422 | "prompt_number": 247 1423 | }, 1424 | { 1425 | "cell_type": "code", 1426 | "collapsed": true, 1427 | "input": [ 1428 | "request = requestftp.RequestFTP(template, 'myFTP1', ricList.values(), ['2012-08-06', '2012-08-13'], ('0:00', '23:59:59.999'), 'myFTP.csv')" 1429 | ], 1430 | "language": "python", 1431 | "outputs": [], 1432 | "prompt_number": 248 1433 | }, 1434 | { 1435 | "cell_type": "code", 1436 | "collapsed": true, 1437 | "input": [ 1438 | "id1 = trth.SubmitFTPRequest(request.generateLargeRequestSpec(trth))" 1439 | ], 1440 | "language": "python", 1441 | "outputs": [], 1442 | "prompt_number": 249 1443 | }, 1444 | { 1445 | "cell_type": "code", 1446 | "collapsed": false, 1447 | "input": [ 1448 | "trth.GetRequestResult(id1)" 1449 | ], 1450 | "language": "python", 1451 | "outputs": [ 1452 | { 1453 | "output_type": "pyout", 1454 | "prompt_number": 253, 1455 | "text": [ 1456 | "(RequestResult){", 1457 | " status = \"Complete\"", 1458 | " data = None", 1459 | " queuePosition = 0", 1460 | " }" 1461 | ] 1462 | } 1463 | ], 1464 | "prompt_number": 253 1465 | }, 1466 | { 1467 | "cell_type": "code", 1468 | "collapsed": false, 1469 | "input": [ 1470 | "id1" 1471 | ], 1472 | "language": "python", 1473 | "outputs": [ 1474 | { 1475 | "output_type": "pyout", 1476 | "prompt_number": 251, 1477 | "text": [ 1478 | "StarMineQSE@thomsonreuters.com-myFTP1-N39761145" 1479 | ] 1480 | } 1481 | ], 1482 | "prompt_number": 251 1483 | }, 1484 | { 1485 | "cell_type": "markdown", 1486 | "source": [ 1487 | "#Now load the files into MySQL" 1488 | ] 1489 | }, 1490 | { 1491 | "cell_type": "code", 1492 | "collapsed": true, 1493 | "input": [ 1494 | "f = file('/var/ftp/xfer/StarMineQSE@thomsonreuters.com-myFTP1-N39761145.csv')" 1495 | ], 1496 | "language": "python", 1497 | "outputs": [], 1498 | "prompt_number": 275 1499 | }, 1500 | { 1501 | "cell_type": "code", 1502 | "collapsed": true, 1503 | "input": [ 1504 | "csvData = f.readlines()" 1505 | ], 1506 | "language": "python", 1507 | "outputs": [], 1508 | "prompt_number": 276 1509 | }, 1510 | { 1511 | "cell_type": "code", 1512 | "collapsed": false, 1513 | "input": [ 1514 | "pricetable = 'pricing1Sec_pt2'", 1515 | "for i in range(1,len(csvData)):", 1516 | " if mod(i, 100000) == 0:", 1517 | " print i", 1518 | " row = csvData[i]", 1519 | " row = row.split(\",\")", 1520 | " db.execute(\"INSERT IGNORE INTO %s VALUES ('%s', '%s', '%s', %i, %f, %i);\"\"\" % (pricetable, \\", 1521 | " row[0].split(\".\")[0], row[1], row[2].split(\".\")[0], int(row[2].split(\".\")[1]), float(row[5]), int(row[6])))", 1522 | "", 1523 | "db.commit()" 1524 | ], 1525 | "language": "python", 1526 | "outputs": [ 1527 | { 1528 | "output_type": "stream", 1529 | "stream": "stdout", 1530 | "text": [ 1531 | "100000", 1532 | "200000" 1533 | ] 1534 | }, 1535 | { 1536 | "output_type": "stream", 1537 | "stream": "stdout", 1538 | "text": [ 1539 | "", 1540 | "300000" 1541 | ] 1542 | }, 1543 | { 1544 | "output_type": "stream", 1545 | "stream": "stdout", 1546 | "text": [ 1547 | "", 1548 | "400000" 1549 | ] 1550 | }, 1551 | { 1552 | "output_type": "stream", 1553 | "stream": "stdout", 1554 | "text": [ 1555 | "", 1556 | "500000" 1557 | ] 1558 | }, 1559 | { 1560 | "output_type": "stream", 1561 | "stream": "stdout", 1562 | "text": [ 1563 | "", 1564 | "600000" 1565 | ] 1566 | }, 1567 | { 1568 | "output_type": "stream", 1569 | "stream": "stdout", 1570 | "text": [ 1571 | "", 1572 | "700000" 1573 | ] 1574 | }, 1575 | { 1576 | "output_type": "stream", 1577 | "stream": "stdout", 1578 | "text": [ 1579 | "", 1580 | "800000" 1581 | ] 1582 | }, 1583 | { 1584 | "output_type": "stream", 1585 | "stream": "stdout", 1586 | "text": [ 1587 | "", 1588 | "900000" 1589 | ] 1590 | }, 1591 | { 1592 | "output_type": "stream", 1593 | "stream": "stdout", 1594 | "text": [ 1595 | "" 1596 | ] 1597 | } 1598 | ], 1599 | "prompt_number": 278 1600 | }, 1601 | { 1602 | "cell_type": "code", 1603 | "collapsed": false, 1604 | "input": [ 1605 | "len(csvData)" 1606 | ], 1607 | "language": "python", 1608 | "outputs": [ 1609 | { 1610 | "output_type": "pyout", 1611 | "prompt_number": 277, 1612 | "text": [ 1613 | "972771" 1614 | ] 1615 | } 1616 | ], 1617 | "prompt_number": 277 1618 | }, 1619 | { 1620 | "cell_type": "code", 1621 | "collapsed": false, 1622 | "input": [ 1623 | "mod(200000,100000)" 1624 | ], 1625 | "language": "python", 1626 | "outputs": [ 1627 | { 1628 | "output_type": "pyout", 1629 | "prompt_number": 263, 1630 | "text": [ 1631 | "0" 1632 | ] 1633 | } 1634 | ], 1635 | "prompt_number": 263 1636 | }, 1637 | { 1638 | "cell_type": "markdown", 1639 | "source": [ 1640 | "", 1641 | "1 mchan mchan 6.9M Aug 14 20:27 StarMineQSE@thomsonreuters.com-myFTP1-N39574595.csv", 1642 | "", 1643 | "", 1644 | "1 mchan mchan 135M Aug 14 21:57 StarMineQSE@thomsonreuters.com-myFTP1-N39578433.csv", 1645 | "", 1646 | "", 1647 | "1 ftpuser ftpuser 126M Aug 16 13:10 StarMineQSE@thomsonreuters.com-myFTP1-N39636065.csv", 1648 | "", 1649 | "", 1650 | "1 ftpuser ftpuser 194M Aug 16 13:47 StarMineQSE@thomsonreuters.com-myFTP1-N39637209.csv", 1651 | "", 1652 | "", 1653 | "1 ftpuser ftpuser 57M Aug 17 08:43 StarMineQSE@thomsonreuters.com-myFTP1-N39761145.csv" 1654 | ] 1655 | } 1656 | ] 1657 | } 1658 | ] 1659 | } -------------------------------------------------------------------------------- /IPynb/Untitled0.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "metadata": { 3 | "name": "Untitled0" 4 | }, 5 | "nbformat": 2, 6 | "worksheets": [] 7 | } -------------------------------------------------------------------------------- /IPynb/Untitled1.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "metadata": { 3 | "name": "Untitled1" 4 | }, 5 | "nbformat": 2, 6 | "worksheets": [] 7 | } -------------------------------------------------------------------------------- /IPynb/Untitled2.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "metadata": { 3 | "name": "Untitled2" 4 | }, 5 | "nbformat": 2, 6 | "worksheets": [] 7 | } -------------------------------------------------------------------------------- /IPynb/earnings_analysisv3.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "metadata": { 3 | "name": "earnings_analysisv3" 4 | }, 5 | "nbformat": 2, 6 | "worksheets": [ 7 | { 8 | "cells": [ 9 | { 10 | "cell_type": "code", 11 | "collapsed": true, 12 | "input": [ 13 | "import sys", 14 | "sys.path.append('/home/mchan/git/Artemis/brotchie-pytrth-381894a/trth/')", 15 | "sys.path.append('/home/mchan/git/Artemis/util/')", 16 | "import dbutil", 17 | "import re", 18 | "import pandas", 19 | "import pandas.io.sql", 20 | "import matplotlib.pyplot as plt", 21 | "import datetime", 22 | "from pandas.tseries.offsets import *", 23 | "import random" 24 | ], 25 | "language": "python", 26 | "outputs": [], 27 | "prompt_number": 1 28 | }, 29 | { 30 | "cell_type": "code", 31 | "collapsed": false, 32 | "input": [ 33 | "db = dbutil.db(h='127.0.0.1', schema='mchan')", 34 | "db.query(\"show tables;\")" 35 | ], 36 | "language": "python", 37 | "outputs": [ 38 | { 39 | "output_type": "pyout", 40 | "prompt_number": 70, 41 | "text": [ 42 | "[['consensus_quant'],", 43 | " ['consensus_quant_backup'],", 44 | " ['earnings'],", 45 | " ['earnings_clean'],", 46 | " ['earnings_clean_pt2'],", 47 | " ['earnings_test'],", 48 | " ['eq_daily'],", 49 | " ['flyonthewall'],", 50 | " ['flyonthewall2'],", 51 | " ['mapping'],", 52 | " ['mapping2'],", 53 | " ['pricing1'],", 54 | " ['pricing1Min'],", 55 | " ['pricing1Sec'],", 56 | " ['pricing1Sec_pt2'],", 57 | " ['pricing_test'],", 58 | " ['research_mapping_ds2'],", 59 | " ['security_price'],", 60 | " ['s_daily']]" 61 | ] 62 | } 63 | ], 64 | "prompt_number": 70 65 | }, 66 | { 67 | "cell_type": "code", 68 | "collapsed": true, 69 | "input": [ 70 | "PosEarnings = db.query(\"\"\"select e.*, q.*, m.name, d.*, s.market_cap_usd_mm from mchan.earnings_clean e", 71 | " inner join mchan.consensus_quant q", 72 | " on e.id = q.id", 73 | " inner join mchan.mapping m", 74 | " on m.ticker = e.ticker", 75 | " inner join mchan.security_price s", 76 | " on s.security_id = m.security_id", 77 | " inner join mchan.s_daily d", 78 | " on m.security_id = d.security_id", 79 | " and date(e.release_date) = d.as_of_date", 80 | " where q.outperform > 0.01", 81 | " and e.headline like '%see%'", 82 | " and e.headline not like '%adjusted%';\"\"\")" 83 | ], 84 | "language": "python", 85 | "outputs": [], 86 | "prompt_number": 36 87 | }, 88 | { 89 | "cell_type": "code", 90 | "collapsed": true, 91 | "input": [ 92 | "PosEarnings = db.query(\"\"\"select e.*, q.*, m.name, d.*, s.market_cap_usd_mm from mchan.earnings_clean e", 93 | " inner join mchan.consensus_quant q", 94 | " on e.id = q.id", 95 | " inner join mchan.mapping m", 96 | " on m.ticker = e.ticker", 97 | " inner join mchan.security_price s", 98 | " on s.security_id = m.security_id", 99 | " inner join mchan.s_daily d", 100 | " on m.security_id = d.security_id", 101 | " and date(e.release_date) = d.as_of_date", 102 | " where q.outperform > 0.03", 103 | " and q.outperform < 2", 104 | " and e.headline like '%see%'", 105 | " and e.headline not like '%adjusted%'", 106 | " and e.headline not like '%c)%'", 107 | " and s.market_cap_usd_mm < 5000", 108 | " and s.market_cap_usd_mm > 500", 109 | " and d.eq_region_rank > 10;\"\"\")" 110 | ], 111 | "language": "python", 112 | "outputs": [], 113 | "prompt_number": 77 114 | }, 115 | { 116 | "cell_type": "code", 117 | "collapsed": false, 118 | "input": [ 119 | "PosEarnings2 = PosEarnings", 120 | "len(PosEarnings)" 121 | ], 122 | "language": "python", 123 | "outputs": [ 124 | { 125 | "output_type": "pyout", 126 | "prompt_number": 79, 127 | "text": [ 128 | "46" 129 | ] 130 | } 131 | ], 132 | "prompt_number": 79 133 | }, 134 | { 135 | "cell_type": "code", 136 | "collapsed": true, 137 | "input": [ 138 | "PosEarnings2 = []", 139 | "for row in PosEarnings:", 140 | " count = 0", 141 | " for el in row[14:21]:", 142 | " count = count + 1 if el > 70 else count", 143 | " if count > 2:", 144 | " PosEarnings2.append(row)", 145 | " elif row[14] > 90:", 146 | " PosEarnings2.append(row)", 147 | " " 148 | ], 149 | "language": "python", 150 | "outputs": [], 151 | "prompt_number": 65 152 | }, 153 | { 154 | "cell_type": "code", 155 | "collapsed": false, 156 | "input": [ 157 | "len(PosEarnings2)" 158 | ], 159 | "language": "python", 160 | "outputs": [ 161 | { 162 | "output_type": "pyout", 163 | "prompt_number": 66, 164 | "text": [ 165 | "47" 166 | ] 167 | } 168 | ], 169 | "prompt_number": 66 170 | }, 171 | { 172 | "cell_type": "code", 173 | "collapsed": false, 174 | "input": [ 175 | "pricesDF = pandas.DataFrame()", 176 | "for j in range(len(PosEarnings2)):", 177 | " tEvent = PosEarnings2[j][2]", 178 | " ticker = PosEarnings2[j][1]", 179 | " #tStart = tEvent + datetime.timedelta(seconds=-3600)", 180 | " tStart = tEvent + datetime.timedelta(seconds=0)", 181 | " tEnd = tEvent + datetime.timedelta(hours=24)", 182 | " dataPrices = db.query(\"\"\"select ticker, timestamp(date, time), last, volume from pricing1Sec where ticker = '%s'", 183 | " and timestamp(date,time) >= '%s'", 184 | " and timestamp(date,time) <= '%s';\"\"\" % (ticker, tStart.isoformat(), tEnd.isoformat()) )", 185 | " if len(dataPrices) == 0:", 186 | " continue", 187 | " #print dataPrices", 188 | " tOpening = dataPrices[0][1]", 189 | " for row in dataPrices:", 190 | " if tOpening < tEvent:", 191 | " delta = row[1] - tEvent", 192 | " else:", 193 | " delta = row[1] - tOpening", 194 | " row[1] = datetime.datetime(2012, 1, 1, 0, 0, 0) + delta", 195 | " if ticker not in pricesDF:", 196 | " print \"Ticker: \", ticker, \"Start: \", tStart, \" End: \", tEnd ,\" Event: \", tEvent, \" Opening: \", tOpening", 197 | " #print dataPrices[0], ticker", 198 | " dataPrices2 = pandas.DataFrame.from_records(dataPrices, index='datetime', columns=['ticker', 'datetime', dataPrices[0][0], 'volume'])", 199 | " del dataPrices2['ticker']; del dataPrices2['volume']", 200 | " del dataPrices", 201 | " pricesDF = pricesDF.join(dataPrices2, how=\"outer\")", 202 | "", 203 | "pricesDF = pricesDF.pct_change()", 204 | "for col in pricesDF:", 205 | " pricesDF[col][1:] += 1", 206 | " pricesDF[col][0] = 1", 207 | "pricesDF = pricesDF.cumprod()", 208 | "pricesDF = pricesDF.fillna(method='pad')" 209 | ], 210 | "language": "python", 211 | "outputs": [ 212 | { 213 | "output_type": "stream", 214 | "stream": "stdout", 215 | "text": [ 216 | "Ticker: ASGN Start: 2012-04-26 16:15:54 End: 2012-04-27 16:15:54 Event: 2012-04-26 16:15:54 Opening: 2012-04-26 16:17:48", 217 | "Ticker: BHE Start: 2012-04-26 07:19:58 End: 2012-04-27 07:19:58 Event: 2012-04-26 07:19:58 Opening: 2012-04-26 09:30:01", 218 | "Ticker: BOBE Start: 2012-06-05 16:15:31 End: 2012-06-06 16:15:31 Event: 2012-06-05 16:15:31 Opening: 2012-06-05 16:20:29", 219 | "Ticker: " 220 | ] 221 | }, 222 | { 223 | "output_type": "stream", 224 | "stream": "stdout", 225 | "text": [ 226 | " CACI Start: 2012-06-06 16:29:55 End: 2012-06-07 16:29:55 Event: 2012-06-06 16:29:55 Opening: 2012-06-07 09:31:51", 227 | "Ticker: CLGX Start: 2012-04-25 16:47:18 End: 2012-04-26 16:47:18 Event: 2012-04-25 16:47:18 Opening: 2012-04-26 09:30:13", 228 | "Ticker: JACK Start: 2012-05-16 16:07:07 End: 2012-05-17 16:07:07 Event: 2012-05-16 16:07:07 Opening: 2012-05-16 16:47:21", 229 | "Ticker: " 230 | ] 231 | }, 232 | { 233 | "output_type": "stream", 234 | "stream": "stdout", 235 | "text": [ 236 | " GWR Start: 2012-05-01 06:03:09 End: 2012-05-02 06:03:09 Event: 2012-05-01 06:03:09 Opening: 2012-05-01 09:32:24", 237 | "Ticker: KLIC Start: 2012-05-01 07:02:22 End: 2012-05-02 07:02:22 Event: 2012-05-01 07:02:22 Opening: 2012-05-01 08:01:48", 238 | "Ticker: " 239 | ] 240 | }, 241 | { 242 | "output_type": "stream", 243 | "stream": "stdout", 244 | "text": [ 245 | " MCRL Start: 2012-04-26 16:31:32 End: 2012-04-27 16:31:32 Event: 2012-04-26 16:31:32 Opening: 2012-04-26 16:31:56", 246 | "Ticker: MTOR Start: 2012-05-02 08:03:54 End: 2012-05-03 08:03:54 Event: 2012-05-02 08:03:54 Opening: 2012-05-02 09:32:44", 247 | "Ticker: MSCC Start: 2012-04-25 16:09:57 End: 2012-04-26 16:09:57 Event: 2012-04-25 16:09:57 Opening: 2012-04-25 16:15:24", 248 | "Ticker: " 249 | ] 250 | }, 251 | { 252 | "output_type": "stream", 253 | "stream": "stdout", 254 | "text": [ 255 | " NDSN Start: 2012-05-21 16:36:35 End: 2012-05-22 16:36:35 Event: 2012-05-21 16:36:35 Opening: 2012-05-21 16:40:14", 256 | "Ticker: NUS Start: 2012-04-26 07:55:30 End: 2012-04-27 07:55:30 Event: 2012-04-26 07:55:30 Opening: 2012-04-26 09:30:31", 257 | "Ticker: " 258 | ] 259 | }, 260 | { 261 | "output_type": "stream", 262 | "stream": "stdout", 263 | "text": [ 264 | " POWI Start: 2012-05-03 16:24:43 End: 2012-05-04 16:24:43 Event: 2012-05-03 16:24:43 Opening: 2012-05-03 16:33:14", 265 | "Ticker: SHAW Start: 2012-05-21 16:38:33 End: 2012-05-22 16:38:33 Event: 2012-05-21 16:38:33 Opening: 2012-05-22 09:30:01", 266 | "Ticker: " 267 | ] 268 | }, 269 | { 270 | "output_type": "stream", 271 | "stream": "stdout", 272 | "text": [ 273 | " SNPS Start: 2012-05-23 16:13:48 End: 2012-05-24 16:13:48 Event: 2012-05-23 16:13:48 Opening: 2012-05-23 16:16:15", 274 | "Ticker: DF Start: 2012-05-09 08:05:08 End: 2012-05-10 08:05:08 Event: 2012-05-09 08:05:08 Opening: 2012-05-09 09:33:11", 275 | "Ticker: " 276 | ] 277 | }, 278 | { 279 | "output_type": "stream", 280 | "stream": "stdout", 281 | "text": [ 282 | " TKR Start: 2012-04-24 17:17:38 End: 2012-04-25 17:17:38 Event: 2012-04-24 17:17:38 Opening: 2012-04-25 09:31:06", 283 | "Ticker: WHR Start: 2012-05-16 11:43:44 End: 2012-05-17 11:43:44 Event: 2012-05-16 11:43:44 Opening: 2012-05-16 11:44:23", 284 | "Ticker: " 285 | ] 286 | }, 287 | { 288 | "output_type": "stream", 289 | "stream": "stdout", 290 | "text": [ 291 | " AGCO Start: 2012-05-01 08:25:27 End: 2012-05-02 08:25:27 Event: 2012-05-01 08:25:27 Opening: 2012-05-01 09:32:14", 292 | "Ticker: MTZ Start: 2012-05-03 16:51:57 End: 2012-05-04 16:51:57 Event: 2012-05-03 16:51:57 Opening: 2012-05-04 09:30:01", 293 | "Ticker: " 294 | ] 295 | }, 296 | { 297 | "output_type": "stream", 298 | "stream": "stdout", 299 | "text": [ 300 | " CMTL Start: 2012-06-07 16:13:11 End: 2012-06-08 16:13:11 Event: 2012-06-07 16:13:11 Opening: 2012-06-07 16:13:18", 301 | "Ticker: THC Start: 2012-05-08 07:41:46 End: 2012-05-09 07:41:46 Event: 2012-05-08 07:41:46 Opening: 2012-05-08 09:30:01", 302 | "Ticker: OFC Start: 2012-04-26 06:09:25 End: 2012-04-27 06:09:25 Event: 2012-04-26 06:09:25 Opening: 2012-04-26 09:30:11", 303 | "Ticker: " 304 | ] 305 | }, 306 | { 307 | "output_type": "stream", 308 | "stream": "stdout", 309 | "text": [ 310 | " TRN Start: 2012-04-25 16:10:34 End: 2012-04-26 16:10:34 Event: 2012-04-25 16:10:34 Opening: 2012-04-26 09:30:10", 311 | "Ticker: UNF Start: 2012-06-27 08:03:15 End: 2012-06-28 08:03:15 Event: 2012-06-27 08:03:15 Opening: 2012-06-27 09:31:15", 312 | "Ticker: " 313 | ] 314 | }, 315 | { 316 | "output_type": "stream", 317 | "stream": "stdout", 318 | "text": [ 319 | " ARRS Start: 2012-04-25 17:33:39 End: 2012-04-26 17:33:39 Event: 2012-04-25 17:33:39 Opening: 2012-04-25 19:34:26", 320 | "Ticker: LF Start: 2012-05-03 16:11:54 End: 2012-05-04 16:11:54 Event: 2012-05-03 16:11:54 Opening: 2012-05-04 09:32:14", 321 | "Ticker: " 322 | ] 323 | }, 324 | { 325 | "output_type": "stream", 326 | "stream": "stdout", 327 | "text": [ 328 | " CRI Start: 2012-04-26 06:35:33 End: 2012-04-27 06:35:33 Event: 2012-04-26 06:35:33 Opening: 2012-04-26 09:34:53", 329 | "Ticker: TWGP Start: 2012-05-07 16:07:58 End: 2012-05-08 16:07:58 Event: 2012-05-07 16:07:58 Opening: 2012-05-07 16:09:49", 330 | "Ticker: DRH Start: 2012-04-30 08:08:30 End: 2012-05-01 08:08:30 Event: 2012-04-30 08:08:30 Opening: 2012-04-30 09:30:01", 331 | "Ticker: " 332 | ] 333 | }, 334 | { 335 | "output_type": "stream", 336 | "stream": "stdout", 337 | "text": [ 338 | " HPY Start: 2012-05-01 07:38:58 End: 2012-05-02 07:38:58 Event: 2012-05-01 07:38:58 Opening: 2012-05-01 09:30:20", 339 | "Ticker: ACCO Start: 2012-05-10 07:06:04 End: 2012-05-11 07:06:04 Event: 2012-05-10 07:06:04 Opening: 2012-05-10 09:31:14", 340 | "Ticker: " 341 | ] 342 | }, 343 | { 344 | "output_type": "stream", 345 | "stream": "stdout", 346 | "text": [ 347 | " LQDT Start: 2012-05-03 06:59:36 End: 2012-05-04 06:59:36 Event: 2012-05-03 06:59:36 Opening: 2012-05-03 08:08:00", 348 | "Ticker: " 349 | ] 350 | }, 351 | { 352 | "output_type": "stream", 353 | "stream": "stdout", 354 | "text": [ 355 | " SPRD Start: 2012-05-03 16:59:58 End: 2012-05-04 16:59:58 Event: 2012-05-03 16:59:58 Opening: 2012-05-03 17:00:05", 356 | "Ticker: " 357 | ] 358 | }, 359 | { 360 | "output_type": "stream", 361 | "stream": "stdout", 362 | "text": [ 363 | " LOPE Start: 2012-05-07 16:21:43 End: 2012-05-08 16:21:43 Event: 2012-05-07 16:21:43 Opening: 2012-05-07 16:25:06", 364 | "Ticker: " 365 | ] 366 | }, 367 | { 368 | "output_type": "stream", 369 | "stream": "stdout", 370 | "text": [ 371 | " LOGM Start: 2012-04-25 16:37:50 End: 2012-04-26 16:37:50 Event: 2012-04-25 16:37:50 Opening: 2012-04-25 16:56:22", 372 | "Ticker: SYA Start: 2012-04-25 16:29:01 End: 2012-04-26 16:29:01 Event: 2012-04-25 16:29:01 Opening: 2012-04-26 09:32:24", 373 | "Ticker: " 374 | ] 375 | }, 376 | { 377 | "output_type": "stream", 378 | "stream": "stdout", 379 | "text": [ 380 | " RPXC Start: 2012-05-01 16:43:02 End: 2012-05-02 16:43:02 Event: 2012-05-01 16:43:02 Opening: 2012-05-01 17:35:50", 381 | "Ticker: " 382 | ] 383 | }, 384 | { 385 | "output_type": "stream", 386 | "stream": "stdout", 387 | "text": [ 388 | " Z Start: 2012-05-02 16:40:34 End: 2012-05-03 16:40:34 Event: 2012-05-02 16:40:34 Opening: 2012-05-02 16:40:42", 389 | "Ticker: " 390 | ] 391 | }, 392 | { 393 | "output_type": "stream", 394 | "stream": "stdout", 395 | "text": [ 396 | " FRAN Start: 2012-06-07 16:07:54 End: 2012-06-08 16:07:54 Event: 2012-06-07 16:07:54 Opening: 2012-06-07 16:08:03" 397 | ] 398 | } 399 | ], 400 | "prompt_number": 80 401 | }, 402 | { 403 | "cell_type": "code", 404 | "collapsed": false, 405 | "input": [ 406 | "average(pricesDF.ix[-1, :])" 407 | ], 408 | "language": "python", 409 | "outputs": [ 410 | { 411 | "output_type": "pyout", 412 | "prompt_number": 81, 413 | "text": [ 414 | "1.0191177280516519" 415 | ] 416 | } 417 | ], 418 | "prompt_number": 81 419 | }, 420 | { 421 | "cell_type": "code", 422 | "collapsed": false, 423 | "input": [ 424 | "std(pricesDF.ix[-1, :])" 425 | ], 426 | "language": "python", 427 | "outputs": [ 428 | { 429 | "output_type": "pyout", 430 | "prompt_number": 82, 431 | "text": [ 432 | "0.049629860185440057" 433 | ] 434 | } 435 | ], 436 | "prompt_number": 82 437 | }, 438 | { 439 | "cell_type": "code", 440 | "collapsed": false, 441 | "input": [ 442 | "pricesDF.ix[-1,:]" 443 | ], 444 | "language": "python", 445 | "outputs": [ 446 | { 447 | "output_type": "pyout", 448 | "prompt_number": 83, 449 | "text": [ 450 | "ASGN 1.060335", 451 | "BHE 1.043279", 452 | "BOBE 0.978917", 453 | "CACI 1.034267", 454 | "CLGX 1.040491", 455 | "JACK 1.025163", 456 | "GWR 1.050397", 457 | "KLIC 0.927857", 458 | "MCRL 1.038594", 459 | "MTOR 0.967832", 460 | "MSCC 1.042657", 461 | "NDSN 1.047269", 462 | "NUS 0.927167", 463 | "POWI 1.123848", 464 | "SHAW 0.952072", 465 | "SNPS 1.050284", 466 | "DF 1.023138", 467 | "TKR 0.993301", 468 | "WHR 0.962062", 469 | "AGCO 0.970114", 470 | "MTZ 1.059701", 471 | "CMTL 1.059181", 472 | "THC 1.017964", 473 | "OFC 1.012190", 474 | "TRN 0.954426", 475 | "UNF 1.044610", 476 | "ARRS 0.903950", 477 | "LF 1.050000", 478 | "CRI 1.000903", 479 | "TWGP 1.010992", 480 | "DRH 0.988837", 481 | "HPY 1.024244", 482 | "ACCO 1.028770", 483 | "LQDT 1.104035", 484 | "SPRD 1.004347", 485 | "LOPE 1.129152", 486 | "LOGM 1.000000", 487 | "SYA 0.987448", 488 | "RPXC 0.994854", 489 | "Z 1.070199", 490 | "FRAN 1.078980", 491 | "Name: 2012-01-01 23:59:09" 492 | ] 493 | } 494 | ], 495 | "prompt_number": 83 496 | }, 497 | { 498 | "cell_type": "code", 499 | "collapsed": false, 500 | "input": [ 501 | "for row in PosEarnings2:", 502 | " if row[1] == 'ULTA':", 503 | " print row" 504 | ], 505 | "language": "python", 506 | "outputs": [ 507 | { 508 | "output_type": "stream", 509 | "stream": "stdout", 510 | "text": [ 511 | "[1630728L, 'ULTA', datetime.datetime(2012, 5, 7, 16, 52, 3), ' Ulta Salon sees Q1 EPS 52-53c, consensus 48c', 'Sees revenue $474M, consensus $459.82M.', 1630728L, 0.53, 0.53, 0.53, 0.48, 0.104167, 'ULTA SALON COSMETCS & FRAG I COM', datetime.date(2012, 5, 7), 401157L, 75L, 73L, 7L, 11L, 90L, 37L, 72L, 67L, 5877.57468957]", 512 | "[1647328L, 'ULTA', datetime.datetime(2012, 6, 5, 16, 8, 7), ' Ulta Salon sees Q2 EPS with items 49c-51c, consensus 48c', \"Q2 EPS guidance range includes approximately 2c per diluted share of additional costs associated with the planned expansion of prestige brand boutiques and the start-up of the company's new Chambersburg distribution center.The company sees revenue $466M-$473M, consensus $467.4M. \", 1647328L, 0.49, 0.51, 0.5, 0.48, 0.041667, 'ULTA SALON COSMETCS & FRAG I COM', datetime.date(2012, 6, 5), 401157L, 86L, 74L, 7L, 10L, 78L, 38L, 60L, 73L, 5877.57468957]" 513 | ] 514 | } 515 | ], 516 | "prompt_number": 46 517 | }, 518 | { 519 | "cell_type": "code", 520 | "collapsed": true, 521 | "input": [], 522 | "language": "python", 523 | "outputs": [] 524 | } 525 | ] 526 | } 527 | ] 528 | } -------------------------------------------------------------------------------- /NewsScrape/flyonthewall.py: -------------------------------------------------------------------------------- 1 | import urllib, urllib2, cookielib, re 2 | from bs4 import BeautifulSoup 3 | from time import gmtime, localtime, strftime 4 | import sys 5 | from datetime import datetime, date 6 | 7 | theurl = "http://www.theflyonthewall.com/beta/news.php" 8 | theurl2 = "http://www.theflyonthewall.com/beta/paraDesarrollar/getNews.php" 9 | loginurl = "http://www.theflyonthewall.com/login.php" 10 | loginurl2 = "http://www.theflyonthewall.com/beta/paraDesarrollar/login.php" 11 | 12 | username = "" 13 | password = "" 14 | txheader = {'User-Agent' : 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'} 15 | data = {'username':username, 'password':password} 16 | 17 | import dbutil 18 | 19 | __homeserv = dbutil.db(h='127.0.0.1', schema='mchan') 20 | __cursor = __homeserv.cursor 21 | 22 | 23 | txdata = urllib.urlencode(data) 24 | # Setup Cookie manager 25 | cj = cookielib.CookieJar() 26 | opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj)) 27 | resp = opener.open(theurl) 28 | resp = opener.open(loginurl2, txdata) 29 | # Now get the unlocked data 30 | try: 31 | resp2 = opener.open(theurl) 32 | except urllib2.HTTPError, e: 33 | print 'The server couldn\'t fulfill the request.' 34 | print 'Error code: ', e.code 35 | except urllib2.URLError, e: 36 | print 'We failed to reach a server.' 37 | print 'Reason: ', e.reason 38 | 39 | # Parse the page response 40 | soup = BeautifulSoup(resp2.read()) 41 | # Grab the necessary data 42 | 43 | for i in soup.find_all('li'): 44 | if i.has_key('id'): 45 | if i['id'].startswith('li_'): 46 | xvar = i 47 | id = re.sub(r'li_', '', i['id']) 48 | time = i.find(id="horaCompleta").string 49 | tickers = [] 50 | links = [] 51 | links_str = "" 52 | for j in i.find_all(attrs={'onclick':re.compile("^searchSymbols")}): 53 | clean_ticker = re.sub(r'\(|\)|\+', '', j.string) 54 | tickers.append(clean_ticker) 55 | if(i.find(attrs={'class':'Headline'})): 56 | headline = i.find(attrs={'class':'Headline'}).string 57 | elif(i.find(attrs={'class':'withOutHeadline'})): 58 | headline = i.find(attrs={'class':'withOutHeadline'}).string 59 | text = i.find(attrs={'class':'withOutHeadline'}).string 60 | if(i.find(attrs={'class':re.compile("^nw")})): 61 | text = i.find(attrs={'class':re.compile("^nw")}).get_text() 62 | elif(i.find(attrs={'class':'pAlone'})): 63 | text = i.find(attrs={'class':'pAlone'}).get_text() 64 | if(i.find(attrs={'class':re.compile("^iconos")})): 65 | classification = i.find(attrs={'class':re.compile("^iconos")})['title'] 66 | for j in i.find_all('a'): 67 | links.append(j.get('href')) 68 | now = strftime("%Y-%m-%d %H:%M:%S", localtime()) 69 | tickers_str = ','.join(tickers) 70 | links_str = ','.join(links) 71 | # Cant find a headline or story 72 | if (headline == None and text == None): 73 | continue 74 | if (headline == None): 75 | headline = text 76 | sql = """INSERT IGNORE INTO mchan.flyonthewall 77 | VALUES (%i, '%s', '%s', '%s', '%s', '%s', '%s', '%s')""" \ 78 | % (int(id), time, now, tickers_str, classification, headline.replace("'","\\'").replace("theflyonthewall.com",""), text.replace("'", "\\'").replace("theflyonthewall.com",""), links_str) 79 | if __cursor.execute(sql): 80 | print(id, time, classification, tickers, headline, text, links_str) 81 | id = None; tickers_str = None; classification = None; headline = None; text = None; 82 | __homeserv.commit() 83 | 84 | 85 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # IBAlgoTrading 2 | Example python scripts to transmit/receive data/orders from Interactive Brokers using swigibpy 3 | -------------------------------------------------------------------------------- /Trading/ATS.py: -------------------------------------------------------------------------------- 1 | import strategy 2 | import fowscanner 3 | import datetime 4 | import time 5 | import sys 6 | from swigibpy import EWrapper, EPosixClientSocket, Contract, TWSError, Order 7 | sys.path.append('/home/mchan/git/Artemis/SwigIbPy') 8 | #from ArtemisIBWrapperSilent import ArtemisIBWrapper 9 | import ArtemisIBWrapperSilent 10 | sys.path.append('/home/mchan/git/Artemis/util') 11 | import dbutil 12 | #import pdb 13 | 14 | class TradeManager(object): 15 | def __init__(self): 16 | self.accountNumber = '' 17 | self.optionExpiry = '20121221' # This needs manual updating! 18 | self.maxAskBidRatio = 1.25 19 | self.maxAskLastPriceRatio = 1.02 20 | self.maxOrderQueueLength = 3 21 | # Create a file for TWS logging 22 | self.twslog_fh = open('/home/mchan/git/Artemis/twslog.txt', 'a', 0) 23 | self.twslog_fh.write("Session Started " + str(datetime.datetime.now()) + "\n") 24 | self.callback = ArtemisIBWrapperSilent.ArtemisIBWrapper() 25 | self.tws = EPosixClientSocket(self.callback) 26 | self.orderIdCount = 1 # This will be updated automatically 27 | self.requestIdCount = 1 28 | self.invested = False 29 | self.maxLimitPriceFactor = 1.02 # No limit orders above 2% of current ask price 30 | # Connect the socket 31 | self.socketnum = 30 32 | self.tws.eConnect("", 7496, self.socketnum, poll_interval=1) 33 | # Strategy Generic object, has methods for interpreting consensus out/under performance 34 | self.Strat = strategy.Strategy() 35 | # Queue for orders 36 | self.orderQueue = [] 37 | # Setup DB connector 38 | self.db = dbutil.db(h='127.0.0.1', schema='mchan') 39 | 40 | # Query Cash Account Balance 41 | self.updateBuyingPowerNextId() 42 | 43 | def updateBuyingPowerNextId(self): 44 | self.callback.myNextValidId = None 45 | self.callback.buyingPower = None 46 | self.tws.reqAccountUpdates(1, self.accountNumber) 47 | while (self.callback.buyingPower is None or self.callback.myNextValidId is None): 48 | pass 49 | self.buyingPower = float(self.callback.buyingPower) 50 | self.orderIdCount = int(self.callback.myNextValidId) 51 | print "Buying Power recognized: ", self.buyingPower, " Next valid id recognized: ", self.orderIdCount 52 | self.tws.reqAccountUpdates(0, self.accountNumber) 53 | 54 | def calcInvSize(self): 55 | ''' 56 | Calculates proper investment size 57 | ''' 58 | # We take the total size of the portfolio, cash plus stock, and we divide by four 59 | # The reasoning is that we want to avoid the day pattern trader restriction 60 | # Dividing our portfolio size by four ensures that we have enough capital 61 | # to trade for the four trading opportunities that will happen until we can 62 | # finally sell our positions 63 | # This also allows for diversification 64 | self.updateBuyingPowerNextId() 65 | portfolioList = self.getPortfolio() 66 | secMarketPositions = 0 67 | for myContract, myPosition, myMarketValue in portfolioList: 68 | secMarketPositions += myMarketValue 69 | totalPortfolioSize = secMarketPositions + self.buyingPower 70 | investmentSize = min(self.buyingPower, (totalPortfolioSize/4.0)) 71 | print "CALCULATE INVESTMENT SIZE: ", str(investmentSize) 72 | return investmentSize 73 | 74 | 75 | def twsReconnect(self): 76 | print "Reconnecting TWS" 77 | self.twslog_fh.write("Reconnecting TWS" + str(datetime.datetime.now()) + '\n') 78 | self.tws.eDisconnect() 79 | try: 80 | self.tws.eConnect("", 7496, self.socketnum, poll_interval=1) 81 | except TWSError, e: 82 | print e 83 | print "Attempting to reconnect:" 84 | for i in range(0,5): 85 | time.sleep(5) 86 | print "Try ", i 87 | try: 88 | self.tws.eConnect("", 7496, self.socketnum, poll_interval=1) 89 | break 90 | except TWSError, e: 91 | print e 92 | 93 | def run(self): 94 | # Operates every half hour on the clock 95 | # If the hour is even reconnect the TWS socket 96 | if (datetime.datetime.now().hour % 3 == 1 and datetime.datetime.now().minute == 0): 97 | self.twsReconnect() 98 | if (datetime.datetime.now().hour == 6 and datetime.datetime.now().minute == 0): 99 | # send in order 100 | #self.submitOrders() 101 | pass 102 | 103 | if (datetime.datetime.now().hour == 12 and datetime.datetime.now().minute == 30): 104 | # leave positions 105 | pass 106 | 107 | 108 | def storeOrder(self, orderId, contract, order): 109 | myNow = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) 110 | # Assumption here is that the order types are only STK or OPT 111 | if contract.secType == "STK": 112 | self.db.execute('''INSERT INTO mchan.twsOrders VALUES (%i, "%s", "%s", "STK", NULL, NULL, NULL, "%s", %i, "%s");''' % \ 113 | (orderId, contract.exchange, contract.symbol, order.action, order.totalQuantity, myNow)) 114 | self.db.commit() 115 | else: 116 | expiry = contract.expiry[0:4] + '-' + contract.expiry[4:6] + '-' + contract.expiry[6:8] 117 | self.db.execute('''INSERT INTO mchan.twsOrders VALUES (%i, "%s", "%s", "OPT", "%s", "%s", %f, "%s", %i, "%s");''' % \ 118 | (orderId, contract.exchange, contract.symbol, contract.right, expiry, contract.strike, order.action, order.totalQuantity, myNow)) 119 | self.db.commit() 120 | 121 | def submitOrders(self): 122 | for i in self.orderQueue: 123 | self.tws.placeOrder(i['order'].orderId, i['contract'], i['order']) 124 | self.storeOrder(i['order'].orderId, i['contract'], i['order']) 125 | self.orderQueue = [] 126 | 127 | def createContract(self, ticker, secType): 128 | contract = Contract() 129 | contract.exchange = "SMART" # Default exchange, IB routing algo 130 | contract.symbol = ticker 131 | contract.secType = secType 132 | contract.currency = "USD" 133 | return contract 134 | 135 | def createOrderBuy(self): 136 | order = Order() 137 | order.orderId = self.orderIdCount 138 | self.orderIdCount += 1 139 | order.clientId = self.socketnum 140 | order.action = "BUY" 141 | order.orderType = "MKT" 142 | order.tif = "DAY" 143 | order.transmit = True 144 | order.sweepToFill = True 145 | order.outsideRth = True 146 | return order 147 | 148 | def createMarketOrderEquityBuy(self, contract): 149 | order = self.createOrderBuy() 150 | # Tweak the default settings 151 | order.orderType = "LMT" 152 | 153 | # Grab the current ask price 154 | self.callback.askPrice = None 155 | self.callback.lastPrice = None 156 | self.callback.tickDataEnd = False 157 | # snapshot = 1 means get one snapshot of market data 158 | self.tws.reqMktData(self.requestIdCount, contract, "", 1) # Arguments are id, contract, generic tick types, and snapshot 159 | self.requestIdCount += 1 160 | # Wait until tws responds before proceeding 161 | #while (self.callback.askPrice is None): 162 | max_wait = datetime.timedelta(seconds=60) + datetime.datetime.now() 163 | while (self.callback.askPrice is None): 164 | if datetime.datetime.now() > max_wait: 165 | print "Max wait period reached giving up on market data" 166 | order.totalQuantity = 0 167 | return order 168 | 169 | askPrice = self.callback.askPrice 170 | lastPrice = self.callback.lastPrice 171 | print "Ask Price for order is: ", askPrice 172 | print "Last Price for order is: ", lastPrice 173 | print "Order Processing..." 174 | 175 | # Bail if no ask price, or if the difference between ask and the last price is too high 176 | if askPrice == 0 or askPrice is None or (askPrice/lastPrice) > self.maxAskLastPriceRatio: 177 | order.totalQuantity = 0 178 | return order 179 | 180 | divPrice = askPrice 181 | investmentSize = self.calcInvSize() 182 | # Need to get the ask price from IB. wait until the call back variable is set 183 | order.totalQuantity = int( investmentSize / divPrice ) # may have to calculate a smarter number 184 | order.lmtPrice = round(self.maxLimitPriceFactor * divPrice, 2) 185 | print "Order Quantitiy: ", order.totalQuantity, " Limit Price: ", order.lmtPrice 186 | return order 187 | 188 | def processEvent(self, event, direction, recTime): 189 | # Asynchronous order receiver 190 | #if self.invested: 191 | # print "Already invested passing" 192 | # return 193 | if direction == "LONG": 194 | # Here we recieved a long signal. We want to send a buy order asap, and then check to see if the market is closed 195 | contract = self.createContract(str(event['ticker']), "STK") 196 | order = self.createMarketOrderEquityBuy(contract) 197 | # Make sure order.totalQuantity is decent size else break out 198 | if order.totalQuantity == 0: 199 | print "Market for security is closed or not liquid, trying option market" 200 | if datetime.datetime.now().hour <= 9: 201 | self.enqueueOptionOrder(event, direction, recTime) 202 | return 203 | print "Placing order..." 204 | self.callback.orderState = None 205 | self.tws.placeOrder(order.orderId, contract, order) 206 | time.sleep(2) 207 | if self.callback.orderState == "PreSubmitted": 208 | # We know that the order happened outside of any trading whatsoever 209 | print "After market conditions. Appending to queue. Cancelling Order" 210 | self.tws.cancelOrder(order.orderId) 211 | # We still want to send the order in the morning 212 | if datetime.datetime.now().hour <= 9: 213 | self.enqueueOptionOrder(event, direction, recTime) 214 | else: 215 | pass 216 | #self.invested = True # Order has gone through 217 | else: 218 | # Short position but the IRA account cant allow shorting so we enqueue option order 219 | # We also know that option markets after hours is non-existant 220 | # We only want to enqueue morning orders 221 | # Later we can treat short orders like long orders, ie different types of strategies, not earnings releases which almost 222 | # always occurs during non regular trading hours 223 | if datetime.datetime.now().hour <= 9: 224 | self.enqueueOptionOrder(event, direction, recTime) 225 | else: 226 | print "Disallow shorting of after hours poor earnings report" 227 | 228 | def createOptionContract(self, ticker, direction): 229 | # Need to find current price of the equity 230 | contract = self.createContract(ticker, "STK") 231 | 232 | self.callback.lastPrice = None 233 | self.callback.closePrice = None 234 | self.callback.tickDataEnd = False 235 | print "Create option contract For: ", contract.symbol, " Type: ", contract.secType 236 | # snapshot = 1 means get one snapshot of market data 237 | #print "Request ID " , self.requestIdCount 238 | self.tws.reqMktData(self.requestIdCount, contract, "", 1) # Arguments are id, contract, generic tick types, and snapshot 239 | self.requestIdCount += 1 240 | # Wait until tws responds before proceeding 241 | max_wait = datetime.timedelta(seconds=60) + datetime.datetime.now() 242 | #while (self.callback.lastPrice is None and self.callback.closePrice is None): 243 | while (not self.callback.tickDataEnd): 244 | if datetime.datetime.now() > max_wait: 245 | print "Max wait period reached giving up on market data for create option contract" 246 | break 247 | 248 | if self.callback.lastPrice is None and self.callback.closePrice is None: 249 | return False 250 | 251 | lastPrice = self.callback.lastPrice if self.callback.lastPrice is not None else self.callback.closePrice 252 | 253 | # Setup the option contract to request further details 254 | contract.right = "CALL" if direction == "LONG" else "PUT" 255 | contract.secType = "OPT" 256 | contract.expiry = self.optionExpiry 257 | 258 | # Reset the callback object. We'll get a list of option contracts with the given 259 | # ticker, expiry, and call/put. But we need the right strke price. 260 | # The reqContractDetails socket method will return a list of contracts with different Strikes 261 | # callback EWrapper class method will be called which appends values to the array Strikes 262 | # and fills out StrikesHash 263 | # StrikesHash is a dictionary keyed on strike price, with a value of a tuple, contractId and multiplier 264 | self.callback.Strikes = [] 265 | self.callback.StrikesHash = dict() 266 | self.callback.contractDataEnd = False 267 | 268 | self.tws.reqContractDetails(self.requestIdCount, contract) 269 | self.requestIdCount += 1 270 | # Wait for contract data end 271 | max_wait = datetime.timedelta(seconds=60) + datetime.datetime.now() 272 | while not self.callback.contractDataEnd: 273 | if datetime.datetime.now() > max_wait: 274 | print "Max wait period reached giving up on contract details data" 275 | break 276 | 277 | if not self.callback.contractDataEnd: 278 | return False 279 | 280 | # Get the JUST barely in the money call or put These options seem to be the most liquid 281 | # depends on call or put 282 | for i in range(0, len(sorted(self.callback.Strikes))): 283 | if sorted(self.callback.Strikes)[i] > lastPrice: 284 | callStrikePrice = sorted(self.callback.Strikes)[i-1] 285 | callConId = self.callback.StrikesHash[callStrikePrice][0] 286 | callMultiplier = self.callback.StrikesHash[callStrikePrice][1] 287 | putStrikePrice = sorted(self.callback.Strikes)[i] 288 | putConId = self.callback.StrikesHash[putStrikePrice][0] 289 | putMultiplier = self.callback.StrikesHash[putStrikePrice][1] 290 | break 291 | 292 | # Fill out the rest of the option contract details 293 | contract.strike = callStrikePrice if direction == "LONG" else putStrikePrice 294 | contract.conId = callConId if direction == "LONG" else putConId 295 | contract.multiplier = callMultiplier if direction == "LONG" else putMultiplier 296 | return contract 297 | 298 | # def createOptionOrder(self, contract): 299 | 300 | def verifyOptionLiquidity(self, contract): 301 | print "Check option liquidity" 302 | bidClose = self.getLastClose(contract, "BID") 303 | askClose = self.getLastClose(contract, "ASK") 304 | if not bidClose or not askClose: 305 | return False 306 | return False if (askClose / bidClose) > self.maxAskBidRatio else True 307 | 308 | def getLastClose(self, contract, askbid): 309 | self.callback.histClose = None # closing bar value for ask/bid 310 | self.tws.reqHistoricalData(self.requestIdCount, contract, datetime.datetime.today().strftime("%Y%m%d %H:%M:%S %Z"), \ 311 | "1 D", "1 hour", askbid, 0, 1) 312 | self.requestIdCount += 1 313 | max_wait = datetime.timedelta(seconds=60) + datetime.datetime.now() 314 | while (self.callback.histClose is None): 315 | if datetime.datetime.now() > max_wait: 316 | print "Max wait period reached giving up on last close price" 317 | break 318 | close = self.callback.histClose if self.callback.histClose is not None else 10000000 319 | return float(close) 320 | 321 | def updateOrderQueueOrderSizes(self): 322 | # Goes through the orderQueue and sets the number of contracts to buy 323 | orderDollarSize = self.calcInvSize() / len(self.orderQueue) 324 | for i in self.orderQueue: 325 | askClose = self.getLastClose(i['contract'], "ASK") 326 | contractPrice = askClose * int(i['contract'].multiplier) 327 | i['order'].totalQuantity = int( (0.9 * orderDollarSize) / contractPrice ) 328 | 329 | def enqueueOptionOrder(self, event, direction, recTime): 330 | # Go through current orderQueue and see if there are any worse out/under performance 331 | # Kick it out. Max of three orders in orderQueue 332 | if len(self.orderQueue) == self.maxOrderQueueLength: 333 | for i in self.orderQueue: 334 | if abs(self.Strat.calcConsensus(event['headline'])) <= abs(self.Strat.calcConsensus(i['event']['headline'])) \ 335 | or event['ticker'] == i['event']['ticker']: 336 | return 337 | 338 | optionContract = self.createOptionContract(str(event['ticker']), direction) 339 | # If we cant find market data to create option contract 340 | if not optionContract: 341 | print "Option contract creation failed skipping order" 342 | return 343 | # We come up with the optionOrder but we mush also check to see if the market is liquid enough. 344 | if not self.verifyOptionLiquidity(optionContract): 345 | print "Option order not liquid, skipping order" 346 | return 347 | optionOrder = self.createOrderBuy() 348 | 349 | # Put the order in the queue or kick out a crappier one if its max length 350 | if len(self.orderQueue) < self.maxOrderQueueLength: 351 | self.orderQueue.append({'event':event, 'order':optionOrder, 'contract':optionContract}) 352 | print "Order appended to queue ", optionContract.symbol, " ", optionContract.secType, " ", optionContract.expiry, " ", optionContract.right, " ", optionContract.strike, " ", " NumContracts: ", optionOrder.totalQuantity 353 | else: 354 | for i in range(0, len(self.orderQueue)): 355 | if abs(self.Strat.calcConsensus(event['headline'])) > abs(self.Strat.calcConsensus(self.orderQueue[i]['event']['headline'])): 356 | del self.orderQueue[i] 357 | self.orderQueue.append({'event':event, 'order':optionOrder, 'contract':optionContract}) 358 | print "Order appended to queue ", optionContract.symbol, " ", optionContract.secType, " ", optionContract.expiry, " ", optionContract.right, " ", optionContract.strike, " ", " NumContracts: ", optionOrder.totalQuantity 359 | # Update the order sizes now that the queue has changed 360 | self.updateOrderQueueOrderSizes() 361 | 362 | def getPortfolio(self): 363 | ''' 364 | Returns list of triplets of current (contract, position in number of shares/contracts, market value of position) 365 | ''' 366 | portfolioList = [] 367 | # setup call back variables 368 | self.callback.accountEnd = False 369 | #self.callback.portfolioContract = None 370 | #self.callback.portfolioPosition = None 371 | #self.callback.portfolioSecMarketValue = None 372 | 373 | self.tws.reqAccountUpdates(1, self.accountNumber) 374 | while (not self.callback.accountEnd): 375 | self.callback.portfolioContract = None 376 | self.callback.portfolioPosition = None 377 | self.callback.portfolioSecMarketValue = None 378 | max_wait = datetime.timedelta(seconds=60) + datetime.datetime.now() 379 | while (self.callback.portfolioPosition is None or self.callback.portfolioContract is None or self.callback.portfolioSecMarketValue is None): 380 | if datetime.datetime.now() > max_wait: 381 | break 382 | if self.callback.portfolioPosition is not None and self.callback.portfolioContract is not None and self.callback.portfolioSecMarketValue is not None: 383 | myContract = Contract() 384 | myContract.exchange = "SMART" 385 | myContract.currency = "USD" 386 | myContract.symbol = self.callback.portfolioContractSymbol 387 | myContract.conId = self.callback.portfolioContractConId 388 | myContract.secType = self.callback.portfolioContractSecType 389 | myContract.strike = self.callback.portfolioContractStrike 390 | myContract.expiry = self.callback.portfolioContractExpiry 391 | myContract.right = self.callback.portfolioContractRight 392 | myPosition = self.callback.portfolioPosition 393 | mySecMarketValue = self.callback.portfolioSecMarketValue 394 | portfolioList.append((myContract, myPosition, mySecMarketValue)) 395 | 396 | self.tws.reqAccountUpdates(0, self.accountNumber) 397 | return portfolioList 398 | 399 | 400 | def sellOut(self): 401 | ''' 402 | Dump all positions 403 | ''' 404 | # need to clear orderQueue regularly 405 | self.orderQueue = [] 406 | # Data holder for positions 407 | portfolioList = self.getPortfolio() 408 | 409 | if len(portfolioList) == 0: 410 | print "No sellout orders today" 411 | self.invested = False 412 | return 413 | 414 | # Get list of tickers that we want to get sold. Need to follow day pattern trade restrictions (>24 holding period) 415 | maxTransactionDatetime = (datetime.datetime.now() - datetime.timedelta(days=1, seconds=60)).strftime("%Y-%m-%d %H:%M:%S") 416 | minTransactionDatetime = (datetime.datetime.now() - datetime.timedelta(days=3)).strftime("%Y-%m-%d %H:%M:%S") 417 | sql = '''SELECT DISTINCT(ord.symbol) FROM mchan.twsOrders ord 418 | INNER JOIN mchan.twsOrderStatus st 419 | ON ord.orderId = st.orderId 420 | WHERE st.orderStatus = 'Filled' 421 | AND st.receive_date < '%s' 422 | AND st.receive_date > '%s';''' % (maxTransactionDatetime, minTransactionDatetime) 423 | sellTickerList = self.db.query(sql) 424 | 425 | orderList = [] 426 | print "Sell Out orders:" 427 | for curContract, curPosition, curMarketSize in portfolioList: 428 | if curPosition == 0: 429 | print curContract.symbol, ": zero size position, skipping" 430 | continue 431 | if [curContract.symbol] not in sellTickerList: 432 | continue 433 | curOrder = self.createOrderBuy() 434 | curOrder.totalQuantity = int(curPosition) 435 | curOrder.action = "SELL" 436 | curOrder.sweepToFill = False 437 | orderList.append([curContract, curOrder]) 438 | print curContract.symbol, " ", curOrder.totalQuantity 439 | for orders in orderList: 440 | # Arguments are orderId, contract, and order 441 | self.tws.placeOrder(orders[1].orderId, orders[0], orders[1]) 442 | #pass 443 | print "Sell orders sent out!" 444 | #self.invested = False 445 | 446 | def FOWScanner(tradeMgr): 447 | fh1 = open('/home/mchan/git/Artemis/fowscanlog.txt', 'a', 0) 448 | fh2 = open('/home/mchan/git/Artemis/signal.txt', 'a', 0) 449 | fh1.write("Starting Session" + str(datetime.datetime.now()) + '\n') 450 | fh2.write("Starting Session" + str(datetime.datetime.now()) + '\n') 451 | pastEvents = [] 452 | 453 | longStrat = strategy.LongEarningsGuidance() 454 | shortStrat = strategy.ShortEarningsGuidance() 455 | while(1): 456 | myTimer = datetime.datetime.now() 457 | # Housekeeping, buy-in, sell-out section 458 | if (myTimer.minute % 15 == 0 and myTimer.second == 0): 459 | print "Artemis HeartBeat ", str(myTimer) 460 | if (myTimer.hour == 6 and myTimer.minute == 28): 461 | # OK to run many times during this minute 462 | tradeMgr.submitOrders() 463 | if (myTimer.hour == 6 and (myTimer.minute == 45 or myTimer.minute == 46)): 464 | tradeMgr.sellOut() 465 | time.sleep(120) 466 | 467 | # Article Scanning Section 468 | if len(pastEvents) > 500: 469 | pastEvents = [] 470 | events = fowscanner.scan() 471 | for row in events: 472 | if row['id'] not in pastEvents: 473 | pastEvents.append(row['id']) 474 | recTime = datetime.datetime.now() 475 | fh1.write(str(row) + " RECV" + str(recTime) + "\n") 476 | if len(row['ticker']) != 1: 477 | continue 478 | event = dict({'ticker':row['ticker'][0], 'classification':row['classification'], 'headline':row['headline']}) 479 | if longStrat.isEvent(event): 480 | print row, " RECV", str(recTime) 481 | print "LONG the above event!" 482 | print " PROCESSED", str(datetime.datetime.now()) 483 | fh2.write(str(row) + " LONG" + str(datetime.datetime.now()) + " RECV:" + str(recTime) + " PROCESSED: " + str(datetime.datetime.now()) + "\n") 484 | # Basic time checking 485 | print "Event NYC time: ", str(stryDateTime), " Recv NYC time: ", str(datetime.datetime.now() + datetime.timedelta(hours=3)) 486 | stryDateTime = datetime.datetime.strptime(row['release_datetime'], "%Y-%m-%d %H:%M:%S") 487 | if datetime.datetime.now() + datetime.timedelta(hours=3) < stryDateTime + datetime.timedelta(minutes=10): 488 | tradeMgr.processEvent(event, "LONG", recTime) 489 | else: 490 | print "Story too stale skipping!" 491 | 492 | elif shortStrat.isEvent(event): 493 | print row, " RECV", str(recTime) 494 | print "SHORT the above event!" 495 | print " PROCESSED", str(datetime.datetime.now()) 496 | fh2.write(str(row) + " SHORT" + str(datetime.datetime.now()) + " RECV:" + str(recTime) + " PROCESSED: " + str(datetime.datetime.now()) + "\n") 497 | stryDateTime = datetime.datetime.strptime(row['release_datetime'], "%Y-%m-%d %H:%M:%S") 498 | print "Event NYC time: ", str(stryDateTime), " Recv NYC time: ", str(datetime.datetime.now() + datetime.timedelta(hours=3)) 499 | if datetime.datetime.now() + datetime.timedelta(hours=3) < stryDateTime + datetime.timedelta(minutes=10): 500 | tradeMgr.processEvent(event, "SHORT", recTime) 501 | else: 502 | print "Story too stale skipping!" 503 | else: 504 | fh1.write(" PROCESSED: " + str(datetime.datetime.now())) 505 | 506 | def TimerDaemon(tradeMgr): 507 | print "TimerDaemon started" 508 | print tradeMgr 509 | # Get to the 30 minute mark 510 | while(datetime.datetime.now().minute != 30): 511 | time.sleep(1) 512 | # Now sleep every 30 min 513 | while(1): 514 | print str(datetime.datetime.now()) 515 | time.sleep(1800) 516 | tradeMgr.run() 517 | 518 | if __name__ == '__main__': 519 | 520 | tradeMgr = TradeManager() 521 | FOWScanner(tradeMgr) 522 | 523 | 524 | # Psuedo Code 525 | # Wait for stories to come in 526 | # When story reaches send out order 527 | # If order fails because of: 528 | # 1. Wrong order settings (no contract found) 529 | # then: skip order 530 | # 2. Market Closed 531 | # then: Add order to queue. Wait for market open, order a market on open order 532 | # 533 | # If no active order and 930am has reached: 534 | # Buy all orders and wait until 330pm and sell 535 | # 536 | # 537 | # Sending out orders 538 | # 1. reqMktData to get current price of stock <- Wait for IB response 539 | # 2. Come up with in the money option details. Variables: In the money Strike, Expiry, Call/Put, 540 | # 3. reqContractDetails to get contractID, <- Wait for IB response 541 | # 4. reqMktData to get option price <- Wait for IB response 542 | # 5. reqAccountUpdates to see how much Cash <- Wait for IB response 543 | # 6. calculate number of option contracts to buy 544 | # 7. placeOrder() 545 | -------------------------------------------------------------------------------- /Trading/fowscanner.py: -------------------------------------------------------------------------------- 1 | import urllib, urllib2, cookielib, re 2 | from urllib2 import HTTPError, URLError 3 | from httplib import IncompleteRead, BadStatusLine 4 | from ssl import SSLError 5 | from bs4 import BeautifulSoup 6 | from time import gmtime, localtime, strftime 7 | import sys 8 | from datetime import datetime, date 9 | 10 | theurl = "http://www.theflyonthewall.com/beta/news.php" 11 | txheader = {'User-Agent' : 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'} 12 | 13 | def scan(): 14 | 15 | # From 4pm to 6pm EST we will hit the server without Privoxy, we get 200ms response time. o'wise its 400ms 16 | mylocaltime = datetime.now() 17 | if mylocaltime.hour >= 13 and mylocaltime.hour <= 16: 18 | cj = cookielib.CookieJar() 19 | opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj)) 20 | else: 21 | proxy_support = urllib2.ProxyHandler({"http" : "127.0.0.1:8118"}) 22 | opener = urllib2.build_opener(proxy_support) 23 | 24 | try: 25 | resp = opener.open(theurl) 26 | except HTTPError: 27 | #print "HTTPError found" 28 | return [] 29 | except SSLError: 30 | #print "SSLError found" 31 | return [] 32 | except URLError: 33 | #print "URLError found" 34 | return [] 35 | 36 | # Parse the page response 37 | try: 38 | soup = BeautifulSoup(resp.read()) 39 | except IncompleteRead: 40 | print "Incomplete Read" 41 | return [] 42 | except BadStatusLine: 43 | print "BadStatusLine" 44 | return [] 45 | # Grab the necessary data 46 | events = [] 47 | 48 | for i in soup.find_all('li'): 49 | if i.has_key('id'): 50 | if i['id'].startswith('li_'): 51 | xvar = i 52 | id = re.sub(r'li_', '', i['id']) 53 | time = i.find(id="horaCompleta").string 54 | tickers = [] 55 | headline = None 56 | text = None 57 | links = [] 58 | links_str = "" 59 | for j in i.find_all(attrs={'onclick':re.compile("^searchSymbols")}): 60 | clean_ticker = re.sub(r'\(|\)|\+', '', j.string) 61 | tickers.append(clean_ticker) 62 | if(i.find(attrs={'class':'Headline'})): 63 | headline = i.find(attrs={'class':'Headline'}).string 64 | elif(i.find(attrs={'class':'withOutHeadline'})): 65 | headline = i.find(attrs={'class':'withOutHeadline'}).string 66 | text = i.find(attrs={'class':'withOutHeadline'}).string 67 | if(i.find(attrs={'class':re.compile("^nw")})): 68 | text = i.find(attrs={'class':re.compile("^nw")}).get_text() 69 | elif(i.find(attrs={'class':'pAlone'})): 70 | text = i.find(attrs={'class':'pAlone'}).get_text() 71 | if(i.find(attrs={'class':re.compile("^iconos")})): 72 | classification = i.find(attrs={'class':re.compile("^iconos")})['title'] 73 | for j in i.find_all('a'): 74 | links.append(j.get('href')) 75 | now = strftime("%Y-%m-%d %H:%M:%S", localtime()) 76 | tickers_str = ','.join(tickers) 77 | links_str = ','.join(links) 78 | # Cant find a headline or story 79 | if (headline == None and text == None): 80 | continue 81 | if (headline == None): 82 | headline = text 83 | event = dict({'id':id, 'release_datetime':time, 'classification':classification, 'ticker':tickers, 'headline':headline, 'story':text}) 84 | events.append(event) 85 | id = None; tickers_str = None; classification = None; headline = None; text = None; 86 | return events 87 | 88 | 89 | -------------------------------------------------------------------------------- /Trading/strategy.py: -------------------------------------------------------------------------------- 1 | import re 2 | import sys 3 | sys.path.append('/home/mchan/git/Artemis/util') 4 | import dbutil 5 | 6 | class Strategy(object): 7 | """ 8 | Strategy class to define enter and exit points given a ticker, and event headline from theflyonthewall.com 9 | """ 10 | def __init__(self): 11 | self.rank = None 12 | self.db = dbutil.db(h='127.0.0.1', schema='mchan') 13 | self.cursor = self.db.cursor 14 | 15 | def epsParse(self, value): 16 | if value == None or value == '': 17 | return 18 | mult = -1 if re.search(r'\(', value) else 1 19 | divider = 100 if re.search(r'c', value) else 1 20 | mult = 1000*mult if re.search(r'B', value) else mult 21 | scrubbed = re.sub(r'[^0-9.]', '', value) 22 | try: 23 | return mult * float(scrubbed)/divider 24 | except ValueError, e: 25 | print "ValueError ", e 26 | return 27 | 28 | def earningsPerformance(self, actual, expected): 29 | mult = -1 if actual < expected else 1 30 | expected = expected if expected != 0 else 0.0001 31 | return mult * abs( (actual - expected) / expected) 32 | 33 | 34 | def calcConsensus(self, Headline): 35 | regex = re.compile('\d+c|\(\d+c\)|\(\$\d+.\d*[MB]*\)|\$\d+.\d*[MB]*|[cC]onsensus|from|estimate|outlook|vs\.') 36 | HeadlineValues = regex.findall(Headline) 37 | #print HeadlineValues 38 | parsedHeadline = [] 39 | #print parsedHeadline 40 | for i in range(0, len(HeadlineValues)): 41 | if re.search(r'[cC]onsensus|from|estimate|outlook|vs\.', HeadlineValues[i]): 42 | if i+1 <= len(HeadlineValues)-1: 43 | parsedHeadline.append(HeadlineValues[i+1]) 44 | break 45 | else: 46 | parsedHeadline.append(HeadlineValues[i]) 47 | values = [self.epsParse(value) for value in parsedHeadline] 48 | #print values 49 | if len(values) == 2: 50 | performance = self.earningsPerformance(values[0], values[1]) 51 | return performance 52 | elif len(values) == 3: 53 | lowActual = values[0] 54 | highActual = values[1] 55 | meanActual = (lowActual + highActual) / 2 56 | performance = self.earningsPerformance(meanActual, values[2]) 57 | return performance 58 | else: 59 | return False 60 | 61 | 62 | class LongEarningsGuidance(Strategy): 63 | """ 64 | This strategy goes for earnings forecast surprises (headline contains 'sees') of greater than 3% 65 | Market cap of company must be < 5000M and > 500M 66 | Must have a eq_region_rank of > 10 67 | Headline must not contain test with 'c)' since we do not want negative earnings companies 68 | Headline must not contain 'adjusted' 69 | Headline must contain 'consensus' and 'see' 70 | """ 71 | 72 | def __init__(self): 73 | #Initialize the super class so variables are available 74 | Strategy.__init__(self) 75 | self.rank = 0 76 | self.surprise_min = 0.03 77 | self.marketcap_min = 500 # in millions 78 | self.marketcap_max = 5000 79 | self.eqscore_min = 7 80 | 81 | 82 | def isEvent(self, Event): 83 | """ 84 | Event is a dictionary with keys 'ticker', 'classification', 'headline' 85 | Function will return True/False 86 | """ 87 | hline = Event['headline'] 88 | if Event['classification'] != 'Earnings': 89 | return False 90 | # All conditions for allowing based on headline 91 | if not re.search(r'see|[cC]onsensus|rais|affirm|prior|estimate|outlook|from', hline) \ 92 | or re.search(r'c\)|adjusted|report|says', hline): 93 | return False 94 | 95 | # Must have either "consensus" or "from" 96 | if not re.search(r'[cC]onsensus|from', hline): 97 | return False 98 | 99 | # Calculate the consensus eps surprise 100 | #print self.calcConsensus(hline) 101 | if self.calcConsensus(hline) == False or self.calcConsensus(hline) < self.surprise_min: 102 | return False 103 | #print "High enough outperform" 104 | # Now check some requirements that can only be found in sql tables, like market cap, eq score 105 | sql = """SELECT s.market_cap_usd_mm FROM mchan.security_price s 106 | INNER JOIN mchan.mapping m 107 | ON m.security_id = s.security_id 108 | WHERE m.ticker = '%s' 109 | ORDER BY as_of_date DESC 110 | LIMIT 1;""" % Event['ticker'] 111 | marketcap = self.db.query(sql) 112 | try: 113 | test = marketcap[0][0] 114 | except: 115 | print "Cant get market cap for" , Event['ticker'] 116 | return False 117 | if marketcap[0][0] < self.marketcap_min or marketcap[0][0] > self.marketcap_max: 118 | return False 119 | 120 | #print "Good marketcap" 121 | 122 | sql = """SELECT s.eq_region_rank FROM mchan.s_daily s 123 | INNER JOIN mchan.mapping m 124 | ON m.security_id = s.security_id 125 | WHERE m.ticker = '%s' 126 | ORDER BY as_of_date DESC 127 | LIMIT 1;""" % Event['ticker'] 128 | eqscore = self.db.query(sql) 129 | #print "EQ score is: " , eqscore[0][0] 130 | if eqscore[0][0] < self.eqscore_min: 131 | return False 132 | #print "Good eq score" 133 | # We've made it! All conditions met, return True 134 | #print "Result is True LONG", Event 135 | return True 136 | 137 | 138 | class ShortEarningsGuidance(Strategy): 139 | """ 140 | This strategy goes for earnings forecast surprises (headline contains 'sees') of worse than -5% 141 | Market cap of company must be < 2000M and > 500M 142 | Must have a eq of < 50 143 | Headline must contain 'consensus' and 'see' 144 | """ 145 | 146 | def __init__(self): 147 | #Initialize the super class so variables are available 148 | Strategy.__init__(self) 149 | self.rank = 0 150 | self.surprise_max = -0.05 151 | self.marketcap_min = 500 # in millions 152 | self.marketcap_max = 2000 153 | self.eqscore_max = 75 154 | # self.eqscore_max = 50 155 | 156 | def isEvent(self, Event): 157 | """ 158 | Event is a dictionary with keys 'ticker', 'classification', 'headline' 159 | Function will return True/False 160 | """ 161 | hline = Event['headline'] 162 | if Event['classification'] != 'Earnings': 163 | return False 164 | # All conditions for allowing based on headline 165 | if not re.search(r'see|[cC]onsensus|lower|cuts|prior|outlook|from|estimate', hline): 166 | return False 167 | if re.search(r'report|says', hline): 168 | return False 169 | 170 | # Must have either "consensus" or "from" 171 | if not re.search(r'[cC]onsensus|from', hline): 172 | return False 173 | 174 | # Calculate the consensus eps surprise 175 | if self.calcConsensus(hline) == False or self.calcConsensus(hline) > self.surprise_max: 176 | return False 177 | #print "High enough outperform" 178 | # Now check some requirements that can only be found in sql tables, like market cap, eq score 179 | sql = """SELECT s.market_cap_usd_mm FROM mchan.security_price s 180 | INNER JOIN mchan.mapping m 181 | ON m.security_id = s.security_id 182 | WHERE m.ticker = '%s' 183 | ORDER BY as_of_date DESC 184 | LIMIT 1;""" % Event['ticker'] 185 | marketcap = self.db.query(sql) 186 | try: 187 | test = marketcap[0][0] 188 | except: 189 | print "Cant get market cap for" , Event['ticker'] 190 | return False 191 | if marketcap[0][0] < self.marketcap_min or marketcap[0][0] > self.marketcap_max: 192 | return False 193 | 194 | #print "Good marketcap" 195 | 196 | sql = """SELECT s.eq_region_rank FROM mchan.s_daily s 197 | INNER JOIN mchan.mapping m 198 | ON m.security_id = s.security_id 199 | WHERE m.ticker = '%s' 200 | ORDER BY as_of_date DESC 201 | LIMIT 1;""" % Event['ticker'] 202 | eqscore = self.db.query(sql) 203 | #print "EQ score is: " , eqscore[0][0] 204 | if eqscore[0][0] > self.eqscore_max: 205 | return False 206 | #print "Good eq score" 207 | # We've made it! All conditions met, return True 208 | #print "Result is True SHORT", Event 209 | return True 210 | -------------------------------------------------------------------------------- /Trading/tws_reconnect_test.py: -------------------------------------------------------------------------------- 1 | import strategy 2 | import fowscanner 3 | import datetime 4 | import multiprocessing 5 | import time 6 | import sys 7 | from swigibpy import EWrapper, EPosixClientSocket, Contract 8 | sys.path.append('/home/mchan/git/Artemis/SwigIbPy') 9 | from ArtemisIBWrapper import ArtemisIBWrapper 10 | 11 | 12 | callback = ArtemisIBWrapper() 13 | tws = EPosixClientSocket(callback) 14 | # Connect the socket 15 | socketnum = 10 16 | tws.eConnect("", 7496, socketnum, poll_interval=1) 17 | 18 | for i in range(0,4): 19 | socketnum += 1 20 | tws.eDisconnect() 21 | print "Socket number: ", socketnum 22 | tws.eConnect("", 7496, socketnum, poll_interval=1) 23 | time.sleep(3) 24 | -------------------------------------------------------------------------------- /example.py: -------------------------------------------------------------------------------- 1 | ''' Simple example of using the SWIG generated TWS wrapper to request historical 2 | data from interactive brokers. 3 | 4 | Note: 5 | * Communication with TWS is asynchronous; requests to TWS are made through the 6 | EPosixClientSocket class and TWS responds at some later time via the functions 7 | in our EWrapper subclass. 8 | * If you're using a demo account TWS will only respond with a limited time 9 | period, no matter what is requested. Also the data returned is probably wholly 10 | unreliable. 11 | 12 | ''' 13 | 14 | from datetime import datetime 15 | import time 16 | 17 | from swigibpy import EWrapper, EPosixClientSocket, Contract 18 | 19 | ### 20 | 21 | class HistoricalDataExample(EWrapper): 22 | '''Callback object passed to TWS, these functions will be called directly 23 | by TWS. 24 | 25 | ''' 26 | 27 | def nextValidId(self, orderId): 28 | '''Always called by TWS but not relevant for our example''' 29 | pass 30 | 31 | def openOrderEnd(self): 32 | '''Always called by TWS but not relevant for our example''' 33 | pass 34 | 35 | def managedAccounts(self, openOrderEnd): 36 | '''Called by TWS but not relevant for our example''' 37 | pass 38 | 39 | def historicalData(self, reqId, date, open, high, 40 | low, close, volume, 41 | barCount, WAP, hasGaps): 42 | 43 | if date[:8] == 'finished': 44 | print "History request complete" 45 | else: 46 | date = datetime.strptime(date, "%Y%m%d").strftime("%d %b %Y") 47 | print ( "History %s - Open: %s, High: %s, Low: %s, Close: " + 48 | "%s, Volume: %d" ) % (date, open, high, low, close, volume) 49 | 50 | 51 | # Instantiate our callback object 52 | callback = HistoricalDataExample() 53 | 54 | # Instantiate a socket object, allowing us to call TWS directly. Pass our 55 | # callback object so TWS can respond. 56 | tws = EPosixClientSocket(callback) 57 | 58 | # Connect to tws running on localhost 59 | tws.eConnect("", 7496, 42, poll_interval=1) 60 | 61 | # Simple contract for GOOG 62 | contract = Contract() 63 | contract.exchange = "SMART" 64 | contract.symbol = "RIMM" 65 | contract.secType = "STK" 66 | #contract.right = "CALL" 67 | contract.currency = "USD" 68 | today = datetime.today() 69 | 70 | print "Requesting historical data for %s" % contract.symbol 71 | 72 | # Request some historical data. 73 | tws.reqHistoricalData( 74 | 1, #tickerId, 75 | contract, #contract, 76 | today.strftime("%Y%m%d %H:%M:%S %Z"), #endDateTime, 77 | "1 W", #durationStr, 78 | "1 day", #barSizeSetting, 79 | "TRADES", #whatToShow, 80 | 0, #useRTH, 81 | 1 #formatDate 82 | ) 83 | 84 | print "\n=====================================================================" 85 | print " History requested, waiting for TWS responses" 86 | print "=====================================================================\n" 87 | 88 | 89 | print "******************* Press ENTER to quit when done *******************\n" 90 | #raw_input() 91 | 92 | #print "\nDisconnecting..." 93 | #tws.eDisconnect() 94 | #time.sleep(1) 95 | -------------------------------------------------------------------------------- /example2.py: -------------------------------------------------------------------------------- 1 | ''' Simple example of using the SWIG generated TWS wrapper to request historical 2 | data from interactive brokers. 3 | 4 | Note: 5 | * Communication with TWS is asynchronous; requests to TWS are made through the 6 | EPosixClientSocket class and TWS responds at some later time via the functions 7 | in our EWrapper subclass. 8 | * If you're using a demo account TWS will only respond with a limited time 9 | period, no matter what is requested. Also the data returned is probably wholly 10 | unreliable. 11 | 12 | ''' 13 | 14 | from datetime import datetime, timedelta 15 | import time 16 | 17 | from swigibpy import EWrapper, EPosixClientSocket, Contract, Order 18 | 19 | import sys 20 | sys.path.append('/home/mchan/git/Artemis/SwigIbPy/') 21 | from ArtemisIBWrapper import ArtemisIBWrapper 22 | ### 23 | 24 | # Instantiate our callback object 25 | callback = ArtemisIBWrapper() 26 | 27 | # Instantiate a socket object, allowing us to call TWS directly. Pass our 28 | # callback object so TWS can respond. 29 | tws = EPosixClientSocket(callback) 30 | 31 | # Connect to tws running on localhost 32 | #tws.eConnect("", 7496, 47, poll_interval=1) 33 | tws.eConnect("", 7496, 47) 34 | accountNumber = '' 35 | # Simple contract for GOOG 36 | contract = Contract() 37 | #contract.conId = 114376112 38 | contract.exchange = "SMART" 39 | contract.symbol = "PRXL" 40 | contract.secType = "STK" 41 | #contract.right = "PUT" 42 | contract.currency = "USD" 43 | #contract.secType = 'OPT' 44 | #contract.strike = 24 45 | #contract.expiry = '20121116' 46 | today = datetime.today() 47 | 48 | #callback.tickDataEnd = False 49 | #tws.reqMktData(1, contract, "", 1) 50 | #while (not callback.tickDataEnd): 51 | # pass 52 | #print "Market data request sent, ASK price is: ", callback.askPrice 53 | #askPrice = 23.04 54 | callback.contractDataEnd = False 55 | callback.StrikesHash = dict() 56 | callback.Strikes = [] 57 | 58 | #tws.reqContractDetails(1, contract) 59 | #while not callback.contractDataEnd: 60 | # pass 61 | #for i in range(0, len(sorted(callback.Strikes))): 62 | # if sorted(callback.Strikes)[i] > askPrice: 63 | # callStrikePrice = sorted(callback.Strikes)[i-1] 64 | # callConId = callback.StrikesHash[callStrikePrice][0] 65 | # callMultiplier = callback.StrikesHash[callStrikePrice][1] 66 | # putStrikePrice = sorted(callback.Strikes)[i] 67 | # putConId = callback.StrikesHash[putStrikePrice][0] 68 | # putMultiplier = callback.StrikesHash[putStrikePrice][1] 69 | # break 70 | 71 | order = Order() 72 | order.orderId = 7 73 | order.clientId = 46 74 | order.action = "SELL" 75 | order.totalQuantity = 78 # may have to calculate a smarter number 76 | order.orderType = "MKT" 77 | order.tif = "DAY" 78 | order.transmit = True 79 | order.sweepToFill = False 80 | order.outsideRth = True 81 | 82 | 83 | callback.accountEnd = False 84 | portfolioList = [] 85 | callback.portfolioContract = None 86 | callback.portfolioPosition = None 87 | 88 | tws.reqAccountUpdates(1, accountNumber) 89 | #while (not callback.accountEnd): 90 | # callback.portfolioContract = None 91 | # callback.portfolioPosition = None 92 | # max_wait = timedelta(seconds=6) + datetime.now() 93 | # while (callback.portfolioPosition is None or callback.portfolioContract is None): 94 | # if datetime.now() > max_wait: 95 | # break 96 | # if callback.portfolioPosition is not None and callback.portfolioContract is not None: 97 | # myContract = Contract() 98 | # myContract.exchange = "SMART" 99 | # myContract.currency = "USD" 100 | # myContract.symbol = callback.portfolioContractSymbol 101 | # myContract.conId = callback.portfolioContractConId 102 | # myContract.secType = callback.portfolioContractSecType 103 | # myContract.strike = callback.portfolioContractStrike 104 | # myContract.expiry = callback.portfolioContractExpiry 105 | # myContract.right = callback.portfolioContractRight 106 | # myPosition = callback.portfolioPosition 107 | # portfolioList.append((myContract, myPosition)) 108 | # 109 | tws.reqAccountUpdates(0, accountNumber) 110 | 111 | 112 | #contract.symbol = "alkdjflk" 113 | #callback.askPrice = None 114 | #tws.reqMktData(2, contract, "", 1) 115 | #max_wait = timedelta(seconds=30) + datetime.now() 116 | #while callback.askPrice is None: 117 | # if datetime.now() > max_wait: 118 | # print "max wait giving up" 119 | # break 120 | #print callback.askPrice 121 | 122 | #print "\nDisconnecting..." 123 | #tws.eDisconnect() 124 | #time.sleep(1) 125 | 126 | # Request some historical data. 127 | #callback.lastClose = None 128 | #callback.close = None 129 | #tws.reqHistoricalData( 130 | # 2, #tickerId, 131 | # contract, #contract, 132 | # today.strftime("%Y%m%d %H:%M:%S %Z"), #endDateTime, 133 | # "1 D", #durationStr, 134 | # "1 hour", #barSizeSetting, 135 | # "BID_ASK", #whatToShow, 136 | # 0, #useRTH, 137 | # 1 #formatDate 138 | # ) 139 | # 140 | #while (callback.close is None): 141 | # pass 142 | 143 | 144 | #callback.accountEnd = False 145 | #tws.reqAccountUpdates(1, '') 146 | #while not callback.accountEnd: 147 | # pass 148 | 149 | callback.askPrice = None 150 | callback.lastPrice = None 151 | callback.closePrice = None 152 | callback.tickDataEnd = False 153 | tws.reqMktData(2, contract, "", 0) 154 | 155 | max_wait = timedelta(seconds=30) + datetime.now() 156 | while callback.askPrice is None: 157 | time.sleep(0.0001) 158 | if datetime.now() > max_wait: 159 | print "max wait giving up" 160 | break 161 | tws.cancelMktData(2) 162 | print "Here's the ask price: ", callback.askPrice 163 | 164 | -------------------------------------------------------------------------------- /example3.py: -------------------------------------------------------------------------------- 1 | ''' Simple example of using the SWIG generated TWS wrapper to request historical 2 | data from interactive brokers. 3 | 4 | Note: 5 | * Communication with TWS is asynchronous; requests to TWS are made through the 6 | EPosixClientSocket class and TWS responds at some later time via the functions 7 | in our EWrapper subclass. 8 | * If you're using a demo account TWS will only respond with a limited time 9 | period, no matter what is requested. Also the data returned is probably wholly 10 | unreliable. 11 | 12 | ''' 13 | 14 | from datetime import datetime, timedelta 15 | import time 16 | 17 | from swigibpy import EWrapper, EPosixClientSocket, Contract, Order 18 | 19 | import sys 20 | sys.path.append('/home/mchan/git/Artemis/SwigIbPy/') 21 | from ArtemisIBWrapper import ArtemisIBWrapper 22 | ### 23 | 24 | # Instantiate our callback object 25 | class testTWS(object): 26 | def __init__(self): 27 | self.callback = ArtemisIBWrapper() 28 | self.tws = EPosixClientSocket(self.callback) 29 | self.tws.eConnect("", 7496, 44, poll_interval=1) 30 | 31 | def run(self): 32 | # Simple contract for GOOG 33 | contract = Contract() 34 | #contract.conId = 114376112 35 | contract.exchange = "SMART" 36 | contract.symbol = "ATK" 37 | contract.secType = "STK" 38 | #contract.right = "PUT" 39 | contract.currency = "USD" 40 | #contract.secType = 'OPT' 41 | #contract.strike = 24 42 | #contract.expiry = '20121116' 43 | today = datetime.today() 44 | 45 | order = Order() 46 | order.orderId = 89 47 | order.clientId = 44 48 | order.action = "BUY" 49 | order.totalQuantity = 1 # may have to calculate a smarter number 50 | order.orderType = "MKT" 51 | order.tif = "DAY" 52 | order.transmit = True 53 | order.sweepToFill = True 54 | order.outsideRth = True 55 | 56 | contract.symbol = "alkjdf" 57 | self.callback.askPrice = None 58 | self.tws.reqMktData(2, contract, "", 1) 59 | max_wait = timedelta(seconds=30) + datetime.now() 60 | while self.callback.askPrice is None: 61 | if datetime.now() > max_wait: 62 | print "max wait giving up" 63 | break 64 | print self.callback.askPrice 65 | 66 | 67 | if __name__ == '__main__': 68 | myTest = testTWS() 69 | myTest.run() 70 | 71 | 72 | #print "\nDisconnecting..." 73 | #tws.eDisconnect() 74 | #time.sleep(1) 75 | 76 | # Request some historical data. 77 | #callback.lastClose = None 78 | #callback.close = None 79 | #tws.reqHistoricalData( 80 | # 1, #tickerId, 81 | # contract, #contract, 82 | # today.strftime("%Y%m%d %H:%M:%S %Z"), #endDateTime, 83 | # "1 D", #durationStr, 84 | # "1 hour", #barSizeSetting, 85 | # "BID_ASK", #whatToShow, 86 | # 0, #useRTH, 87 | # 1 #formatDate 88 | # ) 89 | # 90 | #while (callback.close is None): 91 | # pass 92 | 93 | 94 | #callback.accountEnd = False 95 | #tws.reqAccountUpdates(1, '') 96 | #while not callback.accountEnd: 97 | # pass 98 | 99 | -------------------------------------------------------------------------------- /example4.py: -------------------------------------------------------------------------------- 1 | ''' Simple example of using the SWIG generated TWS wrapper to request historical 2 | data from interactive brokers. 3 | 4 | Note: 5 | * Communication with TWS is asynchronous; requests to TWS are made through the 6 | EPosixClientSocket class and TWS responds at some later time via the functions 7 | in our EWrapper subclass. 8 | * If you're using a demo account TWS will only respond with a limited time 9 | period, no matter what is requested. Also the data returned is probably wholly 10 | unreliable. 11 | 12 | ''' 13 | 14 | from datetime import datetime, timedelta 15 | import time 16 | 17 | from swigibpy import EWrapper, EPosixClientSocket, Contract, Order 18 | 19 | import sys 20 | sys.path.append('/home/mchan/git/Artemis/SwigIbPy/') 21 | from ArtemisIBWrapper import ArtemisIBWrapper 22 | ### 23 | 24 | # Instantiate our callback object 25 | class testTWS(object): 26 | def __init__(self): 27 | self.callback = ArtemisIBWrapper() 28 | self.tws = EPosixClientSocket(self.callback) 29 | self.tws.eConnect("", 7496, 44, poll_interval=1) 30 | 31 | def run(self): 32 | # Simple contract for GOOG 33 | contract = Contract() 34 | #contract.conId = 114376112 35 | contract.exchange = "SMART" 36 | contract.symbol = "ATK" 37 | contract.secType = "STK" 38 | #contract.right = "PUT" 39 | contract.currency = "USD" 40 | #contract.secType = 'OPT' 41 | #contract.strike = 24 42 | #contract.expiry = '20121116' 43 | today = datetime.today() 44 | 45 | order = Order() 46 | order.orderId = 89 47 | order.clientId = 44 48 | order.action = "BUY" 49 | order.totalQuantity = 1 # may have to calculate a smarter number 50 | order.orderType = "MKT" 51 | order.tif = "DAY" 52 | order.transmit = True 53 | order.sweepToFill = True 54 | order.outsideRth = True 55 | 56 | contract.symbol = "alkjdf" 57 | self.callback.askPrice = None 58 | self.tws.reqMktData(2, contract, "", 1) 59 | max_wait = timedelta(seconds=30) + datetime.now() 60 | while self.callback.askPrice is None: 61 | if datetime.now() > max_wait: 62 | print "max wait giving up" 63 | break 64 | print self.callback.askPrice 65 | 66 | 67 | if __name__ == '__main__': 68 | myTest = testTWS() 69 | myTest.run() 70 | 71 | 72 | #print "\nDisconnecting..." 73 | #tws.eDisconnect() 74 | #time.sleep(1) 75 | 76 | # Request some historical data. 77 | #callback.lastClose = None 78 | #callback.close = None 79 | #tws.reqHistoricalData( 80 | # 1, #tickerId, 81 | # contract, #contract, 82 | # today.strftime("%Y%m%d %H:%M:%S %Z"), #endDateTime, 83 | # "1 D", #durationStr, 84 | # "1 hour", #barSizeSetting, 85 | # "BID_ASK", #whatToShow, 86 | # 0, #useRTH, 87 | # 1 #formatDate 88 | # ) 89 | # 90 | #while (callback.close is None): 91 | # pass 92 | 93 | 94 | #callback.accountEnd = False 95 | #tws.reqAccountUpdates(1, '') 96 | #while not callback.accountEnd: 97 | # pass 98 | 99 | -------------------------------------------------------------------------------- /example_historicaldata.py: -------------------------------------------------------------------------------- 1 | ''' Simple example of using the SWIG generated TWS wrapper to request historical 2 | data from interactive brokers. 3 | 4 | Note: 5 | * Communication with TWS is asynchronous; requests to TWS are made through the 6 | EPosixClientSocket class and TWS responds at some later time via the functions 7 | in our EWrapper subclass. 8 | * If you're using a demo account TWS will only respond with a limited time 9 | period, no matter what is requested. Also the data returned is probably wholly 10 | unreliable. 11 | 12 | ''' 13 | 14 | from datetime import datetime, timedelta 15 | import time 16 | 17 | from swigibpy import EWrapper, EPosixClientSocket, Contract, Order 18 | 19 | import sys 20 | sys.path.append('/home/mchan/git/Artemis/SwigIbPy/') 21 | from DataDownloadIBWrapper import ArtemisIBWrapper 22 | #from ArtemisIBWrapper import ArtemisIBWrapper 23 | ### 24 | 25 | # Instantiate our callback object 26 | callback = ArtemisIBWrapper() 27 | 28 | # Instantiate a socket object, allowing us to call TWS directly. Pass our 29 | # callback object so TWS can respond. 30 | tws = EPosixClientSocket(callback) 31 | 32 | # Connect to tws running on localhost 33 | tws.eConnect("", 7496, 46, poll_interval=1) 34 | accountNumber = '' 35 | contract = Contract() 36 | contract.exchange = "SMART" 37 | contract.symbol = "TOT" 38 | contract.secType = "STK" 39 | #contract.right = "PUT" 40 | contract.currency = "USD" 41 | #contract.secType = 'OPT' 42 | #contract.strike = 24 43 | #contract.expiry = '20121116' 44 | today = datetime.today() 45 | 46 | 47 | #tws.reqAccountUpdates(1, accountNumber) 48 | #tws.reqAccountUpdates(0, accountNumber) 49 | 50 | 51 | callback.histTickerID = contract.symbol 52 | tws.reqHistoricalData( 53 | 1, #tickerId, 54 | contract, #contract, 55 | datetime(2012, 11, 2, 23, 59, 59).strftime("%Y%m%d %H:%M:%S"), #endDateTime, 56 | "2 D", #durationStr, 57 | "1 min", #barSizeSetting, 58 | "TRADES", #whatToShow, 59 | 0, #useRTH, 60 | 1 #formatDate 61 | ) 62 | --------------------------------------------------------------------------------