Esempio n. 1
0
    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)
Esempio n. 2
0
    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)
Esempio n. 3
0
    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())
Esempio n. 4
0
    def evaluate_quote_update(self, context, quote):
        """
        This method is called for every market data tick update on the requested symbols.
        """
        symbol_contexts = context.symbol_contexts[quote.symbol]

        # logging.debug("I'm evaluating the data for %s" % (quote, ))

        if len(symbol_contexts.quotes) > 25:  # i.e. we have enough data
            quoteTimes = [
                time.mktime(o.start_time.timetuple())
                for o in symbol_contexts.quotes
            ]
            closePrices = asarray(symbol_contexts.closes)

            ema_10 = financial.ema(closePrices[-10:], 10)
            ema_25 = financial.ema(closePrices[-15:], 15)
            symbolContext.ema_10.append(ema_10)
            symbolContext.ema_25.append(ema_25)

            if ema_10 > ema_25:
                if context.symbolContexts[quote.symbol].position is False:
                    # create a LONG position
                    logging.debug("Opening position on quote: %s" % (quote, ))
                    context.place_order(
                        Order(quote.symbol,
                              1,
                              Entry(Entry.Type.MARKET),
                              Direction.LONG,
                              stoploss=StopLoss(StopLoss.Type.FIXED, 20),
                              take_profit=25))
                    context.symbol_contexts[quote.symbol].position = True
            else:
                if context.symbol_contexts[quote.symbol].position is True:
                    context.symbol_contexts[quote.symbol].position = False
Esempio n. 5
0
    def evaluate_quote_update(self, context, quote):
        """
        This method is called for every market data tick update on the requested symbols.
        """
        symbol_context = context.get_quote_context(quote)

        if len(symbol_context.quotes) > self.space_to_left:  # i.e. we have enough data

            # if quote.start_time.time() > datetime.time(21, 0) or quote.start_time.time() < datetime.time(7, 0):
            #     # not normal EURUSD active period
            #     return
            # if quote.start_time.weekday() >= 5:
            #     # it's a weekend
            #     return
            # if quote.start_time.weekday() == 4 and quote.start_time.time() > datetime.time(16, 0):
            #     # no positions after 16:00 on Friday
            #     return

            previous_quote = symbol_context.quotes[-1]

            # have we changed direction?
            if self.is_opposite(quote, previous_quote):
                # check if this candle engulfs the previous
                if self.is_body_engulfing(quote, previous_quote):
                    historic_periods = list(symbol_context.quotes)[:-1]
                    if self.is_largest(quote, historic_periods[-self.largest_body_count:]):
                        # are we thinking about long or short?
                        if quote.close < quote.open:  # go short
                            if self.is_strong_candle(quote, Direction.SHORT):
                                if self.has_space_to_left_of_high(quote, previous_quote, historic_periods[-self.space_to_left:-1]):
                                    stop_points = (abs(quote.close - quote.high) * (quote.symbol.lot_size + 1)) + 5
                                    stop_loss = StopLoss(StopLoss.Type.FIXED, stop_points)
                                    qty = self.calculate_position_size(context, stop_points)
                                    if qty > 0:
                                        context.place_order(Order(quote.symbol, qty, Entry(Entry.Type.LIMIT, quote.low - 5), Direction.SHORT, stoploss=stop_loss, take_profit=self.take_profit, expire_time=self.time_period))
                        else:  # go long
                            if self.is_strong_candle(quote, Direction.LONG):
                                if self.has_space_to_left_of_low(quote, previous_quote, historic_periods[-self.space_to_left:-1]):
                                    stop_points = (abs(quote.close - quote.low) * (quote.symbol.lot_size + 1)) + 5
                                    stop_loss = StopLoss(StopLoss.Type.FIXED, stop_points)
                                    qty = self.calculate_position_size(context, stop_points)
                                    if qty > 0:
                                        context.place_order(Order(quote.symbol, qty, Entry(Entry.Type.LIMIT, quote.high + 5), Direction.LONG, stoploss=stop_loss, take_profit=self.take_profit, expire_time=self.time_period))
Esempio n. 6
0
    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())
Esempio n. 7
0
    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)
Esempio n. 8
0
    def evaluate_quote_update(self, context, quote):
        """
        This method is called for every market data tick update on the requested symbols.
        """
        symbolContext = context.symbol_contexts[quote.symbol]

        # logging.debug("I'm evaluating the data for %s" % (quote, ))

        if len(symbolContext.quotes
               ) > self.emaPeriod:  # i.e. we have enough data
            space = 5

            if quote.start_time.time() > datetime.time(
                    21, 0) or quote.start_time.time() < datetime.time(7, 0):
                # not normal EURUSD active period
                return
            if quote.start_time.weekday() >= 5:
                # it's a weekend
                return
            if quote.start_time.weekday(
            ) == 4 and quote.start_time.time() > datetime.time(12, 0):
                # no positions after 12 on Friday
                return

            closePrices = asarray(symbolContext.closes)
            ema = financial.ema(closePrices[-self.emaPeriod:], self.emaPeriod)

            bar_height = symbolContext.high - symbolContext.low
            # bar_is_largest = bar_height > (symbolContext.highs[-1] - symbolContext.lows[-1])
            bar_is_lowest = symbolContext.low < min(
                list(symbolContext.lows)[-space:-1])
            bar_is_highest = symbolContext.high > max(
                list(symbolContext.highs)[-space:-1])

            buy_signal = bar_is_lowest and (
                (min(symbolContext.open, symbolContext.close) -
                 symbolContext.low) * 1.5) >= (symbolContext.high -
                                               symbolContext.low)
            sell_signal = bar_is_highest and (
                (symbolContext.high -
                 max(symbolContext.open, symbolContext.close)) *
                1.5) >= (symbolContext.high - symbolContext.low)
            open_positions = list(context.open_positions())

            if quote.close > ema and sell_signal:
                # if context.quote_contexts[quote.symbol].position is False:
                # create a LONG position
                if len(open_positions) != 0:
                    position = open_positions[0]
                    if position.order.direction is Direction.SHORT:
                        context.close_position(position)
                else:
                    logging.debug("Opening position on quote: %s" % (quote, ))
                    context.place_order(
                        Order(quote.symbol,
                              50,
                              Entry(Entry.Type.MARKET),
                              Direction.SHORT,
                              stoploss=self.stopLoss,
                              take_profit=self.takeProfit))
                # context.quote_contexts[quote.symbol].position = True
            elif quote.close < ema and buy_signal:
                if len(open_positions) != 0:
                    position = open_positions[0]
                    if position.order.direction is Direction.LONG:
                        context.close_position(position)
                else:
                    logging.debug("Opening position on quote: %s" % (quote, ))
                    context.place_order(
                        Order(quote.symbol,
                              50,
                              Entry(Entry.Type.MARKET),
                              Direction.SHORT,
                              stoploss=self.stopLoss,
                              take_profit=self.takeProfit))