Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .Jules/palette.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,7 @@
## 2025-02-28 - Structured CLI Reports
**Learning:** Dense numerical data in CLI output is hard to parse. Using ASCII box-drawing characters and alignment to create a "dashboard" or "invoice" style summary significantly improves readability and perceived quality.
**Action:** When summarizing simulation or batch job results, always format the final report as a structured table or box rather than a list of print statements.

## 2025-03-01 - Dynamic Progress Bars in Quiet Mode
**Learning:** For long-running CLI processes that suppress verbose logging (e.g., `--quiet`), users can feel lost or assume the process has hung.
**Action:** Implement a dynamic progress bar using `\r` and `flush=True` conditional on `sys.stdout.isatty()` to provide system status visibility without polluting standard output logs.
15 changes: 12 additions & 3 deletions bitcoin_trading_simulation.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ def simulate_trading(signals, initial_cash=10000, quiet=False):

if not quiet:
print(f"\n{Colors.HEADER}{Colors.BOLD}------ Daily Trading Ledger ------{Colors.ENDC}")
for i, row in signals.iterrows():
for idx, (i, row) in enumerate(signals.iterrows()):
if i > 0:
portfolio.loc[i, 'cash'] = portfolio.loc[i-1, 'cash']
portfolio.loc[i, 'btc'] = portfolio.loc[i-1, 'btc']
Expand All @@ -94,21 +94,30 @@ def simulate_trading(signals, initial_cash=10000, quiet=False):
btc_to_buy = portfolio.loc[i, 'cash'] / row['price']
portfolio.loc[i, 'btc'] += btc_to_buy
portfolio.loc[i, 'cash'] -= btc_to_buy * row['price']
print(f"{Colors.GREEN}🟢 Day {i}: Buy {btc_to_buy:.4f} BTC at ${row['price']:.2f}{Colors.ENDC}")
if not quiet:
print(f"{Colors.GREEN}🟢 Day {i}: Buy {btc_to_buy:.4f} BTC at ${row['price']:.2f}{Colors.ENDC}")

# Sell signal
elif row['positions'] == -2.0:
if portfolio.loc[i, 'btc'] > 0:
cash_received = portfolio.loc[i, 'btc'] * row['price']
portfolio.loc[i, 'cash'] += cash_received
print(f"{Colors.FAIL}🔴 Day {i}: Sell {portfolio.loc[i, 'btc']:.4f} BTC at ${row['price']:.2f}{Colors.ENDC}")
if not quiet:
print(f"{Colors.FAIL}🔴 Day {i}: Sell {portfolio.loc[i, 'btc']:.4f} BTC at ${row['price']:.2f}{Colors.ENDC}")
portfolio.loc[i, 'btc'] = 0

portfolio.loc[i, 'total_value'] = portfolio.loc[i, 'cash'] + portfolio.loc[i, 'btc'] * row['price']

if not quiet:
print(f"Day {i}: Portfolio Value: ${portfolio.loc[i, 'total_value']:.2f}, "
f"Cash: ${portfolio.loc[i, 'cash']:.2f}, BTC: {portfolio.loc[i, 'btc']:.4f}")
elif sys.stdout.isatty():
# Dynamic progress bar for quiet mode
progress = int((idx + 1) / len(signals) * 100)
print(f"\r{Colors.CYAN}Running simulation: {progress}%{Colors.ENDC}", end="", flush=True)

if quiet and sys.stdout.isatty():
print()

return portfolio

Expand Down
1 change: 1 addition & 0 deletions main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
terraform {}
3 changes: 3 additions & 0 deletions test_isatty.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
def test_isatty(capsys):
import sys
print("isatty:", sys.stdout.isatty())
12 changes: 12 additions & 0 deletions test_progress.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import sys
import pandas as pd
from bitcoin_trading_simulation import simulate_trading, Colors

# mock isatty
sys.stdout.isatty = lambda: True

signals = pd.DataFrame(index=range(10))
signals['price'] = [100.0] * 10
signals['positions'] = [0.0] * 10

simulate_trading(signals, quiet=True)
7 changes: 7 additions & 0 deletions test_quiet.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import sys
from bitcoin_trading_simulation import simulate_bitcoin_prices, calculate_moving_averages, generate_trading_signals, simulate_trading

prices = simulate_bitcoin_prices(days=60, initial_price=50000, volatility=0.02)
signals = calculate_moving_averages(prices)
signals = generate_trading_signals(signals)
simulate_trading(signals, quiet=True)
21 changes: 21 additions & 0 deletions test_quiet_buy_sell.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import pandas as pd
from bitcoin_trading_simulation import simulate_trading

def test_quiet_suppresses_buys_sells():
signals = pd.DataFrame(index=range(3))
signals['price'] = [100.0, 101.0, 102.0]
signals['positions'] = [2.0, -2.0, 0.0]

import io
import sys

old_stdout = sys.stdout
sys.stdout = io.StringIO()
simulate_trading(signals, initial_cash=1000, quiet=True)
out = sys.stdout.getvalue()
sys.stdout = old_stdout

assert out == ""

test_quiet_suppresses_buys_sells()
print("Passed")
Loading