BrainDock/src/integrations/obsidian_logger.py

87 lines
2.6 KiB
Python
Executable File

import logging
from datetime import datetime
from pathlib import Path
from typing import Dict
import json
logger = logging.getLogger(__name__)
class ObsidianLogger:
"""Logs trades directly to Obsidian vault file."""
def __init__(self, vault_path: str, trade_log_file: str):
self.vault_path = Path(vault_path)
self.trade_log_file = trade_log_file
self.log_path = self.vault_path / self.trade_log_file
def log_trade(self, trade_data: Dict) -> bool:
"""
Log trade to Obsidian markdown file.
Args:
trade_data: Trade details (timestamp, order_id, pair, side, quantity, price, stop_loss)
Returns:
True if logged successfully
"""
try:
# Ensure directory exists
self.log_path.parent.mkdir(parents=True, exist_ok=True)
# Format trade entry
timestamp = trade_data.get('timestamp', datetime.utcnow())
entry = self._format_trade_entry(trade_data)
# Append to log file
with open(self.log_path, 'a', encoding='utf-8') as f:
f.write(entry)
logger.info(f"Trade logged to Obsidian: {trade_data.get('order_id')}")
return True
except Exception as e:
logger.error(f"Obsidian log error: {e}")
return False
def _format_trade_entry(self, trade: Dict) -> str:
"""Format trade as markdown entry"""
timestamp = trade.get('timestamp', datetime.utcnow())
entry = f"""
## {timestamp.isoformat()} | {trade['pair']} | {trade['side']}
- **Order ID:** {trade['order_id']}
- **Quantity:** {trade['quantity']} BTC
- **Price:** ${trade['price']}
- **Stop Loss:** ${trade['stop_loss']}
- **Type:** DCA Bot Trade
---
"""
return entry
def log_stop_loss_hit(self, position: Dict, current_price: float) -> bool:
"""Log stop loss event"""
try:
entry = f"""
### ⚠️ STOP LOSS HIT | {position['symbol']}
- **Order ID:** {position['order_id']}
- **Entry Price:** ${position['entry_price']}
- **Stop Loss:** ${position['stop_loss_price']}
- **Current Price:** ${current_price}
- **Loss %:** {((current_price - position['entry_price']) / position['entry_price'] * 100):.2f}%
- **Closed:** {datetime.utcnow().isoformat()}
---
"""
with open(self.log_path, 'a', encoding='utf-8') as f:
f.write(entry)
return True
except Exception as e:
logger.error(f"Stop loss log error: {e}")
return False