Shmuel Newman
Shmuel Newman

Reputation: 11

Saving data to the database in django

I am working on a website to recommend stocks on the stock market, based on historically reliable trading strategies.

When running the server, I can't see any of the data which is supposed to be shown on the website. Looking into the db, it appears that most of the data is not being saved to the db. There is also another problem, which may be related: When running the code, I am getting the company name for the last stock which is being looped through, but for the others there it just says 'None'. I would be grateful if anyone can help me with this.

Here is the code to loop through each stock:

def compile_queue(self):
        from stock.models import Stock
        list_of_stocks = Stock.objects.prefetch_related("stock_data", "strategies", "recommendations").values('ticker')[0:101]
        for i in list_of_stocks.values():
            try:
                #Update db with new data
                ticker = i.ticker
                stock_object = Stock_Class(ticker)
                self.list_of_operations.append(lambda i=i: stock_object.update_data(i))
                
                # Get strategy objects
                moving_average_strategy = Moving_Average_Strategy(ticker)
                rsi_strategy = RSI_Strategy(ticker)
                bollinger_band_strategy = Bollinger_Bands_Strategy(ticker)
                
                # Add strategies to the queue
                self.list_of_operations.append(lambda:moving_average_strategy.apply_strategy())
                self.list_of_operations.append(lambda:rsi_strategy.apply_strategy())
                self.list_of_operations.append(lambda:bollinger_band_strategy.apply_strategy())
                    
                self.list_of_operations.append(lambda:stock_object.set_recommendations(i))
            except Exception as e:
                print(f"(Trading_System.py) The required actions for {i} could not be run due to Error: {e}")

Here is part of the code which gets the data for a given stock and should save it to the database:

 def update_data(self, primary_key):
        stock = yf.Ticker(self.ticker)
        stock_info = stock.info
        current_date_and_time = timezone.now()
        
        try:   # Updates data for Stock model
            stock_model = Stock.objects.get(ticker=self.ticker)
            stock_model.company_name = stock_info.get('shortName')
            stock_model.sector = stock_info.get('sector')
            stock_model.last_updated = current_date_and_time
            stock_model.save()
        except ObjectDoesNotExist:
            print("(Stock.py 1) There was a problem executing getting the data or saving it to the database.")
        
        try:   # Updates data for StockData model
            stock_data_model = StockData.objects.get(ticker=self.ticker)
            stock_data_model.current_date = date.today()
            stock_data_model.current_price = stock_info['currentPrice']
            stock_data_model.last_200_close_prices = self.get_stock_close_prices()
            price_change = stock_data_model.current_price - stock_data_model.last_200_close_prices[-2]
            stock_data_model.price_change = price_change
            stock_data_model.price_change_percent = 100*(price_change/stock_data_model.last_200_close_prices[-2])
            stock_data_model.save()
        except ObjectDoesNotExist:
            print("(Stock.py 2) There was a problem executing getting the data or saving it to the database.")
    

I have checked that I am getting the correct data, and this does not seem to be a problem. I have asked ChatGPT about this, and it has no answer which has worked for me.

I would be grateful if anyone has any suggestions on how to fix this.

Upvotes: 1

Views: 59

Answers (1)

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 477607

You are defining a variables like moving_average_strategy and you then use these in the lambda expression. But at the time the lambda expression is evaluated, the variable has already changed, so it will typically only use the last set one, or if the system is quite fast, the value a few iterations further.

You can set the value in a local variable, like:

def compile_queue(self):
    from stock.models import Stock

    list_of_stocks = Stock.objects.prefetch_related(
        'stock_data', 'strategies', 'recommendations'
    ).values('ticker')[0:101]

    def process(i):
        try:
            # Update db with new data
            ticker = i.ticker
            stock_object = Stock_Class(ticker)
            self.list_of_operations.append(
                lambda i=i: stock_object.update_data(i)
            )

            # Get strategy objects
            moving_average_strategy = Moving_Average_Strategy(ticker)
            rsi_strategy = RSI_Strategy(ticker)
            bollinger_band_strategy = Bollinger_Bands_Strategy(ticker)

            # Add strategies to the queue
            self.list_of_operations.append(
                lambda: moving_average_strategy.apply_strategy()
            )
            self.list_of_operations.append(lambda: rsi_strategy.apply_strategy())
            self.list_of_operations.append(
                lambda: bollinger_band_strategy.apply_strategy()
            )

            self.list_of_operations.append(
                lambda: stock_object.set_recommendations(i)
            )
        except Exception as e:
            print(
                f"(Trading_System.py) The required actions for {i} could not be run due to Error: {e}"
            )

    for i in list_of_stocks.values():
        process(i)

The local variable i in process is key here, since it thus copies the value, and shields off changes to i in the for loop.


Note: Please do not make use of a blanket except: try to limit exception handling to specific exceptions. Other exceptions should not be catched, but handled by the code flow that called the subroutine. By making use of except, you basically will stop any exception, but that is often not a good idea, since the caller thus assumes that the call succeeded.


Note: Be careful with chatbots. A paper titled "The Effects of Generative AI on High Skilled Work: Evidence from Three Field Experiments with Software Developers" shows that there is an increase in productivity, if we take the number of pull requests as metric. All other metrics did not improve in a statistically significant way. The number of build failures however increased as well. This is partly because how a chatbot works, which can easily generate hallucinations.

Upvotes: 0

Related Questions