TypeError: ‘float’对象不可订阅,同时打印

huangapple go评论198阅读模式
英文:

TypeError: 'float' object is not subscriptable while printing

问题

   # 获取指定符号的当前余额
symbols_to_check = ["USDT", "BNB", "BTC", "ETH"]
balances = get_current_balances(symbols_to_check)
print("当前余额:")
for symbol in symbols_to_check:
    balance_info = balances.get(symbol, {"free": 0.0})
    print(f"{symbol}: 可用 - {balance_info['free']}")

出现以下错误:

Traceback (most recent call last):
  File "main.py", line 83, in <module>
    print(f"{symbol}: 可用 - {balance_info['free']}")
TypeError: 'float' object is not subscriptable

对于任何对代码结构感兴趣,以提供可能导致错误或更好的实现预测的提示的人,都欢迎,我对Python相当新,也不是最好的开发人员。


<details>
<summary>英文:</summary>

Get the current balances for the specified symbols

symbols_to_check = ["USDT", "BNB", "BTC", "ETH"]
balances = get_current_balances(symbols_to_check)
print("Current Balances:")
for symbol in symbols_to_check:
balance_info = balances.get(symbol, {"free": 0.0})
print(f"{symbol}: Free - {balance_info['free']}")



Throws a following error:

    Traceback (most recent call last):
      File &quot;main.py&quot;, line 83, in &lt;module&gt;
        print(f&quot;{symbol}: Free - {balance_info[&#39;free&#39;]}&quot;)
    TypeError: &#39;float&#39; object is not subscriptable

for anyone interested in the hole code structure to provide any tips that might lead to errors or better ideas to implement better predictions are welcome, i am pretty new to python and not the best developer overall. 

```

import pandas as pd
import numpy as np
import requests
from binance.client import BinanceAPIException, Client
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import MinMaxScaler
import tensorflow as tf
import schedule
import time
import itertools



tf.config.list_physical_devices(&#39;GPU&#39;)

# Define parameters
api_key = &quot;YOUR_API_KEY&quot;
api_secret = &quot;YOUR_SECRET_KEY&quot;
base_url = &quot;https://api.binance.com&quot;
symbols = [&quot;BTCUSDT&quot;, &quot;ETHUSDT&quot;, &quot;BNBUSDT&quot;]
interval = &quot;1h&quot;
limit = 1000
paper_trading = False



# Create a client object
client = Client(api_key, api_secret)

# Create an empty dictionary to store the profits and losses of each symbol
profit_loss_dict = {}

# Define a threshold for trading (can be adjusted)
threshold = {&quot;BTCUSDT&quot;: 10, &quot;ETHUSDT&quot;: 8, &quot;BNBUSDT&quot;: 5}

# Define the tickSize for each symbol
tick_sizes = {&quot;BTCUSDT&quot;: 0.01, &quot;ETHUSDT&quot;: 0.01, &quot;BNBUSDT&quot;:0.1}

# Define the minimum quantity for each symbol
min_quantity = {&quot;BTCUSDT&quot;: 0.00036, &quot;ETHUSDT&quot;: 0.0059 , &quot;BNBUSDT&quot;: 0.045}

# Define a flag to hold after a buy order is executed
hold = False

# Define a function to get the minimum quantity allowed for each symbol
def get_min_quantity(symbol):
    return min_quantity.get(symbol, 0.01)

# Modify the get_trimmed_price function to return a tuple (trimmed_price, min_qty)
def get_trimmed_price(target_value, symbol):
    tick_size = tick_sizes.get(symbol, 0.01)
    trimmed_price = round(target_value / tick_size) * tick_size
    return trimmed_price, get_min_quantity(symbol)


# Modify the get_current_balances function to return a dictionary with the actual balances
def get_current_balances(symbols):
    try:
        # Use the Binance API to get the account information
        account_info = client.get_account()
        # Create an empty dictionary to store the balances for each symbol
        balances = {}
        # Find the balance for each specified symbol
        for symbol in symbols:
            # Find the balance for the specified symbol in the account_info list
            balance = next((item for item in account_info[&#39;balances&#39;] if item[&#39;asset&#39;] == symbol), None)
            # If the symbol is found, get the &#39;free&#39; value, otherwise set it to 0
            free_balance = float(balance[&#39;free&#39;]) if balance else 0.0
            balances[symbol] = free_balance
        return balances
    except Exception as e:
        print(f&quot;Error fetching balances: {e}&quot;)
        return {}  # Return an empty dictionary if there is an error

    
# Get the current balances for the specified symbols
symbols_to_check = [&quot;USDT&quot;, &quot;BNB&quot;, &quot;BTC&quot;, &quot;ETH&quot;]
balances = get_current_balances(symbols_to_check)
print(&quot;Current Balances:&quot;)
for symbol in symbols_to_check:
    balance_info = balances.get(symbol, {&quot;free&quot;: 0.0})
    print(f&quot;{symbol}: Free - {balance_info[&#39;free&#39;]}&quot;)

# Define a function to get historical data for multiple symbols and save each one to a separate csv file
def get_historical_data(symbols, interval, limit):
    # Create an empty list to store the dataframes
    dfs = []
    # Loop through the symbols
    for symbol in symbols:
        # Construct the url
        url = base_url + &quot;/api/v3/klines&quot;
        params = {&quot;symbol&quot;: symbol, &quot;interval&quot;: interval, &quot;limit&quot;: limit}
        # Send a get request and parse the response
        response = requests.get(url, params=params)
        data = response.json()
        # Convert the data to a dataframe
        df = pd.DataFrame(data, columns=[&quot;open_time&quot;, &quot;open&quot;, &quot;high&quot;, &quot;low&quot;, &quot;close&quot;, &quot;volume&quot;, &quot;close_time&quot;, &quot;quote_volume&quot;,&quot;trades&quot;, &quot;taker_base_volume&quot;, &quot;taker_quote_volume&quot;, &quot;ignore&quot;])
        # Convert the columns to numeric values
        df = df.apply(pd.to_numeric)
        # Convert the time columns to datetime format
        df[&quot;open_time&quot;] = pd.to_datetime(df[&quot;open_time&quot;], unit=&quot;ms&quot;)
        df[&quot;close_time&quot;] = pd.to_datetime(df[&quot;close_time&quot;], unit=&quot;ms&quot;)
        # Add a column for the symbol name
        df[&quot;symbol&quot;] = symbol
        # Add a column for the moving average
        df[&quot;moving_average&quot;] = np.nan
        # Append the dataframe to the list
        dfs.append(df)
    # Concatenate all the dataframes in the list
    df = pd.concat(dfs, ignore_index=True)
    # Save the dataframe to a csv file
    df.to_csv(f&quot;historical_data_{interval}.csv&quot;, index=False)
    # Return the dataframe
    return df

# Define a function to fetch and update historical data
def update_historical_data():
    global df  # Use the global df variable
    # Get historical data for multiple symbols and save it to a csv file
    df = get_historical_data(symbols, interval, limit)
   

# Schedule the update_historical_data function to run at the specified interval
update_interval_hours = 1  # Set the update interval (in hours)
schedule.every(update_interval_hours).hours.do(update_historical_data)

# Define a function to get real-time data for one symbol
def get_realtime_data(symbol):
    # Construct the url
    url = base_url + &quot;/api/v3/ticker/price&quot;
    params = {&quot;symbol&quot;: symbol}
    # Send a get request and parse the response
    response = requests.get(url, params=params)
    data = response.json()
    # Convert the data to a float value
    price = float(data[&quot;price&quot;])
    # Return the price
    return price
    # Check the shape of the dataframe and make sure it has enough rows (at least 250)
   

# Create the MinMaxScaler in a global scope
scaler = MinMaxScaler()


# Define a function to create a neural network model for one symbol using historical data
def create_model(df, symbol):
    global scaler  # Use the global scaler variable
    # Filter the dataframe by the symbol name
    df_symbol = df[df[&quot;symbol&quot;] == symbol]
    # Select the features and the target
    X = df_symbol[[&quot;open&quot;, &quot;high&quot;, &quot;low&quot;, &quot;volume&quot;]].values
    y = df_symbol[&quot;close&quot;].values
    # Scale the features to a range of (0, 1)
    X = scaler.fit_transform(X)
    # Split the data into training and testing sets
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

    # Create a neural network model using Sequential
    model = tf.keras.Sequential([
        tf.keras.layers.Dense(64, activation=&#39;relu&#39;, input_shape=(X_train.shape[1],)),
        tf.keras.layers.Dense(32, activation=&#39;relu&#39;),
        tf.keras.layers.Dense(1)  # Output layer, predicting the closing price
    ])

    # Compile the model
    model.compile(optimizer=&#39;adam&#39;, loss=&#39;mean_squared_error&#39;)

    # Train the model
    epochs = 50
    batch_size = 32
    model.fit(X_train, y_train, epochs=epochs, batch_size=batch_size, validation_split=0.2, verbose=0)

    # Evaluate the model
    loss = model.evaluate(X_test, y_test, verbose=0)
    print(f&quot;Model evaluation for {symbol}: Test loss: {loss}&quot;)

    # Return the model
    return model

def update_model():
    global df, models, mean_reversion_models
    # Check if there is new data available (compare the number of rows with the previous number)
    if df is not None and df.shape[0] &gt;= 250:  # Assuming 250 rows are needed to create a model
        # Loop through the symbols and update the models
        for symbol in symbols:
            if df[df[&quot;symbol&quot;] == symbol].shape[0] &gt;= 250:
                model = create_model(df, symbol)
                models[symbol] = model
            else:
                print(f&quot;Not enough data to update the model for {symbol}&quot;)
    else:
        print(&quot;Not enough data to update models.&quot;)

# Schedule the update_model function to run every hour
schedule.every(1).hour.do(update_model)    

risk_tolerance_percentage = 30  # Set your desired risk tolerance percentage here

# Define a function to save the predicted prices with dates and times to a CSV file
def save_predictions(predictions, symbols, datetimes):
    df = pd.DataFrame({&quot;symbol&quot;: symbols, &quot;predicted_price&quot;: predictions, &quot;datetime&quot;: datetimes})
    df.to_csv(&quot;predictions_main_py.csv&quot;, index=False)

trade_status = {}

# Create an empty dictionary to store the trimmed prices for each symbol
trimmed_prices = {}

def trade(model, symbol, paper_trading):
    global scaler, hold, tick_sizes, min_quantity, trimmed_prices, trade_status, balances

    # Get the current price
    current_price = get_realtime_data(symbol)

    # Add &#39;global balances&#39; statement to specify the global scope
    global balances
    if paper_trading:
        base_asset_balance = get_current_balances([&quot;USDT&quot;]).get(&quot;USDT&quot;, {}).get(&quot;free&quot;, 0.0)
        trading_asset_balance = 0.0  # Since we are paper trading, set the trading asset balance to 0
    else:
        balances = get_current_balances([symbol, &quot;USDT&quot;])
        base_asset_balance = balances.get(&quot;USDT&quot;, {}).get(&quot;free&quot;, 0.0)
        trading_asset_balance = balances.get(symbol, {}).get(&quot;free&quot;, 0.0)

    portfolio_value = base_asset_balance + trading_asset_balance * current_price

    # Trim the current price based on tickSize and store in the trimmed_prices dictionary
    trimmed_price, min_qty = get_trimmed_price((risk_tolerance_percentage / 100) * portfolio_value, symbol)
    trimmed_prices[symbol] = trimmed_price

    # Use the model to make predictions for the new data
    df_symbol = df[df[&quot;symbol&quot;] == symbol]
    X_last_row = df_symbol[[&quot;open&quot;, &quot;high&quot;, &quot;low&quot;, &quot;volume&quot;]].iloc[-1:].values
    X_last_row_scaled = scaler.transform(X_last_row)
    prediction = model.predict(X_last_row_scaled)[0][0]

    # Check if hold flag is True, and if yes, do not execute buy order
    if hold:
        _, trading_asset_balance = get_current_balances([symbol])[symbol][&quot;free&quot;]
        if trading_asset_balance &gt;= min_qty:
            print(f&quot;Holding {symbol} - waiting for sell order to be executed&quot;)
        else:
            print(f&quot;Holding {symbol} - Insufficient quantity to trade. Waiting for sell order to be executed.&quot;)
        return

    if trade_status.get(symbol) == &quot;BOUGHT&quot;:
        # If the trade status is &quot;BOUGHT&quot;, it means we already bought the asset and are waiting for a sell order.
        # Check if we have the minimum quantity to sell.
        _, trading_asset_balance = get_current_balances([symbol])[symbol][&quot;free&quot;]
        if trading_asset_balance &gt;= min_quantity[symbol]:
            print(f&quot;Holding {symbol} - Waiting for sell order to be executed.&quot;)
        else:
            print(f&quot;Holding {symbol} - Insufficient quantity to sell. Waiting for sell order to be executed.&quot;)
    else:
        if not paper_trading:
            # Calculate the trading quantity based on the position size and current price
            quantity = (risk_tolerance_percentage / 100) * portfolio_value / current_price

            # Round the quantity according to the tickSize for each symbol
            decimals = int(-np.log10(tick_sizes[symbol]))
            quantity = round(quantity, decimals)

            # Check the available balance for the trading asset
            _, trading_asset_balance = get_current_balances([symbol])[symbol][&quot;free&quot;]

            # Compare the quantity with the trading asset balance
            if quantity &gt; trading_asset_balance:
                # If the quantity exceeds the available balance, set it to the available balance
                quantity = trading_asset_balance

            # If the calculated quantity is less than the minimum quantity allowed, use the minimum allowed quantity
            if quantity &lt; min_quantity[symbol]:
                quantity = min_quantity[symbol]
                print(f&quot;Quantity is less than the minimum allowed for {symbol}. Using the minimum allowed quantity for the trade.&quot;)

            print(f&quot;Trading {symbol}:&quot;)
            print(f&quot;  Quantity: {quantity}&quot;)
            print(f&quot;  Tick Size: {tick_sizes[symbol]}&quot;)
            print(f&quot;  Current Price: {current_price}&quot;)
            print(f&quot;  Portfolio Value: {portfolio_value}&quot;)
            print(f&quot;  Predicted Price for {symbol}: {prediction}, Current price: {current_price}&quot;)

            try:
                if prediction &lt; trimmed_prices[symbol]:
                    # Place a market buy order using the client object
                    order_buy = client.order_market_buy(symbol=symbol, quantity=quantity)
                    print(order_buy)
                    print(&quot;Market buy order executed.&quot;)

                    # Set trade status to &quot;BOUGHT&quot; after executing the buy order
                    trade_status[symbol] = &quot;BOUGHT&quot;

                    # Set hold flag to True after executing the buy order to wait for the sell order
                    hold = True
                else:
                    print(f&quot;No Buy Signal for {symbol} at current price {current_price}&quot;)
            except BinanceAPIException as e:
                print(f&quot;Error: {e}&quot;)
        else:
            # Use the model to make predictions for the new data
            df_symbol = df[df[&quot;symbol&quot;] == symbol]
            X_last_row = df_symbol[[&quot;open&quot;, &quot;high&quot;, &quot;low&quot;, &quot;volume&quot;]].iloc[-1:].values
            X_last_row_scaled = scaler.transform(X_last_row)
            prediction = model.predict(X_last_row_scaled)[0][0]

            print(f&quot;Price prediction for {symbol}: {prediction}, Current price: {current_price}&quot;)

            # Add the SELL logic here
            if trade_status.get(symbol) == &quot;BOUGHT&quot; and prediction &gt; trimmed_prices[symbol]:
                try:
                    # Place a market sell order using the client object
                    order_sell = client.order_market_sell(symbol=symbol, quantity=min_quantity[symbol])
                    print(order_sell)
                    print(&quot;Market sell order executed.&quot;)
                    # Reset trade status and hold flag after executing the sell order
                    trade_status[symbol] = None
                    hold = False
                except BinanceAPIException as e:
                    print(f&quot;Error: {e}&quot;)


# Define a function to save the profits and losses of trade dates for each symbol
def save_profit_loss(profit_loss_dict):
    # Convert the dictionary to a dataframe
    df = pd.DataFrame.from_dict(profit_loss_dict, orient=&quot;index&quot;)
    # Add a column for the net profit or loss
    df[&quot;net&quot;] = df[&quot;profit&quot;] - df[&quot;loss&quot;]
    # Save the dataframe to a csv file
    df.to_csv(&quot;profit_loss.csv&quot;, index=True)
    # Return the dataframe
    return df



# Initialize &quot;profit&quot; and &quot;loss&quot; keys in the profit_loss_dict for each symbol
for symbol in symbols:
    profit_loss_dict[symbol] = {&quot;profit&quot;: 0, &quot;loss&quot;: 0}


# Get the current balances for the specified symbols
symbols_to_check = [&quot;USDT&quot;, &quot;BNB&quot;, &quot;BTC&quot;, &quot;ETH&quot;]
balances = get_current_balances(symbols_to_check)
print(&quot;Current Balances:&quot;)
for symbol, balance_info in balances.items():
    print(f&quot;{symbol}: Free - {balance_info[&#39;free&#39;]}&quot;)

# Call the update_historical_data function to initialize the df variable before creating the models and starting the trading loop
update_historical_data()

# Loop through the symbols and create a model for each one
models = {}
#mean_reversion_models = {}  # Create a separate dictionary to store mean reversion models

for symbol in symbols:
    # Create a neural network model using historical data
    if df.shape[0] &gt;= 250:
        model = create_model(df, symbol)
        models[symbol] = model
    else:
        print(f&quot;Not enough data to create a model for {symbol}&quot;)

# Save the profit and loss to a csv file
save_profit_loss(profit_loss_dict)

print(df.shape)

# The main trading loop
while True:
    schedule.run_pending()  # Check if the scheduled update_model function needs to run
    if df is not None:  # Add this condition to avoid accessing shape of None
        # Get the current balances for the specified symbols
        balances = get_current_balances([&quot;USDT&quot;, &quot;BNB&quot;, &quot;BTC&quot;, &quot;ETH&quot;])
        print(&quot;Current Balances:&quot;)
        for symbol in symbols:
            trading_asset_balance = balances.get(symbol, 0.0)
            print(f&quot;{symbol}: Free - {trading_asset_balance}&quot;)

        for symbol in symbols:
            # Fetch the latest price data for the symbol
            current_price = get_realtime_data(symbol)

            # Fetch the portfolio value from the account for live or paper trading
            if paper_trading:
                base_asset_balance = balances.get(&quot;USDT&quot;, 0.0)
                trading_asset_balance = balances.get(symbol, 0.0)
            else:
                base_asset_balance = balances.get(&quot;USDT&quot;, 0.0)
                trading_asset_balance = balances.get(symbol, 0.0)

            # Calculate the portfolio value
            portfolio_value = base_asset_balance + trading_asset_balance * current_price

            # Calculate the quantity
            quantity = (risk_tolerance_percentage / 100) * portfolio_value / current_price

            # Round the quantity according to the tickSize for each symbol
            decimals = int(-np.log10(tick_sizes[symbol]))
            quantity = round(quantity, decimals)

            # Perform trading using updated models
            trade(models[symbol], symbol, paper_trading=False)  # Set paper_trading=False for live trading

            # Delay between consecutive API requests to avoid rate limiting
            time.sleep(1)
```




</details>


# 答案1
**得分**: -1

```python
balance_info = balances.get(symbol, {"free": 0.0})
print(f"{symbol}: Free - {balance_info['free']}")
```
`balances`是一个字典,所以如果`symbol`在这个字典中,`balance_info`是这个符号下的余额**值**,因此在您当前的代码中是一个浮点数。在下一行中,您将`balance_info`视为字典,这会导致错误。您可能想要执行以下操作:

```python
free_balance = float(balance['free']) if balance else 0.0
balances[symbol] = {'free': free_balance} # 而不是 ... = free_balance
```
在您的获取当前余额函数中,这样在[symbol]键下实际上仍然有一个字典(而不是一个浮点数)。

<details>
<summary>英文:</summary>

```
    balance_info = balances.get(symbol, {&quot;free&quot;: 0.0})
    print(f&quot;{symbol}: Free - {balance_info[&#39;free&#39;]}&quot;)
```

`balances` is a dictionary, so if `symbol` is inside this dictionary, `balance_info` is a **value** of the balance under this symbol, and thus in your current code - a float. In the next line you treat balance_info as a dictionary, which causes an error. You probably meant to do

```
free_balance = float(balance[&#39;free&#39;]) if balance else 0.0
balances[symbol] = {&#39;free&#39;: free_balance} # instead of ... = free_balance
```
inside your get current balance function, so that under [symbol] key you actually still have a dictionary (rather than a float).


</details>



huangapple
  • 本文由 发表于 2023年8月4日 07:38:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/76832175.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定