From 5d7c715ee1c3678eeffe12ec655eb77a98ccf50a Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Sun, 1 Feb 2026 13:26:11 +0000 Subject: [PATCH 1/2] feat: add CLI arguments for customization and accessibility - Added argparse to bitcoin_trading_simulation.py - Implemented --days, --initial-cash, --initial-price, --volatility arguments - Added --no-color flag for accessibility - Added --quiet flag for reduced verbosity - Updated .gitignore to exclude __pycache__ Co-authored-by: EiJackGH <172181576+EiJackGH@users.noreply.github.com> --- .Jules/palette.md | 4 ++++ .gitignore | 2 ++ bitcoin_trading_simulation.py | 45 ++++++++++++++++++++++++++++------- 3 files changed, 43 insertions(+), 8 deletions(-) diff --git a/.Jules/palette.md b/.Jules/palette.md index 5de3a38..fc95cf2 100644 --- a/.Jules/palette.md +++ b/.Jules/palette.md @@ -1,3 +1,7 @@ ## 2024-05-22 - Visual Hierarchy in CLI Output **Learning:** Adding color-coded indicators (Green/Red) and emojis (💰, 📉) in CLI tools significantly reduces cognitive load when parsing financial data streams. It transforms a wall of text into a scannable narrative. **Action:** For data-heavy CLI applications, always implement a semantic color system and visual anchors (icons/emojis) for key events. + +## 2024-10-24 - CLI Accessibility and Control +**Learning:** While colors improve scannability, they can be inaccessible or noisy in certain contexts. Users also need control over simulation parameters without modifying code. +**Action:** Implement `--no-color` for accessibility and `--quiet` for reduced verbosity. Use `argparse` to expose key parameters like simulation duration and initial capital. diff --git a/.gitignore b/.gitignore index d4fb281..fe1bf1a 100644 --- a/.gitignore +++ b/.gitignore @@ -39,3 +39,5 @@ # debug information files *.dwo +__pycache__/ +*.pyc diff --git a/bitcoin_trading_simulation.py b/bitcoin_trading_simulation.py index 82df43f..aa8abc0 100644 --- a/bitcoin_trading_simulation.py +++ b/bitcoin_trading_simulation.py @@ -1,5 +1,6 @@ import numpy as np import pandas as pd +import argparse class Colors: HEADER = '\033[95m' @@ -9,6 +10,15 @@ class Colors: ENDC = '\033[0m' BOLD = '\033[1m' + @classmethod + def disable(cls): + cls.HEADER = '' + cls.BLUE = '' + cls.GREEN = '' + cls.RED = '' + cls.ENDC = '' + cls.BOLD = '' + def simulate_bitcoin_prices(days=60, initial_price=50000, volatility=0.02): """ Simulates Bitcoin prices for a given number of days using Geometric Brownian Motion. @@ -49,7 +59,7 @@ def generate_trading_signals(signals): signals['positions'] = signals['signal'].diff().shift(1) return signals -def simulate_trading(signals, initial_cash=10000): +def simulate_trading(signals, initial_cash=10000, quiet=False): """ Simulates trading based on signals and prints a daily ledger. """ @@ -59,7 +69,8 @@ def simulate_trading(signals, initial_cash=10000): portfolio['btc'] = 0.0 portfolio['total_value'] = float(initial_cash) - print(f"{Colors.HEADER}{Colors.BOLD}------ Daily Trading Ledger ------{Colors.ENDC}") + if not quiet: + print(f"{Colors.HEADER}{Colors.BOLD}------ Daily Trading Ledger ------{Colors.ENDC}") for i, row in signals.iterrows(): if i > 0: portfolio.loc[i, 'cash'] = portfolio.loc[i-1, 'cash'] @@ -70,24 +81,42 @@ def simulate_trading(signals, initial_cash=10000): 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.RED}Day {i}: 📉 Sell {portfolio.loc[i, 'btc']:.4f} BTC at ${row['price']:.2f}{Colors.ENDC}") + if not quiet: + print(f"{Colors.RED}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'] - print(f"Day {i}: Portfolio Value: ${portfolio.loc[i, 'total_value']:.2f}, Cash: ${portfolio.loc[i, 'cash']:.2f}, BTC: {portfolio.loc[i, 'btc']:.4f}") + if not quiet: + print(f"Day {i}: Portfolio Value: ${portfolio.loc[i, 'total_value']:.2f}, Cash: ${portfolio.loc[i, 'cash']:.2f}, BTC: {portfolio.loc[i, 'btc']:.4f}") return portfolio +def parse_arguments(): + parser = argparse.ArgumentParser(description='Bitcoin Trading Simulation') + parser.add_argument('--days', type=int, default=60, help='Number of days to simulate') + parser.add_argument('--initial-price', type=float, default=50000, help='Initial Bitcoin price') + parser.add_argument('--volatility', type=float, default=0.02, help='Volatility factor') + parser.add_argument('--initial-cash', type=float, default=10000, help='Initial cash') + parser.add_argument('--no-color', action='store_true', help='Disable colored output') + parser.add_argument('--quiet', action='store_true', help='Suppress daily ledger output') + return parser.parse_args() + if __name__ == "__main__": + args = parse_arguments() + + if args.no_color: + Colors.disable() + # Simulate prices - prices = simulate_bitcoin_prices() + prices = simulate_bitcoin_prices(days=args.days, initial_price=args.initial_price, volatility=args.volatility) # Calculate moving averages signals = calculate_moving_averages(prices) @@ -96,11 +125,11 @@ def simulate_trading(signals, initial_cash=10000): signals = generate_trading_signals(signals) # Simulate trading - portfolio = simulate_trading(signals) + portfolio = simulate_trading(signals, initial_cash=args.initial_cash, quiet=args.quiet) # Final portfolio performance final_value = portfolio['total_value'].iloc[-1] - initial_cash = 10000 + initial_cash = args.initial_cash profit = final_value - initial_cash # Compare with buy and hold strategy From 347e796c1856e1fbb86ea34b348af9cb56219097 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Sun, 1 Feb 2026 13:29:14 +0000 Subject: [PATCH 2/2] fix: resolve CI linting errors and test discovery issues - Fixed flake8 errors (E302, E305, W293, E501) in bitcoin_trading_simulation.py - Renamed test.py to test_bitcoin_trading.py for pytest discovery Co-authored-by: EiJackGH <172181576+EiJackGH@users.noreply.github.com> --- bitcoin_trading_simulation.py | 26 +++++++++++++++++--------- test.py => test_bitcoin_trading.py | 0 2 files changed, 17 insertions(+), 9 deletions(-) rename test.py => test_bitcoin_trading.py (100%) diff --git a/bitcoin_trading_simulation.py b/bitcoin_trading_simulation.py index aa8abc0..eb2af0c 100644 --- a/bitcoin_trading_simulation.py +++ b/bitcoin_trading_simulation.py @@ -2,6 +2,7 @@ import pandas as pd import argparse + class Colors: HEADER = '\033[95m' BLUE = '\033[94m' @@ -19,6 +20,7 @@ def disable(cls): cls.ENDC = '' cls.BOLD = '' + def simulate_bitcoin_prices(days=60, initial_price=50000, volatility=0.02): """ Simulates Bitcoin prices for a given number of days using Geometric Brownian Motion. @@ -33,6 +35,7 @@ def simulate_bitcoin_prices(days=60, initial_price=50000, volatility=0.02): prices.append(prices[-1] + price_change) return pd.Series(prices, name='Price') + def calculate_moving_averages(prices, short_window=7, long_window=30): """ Calculates short and long moving averages for a given price series. @@ -43,6 +46,7 @@ def calculate_moving_averages(prices, short_window=7, long_window=30): signals['long_mavg'] = prices.rolling(window=long_window, min_periods=1, center=False).mean() return signals + def generate_trading_signals(signals): """ Generates trading signals based on the Golden Cross strategy. @@ -54,11 +58,12 @@ def generate_trading_signals(signals): signals.loc[signals['short_mavg'] > signals['long_mavg'], 'signal'] = 1.0 # A Death Cross (sell signal) signals.loc[signals['short_mavg'] < signals['long_mavg'], 'signal'] = -1.0 - + # We create 'positions' to represent the trading action: 1 for buy, -1 for sell, 0 for hold signals['positions'] = signals['signal'].diff().shift(1) return signals + def simulate_trading(signals, initial_cash=10000, quiet=False): """ Simulates trading based on signals and prints a daily ledger. @@ -95,10 +100,12 @@ def simulate_trading(signals, initial_cash=10000, quiet=False): 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}, Cash: ${portfolio.loc[i, 'cash']:.2f}, BTC: {portfolio.loc[i, 'btc']:.4f}") - + 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}") + return portfolio + def parse_arguments(): parser = argparse.ArgumentParser(description='Bitcoin Trading Simulation') parser.add_argument('--days', type=int, default=60, help='Number of days to simulate') @@ -109,6 +116,7 @@ def parse_arguments(): parser.add_argument('--quiet', action='store_true', help='Suppress daily ledger output') return parser.parse_args() + if __name__ == "__main__": args = parse_arguments() @@ -117,25 +125,25 @@ def parse_arguments(): # Simulate prices prices = simulate_bitcoin_prices(days=args.days, initial_price=args.initial_price, volatility=args.volatility) - + # Calculate moving averages signals = calculate_moving_averages(prices) - + # Generate trading signals signals = generate_trading_signals(signals) - + # Simulate trading portfolio = simulate_trading(signals, initial_cash=args.initial_cash, quiet=args.quiet) - + # Final portfolio performance final_value = portfolio['total_value'].iloc[-1] initial_cash = args.initial_cash profit = final_value - initial_cash - + # Compare with buy and hold strategy buy_and_hold_btc = initial_cash / prices.iloc[0] buy_and_hold_value = buy_and_hold_btc * prices.iloc[-1] - + print(f"\n{Colors.HEADER}{Colors.BOLD}------ Final Portfolio Performance ------{Colors.ENDC}") print(f"Initial Cash: ${initial_cash:.2f}") print(f"Final Portfolio Value: ${final_value:.2f}") diff --git a/test.py b/test_bitcoin_trading.py similarity index 100% rename from test.py rename to test_bitcoin_trading.py