Ejemplo n.º 1
0
 def __init__(self, name="default", rules=[]):
     self.logger = logging.getLogger("Trader")
     self.name = name
     self.rules = rules
     self.stocks = map(lambda x: x[0], FTSE_100)
     self.data = shelve.open("trader_data_" + name)
     self.getter = GoogleGetter()
     if self.data.has_key('cash'):
         self.cash = self.data['cash']
     else:
         self.cash = 1000
Ejemplo n.º 2
0
class Trader:

    def __init__(self, name="default", rules=[]):
        self.logger = logging.getLogger("Trader")
        self.name = name
        self.rules = rules
        self.stocks = map(lambda x: x[0], FTSE_100)
        self.data = shelve.open("trader_data_" + name)
        self.getter = GoogleGetter()
        if self.data.has_key('cash'):
            self.cash = self.data['cash']
        else:
            self.cash = 1000
    
    def reset(self):
        """ Reset all the data (except for the useful stuff) """
        self.cash = 1000
        for stock in self.stocks:
            stock_data = self.get_stock_data(stock)
            stock_data.reset()
            self.save_stock_data(stock, stock_data)
    
    def run(self):
        """ Run a cycle of applying rules, and updating purchases. """
        for stock in self.stocks:
            self.logger.debug("Applying rules to %s" % stock)
            stock_data = self.get_stock_data(stock)
            for rule in self.rules:
                self.logger.debug("Checking rule [%s]" % rule)
                if rule.rule_applies(stock_data):
                    self.logger.info("Rule [%s] matched..." % rule)
                    rule_result = rule.get_result(stock_data, self.cash)
                    self.logger.info("...Result: %s", rule_result)
                    self.cash -= stock_data.apply_transaction(rule_result)
                    self.save_stock_data(stock, stock_data)
        
    def update_all_stocks(self):
        """ Update the current price of all stocks, adding today's value to the database. """
        for stock in self.stocks:
            self.update_stock(stock)
            
    def update_stock(self, stock, date=None, value=None):
        """ Update the current price of a stock, adding today's value to the database. """
        # Get existing data, add today's entry, and save it back
        stock_data = self.get_stock_data(stock)
        if date == None:
            date = datetime.date.today()
        if value == None:
            value = self.getter.get_stock_value(stock)
        stock_data.add_history_value(value, date)
        self.save_stock_data(stock, stock_data)
            
    def total_stock_value(self):
        """ Get the total value of all stocks held. """
        total = 0.0
        for stock in self.stocks:
            stock_data = self.get_stock_data(stock)
            total += stock_data.last_value * stock_data.holding
        return total 
            
    def get_stock_data(self, stock):
        """ Get the stock data for a specific stock, initializing a new object if one doesn't already exist. """
        if self.data.has_key(stock):
            stock_data = self.data[stock]
            
            # Do some migration if necessary
            if not hasattr(stock_data, "logger"):
                stock_data.logger = logging.getLogger("StockData") 
        else:
            stock_data = StockData()
        return stock_data

    def save_stock_data(self, stock, stock_data):
        """ Save the data for a stock. """
        # Drop the logger first.
        temp_logger = stock_data.logger
        delattr(stock_data, "logger")
        self.data[stock] = stock_data
        stock_data.logger = temp_logger
        
        # Also save cash, as it's likely something has changed.
        self.data['cash'] = self.cash
        
    def expected_return(self):
        """ Calculate the expected return based on the stocks' increase in value """
        # Map stock names to a list of returns
        returns = []
        for stock in self.stocks:
            stock_data = self.get_stock_data(stock)
            initial_value = stock_data.initial_value()
            returns.append(100 * (stock_data.last_value - initial_value) / initial_value)
        return sum(returns) / len(returns)

    def __str__(self):
        stock_value = self.total_stock_value()
        ret_str = "Trader: %s\n\n" % self.name
        total_value = self.cash + stock_value
        ret_str += "Total value: \xa3%.2f\n\n" % total_value
        ret_str += "Cash:   \xa3%.2f\n" % self.cash
        ret_str += "Stocks: \xa3%.2f\n" % stock_value
        ret_str += "\n"
        ret_str += "Return:          %4.2f%%\n" % (100 * (total_value - 1000) / 1000)
        ret_str += "Expected Return: %4.2f%%\n" % self.expected_return()
        ret_str += "\n"        
        all_transactions = []
        for stock in self.stocks:
            stock_data = self.get_stock_data(stock)
            all_transactions.extend(map(lambda x: (stock, x), stock_data.transactions))
            if stock_data.holding > 0:
                orig_value = stock_data.sorted_holdings_value()
                stock_value = stock_data.last_value * stock_data.holding
                pct_increase = 100 * (stock_value - orig_value) / orig_value
                ret_str += "%-6s: %4d : \xa3%7.2f  (%.2f%%)\n" % (stock, stock_data.holding, stock_value, pct_increase)
        ret_str += "\n"
        for (s, t) in sorted(all_transactions, key=lambda x: x[1].date):
            ret_str += "%-4s: %s\n" % (s, t)
        return ret_str