Python 神经网络与 ChatGPT

问题描述 投票:0回答:0
   # 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']}")

所以基本上我收到一条错误消息,每次我要求 ChatGPT 修复它时,它都会修复一半,因为它总是改变一些小东西,所以在大约 1000 次代码迭代之后,它不能与代码的其余部分一起工作。经历了很多尝试和错误,我终于能够克服它并向你们寻求帮助。

回溯(最近一次调用最后一次): 文件“main.py”,第 83 行,位于 print(f"{symbol}: 免费 - {balance_info['free']}") 类型错误:“float”对象不可下标

对于任何对漏洞代码结构感兴趣的人,欢迎提供任何可能导致错误的提示或更好的想法来实现更好的预测,我对 python 很陌生,并不是最好的开发人员。


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('GPU')

# Define parameters
api_key = "YOUR_API_KEY"
api_secret = "YOUR_SECRET_KEY"
base_url = "https://api.binance.com"
symbols = ["BTCUSDT", "ETHUSDT", "BNBUSDT"]
interval = "1h"
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 = {"BTCUSDT": 10, "ETHUSDT": 8, "BNBUSDT": 5}

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

# Define the minimum quantity for each symbol
min_quantity = {"BTCUSDT": 0.00036, "ETHUSDT": 0.0059 , "BNBUSDT": 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['balances'] if item['asset'] == symbol), None)
            # If the symbol is found, get the 'free' value, otherwise set it to 0
            free_balance = float(balance['free']) if balance else 0.0
            balances[symbol] = free_balance
        return balances
    except Exception as e:
        print(f"Error fetching balances: {e}")
        return {}  # Return an empty dictionary if there is an error

    
# 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']}")

# 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 + "/api/v3/klines"
        params = {"symbol": symbol, "interval": interval, "limit": 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=["open_time", "open", "high", "low", "close", "volume", "close_time", "quote_volume","trades", "taker_base_volume", "taker_quote_volume", "ignore"])
        # Convert the columns to numeric values
        df = df.apply(pd.to_numeric)
        # Convert the time columns to datetime format
        df["open_time"] = pd.to_datetime(df["open_time"], unit="ms")
        df["close_time"] = pd.to_datetime(df["close_time"], unit="ms")
        # Add a column for the symbol name
        df["symbol"] = symbol
        # Add a column for the moving average
        df["moving_average"] = 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"historical_data_{interval}.csv", 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 + "/api/v3/ticker/price"
    params = {"symbol": 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["price"])
    # 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["symbol"] == symbol]
    # Select the features and the target
    X = df_symbol[["open", "high", "low", "volume"]].values
    y = df_symbol["close"].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='relu', input_shape=(X_train.shape[1],)),
        tf.keras.layers.Dense(32, activation='relu'),
        tf.keras.layers.Dense(1)  # Output layer, predicting the closing price
    ])

    # Compile the model
    model.compile(optimizer='adam', loss='mean_squared_error')

    # 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"Model evaluation for {symbol}: Test loss: {loss}")

    # 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] >= 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["symbol"] == symbol].shape[0] >= 250:
                model = create_model(df, symbol)
                models[symbol] = model
            else:
                print(f"Not enough data to update the model for {symbol}")
    else:
        print("Not enough data to update models.")

# 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({"symbol": symbols, "predicted_price": predictions, "datetime": datetimes})
    df.to_csv("predictions_main_py.csv", 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 'global balances' statement to specify the global scope
    global balances
    if paper_trading:
        base_asset_balance = get_current_balances(["USDT"]).get("USDT", {}).get("free", 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, "USDT"])
        base_asset_balance = balances.get("USDT", {}).get("free", 0.0)
        trading_asset_balance = balances.get(symbol, {}).get("free", 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["symbol"] == symbol]
    X_last_row = df_symbol[["open", "high", "low", "volume"]].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]["free"]
        if trading_asset_balance >= min_qty:
            print(f"Holding {symbol} - waiting for sell order to be executed")
        else:
            print(f"Holding {symbol} - Insufficient quantity to trade. Waiting for sell order to be executed.")
        return

    if trade_status.get(symbol) == "BOUGHT":
        # If the trade status is "BOUGHT", 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]["free"]
        if trading_asset_balance >= min_quantity[symbol]:
            print(f"Holding {symbol} - Waiting for sell order to be executed.")
        else:
            print(f"Holding {symbol} - Insufficient quantity to sell. Waiting for sell order to be executed.")
    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]["free"]

            # Compare the quantity with the trading asset balance
            if quantity > 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 < min_quantity[symbol]:
                quantity = min_quantity[symbol]
                print(f"Quantity is less than the minimum allowed for {symbol}. Using the minimum allowed quantity for the trade.")

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

            try:
                if prediction < 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("Market buy order executed.")

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

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

            print(f"Price prediction for {symbol}: {prediction}, Current price: {current_price}")

            # Add the SELL logic here
            if trade_status.get(symbol) == "BOUGHT" and prediction > 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("Market sell order executed.")
                    # Reset trade status and hold flag after executing the sell order
                    trade_status[symbol] = None
                    hold = False
                except BinanceAPIException as e:
                    print(f"Error: {e}")


# 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="index")
    # Add a column for the net profit or loss
    df["net"] = df["profit"] - df["loss"]
    # Save the dataframe to a csv file
    df.to_csv("profit_loss.csv", index=True)
    # Return the dataframe
    return df



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


# 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, balance_info in balances.items():
    print(f"{symbol}: Free - {balance_info['free']}")

# 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] >= 250:
        model = create_model(df, symbol)
        models[symbol] = model
    else:
        print(f"Not enough data to create a model for {symbol}")

# 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(["USDT", "BNB", "BTC", "ETH"])
        print("Current Balances:")
        for symbol in symbols:
            trading_asset_balance = balances.get(symbol, 0.0)
            print(f"{symbol}: Free - {trading_asset_balance}")

        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("USDT", 0.0)
                trading_asset_balance = balances.get(symbol, 0.0)
            else:
                base_asset_balance = balances.get("USDT", 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)
python deep-learning neural-network runtime-error trading
© www.soinside.com 2019 - 2024. All rights reserved.