56 lines
2.1 KiB
Python
56 lines
2.1 KiB
Python
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}")
|