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

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

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:

确定