コード例 #1
0
ファイル: daemon.py プロジェクト: karthikm1/algo
    def recover_trades(cls):
        """Returns: None on failure, any value on success
        See if there are any open trades, and resume babysitting.
        -
        If trades are opened without writing their info to the db,
        the trade cannot be distributed back to the strategy that opened
        it, because it is unknown what strategy placed the order.
        This could be solved by writing to the db before placing the order,
        synchronously. However if placing the order failed, then the database
        record would have to be deleted, and this would be messy.
        Instead, designate a backup strategy that adopts orphan trades.
        """

        # Get trades from broker.
        open_trades_broker = Broker.get_open_trades()  # instance of <Trades>
        if open_trades_broker == None:
            Log.write(
                'daemon.py recover_trades(): Broker.get_open_trades() failed.')
            return None

        # Delete any trades from the database that are no longer open.
        #   First, ignore trades that the broker has open.
        db_trades = DB.execute('SELECT trade_id FROM open_trades_live')
        Log.write(
            '"daemon.py" recover_trades():\ndb open trades: {}\nbroker open trades: {}'
            .format(db_trades, open_trades_broker))
        for index, dbt in enumerate(db_trades):  # O(n^3)
            for otb in open_trades_broker:
                if str(dbt[0]) == str(otb.trade_id):  # compare trade_id
                    del db_trades[index]
        #   The remaining trades are in the "open trades" db table, but
        #   the broker is not listing them as open.
        #   They may have closed since the daemon last ran; confirm this.
        #   Another cause is that trades are automatically removed from
        #   Oanda's history after much time passes.
        for dbt in db_trades:
            if Broker.is_trade_closed(dbt[0])[0]:
                # Trade is definitely closed; update db.
                Log.write(
                    '"daemon.py" recover_trades(): Trade {} is closed. Deleting from db.'
                    .format(dbt[0]))
            else:
                # Trade is in "open trades" db table and the broker
                # says the trade is neither open nor closed.
                DB.bug('Trade w/ID ({}) is neither open nor closed.'.format(
                    dbt[0]))
                Log.write('"daemon.py" recover_trades(): Trade w/ID (',
                          '{}) is neither open nor closed.'.format(dbt[0]))
            DB.execute(
                'DELETE FROM open_trades_live WHERE trade_id="{}"'.format(
                    dbt[0]))
        """
        Fill in info not provided by the broker, e.g.
        the name of the strategy that opened the trade.

        It's possible that a trade will be opened then the system is
        unexpectedly terminated before info about the trade can be saved to
        the database. Thus a trade may not have a corresponding trade in the database.
        """
        for i in range(0, len(open_trades_broker)):
            broker_trade = open_trades_broker[i]
            db_trade_info = DB.execute(
                'SELECT strategy, broker FROM open_trades_live WHERE trade_id="{}"'
                .format(broker_trade.trade_id))
            if len(db_trade_info) > 0:
                # Verify broker's info and database info match, just to be safe.
                # - broker name
                if db_trade_info[0][1] != broker_trade.broker_name:
                    Log.write(
                        '"daemon.py" recover_trades(): ERROR: "{}" != "{}"'.
                        format(db_trade_info[0][1], broker_trade.broker_name))
                    raise Exception
                # set strategy
                broker_trade.strategy = None  # TODO: use a different default?
                for s in cls.strategies:
                    if s.get_name == db_trade_info[0][0]:
                        broker_trade.strategy = s  # reference to class instance
            else:
                # Trade in broker but not db.
                # Maybe the trade was opened manually. Ignore it.
                # Remove from list.
                open_trades_broker = open_trades_broker[
                    0:i] + open_trades_broker[i + 1:len(
                        open_trades_broker)]  # TODO: optimize speed

        # Distribute trades to their respective strategy modules
        for broker_trade in open_trades_broker:
            if broker_trade.strategy != None:
                # Find the strategy that made this trade and notify it.
                for s in cls.strategies:
                    if broker_trade.strategy.get_name() == s.get_name():
                        s.adopt(broker_trade.trade_id)
                        open_trades_broker.remove(broker_trade.trade_id)
                        break
            else:
                # It is not known what strategy opened this trade.
                # One possible reason is that the strategy that opened the
                # trade is no longer open.
                # Assign it to the backup strategy.
                Log.write(
                    '"daemon.py" recover_trades(): Assigning trade ',
                    ' ({}) to backup strategy ({}).'.format(
                        broker_trade.trade_id, cls.backup_strategy.get_name()))
                cls.backup_strategy.adopt(broker_trade.trade_id)
        return 0  # success
