Ejemplo n.º 1
0
    def run(cls, stdcsr):
        """Returns: void
        This is the main program loop.
        """
        # initialize user interface
        cls._curses_init(stdcsr)

        # Read in existing trades
        while not cls.stopped and cls.recover_trades() == None:
            Log.write('"daemon.py" run(): Recovering trades...')
            cls._curses_refresh(stdcsr)

        # logging
        if Config.live_trading:
            Log.write('"daemon.py" start(): Using live account.')
        else:
            Log.write('"daemon.py" start(): Using practice mode.')

        """
        Main loop:
        1. Gather opportunities from each strategy.
        2. Decide which opportunities to execute.
        3. Clear the opportunity list.
        """
        while not cls.stopped:
            # refresh user interface
            cls._curses_refresh(stdcsr)

            # Let each strategy suggest an order
            for s in cls.strategies:
                new_opp = s.refresh()
                if new_opp == None:
                    Log.write('daemon.py run(): {} has nothing to offer now.'
                        .format(s.get_name()))
                    pass
                else:
                    cls.opportunities.push(new_opp)
        
            # Decide which opportunity (or opportunities) to execute
            Log.write('"daemon.py" run(): Picking best opportunity...')
            best_opp = cls.opportunities.pick()
            if best_opp == None:
                # Nothing is being suggested.
                pass
            else:
                # An order was suggested by a strategy, so place the order.
                #   Don't use all the money available.
                SLIPPAGE_WIGGLE = 0.95
                ###available_money = Broker.get_margin_available(Config.account_id) * SLIPPAGE_WIGGLE
                available_money = 100 # USD - testing
                #   Get the current price of one unit.
                instrument_price = 0
                Log.write('best opp: {}'.format(best_opp))
                go_long = best_opp.order.units > 0
                if go_long:
                    instrument_price = Broker.get_ask(best_opp.order.instrument)
                else:
                    instrument_price = Broker.get_bid(best_opp.order.instrument)
                #   How much leverage available:
                margin_rate = Broker.get_margin_rate(best_opp.order.instrument) 
                #   TODO: A bit awkward, but overwrite the existing value that was used to 
                #   determine long/short.
                units = available_money
                units /= cls.num_strategies_with_no_positions() # save money for other strategies
                units /= margin_rate
                units = int(units) # floor
                if units <= 0: # verify
                    Log.write('daemon.py run(): units <= 0')
                    raise Exception # abort
                if not go_long: # negative means short
                    units = -units
                best_opp.order.units = units
                Log.write('daemon.py run(): Executing opportunity:\n{}'.format(best_opp))
                order_result = Broker.place_order(best_opp.order)
                # Notify the strategies.
                if 'orderFillTransaction' in order_result:
                    try:
                        opened_trade_id = order_result['orderFillTransaction']['tradeOpened']['tradeID']
                        best_opp.strategy.trade_opened(trade_id=opened_trade_id)
                    except:
                        Log.write(
                            'daemon.py run(): Failed to extract opened trade from order result:\n{}'
                            .format(order_result) )
                        raise Exception
                elif 'tradesClosed' in order_result:
                    try:
                        for trade in order_result['orderFillTransaction']['tradesClosed']:
                            best_opp.strategy.trade_closed(trade_id=trade['tradeID'])
                    except:
                        Log.write(
                            'daemon.py run(): Failed to extract closed trades from order result:\n{}'
                            .format(order_result) )
                        raise Exception
                elif 'tradeReduced' in order_result:
                    try:
                        closed_trade_id = order_result['orderFillTransaction']['tradeReduced']['tradeID']
                        best_opp.strategy.trade_reduced(
                            closed_trade_id,
                            instrument_id=Instrument.get_id_from_name(order_result['instrument'])
                        )
                    except:
                        Log.write(
                            'daemon.py run(): Failed to extract reduced trades from order result:\n{}'
                            .format(order_result) )
                        raise Exception
                else:
                    Log.write(
                        '"daemon.py" run(): Unrecognized order result:\n{}'
                        .format(order_result) )
                    raise Exception

            """
            Clear opportunity list.
            Opportunities should be considered to exist only in the moment,
            so there is no need to save them for later.
            """
            cls.opportunities.clear()
        """
        Shutdown stuff. This runs after shutdown() is called, and is the
        last code that runs before returning to algo.py.
        """
        DB.shutdown()  # atexit() used in db.py, but call to be safe.
