def testAlgoExpiredOrder(self): symbol = Symbol.get('TEST') start_time = datetime.datetime(2015, 7, 7, 12) order = Order(symbol, 1, Entry(Entry.Type.STOP_ENTRY, 12.5), Direction.LONG, expire_time=datetime.timedelta(seconds=90), entry_time=start_time) # symbol = algo.analysis_symbols()[0] ticks = [] ticks.append(Tick(start_time.timestamp(), 10.0, 10.1)) start_time = start_time + MarketDataPeriod.MIN_1 ticks.append(Tick(start_time.timestamp(), 11.0, 11.1)) start_time = start_time + MarketDataPeriod.MIN_1 ticks.append(Tick(start_time.timestamp(), 12.0, 12.1)) start_time = start_time + MarketDataPeriod.MIN_1 ticks.append(Tick(start_time.timestamp(), 12.3, 12.4)) start_time = start_time + MarketDataPeriod.MIN_1 ticks.append(Tick(start_time.timestamp(), 12.8, 12.9)) dataProvider = SimulatedDataProvider(symbol, ticks) order_manager = Broker(dataProvider) order_manager.subscribeSymbol(symbol) order_creator = OrderCreator(order_manager, symbol, order) order_manager.addPriceObserver(order_creator.handle_data) order_manager.start() self.assertEqual(0, len(order_manager.orders)) self.assertEqual(0, len(order_manager.positions)) self.assertEqual(State.EXPIRED, order.status)
def testTakeProfitMarketOrder(self): symbol = Symbol.get('TEST') symbol.lot_size = 1 start_time = datetime.datetime(2015, 7, 7, 12) # symbol = algo.analysis_symbols()[0] ticks = [] ticks.append(Tick(start_time.timestamp(), 10.0, 10.1)) start_time = start_time + MarketDataPeriod.MIN_1 ticks.append(Tick(start_time.timestamp(), 11.0, 11.1)) start_time = start_time + MarketDataPeriod.MIN_1 ticks.append(Tick(start_time.timestamp(), 13.0, 13.1)) dataProvider = SimulatedDataProvider(symbol, ticks) order_manager = Broker(dataProvider) order_manager.subscribeSymbol(symbol) order = Order(symbol, 1, Entry(Entry.Type.MARKET), Direction.LONG, take_profit=2) order_creator = OrderCreator(order_manager, symbol, order) order_manager.addPriceObserver(order_creator.handle_data) order_manager.addPositionObserver(lambda position, state: self.setPosition(position)) order_manager.start() self.assertEqual(0, len(order_manager.orders)) self.assertEqual(0, len(order_manager.positions)) self.assertEqual(State.FILLED, order.status) self.assertIsNotNone(self.position) self.assertEqual(Position.PositionStatus.TAKE_PROFIT, self.position.status) self.assertEqual(12.1, self.position.exit_price) self.assertAlmostEquals(2.0, self.position.points_delta())
def testAlgoStopEntryOrder(self): symbol = Symbol.get('TEST') start_time = datetime.datetime(2015, 7, 7, 12) # symbol = algo.analysis_symbols()[0] ticks = [] ticks.append(Tick(start_time.timestamp(), 10.0, 10.1)) start_time = start_time + MarketDataPeriod.MIN_1 ticks.append(Tick(start_time.timestamp(), 11.0, 11.1)) start_time = start_time + MarketDataPeriod.MIN_1 ticks.append(Tick(start_time.timestamp(), 12.0, 12.1)) start_time = start_time + MarketDataPeriod.MIN_1 ticks.append(Tick(start_time.timestamp(), 12.3, 12.4)) start_time = start_time + MarketDataPeriod.MIN_1 ticks.append(Tick(start_time.timestamp(), 12.8, 12.9)) dataProvider = SimulatedDataProvider(symbol, ticks) order_manager = Broker(dataProvider) order_manager.subscribeSymbol(symbol) order = Order(symbol, 1, Entry(Entry.Type.STOP_ENTRY, 11.3), Direction.LONG) order_creator = OrderCreator(order_manager, symbol, order) order_manager.addPriceObserver(order_creator.handle_data) order_manager.start() self.assertEqual(0, len(order_manager.orders)) self.assertEqual(1, len(order_manager.positions)) self.assertEqual(State.FILLED, order.status) position = order_manager.positions[0] self.assertEqual(Position.PositionStatus.OPEN, position.status) self.assertEqual(12.1, position.entry_price)
def testQuoteConstruction(self): s = Symbol.get("TEST") conflator = PriceConflator("TEST", MarketDataPeriod.MIN_5, self.callback) start_time = datetime.datetime(2015, 7, 7, 14, 10, 0) start_time = start_time + MarketDataPeriod.MIN_1 tick = Tick(start_time.timestamp(), 9.0, 9.2) # 14:11:00 conflator.add_tick(tick) start_time = start_time + MarketDataPeriod.MIN_1 tick = Tick(start_time.timestamp(), 8.7, 8.9) # 14:12:00 conflator.add_tick(tick) start_time = start_time + MarketDataPeriod.MIN_1 tick = Tick(start_time.timestamp(), 11.0, 11.2) # 14:13:00 conflator.add_tick(tick) start_time = start_time + MarketDataPeriod.MIN_1 tick = Tick(start_time.timestamp(), 10.5, 10.7) # 14:14:00 conflator.add_tick(tick) start_time = start_time + MarketDataPeriod.MIN_1 tick = Tick(start_time.timestamp(), 9.0, 9.2) # 14:15:00 conflator.add_tick(tick) self.assertEqual(1, len(self.callbackQuote)) quote = self.callbackQuote[0] self.assertEqual(9.1, quote.open) self.assertEqual(11.1, quote.high) self.assertEqual(8.8, quote.low) self.assertEqual(10.6, quote.close)
def testShortLoss(self): s1 = Symbol.get("TEST") s1.lot_size = 10000 # LONG order = Order(s1, 1, Entry(Entry.Type.MARKET), Direction.SHORT) tick = Tick(datetime.utcnow(), 1.12239, 1.12245) # spread of 0.6 position = Position(order, tick) tick = Tick(datetime.utcnow(), 1.12259, 1.12265) position.close(tick) self.assertAlmostEquals(-2, position.points_delta())
def getTickData(self, queue): # self._db_connection = mysql.connector.connect(user='******', database='blackbox', host="192.168.0.8") cursor = self._db_connection.cursor() cursor.callproc('aggregated_data', [ self.symbol.identifier, self.period, self.start_date.timestamp(), self.end_date.timestamp() ]) for tick in self.cursor.stored_results(): quote = Quote(self.symbol, tick[0], self.period, Tick(tick[0], tick[1], tick[1])) # open quote.add_tick(Tick(tick[0], tick[2], tick[2])) # high quote.add_tick(Tick(tick[0], tick[3], tick[3])) # low quote.add_tick(Tick(tick[0], tick[4], tick[4])) # close queue.put(quote) queue.put(None)
def testQuoteConstructionOnInterval(self): s = Symbol.get("TEST") conflator = PriceConflator("TEST", MarketDataPeriod.MIN_5, self.callback) start_time = datetime.datetime(2015, 7, 7, 14, 0, 0) tick = Tick(start_time.timestamp(), 9.0, 9.2) conflator.add_tick(tick) tick = Tick((start_time + datetime.timedelta(seconds=60)).timestamp(), 9.0, 9.2) conflator.add_tick(tick) tick = Tick((start_time + datetime.timedelta(seconds=120)).timestamp(), 8.7, 8.9) conflator.add_tick(tick) tick = Tick((start_time + datetime.timedelta(seconds=180)).timestamp(), 11.0, 11.2) conflator.add_tick(tick) tick = Tick((start_time + datetime.timedelta(seconds=240)).timestamp(), 10.5, 10.7) conflator.add_tick(tick) tick = Tick((start_time + datetime.timedelta(seconds=300)).timestamp(), 9.0, 9.2) conflator.add_tick(tick) tick = Tick((start_time + datetime.timedelta(seconds=360)).timestamp(), 9.0, 9.2) conflator.add_tick(tick) self.assertEqual(1, len(self.callbackQuote)) quote = self.callbackQuote[0] self.assertEqual(5, quote.ticks) self.assertEqual(9.1, quote.open) self.assertEqual(11.1, quote.high) self.assertEqual(8.8, quote.low) self.assertEqual(10.6, quote.close)
def start_publishing(self, callback): if self.multithreaded is True: queue = multiprocessing.Queue() p = Process(target=self.getTickData, args=(queue, )) p.start() for quote in iter(queue.get, None): callback(self.symbol, quote) self.progress_count += 1 if self.progress_callback is not None: if self.progress_count % self._callback_interval == 0: self.progress_callback(self.progress_count) else: st = self.start_date.timestamp() en = self.end_date.timestamp() self.cursor.callproc('aggregated_data', [ self.symbol.identifier, self.period, self.start_date.timestamp(), self.end_date.timestamp() ]) for results in self.cursor.stored_results(): for tick in ResultIter(results): # quote = Quote(self.symbol, tick[0], self.period, Tick(tick[0], float(tick[1]), float(tick[1]))) # open # quote.add_tick(Tick(tick[0], tick[2], tick[2])) # high # quote.add_tick(Tick(tick[0], tick[3], tick[3])) # low # quote.add_tick(Tick(tick[0], float(tick[4]), float(tick[4]))) # close # callback(self.symbol, quote) callback(self.symbol, Tick(tick[0], float(tick[1]), float(tick[1]))) # open callback(self.symbol, Tick(tick[0], tick[2], tick[2])) # high callback(self.symbol, Tick(tick[0], tick[3], tick[3])) # low callback(self.symbol, Tick(tick[0], float(tick[4]), float(tick[4]))) # close self.progress_count += 1 if self.progress_callback is not None: if self.progress_count % self._callback_interval == 0: self.progress_callback(self.progress_count)
def start_publishing(self, callback): for tick in self.collection.tick_data.find( self.query).sort("timestamp"): callback( self.symbol, Tick(tick['timestamp'] / 1000, tick['bid'], tick['offer'])) self.progress_count += 1 if self.progress_callback is not None: if self.progress_count % self._callback_interval == 0: self.progress_callback(self.progress_count)
def start_publishing(self, callback): self.cursor.execute( "SELECT timestamp, bid, offer FROM tick_data WHERE symbol = ? AND timestamp >= ? and timestamp <= ? ORDER BY timestamp", (self.symbol.sid, self.startDate, self.endDate)) for tick in self.cursor: callback(self.symbol, Tick(tick[0].timestamp(), tick[1], tick[2])) self.progress_count += 1 if self.progress_callback is not None: if self.progress_count % self._callback_interval == 0: self.progress_callback(self.progress_count)
def start_publishing(self, callback): for i in range(0, self.iterations): price = base_price + random() - (spread / 2.0) callback( self.symbol, Tick(self.last_publish_time, float(price), float(price + spread))) self.last_publish_time = self.last_publish_time + self.interval if self.progress_callback is not None: self.progress_callback(i)
def testModifiedStopLoss(self): s1 = Symbol.get("TEST") s1.lot_size = 10000 # LONG order = Order(s1, 1, Entry(Entry.Type.MARKET), Direction.SHORT) tick = Tick(datetime.utcnow(), 1.12239, 1.12245) # spread of 0.6 position = Position(order, tick) self.assertIsNone(position.stop_price) position.update(stop_loss=StopLoss(StopLoss.Type.FIXED, 2)) self.assertIsNotNone(position.stop_price) self.assertEqual(1.12265, position.stop_price)
def start_publishing(self, callback): if self.multithreaded is True: queue = multiprocessing.Queue() p = Process(target=self._get_tick_data, args=(queue, )) p.start() for tick in iter(queue.get, None): callback(self.symbol, Tick(tick[0], tick[1], tick[2])) self.progress_count += 1 if self.progress_callback is not None: if self.progress_count % self._callback_interval == 0: self.progress_callback(self.progress_count) else: self.cursor.execute( "SELECT timestamp, bid, offer FROM tick_data2 WHERE symbol_id = %s AND timestamp BETWEEN %s and %s ORDER BY timestamp", (self.symbol.identifier, self.start_date.timestamp(), self.end_date.timestamp())) for tick in ResultIter(self.cursor): callback(self.symbol, Tick(tick[0], tick[1], tick[2])) self.progress_count += 1 if self.progress_callback is not None: if self.progress_count % self._callback_interval == 0: self.progress_callback(self.progress_count)
def testBodyEngulfing(self): start_time = datetime.datetime(2015, 7, 26, 12, 0, 0) symbol = self.algo.analysis_symbols()[0] t = (0.6, 0.8, 0.2, 0.4) tick = Tick(start_time.timestamp(), t[0], t[0]) quote = Quote(symbol, start_time, MarketDataPeriod.HOUR_1, tick) quote.add_tick(Tick(start_time.timestamp(), t[1], t[1])) quote.add_tick(Tick(start_time.timestamp(), t[2], t[2])) quote.add_tick(Tick(start_time.timestamp(), t[3], t[3])) t = (0.8, 1.0, 0.0, 0.2) tick = Tick(start_time.timestamp(), t[0], t[0]) quote2 = Quote(symbol, start_time, MarketDataPeriod.HOUR_1, tick) quote2.add_tick(Tick(start_time.timestamp(), t[1], t[1])) quote2.add_tick(Tick(start_time.timestamp(), t[2], t[2])) quote2.add_tick(Tick(start_time.timestamp(), t[3], t[3])) self.assertFalse(self.algo.is_body_engulfing(quote, quote2)) self.assertTrue(self.algo.is_body_engulfing(quote2, quote))
def testStrongCandleBull(self): start_time = datetime.datetime(2015, 7, 26, 12, 0, 0) symbol = self.algo.analysis_symbols()[0] t = (0.2, 0.0, 1.0, 0.8) tick = Tick(start_time.timestamp(), t[0], t[0]) quote = Quote(symbol, start_time, MarketDataPeriod.HOUR_1, tick) quote.add_tick(Tick(start_time.timestamp(), t[1], t[1])) quote.add_tick(Tick(start_time.timestamp(), t[2], t[2])) quote.add_tick(Tick(start_time.timestamp(), t[3], t[3])) self.assertTrue(self.algo.is_strong_candle(quote, Direction.LONG)) t = (0.2, 0.0, 1.0, 0.7) tick = Tick(start_time.timestamp(), t[0], t[0]) quote = Quote(symbol, start_time, MarketDataPeriod.HOUR_1, tick) quote.add_tick(Tick(start_time.timestamp(), t[1], t[1])) quote.add_tick(Tick(start_time.timestamp(), t[2], t[2])) quote.add_tick(Tick(start_time.timestamp(), t[3], t[3])) self.assertFalse(self.algo.is_strong_candle(quote, Direction.LONG))
def add_tick(self, tick): grouping_period = self.period.total_seconds() if not self.current_quote: self.period_starting_timestamp = PriceConflator.round_datetime_to_period( tick.timestamp, grouping_period) self.current_quote = Quote( self.symbol, datetime.datetime.utcfromtimestamp( self.period_starting_timestamp), self.period, tick) return self.current_quote else: current_tick_timeblock = PriceConflator.round_datetime_to_period( tick.timestamp, grouping_period) if (current_tick_timeblock - self.period_starting_timestamp) < grouping_period: self.current_quote.add_tick(tick) else: if self.callback is not None: self.callback(self.current_quote) t = self.period_starting_timestamp + grouping_period while current_tick_timeblock >= (t + grouping_period): self.callback( Quote( self.symbol, datetime.datetime.utcfromtimestamp(t), self.period, Tick(self.period_starting_timestamp, self.current_quote.close, self.current_quote.close))) t += grouping_period self.current_quote = Quote( self.symbol, datetime.datetime.utcfromtimestamp(t), self.period, tick) self.period_starting_timestamp = t return self.current_quote return None
def testQuoteGap(self): s = Symbol.get("TEST") conflator = PriceConflator("TEST", MarketDataPeriod.MIN_5, self.callback) start_time = datetime.datetime(2015, 7, 7, 14, 10, 0) start_time = start_time + MarketDataPeriod.MIN_1 tick = Tick(start_time.timestamp(), 9.0, 9.2) # 14:11 conflator.add_tick(tick) start_time = start_time + MarketDataPeriod.MIN_1 tick = Tick(start_time.timestamp(), 8.7, 8.9) # 14:12 conflator.add_tick(tick) start_time = start_time + MarketDataPeriod.MIN_1 tick = Tick(start_time.timestamp(), 11.0, 11.2) # 14:13 conflator.add_tick(tick) start_time = start_time + MarketDataPeriod.MIN_1 tick = Tick(start_time.timestamp(), 10.5, 10.7) # 14:14 conflator.add_tick(tick) self.assertEqual(0, len(self.callbackQuote)) # (All in 14:10:00) start_time = start_time + MarketDataPeriod.MIN_15 tick = Tick(start_time.timestamp(), 9.0, 9.2) # 14:29 conflator.add_tick(tick) self.assertEqual(3, len(self.callbackQuote)) # 14:15:00, 14:20:00, 14:25:00 start_time = start_time + MarketDataPeriod.MIN_1 tick = Tick(start_time.timestamp(), 10.5, 10.7) # 14:30 conflator.add_tick(tick) self.assertEqual(4, len(self.callbackQuote)) quote = self.callbackQuote[0] self.assertEqual(9.1, quote.open) self.assertEqual(11.1, quote.high) self.assertEqual(8.8, quote.low) self.assertEqual(10.6, quote.close) quote = self.callbackQuote[1] self.assertEqual(10.6, quote.open) self.assertEqual(10.6, quote.high) self.assertEqual(10.6, quote.low) self.assertEqual(10.6, quote.close)
def testLargestCandle(self): start_time = datetime.datetime(2015, 7, 26, 12, 0, 0) symbol = self.algo.analysis_symbols()[0] history = [] t = (0.6, 0.8, 0.2, 0.4) tick = Tick(start_time.timestamp(), t[0], t[0]) quote = Quote(symbol, start_time, MarketDataPeriod.HOUR_1, tick) quote.add_tick(Tick(start_time.timestamp(), t[1], t[1])) quote.add_tick(Tick(start_time.timestamp(), t[2], t[2])) quote.add_tick(Tick(start_time.timestamp(), t[3], t[3])) history.append(quote) t = (0.7, 0.9, 0.1, 0.3) tick = Tick(start_time.timestamp(), t[0], t[0]) quote = Quote(symbol, start_time, MarketDataPeriod.HOUR_1, tick) quote.add_tick(Tick(start_time.timestamp(), t[1], t[1])) quote.add_tick(Tick(start_time.timestamp(), t[2], t[2])) quote.add_tick(Tick(start_time.timestamp(), t[3], t[3])) history.append(quote) t = (0.8, 1.0, 0.0, 0.2) tick = Tick(start_time.timestamp(), t[0], t[0]) quote = Quote(symbol, start_time, MarketDataPeriod.HOUR_1, tick) quote.add_tick(Tick(start_time.timestamp(), t[1], t[1])) quote.add_tick(Tick(start_time.timestamp(), t[2], t[2])) quote.add_tick(Tick(start_time.timestamp(), t[3], t[3])) self.assertTrue(self.algo.is_largest(quote, history)) t = (0.7, 0.8, 0.0, 0.31) tick = Tick(start_time.timestamp(), t[0], t[0]) quote = Quote(symbol, start_time, MarketDataPeriod.HOUR_1, tick) quote.add_tick(Tick(start_time.timestamp(), t[1], t[1])) quote.add_tick(Tick(start_time.timestamp(), t[2], t[2])) quote.add_tick(Tick(start_time.timestamp(), t[3], t[3])) self.assertFalse(self.algo.is_largest(quote, history))
def start_publishing(self, callback): for timestamp, bid, ask, volume in self.reader: ts = datetime.datetime.strptime(timestamp, "%Y%m%d %H%M%S%f") ts = self.tz.localize(ts) callback(self.symbol, Tick(ts.astimezone(pytz.utc), float(bid), float(ask)))