def getQuotes(self, theo, book): """Returns quotes, if quoter disabled returns quotes at max width """ self.expireOrders() best_bid = book["bids"][0][0] best_ask = book["asks"][0][0] if self.bid["enabled"] and self.quoter and self.bid[ "status"] == "dead" and not np.isnan(theo): bid_price = int(theo - self.edge) bid_size = self.size bid_expiry = tools.curTime() + self.duration if bid_price > best_ask: bid_price = best_ask - self.backup else: bid_price = 0 bid_size = 0 bid_expiry = 0 if self.ask["enabled"] and self.quoter and self.ask[ "status"] == "dead" and not np.isnan(theo): ask_price = int(round(theo + self.edge + 0.5)) ask_size = self.size ask_expiry = tools.curTime() + self.duration if ask_price < best_bid: ask_price = best_bid + self.backup else: ask_price = 100 ask_size = 0 ask_expiry = 0 return [(bid_price, int(bid_size), int(bid_expiry)), (ask_price, int(ask_size), int(ask_expiry))]
def loadStrategies(self, league="all", matchType="all", edge=3, size=10000000000000000, duration=tools.MINUTE * 10, quoter=False, hitter=False): """Loads strategies in league specified of type specified """ for m in self.gateway.matches: match = self.gateway.matches[m] if match.details["expiry"] < tools.curTime(): continue if match.details["league"] != league and league != "all": continue if match.details["type"] != matchType and matchType != "all": continue if match.matchName in self.strategiesByMatch: if len(self.strategiesByMatch[ match.matchName]) >= self.maxStrategiesPerMatch: continue else: self.strategiesByMatch[match.matchName] = [] #if we've made it this far, we want to add this match self.logger.info( "Adding strategy for {0} with edge {1}, size {2}, quoter status {3}, hitter status {4}" .format(match.matchName, edge, size, quoter, hitter)) s = strategy.Strategy(match, edge, size, duration, quoter, hitter) idx = len(self.strategies) self.strategies.append(s) self.strategiesByMatch[match.matchName].append(idx)
def refreshOdds(self): """Loads odds, checks if empty or update time exceeds refresh interval. If exceed refresh interval queries odds. """ if tools.curTime() - self.last_refresh > self.refresh_interval: print("Loading odds") self.loadOdds() if len(self.df_odds) == 0: print("Odds not found, querying odds") self.queryOdds() else: #check if the last query was recent if tools.curTime() - self.df_odds.lastUpdated.min( ) > self.refresh_interval: print("Odds stale, querying odds") self.queryOdds() self.last_refresh = tools.curTime()
def submitOrders(self, strategy): """Gets orders from a given strategy and submits if applicable """ if strategy.match.details['expiry'] < tools.curTime(): return theo = self.pricing.getTheo(strategy.match) book = self.getBook(strategy.match.matchName) self.updateOrders(strategy) #get quotes and submit quotes = strategy.getQuotes(theo, book) #hits = strategy.getHits(theo) bid = quotes[0] ask = quotes[1] if not self.pretrade_riskcheck(): return if bid[0] > 0 and bid[1] > 0 and bid[2] > tools.curTime(): bidId = self.gateway.submitOrder(strategy.match.matchName, "buy", bid[0], bid[1], bid[2]) strategy.updateOrder(strategy.bid, sideId=bidId, price=bid[0], status="pending", expiry=bid[2], quantity=bid[1]) log_string = "Submitting bid: '{0}' Buy '{1}' @ '{2}'".format( strategy.match.matchName, bid[1], bid[0]) print(log_string) self.logger.info(log_string) if not self.pretrade_riskcheck(): return if ask[0] > 0 and ask[1] > 0 and ask[2] > tools.curTime(): askId = self.gateway.submitOrder(strategy.match.matchName, "sell", ask[0], ask[1], ask[2]) strategy.updateOrder(strategy.ask, sideId=askId, price=ask[0], status="pending", expiry=ask[2], quantity=bid[1]) log_string = "Submitting ask: '{0}' Sell '{1}' @ '{2}'".format( strategy.match.matchName, ask[1], ask[0]) print(log_string) self.logger.info(log_string)
def pack(self, contractAddr, matchId, amount, expiry, price, direction, fromAddress): """Takes [contractAddr], [matchId] and [fromAddress] and hex and amount, expiry, price, direction as integers. Note that expiry is expected to be in nanoseconds (ERM native) and will be converted to seconds """ orderDict = { "details": { "matchId": matchId, "amount": amount, "expiry": expiry, "nonce": hex(int(tools.curTime() / 10**9)).replace('0x', '').zfill(10), "price": price, "direction": direction, "fromAddress": fromAddress }, "hash": '', "sig": { "v": "", "r": "", "s": "" } } rawOrderDict = self.toRaw(orderDict) # int0 = tools.parseInt(rawOrderDict['details']['matchId']) # int1 = tools.parseInt(rawOrderDict['details']['amount']) # int2 = tools.parseInt('{0}{1}{2}{3}{4}'.format(rawOrderDict['details']['expiry'], # rawOrderDict['details']['nonce'], # rawOrderDict['details']['price'], # rawOrderDict['details']['direction'], # rawOrderDict['details']['fromAddress'])) #toHash = "{0}{1}{2}{3}".format(contractAddr, int0, int1, int2) toHash = '{0}{1}{2}{3}{4}{5}{6}{7}'.format( contractAddr, rawOrderDict['details']['matchId'], rawOrderDict['details']['amount'], rawOrderDict['details']['expiry'], rawOrderDict['details']['nonce'], rawOrderDict['details']['price'], rawOrderDict['details']['direction'], rawOrderDict['details']['fromAddress'], ) orderHash0 = sha3.keccak_256() orderHash0.update(codecs.decode(toHash, 'hex_codec')) orderHash1 = sha3.keccak_256() orderHash1.update(u"\x19Ethereum Signed Message:\n32".encode('utf-8') + orderHash0.digest()) orderHash = w3.toHex(orderHash1.digest()) return toHash, orderHash
def expireOrders(self): """Removes orders from order map if expired """ to_del = [] for order in self.orders: orderDict = self.orders[order] expiry = orderDict["details"]["expiry"] if expiry < tools.curTime(): to_del.append(order) for order in to_del: self.orders.pop(order, None)
def expireOrders(self): """Expires outstanding bid and ask if past expiration time """ now = tools.curTime() if self.bid["expiry"] < now: self.bid["price"] = 0 self.bid["orderId"] = 0 self.bid["status"] = "dead" self.bid["expiry"] = 0 self.bid["quantity"] = 0 if self.ask["expiry"] < now: self.ask["price"] = 100 self.ask["orderId"] = 0 self.ask["status"] = "dead" self.ask["expiry"] = 0 self.ask["quantity"] = 0
def checkMatches(self): """Takes a list of matches and returns match status response """ matches = [ self.matches[m].matchId for m in self.matches if self.matches[m].details["expiry"] > tools.curTime() ] ret = [] for i in range(0, len(matches), 16): out = self.spc.checkMatchBatch(matches[i:i + 16]) if len(ret) == 0: ret = out else: ret[0] += out[0] ret[1] += out[1] ret[2] += out[2] # for i in range(len(matches)): # matchId = matches[i] # matchName = self.matchIdtoName[matchId] # position = ret[0][i] # self.matches[matchName].position = position return ret
def queryOdds(self): """Query JSONOdds source, log query time, save dataframe of results """ with open(self.query_log, 'a+') as f: lines = 0 lines_today = 0 for line in f: query_date = datetime.datetime.strptime( line, "%Y%m%d.%H:%M:%S") if query_date.date() == datetime.datetime.utcnow().date(): lines_today += 1 lines += 1 if lines_today >= self.query_per_month / 30: print("Max queries exceeded today") return else: #going to query, write date f.write( datetime.datetime.utcnow().strftime("%Y%m%d.%H:%M:%S") + "\n") url = "https://jsonodds.com/api/odds/?oddType=Game" header = {"x-api-key": config.JSONODDS_API_KEY} r = requests.get(url, headers=header) data = json.loads(r.content) for match in data: for odd in match["Odds"][0]: match[odd] = match["Odds"][0][odd] df = pd.DataFrame(data) df['lastUpdated'] = tools.curTime() df['league'] = df.Sport.map(self.league_enum) df.to_csv(self.query_df, index=False) self.df_odds = df return
def addOrder(self, rawOrderDict, orderId=None): orderDict = self.fromRaw(rawOrderDict) if orderDict["details"]["expiry"] >= tools.curTime(): self.orders[orderId if orderId else self.internal_id] = orderDict self.internal_id += 0 if orderId else 1