Ejemplo n.º 2
0
    def _babysit(self):
        """ (See strategy.py for documentation) """
        Log.write('fifty.py babysit(): _open_tade_ids: {}'.format(self.open_trade_ids))

        for open_trade_id in self.open_trade_ids:
            is_closed = Broker.is_trade_closed(open_trade_id)
            if is_closed[0]:
                Log.write('"fifty.py" _babysit(): Trade ({}) has closed with reason: {}'
                    .format( open_trade_id, str(is_closed[1]) )
                )
                # If SL hit, reverse direction.
                if is_closed[1] == TradeClosedReason.STOP_LOSS_ORDER:
                    if self.go_long:
                        self.go_long = False
                    else:
                        self.go_long = True
                self.open_trade_ids.remove(open_trade_id)
            else:
                trade = Broker.get_trade(open_trade_id)
                instrument = trade.instrument
                sl = round( float(trade.stop_loss), 2 )
                go_long = int(trade.units) > 0

                if go_long: # currently long
                    cur_bid = Broker.get_bid(instrument)
                    if cur_bid != None:
                        if cur_bid - sl > self.sl_price_diff:
                            new_sl = cur_bid - self.sl_price_diff
                            resp = Broker.modify_trade(
                                trade_id=open_trade_id,
                                stop_loss_price=str(round(new_sl, 2))
                            )
                            if resp == None:
                                Log.write('"fifty.py" _babysit(): Modify failed. Checking if trade is closed.')
                                closed = Broker.is_trade_closed(open_trade_id)
                                Log.write('fifty.py babysit(): is_trade_closed returned:\n{}'.format(closed))
                                if closed[0]:
                                    Log.write('"fifty.py" _babysit(): BUY trade has closed. (BUY)')
                                    self.open_trade_ids.remove(open_trade_id)
                                    # If SL hit, reverse direction.
                                    if closed[1] == TradeClosedReason.STOP_LOSS_ORDER:
                                        self.go_long = False
                                else:
                                    Log.write('"fifty.py" _babysit(): Failed to modify BUY trade.')
                                    raise Exception
                            else:                                       
                                Log.write('"fifty.py" _babysit(): Modified BUY trade with ID (',\
                                     open_trade_id, ').')
                    else:
                        Log.write('"fifty.py" _babysit(): Failed to get bid while babysitting.')
                        raise Exception
                else: # currently short
                    cur_bid = Broker.get_bid(instrument)
                    if cur_bid != None:
                        if sl - cur_bid > self.sl_price_diff:
                            new_sl = cur_bid + self.sl_price_diff
                            resp = Broker.modify_trade(
                                trade_id=open_trade_id, 
                                stop_loss_price=str(round(new_sl, 2))
                            )
                            if resp == None:
                                closed = Broker.is_trade_closed(open_trade_id)
                                Log.write('fifty.py babysit(): is_trade_closed returned:\n{}'.format(closed))
                                if closed[0]:
                                    Log.write('"fifty.py" _babysit(): SELL trade has closed. (BUY)')
                                    self.open_trade_ids.remove(open_trade_id)
                                    # If SL hit, reverse direction.
                                    if closed[1] == TradeClosedReason.STOP_LOSS_ORDER:
                                        self.go_long = True
                                else:
                                    Log.write('"fifty.py" in _babysit(): Failed to modify SELL trade.')
                                    raise Exception
                            else:
                                Log.write('"fifty.py" _babysit(): Modified SELL trade with ID (',\
                                    open_trade_id, ').')
                    else:
                        Log.write('"fifty.py" _babysit(): Failed to get ask while babysitting.')
                        raise Exception
