def test_one_up_then_reversal(self): tick = TickEvent("EURUSD", time.time(), 1.1456, 1.1458) # Mock tick event events = queue.Queue() strategy = GridIron("EURUSD", events) strategy.calculate_signals(tick) self.assertEqual(strategy.grid.grid_mid, 1.1457, "Grid Mid was not correct") self.assertEqual(strategy.grid.buy_level_one, 1.1459, "Grid Buy Level 1 was not correct") self.assertEqual(strategy.grid.sell_level_one, 1.1455, "Grid Sell Level 1 was not correct") self.assertEqual(strategy.grid.buy_level_two, 1.1461, "Grid Buy Level 2 was not correct") self.assertEqual(strategy.grid.sell_level_two, 1.1453, "Grid Sell Level 2 was not correct") self.assertEqual(strategy.grid.stop_loss_buy, 1.1455, "Grid Stop Loss was not correct") tick2 = TickEvent("EURUSD", time.time(), 1.1459, 1.1461) strategy.calculate_signals(tick2) # now check signal signal = events.get() self.assertEqual(signal.side, "buy", "Buy Signal not generated") self.assertEqual(signal.order_type, "market", "Market Signal not generated") self.assertEqual(strategy.grid.stop_loss_buy, 1.1457, "Grid Stop Loss was not correct") self.assertEqual(strategy.grid.sell_level_one, 1.1455, "Grid Sell Level 1 was not correct") self.assertEqual(strategy.grid.buy_level_two, 1.1461, "Grid Buy Level 2 was not correct") self.assertEqual(strategy.grid.sell_level_two, 1.1453, "Grid Sell Level 2 was not correct") # Now reverse the up move tick3 = TickEvent("EURUSD", time.time(), 1.1455, 1.1457) strategy.calculate_signals(tick3) # now check signal signal = events.get() self.assertEqual(signal.side, "closeAll", "Close Out Signal not generated") self.assertEqual(signal.order_type, "market", "Market Signal not generated") self.assertEqual(strategy.grid, None, "Grid not removed")
def stream_to_queue(self): response = self.connect_to_stream() if response.status_code != 200: return for line in response.iter_lines(1): if line: try: dline = line.decode('utf-8') msg = json.loads(dline) except Exception as e: self.logger.error( "Caught exception when converting message into json: %s" % str(e)) return if "instrument" in msg or "tick" in msg: self.logger.debug(msg) getcontext().rounding = ROUND_HALF_DOWN instrument = msg["tick"]["instrument"].replace("_", "") time = msg["tick"]["time"] bid = Decimal(str(msg["tick"]["bid"])).quantize( Decimal("0.00001")) ask = Decimal(str(msg["tick"]["ask"])).quantize( Decimal("0.00001")) self.prices[instrument]["bid"] = bid self.prices[instrument]["ask"] = ask # Invert the prices (GBP_USD -> USD_GBP) inv_pair, inv_bid, inv_ask = self.invert_prices( instrument, bid, ask) self.prices[inv_pair]["bid"] = inv_bid self.prices[inv_pair]["ask"] = inv_ask self.prices[inv_pair]["time"] = time tev = TickEvent(instrument, time, bid, ask) self.events_queue.put(tev)
def stream_next_tick(self): """ The Backtester has now moved over to a single-threaded model in order to fully reproduce results on each run. This means that the stream_to_queue method is unable to be used and a replacement, called stream_next_tick, is used instead. This method is called by the backtesting function outside of this class and places a single tick onto the queue, as well as updating the current bid/ask and inverse bid/ask. """ df = pd.read_csv("%s.csv" % self.pairs[0].replace("/", "")) end = len(df) if (self.cur_date_indx < end): row = df[self.cur_date_indx:(self.cur_date_indx + 1)] bid = Decimal(str(row["bidopen"][self.cur_date_indx])).quantize( Decimal("0.00001")) ask = Decimal(str(row["askopen"][self.cur_date_indx])).quantize( Decimal("0.00001")) time = row["time"][self.cur_date_indx] # Create decimalised prices for traded pair self.prices[self.pairs[0]]["bid"] = bid self.prices[self.pairs[0]]["ask"] = ask self.prices[self.pairs[0]]["time"] = time # Create the tick event for the queue tev = TickEvent(self.pairs[0], time, bid, ask) self.events_queue.put(tev) self.cur_date_indx += 1 else: self.continue_backtest = False return
def stream_to_queue(self): response = self.connect_to_stream() if response.status_code != 200: with open("history2.txt", "a") as file: file.write("not 200\n") return for line in response.iter_lines(1): with open("history2.txt", "a") as file: file.write("200\n") if line: try: msg = json.loads(line) except Exception as e: errmsg = "Caught exception when converting message into json\n" + str( e) print(errmsg) with open("history2.txt", "a") as file: file.write("{}\n".format(errmsg)) return if msg.has_key('instrument') or msg.has_key('tick'): print(msg) instrument = msg['tick']['instrument'] time = msg['tick']['time'] bid = msg['tick']['bid'] ask = msg['tick']['ask'] tev = TickEvent(instrument, time, bid, ask) self.events.put(tev) with open("history2.txt", "a") as file: file.write("time:{} bid:{}\n".format(time, bid))
def stream_to_queue(self): client = None req = None try: client = oandapyV20.API(access_token=self.access_token) params = {'instruments': self.instruments} req = pricing.PricingInfo(accountID=self.account_id, params=params) except Exception as e: errmsg = 'Caught exception when connecting to stream\n' + str(e) rq.terminate(errmsg) res = client.request(req) with open("history_stream.txt", "a") as file: file.write("@streming\tinit on ready\n") while (True): if StreamingForexPrices.put_event.is_set(): res = client.request(req) tick = res['prices'][0] instrument = tick['instrument'] time = pd.Timestamp(tick['time']) bid = tick['bids'][0]['price'] ask = tick['asks'][0]['price'] tev = TickEvent(instrument, time, bid, ask) self.events.put(tev) self.clear_tick_event() with open("history_stream.txt", "a") as file: file.write("--- put --->\n") with open("history_stream.txt", "a") as file: file.write("@Streaming\t{} {} (B:{}, A:{})\n".format( tev.time, tev.instrument, tev.bid, tev.ask))
def historic_stream_to_queue(self, dateTo, duration,instrumentList): dateFrom=dateTo-duration delta = dateTo - dateFrom dataStore=[] for index,instrument in enumerate(instrumentList): for ii in range(delta.days + 1): fileDates=((dateFrom + datetime.timedelta(days=ii))).strftime("%d-%m-%Y") path=instrument+"_"+'_'+fileDates+".h5" dataStore.append(pd.read_hdf(path, 'df')) data=pd.concat(dataStore) data=data.sort_index() for ii in range(len(data)): instrument = data['Instrument'][ii] time = data.index[ii] bid = data['Bid'][ii] ask = data['Ask'][ii] tev = TickEvent(instrument, time, bid, ask) self.events_queue.put((2,time,tev)) # Time.sleep(0.1) # print(time, bid, ask) tend=EndBT(instrument, time) self.events_queue.put((3,time,tend)) print('end of stream')
def stream_to_queue(self): response = self.ctx_stream.pricing.stream(self.account_id, snapshot=True, instruments=self.instruments) for msg_type, msg in response.parts(): if msg_type == "pricing.Price": #msg = self.on_success(msg.time, msg.asks[0].price) print(msg.instrument, msg.time, msg.asks[0].price, msg.bids[0].price) instrument = msg.instrument time = msg.time bid = msg.bids[0].price ask = msg.asks[0].price tev = TickEvent(instrument, time, bid, ask) self.events_queue.put(tev) #self.ticks += 1 #print(self.ticks, end=' ') #self.data = self.data.append( # pd.DataFrame({"time": [time], "ask": [ask]})) #self.data.index = pd.DatetimeIndex(self.data["time"]) #resam = self.data.resample("1min").last() #print(resam[["ask", "returns", "positions"]].tail()) elif msg_type == "pricing.Heartbeat" and args.show_heartbeats: print(msg)
def begin(self, instruments="BTC_JPY"): while True: data = json.dumps(self.api.ticker(product_code=instruments)) dict_data = json.loads(data) time, symbol, bid, ask = self.parse_tick_data(dict_data) event = TickEvent(symbol, time, bid, ask) self.event_queue.put(event)
def stream_to_queue(self): try: response = self.connect_to_stream() a=response.lines # print(response) if response.status != 200: print("bad request") Time.sleep(3600) self.stream_to_queue() return for line in response.lines: if line: try: msg = json.loads(line) # print(msg) except Exception as e: print("Caught exception when converting message into json\n" + str(e)) Time.sleep(3600) self.stream_to_queue() return if "instrument" in msg or "tick" in msg: # print(msg) instrument = msg["instrument"] time = msg["time"] # bid = msg["bids"] # ask = msg["asks"] ask = float(msg['asks'][0]["price"]) bid=float(msg['bids'][0]["price"]) tev = TickEvent(instrument, time, bid, ask) self.events_queue.put((2,time,tev)) except Exception: Time.sleep(3600) self.stream_to_queue()
def begin(self): while True: data = json.dumps(self.api.ticker()) dict_data = json.loads(data) time, symbol, bid, ask = self.parse_tick_data(dict_data) event = TickEvent(symbol, time, bid, ask) self.event_queue.put(event)
def stream_to_queue(self): self._open_convert_csv_files() for index, row in self.data.iterrows(): posix_time = row["UnixTime"] time = datetime.utcfromtimestamp(posix_time).strftime( self.dt_format) event = TickEvent("BTC_JPY", time, float(row["Price"]), float(row["Price"])) self.events_queue.put(event)
def _create_event(self, data): """ ticker = dfr['instrument'] time = dfr['time'] bid = dfr['bid'] ask = dfr['ask'] """ ticker = data['instrument'] time = pd.to_datetime(data['time']) bid = PriceParser.parse(data['bid']) ask = PriceParser.parse(data['ask']) return TickEvent(ticker, time, bid, ask)
def setUp(self): data = { 'tick': { 'instrument': 'EUR_USD', 'time': '2015-07-03T11:55:53.198607Z', 'bid': 1.10999, 'ask': 1.11004 } } ticker = data['tick']['instrument'] time = pd.to_datetime(data['tick']['time']) bid = data['tick']['bid'] ask = data['tick']['ask'] self.events_queue = queue.Queue() self.events_queue.put(TickEvent(ticker, time, bid, ask))
def on_price_update(self, msg): response = json.loads(msg) self.logger.info(response) print(response) time = response["Updated"] bid = response["Rates"][0] ask = response["Rates"][1] symbol = response["Symbol"] self.cur_ask = ask self.cur_bid = bid self.prices[symbol]["bid"] = bid self.prices[symbol]["ask"] = ask self.prices[symbol]["time"] = time tev = TickEvent(symbol, time, bid, ask) self.events_queue.put(tev)
def stream_to_queue(self): response = self.connect_to_stream() print(response.status) if response.status == 200: resptext = response.read() try: data = json.loads(resptext) except Exception as e: print('Caught exception when converting message into json' + str(e)) return else: print(data) instrument = data['prices'][0]['instrument'] time = data['prices'][0]['time'] bid = data['prices'][0]['bid'] ask = data['prices'][0]['ask'] tev = TickEvent(instrument, time, bid, ask) self.events_queue.put(tev)
def stream_to_queue(self): response = self.connect_to_stream() if response.status_code != 200: return for line in response.iter_lines(1): if line: try: msg = json.loads(line) except Exception as e: print(("Caught exception when converting message into json\n") + str(e)) return if "instrument" in msg or "tick" in msg: print(msg) instrument = msg["tick"]["instrument"] time = msg["tick"]["time"] bid = msg["tick"]["bid"] ask = msg["tick"]["ask"] tev = TickEvent(instrument, time, bid, ask) self.events_queue.put(tev)
def stream_next_tick(self): """ The Backtester has now moved over to a single-threaded model in manager to fully reproduce results on each run. This means that the stream_to_queue method is unable to be used and a replacement, called stream_next_tick, is used instead. This method is called by the backtesting function outside of this class and places a single tick onto the queue, as well as updating the current bid/ask and inverse bid/ask. """ try: index, row = next(self.cur_date_pairs) except StopIteration: # End of the current days data if self._update_csv_for_day(): index, row = next(self.cur_date_pairs) else: # End of the data self.continue_backtest = False return getcontext().rounding = ROUND_HALF_DOWN pair = row["Pair"] bid = Decimal(str(row["Bid"])).quantize(Decimal("0.00001")) ask = Decimal(str(row["Ask"])).quantize(Decimal("0.00001")) # Create decimalised prices for traded pair self.prices[pair]["bid"] = bid self.prices[pair]["ask"] = ask self.prices[pair]["time"] = index # Create decimalised prices for inverted pair inv_pair, inv_bid, inv_ask = self.invert_prices(pair, bid, ask) self.prices[inv_pair]["bid"] = inv_bid self.prices[inv_pair]["ask"] = inv_ask self.prices[inv_pair]["time"] = index # Create the tick event for the queue tev = TickEvent(pair, index, bid, ask) self.events_queue.put(tev)
def on_message(self, msg): b = len(PRODUCTS) if msg['type'] == 'ticker': if self.message_count > b: self.events_queue.put( TickEvent(product=msg['product_id'], sequence=msg['sequence'], time=msg['time'], price=Decimal(msg['price']), bid=Decimal(msg['best_bid']), ask=Decimal(msg['best_ask']), spread=Decimal(msg['best_ask']) - Decimal(msg['best_bid']), side=msg['side'], size=Decimal(msg['last_size']).quantize( Decimal('0.000000001'), rounding=ROUND_HALF_DOWN))) else: print(msg) self.message_count += 1
def stream_next_tick(self): """ Il Backtester è ora passato ad un modello a un thread singolo in modo da riprodurre completamente i risultati su ogni esecuzione. Ciò significa che il metodo stream_to_queue non può essere usato ed è sostituito dal metodo stream_next_tick. Questo metodo viene chiamato dalla funzione di backtesting, esterna a questa classe e inserisce un solo tick nella coda, ed inoltre aggiornare l'attuale bid / ask e l'inverso bid / ask. """ try: index, row = next(self.cur_date_pairs) except StopIteration: # Fine dei dati per un giorno if self._update_csv_for_day(): index, row = next(self.cur_date_pairs) else: # Fine dei dati self.continue_backtest = False return getcontext().rounding = ROUND_HALF_DOWN pair = row["Pair"] bid = Decimal(str(row["Bid"])).quantize(Decimal("0.00001")) ask = Decimal(str(row["Ask"])).quantize(Decimal("0.00001")) # Create decimalised prices for traded pair self.prices[pair]["bid"] = bid self.prices[pair]["ask"] = ask self.prices[pair]["time"] = index # Create decimalised prices for inverted pair inv_pair, inv_bid, inv_ask = self.invert_prices(pair, bid, ask) self.prices[inv_pair]["bid"] = inv_bid self.prices[inv_pair]["ask"] = inv_ask self.prices[inv_pair]["time"] = index # Create the tick event for the queue tev = TickEvent(pair, index, bid, ask) self.events_queue.put(tev)
def stream_to_queue(self): response = self.connect_to_stream() if response.status_code != 200: return for line in response.iter_lines(1): if line: try: msg = json.loads(line) except Exception as e: print "Caught exception when converting message into json\n" + str( e) return if msg.has_key("instrument") or msg.has_key("tick"): print msg instrument = msg["tick"]["instrument"] time = msg["tick"]["time"] bid = msg["tick"]["bid"] ask = msg["tick"]["ask"] self.cur_bid = bid self.cur_ask = ask tev = TickEvent(instrument, time, bid, ask) self.events_queue.put(tev)
def test_large_down_trend(self): tick = TickEvent("EURUSD", time.time(), 1.1456, 1.1458) # Mock tick event events = queue.Queue() strategy = GridIron("EURUSD", events) strategy.calculate_signals(tick) self.assertEqual(strategy.grid.grid_mid, 1.1457, "Grid Mid was not correct") self.assertEqual(strategy.grid.buy_level_one, 1.1459, "Grid Buy Level 1 was not correct") self.assertEqual(strategy.grid.sell_level_one, 1.1455, "Grid Sell Level 1 was not correct") self.assertEqual(strategy.grid.buy_level_two, 1.1461, "Grid Buy Level 2 was not correct") self.assertEqual(strategy.grid.sell_level_two, 1.1453, "Grid Sell Level 2 was not correct") self.assertEqual(strategy.grid.stop_loss_buy, 1.1455, "Grid Stop Loss was not correct") tick2 = TickEvent("EURUSD", time.time(), 1.1453, 1.1455) strategy.calculate_signals(tick2) # now check signal signal = events.get() self.assertEqual(signal.side, "sell", "Sell Signal not generated") self.assertEqual(signal.order_type, "market", "Market Signal not generated") self.assertEqual(strategy.grid.stop_loss_sell, 1.1457, "Grid Stop Loss was not correct") self.assertEqual(strategy.grid.sell_level_two, 1.1453, "Grid Sell Level 2 was not correct") self.assertEqual(strategy.grid.level_triggered, -1, "Unexpected level triggered") tick3 = TickEvent("EURUSD", time.time(), 1.1452, 1.1453) strategy.calculate_signals(tick3) # now check signal signal = events.get() self.assertEqual(signal.side, "sell", "Sell Signal not generated") self.assertEqual(signal.order_type, "market", "Market Signal not generated") self.assertEqual(strategy.grid.stop_loss_buy, 1.1455, "Grid Stop Loss was not correct") self.assertEqual(strategy.grid.level_triggered, -2, "Unexpected level triggered") tick4 = TickEvent("EURUSD", time.time(), 1.1451, 1.1452) strategy.calculate_signals(tick4) # now check signal signal = events.get() self.assertEqual(signal.side, "closeAll", "Close Out Signal not generated") self.assertEqual(signal.order_type, "market", "Market Signal not generated") self.assertEqual(strategy.grid, None, "Grid not removed")
def stream_to_queue(self): self._open_convert_csv_files() for index, row in self.pair: tev = TickEvent(self.pairs, index, row["Bid"], row["Ask"]) self.events_queue.put(tev)
def stream_to_queue(self): self._open_convert_csv_files() for index, row in self.pair: date = parse(row["Date"] + " " + row["Time"]) tev = TickEvent(self.pairs, date, row["Start"], row["Start"]) self.events_queue.put(tev)
def on_success(self, data): time, symbol, bid, ask = self.parse_tick_data(data["tick"]) event = TickEvent(symbol, time, bid, ask) self.event_queue.put(event)