我的 python 脚本执行时效果很好。但是,我要求将其作为独立的 .exe 文件。 所以,我尝试使用 Pyinstaller 来转换它。我已经克服/解决了许多错误 - 但是,这个错误却困扰着我!
Traceback (most recent call last):
File "Convert_TopStepX_Orders_to_Pinescript.py", line 133, in <module>
modify_spreadsheet(os.path.join(script_dir, xlsx_file), output_file)
~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^
File "<frozen ntpath>", line 139, in join
File "<frozen genericpath>", line 188, in _check_arg_types
TypeError: join() argument must be str, bytes, or os.PathLike object, not 'list'
[PYI-10584:ERROR] Failed to execute script 'Convert_TopStepX_Orders_to_Pinescript' due to unhandled exception!
如有任何帮助,我们将不胜感激!
上面提到的修改电子表格代码行上面有一个注释“# Call the function”
我怀疑这可能与此处回复中提出的解决方案有关: https://devsolus.com/2021/12/02/python-typeerror-join-argument-must-be-str-bytes-or-os-pathlike-object-not-list/?amp=1
不幸的是,我对 Python 的了解不够,无法理解如何将特定的解决方案应用于我的问题。
这是整个脚本:
import pandas as pd
import sys, os
from datetime import datetime
import glob
from shutil import rmtree
import re
import ntpath
def CLEANMEIFOLDERS():
#Getting the current run _MEI path
try:
base_path = sys._MEIPASS
#I don't know if this part is crucial or not since it only works if you don't use
#--onefile in pyinstaller, which makes the use of this function unnecessary
except Exception:
base_path = os.path.abspath(".")
#Extracting the updir of current run path to search for _MEI folders for the previous runs,
#cave man style. Please update this part if you know a better way.
base_path = base_path.split("\\")
base_path.pop(-1)
temp_path = ""
for item in base_path:
temp_path = temp_path + item + "\\"
#Search the path for _MEI folders and delete them if they are not for the current run
mei_folders = [f for f in glob.glob(temp_path + "**/", recursive=False)]
for item in mei_folders:
if item.find('_MEI') != -1 and item != sys._MEIPASS + "\\":
rmtree(item)
# Get the script directory
script_dir = os.path.dirname(__file__)
# Get a list of all CSV files in the directory
csv_files = [f for f in os.listdir(script_dir) if f.endswith(".csv")]
# Loop over the CSV files
for csv_file in csv_files:
# Extract the file name without the extension
file_name = os.path.splitext(csv_file)[0]
# Extract the text prior to "orders" from the file name
if "orders" in file_name:
new_file_name = file_name.split("orders")[0]
else:
new_file_name = file_name
# Construct the output Excel file name
xlsx_file = f"{new_file_name}.xlsx"
# Read the CSV file into a pandas DataFrame
df = pd.read_csv(os.path.join(script_dir, csv_file))
# Save the DataFrame to an Excel file
df.to_excel(os.path.join(script_dir, xlsx_file), index=False)
# Delete the original CSV file
#os.remove(os.path.join(script_dir, csv_file))
print(f"Converted {csv_file} to {xlsx_file} and deleted the original CSV file")
# Create the output folder if it doesn't exist
output_folder = os.path.join(script_dir, "Trade Executions Scripts")
os.makedirs(output_folder, exist_ok=True)
def modify_spreadsheet(input_file, output_file):
# Read the Excel file
df = pd.read_excel(input_file)
# Remove rows with "cancelled by system" or "cancelled by trader" in any cell
df = df[~df.apply(lambda row: row.astype(str).str.contains('cancelled by system|cancelled by trader|Maximum position exceeded', case=False).any(), axis=1)]
# Convert the date and time column to the desired format
df.iloc[:, 9] = pd.to_datetime(df.iloc[:, 9]).apply(lambda x: f"{x.year}, {x.month}, {x.day}, {x.hour}, {x.minute}, {x.second}")
# Replace the text in column 15 with pinescript colors\code
df.iloc[:, 15] = df.iloc[:, 15].apply(lambda x: 'color = i_close_col' if x == 'ClosePosition' else x)
# Replace the text in column 15 with pinescript colors\code
df.iloc[:, 15] = df.iloc[:, 15].apply(lambda x: 'color = i_stop_loss_col' if x == 'StopLoss' else x)
# Replace the text in column 15 with pinescript colors\code
df.iloc[:, 15] = df.iloc[:, 15].apply(lambda x: 'color = i_take_profit_col' if x == 'TakeProfit' else x)
# Replace the text in column 15 with pinescript colors\code
df.iloc[:, 15] = df.apply(lambda row: 'color = i_buy_col' if (row.iloc[6] == 'Bid' and row.iloc[14] == 'Opening' and row.iloc[15] == 'Trader') else row.iloc[15], axis=1)
# Replace the text in column 15 with pinescript colors\code
df.iloc[:, 15] = df.apply(lambda row: 'color = i_sell_col' if (row.iloc[6] == 'Ask' and row.iloc[14] == 'Opening' and row.iloc[15] == 'Trader') else row.iloc[15], axis=1)
# Replace the text in column 15 with pinescript colors\code
df.iloc[:, 15] = df.apply(lambda row: 'color = i_close_col' if (row.iloc[6] == 'Ask' and row.iloc[14] == 'Closing' and row.iloc[15] == 'Trader') else row.iloc[15], axis=1)
# Replace the text in column 15 with pinescript colors\code
df.iloc[:, 15] = df.apply(lambda row: 'color = i_close_col' if (row.iloc[6] == 'Bid' and row.iloc[14] == 'Closing' and row.iloc[15] == 'Trader') else row.iloc[15], axis=1)
#-------------------
# Replace the text in column 14 with pinescript code for arrows that relate to the color codes in the section above
df.iloc[:, 14] = df.apply(lambda row: "char = '\u25B2'+' '" if (row.iloc[15] == 'color = i_buy_col') else row.iloc[14], axis=1)
# Replace the text in column 14 with pinescript code for arrows that relate to the color codes in the section above
df.iloc[:, 14] = df.apply(lambda row: "char = '\u25BC'" if (row.iloc[15] == 'color = i_sell_col') else row.iloc[14], axis=1)
# Replace the text in column 14 with pinescript code for arrows that relate to the color codes in the section above
df.iloc[:, 14] = df.apply(lambda row: "char = '\u25B6'" if (row.iloc[15] == 'color = i_take_profit_col') else row.iloc[14], axis=1)
# Replace the text in column 14 with pinescript code for arrows that relate to the color codes in the section above
df.iloc[:, 14] = df.apply(lambda row: "char = '\u25C0'" if (row.iloc[15] == 'color = i_close_col' or row.iloc[15] == 'color = i_stop_loss_col') else row.iloc[14], axis=1)
#-------------------
# Remove unwanted columns: A, B, C, D, K, Q
df = df.drop(df.columns[[0, 1, 2, 3, 4, 6, 7, 8, 10, 11, 12, 16]], axis=1)
# Save the updated spreadsheet without header\title row
df.to_excel(output_file, index=False, header=False)
# Get the list of all xlsx files in the input directory
xlsx_file = [file for file in os.listdir(output_folder) if file.endswith(".xlsx")]
xlsx_files = [f for f in os.listdir(script_dir) if f.endswith(".xlsx")]
# Loop over the xlsx files and modify them
for xlsx_file in xlsx_files:
input_file = os.path.join(script_dir, xlsx_file)
output_file = os.path.join(output_folder, f"{os.path.splitext(xlsx_file)[0]}_modified.xlsx")
modify_spreadsheet(input_file, output_file)
print(f"Modified {xlsx_file} and saved to {output_file}")
# Call the function
modify_spreadsheet(os.path.join(script_dir, xlsx_file), output_file)
#------------------
# Get the current date
current_date = datetime.now().strftime("%Y-%m-%d")
# Get a list of all files in the folder that end with ".xlsx"
split_files = [f for f in os.listdir(output_folder) if f.endswith(".xlsx")]
# Loop over the split files
for split_file in split_files:
# Load the Excel spreadsheet
df = pd.read_excel(f"{output_folder}/{split_file}")
# Determine the number of rows in the spreadsheet
num_rows = len(df)
# Determine the number of splits needed
num_splits = (num_rows + 20) // 25
# Loop over the splits
for i in range(num_splits):
# Determine the start and end row indices for this split
start_row = i * 25
end_row = min((i + 1) * 25 + 5, num_rows)
# Extract the subset of rows for this split
subset_df = df.iloc[start_row:end_row]
# Save the subset to a new spreadsheet with "modified" at the end of the file name
output_file = f"{output_folder}/{split_file[:-5]}_split_{str(i+1)}.xlsx"
subset_df.to_excel(output_file, index=False)
print(f"Split {split_file} and saved to {output_file}")
# Delete unwanted files
for file in os.listdir(output_folder):
file_path = f"{output_folder}/{file}"
if not file.endswith(".txt") and not "split" in file and os.path.exists(file_path):
try:
os.remove(file_path)
except Exception as e:
print(f"Error deleting file {file}: {str(e)}")
#-------------------
# Get a list of all files in the folder that start with "split"
split_files = [f for f in os.listdir(output_folder) if f.endswith(".xlsx")]
# Loop over the split files
for file in split_files:
try:
# Load the Excel spreadsheet
data = pd.read_excel(f"{output_folder}/{file}", header=None)
# Count the number of rows
row_count = data.shape[0]
# Write the result to a new notepad
base_name = os.path.splitext(file)[0]
output_file = f"{output_folder}/{re.sub(r'modified_split|modified', 'trades', base_name)}.txt"
with open(output_file, 'w', encoding='utf-8') as f:
# Add the color definitions to the top of the file
f.write(f"//@version=5\n")
f.write(f"indicator('My Executions', overlay=true)\n") # Modified line
f.write("i_buy_col = input.color(color.rgb(109, 223, 2, 0), 'Color for Buy Arrows')\n")
f.write("i_close_col = input.color(color.rgb(255, 255, 255, 0), 'Color for Close Order Arrows')\n")
f.write("i_sell_col = input.color(color.rgb(251, 255, 0, 0), 'Color for Sell Arrows')\n")
f.write("i_stop_loss_col = input.color(color.rgb(186, 0, 211, 0), 'Color for Stop Loss Arrows')\n")
f.write("i_take_profit_col = input.color(color.rgb(0, 110, 255, 0), 'Color for Take Profit Arrows')\n\n")
for i in range(row_count):
f.write(f"data{i} = float(na)\n")
for i in range(len(data)):
f.write(f"data{i} := timestamp({data.iloc[i, 1]}) >= time and timestamp({data.iloc[i, 1]}) < time_close ? {data.iloc[i, 2]} : data{i}\n")
# Iterate over the rows in the spreadsheet
for i in range(len(data)):
# Write the text to the notepad
f.write(f"plotchar(data{i}, {data.iloc[i, 3]}, {data.iloc[i, 4]}, force_overlay = true, location=location.absolute, size=size.tiny)\n")
print(f"Created Text Files: {file}, added pine script and saved to {output_file}")
except Exception as e:
print(f"Error processing file {file}: {str(e)}")
#-------------------
# Delete unwanted files
for file in os.listdir(output_folder):
file_path = os.path.join(output_folder, file)
if not file.endswith(".txt") and os.path.exists(file_path):
try:
os.remove(file_path)
except Exception as e:
print(f"Error deleting file {file}: {str(e)}")
# Delete xlsx file
for file in os.listdir(script_dir):
if file.endswith(".xlsx"):
file_path = os.path.join(script_dir, file)
if os.path.exists(file_path):
try:
os.remove(file_path)
except Exception as e:
print(f"Error deleting file {file}: {str(e)}")
input("Press Enter to continue...")
这段代码就是问题所在:
xlsx_file = [file for file in os.listdir(output_folder) if file.endswith(".xlsx")]
xlsx_files = [f for f in os.listdir(script_dir) if f.endswith(".xlsx")]
# Loop over the xlsx files and modify them
for xlsx_file in xlsx_files:
input_file = os.path.join(script_dir, xlsx_file)
output_file = os.path.join(output_folder, f"{os.path.splitext(xlsx_file)[0]}_modified.xlsx")
modify_spreadsheet(input_file, output_file)
print(f"Modified {xlsx_file} and saved to {output_file}")
# Call the function
modify_spreadsheet(os.path.join(script_dir, xlsx_file), output_file)
底部对
os.path.join()
的调用(在对modify_spreadsheet的调用内)将xlsx_file
作为其第二个参数传递。 但是 xlsx_file
是一个列表,正如您在这段代码的顶部看到的那样。 您无法将列表传递给 os.path.join()
,因此会出现错误。