Clean up unused files, organize structure, update docs

- Delete obsolete files: data_fetcher_old.py, market_old.py, base_strategy.py (root),
  strategy_sma_cross.py, and old architecture remnants (address_monitor.py,
  position_monitor.py, trade_log.py, wallet_data.py, whale_tracker.py)
- Delete zero-byte Docker artifacts and runtime files (clp_hedger.log,
  clp_hedger/hedge_status.json)
- Move one-off utility scripts to scripts/ directory
- Move example/template files to .temp/ directory
- Update .gitignore: add entries for clp_hedger.log, clp_hedger/hedge_status.json,
  Docker layer hash files, Using, Running, and backups/
- Update .dockerignore: add clp_hedger.log, clp_hedger/hedge_status.json, backups/
- Create example config files: _data/strategies.json.example,
  _data/backtesting_conf.json.example, _data/coin_precision.json.example
- Update GEMINI.md: remove outdated session summaries and duplicate review section
- Update review.md: add cleanup status section, update remaining recommendations
- Update MIGRATION_PLAN.md: mark completed phases, update file references
- Update DOCKER_MIGRATION_GUIDE.md: update import_csv.py path reference
This commit is contained in:
DiTus
2026-08-05 09:50:36 +02:00
parent 967c86e8e9
commit 1a95fe1caa
39 changed files with 599 additions and 3116 deletions

137
list_latest_candles.py Normal file
View File

@ -0,0 +1,137 @@
import argparse
import json
import logging
import os
import sys
from datetime import datetime, timezone
from contextlib import closing
import psycopg2
from logging_utils import setup_logging
DEFAULT_DB_PATH = os.environ.get(
"PG_CONN_STR",
"postgresql://hyper:hyper@localhost:5432/hyper"
)
def load_coins():
"""Load the list of all coins from the local coin_precision.json file."""
coin_file = "_data/coin_precision.json"
try:
with open(coin_file, 'r') as f:
return list(json.load(f).keys())
except FileNotFoundError:
logging.error(f"'{coin_file}' not found. Please run list_coins.py first.")
sys.exit(1)
except (IOError, json.JSONDecodeError) as e:
logging.error(f"Failed to load or parse '{coin_file}': {e}")
sys.exit(1)
def get_latest_candle(conn, coin, interval="1m"):
"""
Query the database for the most recent candle for a given coin.
Returns a dict with keys: datetime_utc, timestamp_ms, open, high, low, close, volume, number_of_trades
or None if the table doesn't exist or has no rows.
"""
table_name = f"{coin.replace(':', '_')}_{interval}"
try:
with closing(conn.cursor()) as cur:
cur.execute(f'SELECT 1 FROM information_schema.tables WHERE table_name = %s', (table_name,))
if not cur.fetchone()[0]:
return None
cur.execute(
f'SELECT datetime_utc, timestamp_ms, open, high, low, close, volume, number_of_trades '
f'FROM "{table_name}" ORDER BY timestamp_ms DESC LIMIT 1'
)
row = cur.fetchone()
if row is None:
return None
return {
"datetime_utc": row[0],
"timestamp_ms": row[1],
"open": row[2],
"high": row[3],
"low": row[4],
"close": row[5],
"volume": row[6],
"number_of_trades": row[7],
}
except Exception as e:
logging.debug(f"Could not get latest candle for {coin} ({interval}): {e}")
return None
def list_latest_candles(coins, interval="1m", db_path=None):
"""
Fetch and display the newest candle for every coin in the list.
"""
if db_path is None:
db_path = DEFAULT_DB_PATH
conn = psycopg2.connect(db_path)
results = []
for coin in coins:
candle = get_latest_candle(conn, coin, interval)
if candle is not None:
results.append((coin, candle))
else:
results.append((coin, None))
conn.close()
print(f"\n--- Newest {interval} Candles for All Symbols ---")
print(f"Total symbols: {len(coins)} | Symbols with data: {sum(1 for _, c in results if c is not None)}")
print(f"Generated at: {datetime.now(timezone.utc).strftime('%Y-%m-%d %H:%M:%S UTC')}")
print("-" * 120)
print(f"{'Coin':<16} | {'Datetime (UTC)':<22} | {'Open':>12} | {'High':>12} | {'Low':>12} | {'Close':>12} | {'Volume':>12}")
print("-" * 120)
for coin, candle in results:
if candle is not None:
dt = candle["datetime_utc"].strftime('%Y-%m-%d %H:%M:%S') if candle["datetime_utc"] else "N/A"
o = f"{candle['open']:.4f}" if candle['open'] is not None else "N/A"
h = f"{candle['high']:.4f}" if candle['high'] is not None else "N/A"
l = f"{candle['low']:.4f}" if candle['low'] is not None else "N/A"
c = f"{candle['close']:.4f}" if candle['close'] is not None else "N/A"
v = f"{candle['volume']:.4f}" if candle['volume'] is not None else "N/A"
print(f"{coin:<16} | {dt:<22} | {o:>12} | {h:>12} | {l:>12} | {c:>12} | {v:>12}")
else:
print(f"{coin:<16} | {'(no data)':<22} | {'':>12} | {'':>12} | {'':>12} | {'':>12} | {'':>12}")
print("-" * 120)
print(f"Symbols without data: {sum(1 for _, c in results if c is None)}")
if __name__ == "__main__":
parser = argparse.ArgumentParser(
description="List the newest 1-minute candle for all symbols from the database."
)
parser.add_argument(
"--interval",
default="1m",
help="Candle interval to query (default: 1m)."
)
parser.add_argument(
"--db",
default=None,
help="PostgreSQL connection string (default: from PG_CONN_STR env or localhost)."
)
parser.add_argument(
"--log-level",
default="off",
choices=['off', 'normal', 'debug'],
help="Set the logging level."
)
args = parser.parse_args()
setup_logging(args.log_level, 'ListLatestCandles')
coins = load_coins()
list_latest_candles(coins, interval=args.interval, db_path=args.db)