import os import csv from datetime import datetime, timezone import threading # A lock to prevent race conditions when multiple strategies might log at once in the future log_lock = threading.Lock() def log_trade(strategy: str, coin: str, action: str, price: float, size: float, signal: str, pnl: float = 0.0): """ Appends a record of a trade action to a persistent CSV log file. Args: strategy (str): The name of the strategy that triggered the action. coin (str): The coin being traded (e.g., 'BTC'). action (str): The action taken (e.g., 'OPEN_LONG', 'CLOSE_LONG'). price (float): The execution price of the trade. size (float): The size of the trade. signal (str): The signal that triggered the trade (e.g., 'BUY', 'SELL'). pnl (float, optional): The realized profit and loss for closing trades. Defaults to 0.0. """ log_dir = "_logs" file_path = os.path.join(log_dir, "trade_history.csv") # Ensure the logs directory exists if not os.path.exists(log_dir): os.makedirs(log_dir) # Define the headers for the CSV file headers = ["timestamp_utc", "strategy", "coin", "action", "price", "size", "signal", "pnl"] # Check if the file needs a header file_exists = os.path.isfile(file_path) with log_lock: try: with open(file_path, 'a', newline='', encoding='utf-8') as f: writer = csv.DictWriter(f, fieldnames=headers) if not file_exists: writer.writeheader() writer.writerow({ "timestamp_utc": datetime.now(timezone.utc).isoformat(), "strategy": strategy, "coin": coin, "action": action, "price": price, "size": size, "signal": signal, "pnl": pnl }) except IOError as e: # If logging fails, print an error to the main console as a fallback. print(f"CRITICAL: Failed to write to trade log file: {e}")