コード例 #2
0
ファイル: daemon.py プロジェクト: paperduck/algo
    def recover_trades(cls):
        """Returns: None on failure, any value on success
        See if there are any open trades, and resume babysitting.
        -
        If trades are opened without writing their info to the db,
        the trade cannot be distributed back to the strategy that opened
        it, because it is unknown what strategy placed the order.
        This could be solved by writing to the db before placing the order,
        synchronously. However if placing the order failed, then the database
        record would have to be deleted, and this would be messy.
        Instead, designate a backup strategy that adopts orphan trades.
        """

        # Get trades from broker.
        open_trades_broker = Broker.get_open_trades() # instance of <Trades>
        if open_trades_broker == None:
            Log.write('daemon.py recover_trades(): Broker.get_open_trades() failed.')
            return None 

        # Delete any trades from the database that are no longer open.
        #   First, ignore trades that the broker has open.
        db_trades = DB.execute('SELECT trade_id FROM open_trades_live')
        Log.write('"daemon.py" recover_trades():\ndb open trades: {}\nbroker open trades: {}'
            .format(db_trades, open_trades_broker))
        for index, dbt in enumerate(db_trades): # O(n^3)
            for otb in open_trades_broker:
                if str(dbt[0]) == str(otb.trade_id): # compare trade_id
                    del db_trades[index]
        #   The remaining trades are in the "open trades" db table, but 
        #   the broker is not listing them as open.
        #   They may have closed since the daemon last ran; confirm this.
        #   Another cause is that trades are automatically removed from
        #   Oanda's history after much time passes.
        for dbt in db_trades:
            if Broker.is_trade_closed(dbt[0])[0]:
                # Trade is definitely closed; update db.
                Log.write('"daemon.py" recover_trades(): Trade {} is closed. Deleting from db.'
                    .format(dbt[0]))
            else:
                # Trade is in "open trades" db table and the broker
                # says the trade is neither open nor closed.
                DB.bug('Trade w/ID ({}) is neither open nor closed.'
                    .format(dbt[0]))
                Log.write('"daemon.py" recover_trades(): Trade w/ID (',
                    '{}) is neither open nor closed.'.format(dbt[0]))
            DB.execute('DELETE FROM open_trades_live WHERE trade_id="{}"'
                .format(dbt[0]))
            
        """
        Fill in info not provided by the broker, e.g.
        the name of the strategy that opened the trade.

        It's possible that a trade will be opened then the system is
        unexpectedly terminated before info about the trade can be saved to
        the database. Thus a trade may not have a corresponding trade in the database.
        """
        for i in range(0,len(open_trades_broker)):
            broker_trade = open_trades_broker[i]
            db_trade_info = DB.execute(
                'SELECT strategy, broker FROM open_trades_live WHERE trade_id="{}"'
                .format(broker_trade.trade_id)
            )
            if len(db_trade_info) > 0:
                # Verify broker's info and database info match, just to be safe.
                # - broker name
                if db_trade_info[0][1] != broker_trade.broker_name:
                    Log.write('"daemon.py" recover_trades(): ERROR: "{}" != "{}"'
                        .format(db_trade_info[0][1], broker_trade.broker_name))
                    raise Exception
                # set strategy
                broker_trade.strategy = None # TODO: use a different default?
                for s in cls.strategies:
                    if s.get_name == db_trade_info[0][0]:
                        broker_trade.strategy = s # reference to class instance
            else:
                # Trade in broker but not db.
                # Maybe the trade was opened manually. Ignore it.
                # Remove from list.
                open_trades_broker = open_trades_broker[0:i] + open_trades_broker[i+1:len(open_trades_broker)] # TODO: optimize speed

        # Distribute trades to their respective strategy modules
        for broker_trade in open_trades_broker:
            if broker_trade.strategy != None:
                # Find the strategy that made this trade and notify it.
                for s in cls.strategies:
                    if broker_trade.strategy.get_name() == s.get_name(): 
                        s.adopt(broker_trade.trade_id)
                        open_trades_broker.remove(broker_trade.trade_id)
                        break
            else:
                # It is not known what strategy opened this trade.
                # One possible reason is that the strategy that opened the
                # trade is no longer open.
                # Assign it to the backup strategy.
                Log.write('"daemon.py" recover_trades(): Assigning trade ',
                    ' ({}) to backup strategy ({}).'
                    .format(broker_trade.trade_id, cls.backup_strategy.get_name()))
                cls.backup_strategy.adopt(broker_trade.trade_id)
        return 0 # success
コード例 #3
0
ファイル: fifty.py プロジェクト: paperduck/algo
    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