Ejemplo n.º 3
0
    def run(cls, stdcsr):
        """Returns: void
        This is the main program loop.
        """
        # initialize user interface
        cls._curses_init(stdcsr)

        # Read in existing trades
        while not cls.stopped and cls.recover_trades() == None:
            Log.write('"daemon.py" run(): Recovering trades...')
            cls._curses_refresh(stdcsr)

        # logging
        if Config.live_trading:
            Log.write('"daemon.py" start(): Using live account.')
        else:
            Log.write('"daemon.py" start(): Using practice mode.')
        """
        Main loop:
        1. Gather opportunities from each strategy.
        2. Decide which opportunities to execute.
        3. Clear the opportunity list.
        """
        while not cls.stopped:
            # refresh user interface
            cls._curses_refresh(stdcsr)

            # Let each strategy suggest an order
            for s in cls.strategies:
                new_opp = s.refresh()
                if new_opp == None:
                    Log.write(
                        'daemon.py run(): {} has nothing to offer now.'.format(
                            s.get_name()))
                    pass
                else:
                    cls.opportunities.push(new_opp)

            # Decide which opportunity (or opportunities) to execute
            Log.write('"daemon.py" run(): Picking best opportunity...')
            best_opp = cls.opportunities.pick()
            if best_opp == None:
                # Nothing is being suggested.
                pass
            else:
                # An order was suggested by a strategy, so place the order.
                #   Don't use all the money available.
                SLIPPAGE_WIGGLE = 0.95
                ###available_money = Broker.get_margin_available(Config.account_id) * SLIPPAGE_WIGGLE
                available_money = 100  # USD - testing
                #   Get the current price of one unit.
                instrument_price = 0
                Log.write('best opp: {}'.format(best_opp))
                go_long = best_opp.order.units > 0
                if go_long:
                    instrument_price = Broker.get_ask(
                        best_opp.order.instrument)
                else:
                    instrument_price = Broker.get_bid(
                        best_opp.order.instrument)
                #   How much leverage available:
                margin_rate = Broker.get_margin_rate(best_opp.order.instrument)
                #   TODO: A bit awkward, but overwrite the existing value that was used to
                #   determine long/short.
                units = available_money
                units /= cls.num_strategies_with_no_positions(
                )  # save money for other strategies
                units /= margin_rate
                units = int(units)  # floor
                if units <= 0:  # verify
                    Log.write('daemon.py run(): units <= 0')
                    raise Exception  # abort
                if not go_long:  # negative means short
                    units = -units
                best_opp.order.units = units
                Log.write('daemon.py run(): Executing opportunity:\n{}'.format(
                    best_opp))
                order_result = Broker.place_order(best_opp.order)
                # Notify the strategies.
                if 'orderFillTransaction' in order_result:
                    try:
                        opened_trade_id = order_result['orderFillTransaction'][
                            'tradeOpened']['tradeID']
                        best_opp.strategy.trade_opened(
                            trade_id=opened_trade_id)
                    except:
                        Log.write(
                            'daemon.py run(): Failed to extract opened trade from order result:\n{}'
                            .format(order_result))
                        raise Exception
                elif 'tradesClosed' in order_result:
                    try:
                        for trade in order_result['orderFillTransaction'][
                                'tradesClosed']:
                            best_opp.strategy.trade_closed(
                                trade_id=trade['tradeID'])
                    except:
                        Log.write(
                            'daemon.py run(): Failed to extract closed trades from order result:\n{}'
                            .format(order_result))
                        raise Exception
                elif 'tradeReduced' in order_result:
                    try:
                        closed_trade_id = order_result['orderFillTransaction'][
                            'tradeReduced']['tradeID']
                        best_opp.strategy.trade_reduced(
                            closed_trade_id,
                            instrument_id=Instrument.get_id_from_name(
                                order_result['instrument']))
                    except:
                        Log.write(
                            'daemon.py run(): Failed to extract reduced trades from order result:\n{}'
                            .format(order_result))
                        raise Exception
                else:
                    Log.write(
                        '"daemon.py" run(): Unrecognized order result:\n{}'.
                        format(order_result))
                    raise Exception
            """
            Clear opportunity list.
            Opportunities should be considered to exist only in the moment,
            so there is no need to save them for later.
            """
            cls.opportunities.clear()
        """
        Shutdown stuff. This runs after shutdown() is called, and is the
        last code that runs before returning to algo.py.
        """
        DB.shutdown()  # atexit() used in db.py, but call to be safe.
Ejemplo n.º 4
0
 def _scan(self):
     Log.write('fifty.py scan()')
     """ (see strategy.py for documentation) """
     # If we're babysitting a trade, don't open a new one.
     if len(self.open_trade_ids) > 0:
         Log.write('fifty.py _scan(): Trades open; no suggestions.')
         return None
     instrument = Instrument(Instrument.get_id_from_name('USD_JPY'))
     spreads = Broker.get_spreads([instrument])
     if spreads == None:
         Log.write('"fifty.py" in _scan(): Failed to get spread of {}.'
             .format(instrument.get_name())) 
         raise Exception
     elif len(spreads) < 1:
         Log.write('"fifty.py" in _scan(): len(spreads) == {}.'
             .format(len(spreads))) 
         raise Exception
     # This only checks for one instrument.
     elif not spreads[0]['tradeable']:
             Log.write('"fifty.py" in _scan(): Instrument {} not tradeable.'
                 .format(instrument.get_name())) 
             return None
     else:
         spread = spreads[0]['spread']
         if spread < 3:
             Log.write('fifty.py _scan(): spread = {}'.format(spread))
             if self.go_long: # buy
                 Log.write('"fifty.py" _scan(): Going long.') 
                 cur_bid = Broker.get_bid(instrument)
                 if cur_bid != None:
                     # Rounding the raw bid didn't prevent float inaccuracy
                     # cur_bid = round(cur_bid_raw, 2)
                     tp = round(cur_bid + self.tp_price_diff, 2)
                     sl = round(cur_bid - self.sl_price_diff, 2)
                 else:
                     Log.write('"fifty.py" in _scan(): Failed to get bid.')
                     raise Exception
             else: # sell
                 Log.write('"fifty.py" _scan(): Shorting.') 
                 self.go_long = False
                 cur_bid = Broker.get_bid(instrument)
                 if cur_bid != None:
                     tp = round(cur_bid - self.tp_price_diff, 2)
                     sl = round(cur_bid + self.sl_price_diff, 2)
                 else:
                     Log.write('"fifty.py" in _scan(): Failed to get ask.') 
                     raise Exception
             # Prepare the order and sent it back to daemon.
             units = 1 if self.go_long else -1
             confidence = 50
             order = Order(
                 instrument=instrument,
                 order_type="MARKET", # matches Oanda's OrderType definition
                 stop_loss={ "price" : str(sl) },
                 take_profit={ "price" : str(tp) },
                 units=units
             )
             reason = 'happy day'
             opp = Opportunity(order, confidence, self, reason)
             Log.write('"fifty.py" _scan(): Returning opportunity with \
                 order:\n{}'.format(opp))
             return opp
         else:
             Log.write('fifty.py _scan(): Spread is high; no suggestions.')
             return None