From 79d88858a783af5df25c6545937811b07719884f Mon Sep 17 00:00:00 2001 From: Athon Millane Date: Sat, 17 May 2025 18:29:47 +0800 Subject: [PATCH] Remove for-loop style code from templates and currently submitted strategies --- data/leaderboard.json | 2 +- src/core/strategy.py | 13 ------------- src/strategies/athon_buy-and-hold.py | 10 ---------- src/strategies/athon_sma-v1.py | 21 --------------------- src/strategies/ben_sma-v1.py | 22 ---------------------- src/strategies/lucien_sma-v1.py | 22 ---------------------- src/strategies/template.py | 27 --------------------------- 7 files changed, 1 insertion(+), 116 deletions(-) diff --git a/data/leaderboard.json b/data/leaderboard.json index 703a4ef..68b86c6 100644 --- a/data/leaderboard.json +++ b/data/leaderboard.json @@ -18,7 +18,7 @@ "max_drawdown": 0.2941198645359705, "n_trades": 19, "win_rate": 0.21052631578947367 - }, + } }, { "author_name": "Ben", diff --git a/src/core/strategy.py b/src/core/strategy.py index 3e9022e..79a7006 100644 --- a/src/core/strategy.py +++ b/src/core/strategy.py @@ -43,19 +43,6 @@ def validate(self) -> bool: raise ValueError("Strategy must have a description") return True - def process_bar(self, bar: Dict[str, Any]): - """ - Called for each bar (dict with keys: 'time', 'close', 'volume'). - Should update internal state and decide on signal. - """ - self.current_bar = bar - - def get_signal(self) -> str: - """ - Return 'buy', 'sell', or 'hold'. - """ - return 'hold' - def get_signals(self, df: pd.DataFrame) -> pd.Series: """ Vectorized version of signal generation. diff --git a/src/strategies/athon_buy-and-hold.py b/src/strategies/athon_buy-and-hold.py index f8fdd44..56291b9 100644 --- a/src/strategies/athon_buy-and-hold.py +++ b/src/strategies/athon_buy-and-hold.py @@ -14,16 +14,6 @@ def __init__(self, initial_capital=10000): strategy_name="Buy and Hold", description="Buys Bitcoin at the first bar and holds the position for the entire backtest period." ) - self.has_bought = False - - def process_bar(self, bar): - self.current_bar = bar - - def get_signal(self): - if not self.has_bought: - self.has_bought = True - return 'buy' - return 'hold' def get_signals(self, df: pd.DataFrame) -> pd.Series: signals = pd.Series('hold', index=df.index) diff --git a/src/strategies/athon_sma-v1.py b/src/strategies/athon_sma-v1.py index d10b427..bdb7bf0 100644 --- a/src/strategies/athon_sma-v1.py +++ b/src/strategies/athon_sma-v1.py @@ -17,27 +17,6 @@ def __init__(self, initial_capital=10000, fast=20, slow=100): self.prices = [] self.fast = fast self.slow = slow - self.last_signal = 'hold' - - def process_bar(self, bar): - self.current_bar = bar - self.prices.append(bar['close']) - if len(self.prices) < self.slow: - self.last_signal = 'hold' - return - - fast_ma = pd.Series(self.prices).rolling(self.fast).mean().iloc[-1] - slow_ma = pd.Series(self.prices).rolling(self.slow).mean().iloc[-1] - - if fast_ma > slow_ma and self.position == 0: - self.last_signal = 'buy' - elif fast_ma < slow_ma and self.position == 1: - self.last_signal = 'sell' - else: - self.last_signal = 'hold' - - def get_signal(self): - return self.last_signal def get_signals(self, df: pd.DataFrame) -> pd.Series: fast_ma = df['close'].rolling(self.fast).mean() diff --git a/src/strategies/ben_sma-v1.py b/src/strategies/ben_sma-v1.py index ccfb2de..bd356d1 100644 --- a/src/strategies/ben_sma-v1.py +++ b/src/strategies/ben_sma-v1.py @@ -15,30 +15,8 @@ def __init__(self, initial_capital=10000, fast=30, slow=120): strategy_name="SMA Crossover 1 - f30s120", description="Goes long when the 30-period SMA crosses above the 120-period SMA, and exits when it crosses below." ) - self.prices = [] self.fast = fast self.slow = slow - self.last_signal = 'hold' - - def process_bar(self, bar): - self.current_bar = bar - self.prices.append(bar['close']) - if len(self.prices) < self.slow: - self.last_signal = 'hold' - return - - fast_ma = pd.Series(self.prices).rolling(self.fast).mean().iloc[-1] - slow_ma = pd.Series(self.prices).rolling(self.slow).mean().iloc[-1] - - if fast_ma > slow_ma and self.position == 0: - self.last_signal = 'buy' - elif fast_ma < slow_ma and self.position == 1: - self.last_signal = 'sell' - else: - self.last_signal = 'hold' - - def get_signal(self): - return self.last_signal def get_signals(self, df: pd.DataFrame) -> pd.Series: fast_ma = df['close'].rolling(self.fast).mean() diff --git a/src/strategies/lucien_sma-v1.py b/src/strategies/lucien_sma-v1.py index b91a4ab..342b3c6 100644 --- a/src/strategies/lucien_sma-v1.py +++ b/src/strategies/lucien_sma-v1.py @@ -14,30 +14,8 @@ def __init__(self, initial_capital=10000, fast=32, slow=140): strategy_name="SMA Crossover 1", description="Goes long when the 32-period SMA crosses above the 140-period SMA, and exits when it crosses below." ) - self.prices = [] self.fast = fast self.slow = slow - self.last_signal = 'hold' - - def process_bar(self, bar): - self.current_bar = bar - self.prices.append(bar['close']) - if len(self.prices) < self.slow: - self.last_signal = 'hold' - return - - fast_ma = pd.Series(self.prices).rolling(self.fast).mean().iloc[-1] - slow_ma = pd.Series(self.prices).rolling(self.slow).mean().iloc[-1] - - if fast_ma > slow_ma and self.position == 0: - self.last_signal = 'buy' - elif fast_ma < slow_ma and self.position == 1: - self.last_signal = 'sell' - else: - self.last_signal = 'hold' - - def get_signal(self): - return self.last_signal def get_signals(self, df: pd.DataFrame) -> pd.Series: fast_ma = df['close'].rolling(self.fast).mean() diff --git a/src/strategies/template.py b/src/strategies/template.py index c896a3d..076633c 100644 --- a/src/strategies/template.py +++ b/src/strategies/template.py @@ -19,33 +19,6 @@ def __init__(self, initial_capital=10000): # self.lookback_period = 20 # self.threshold = 0.02 - def process_bar(self, bar): - """ - Process each bar of data. - This is where you implement your strategy logic. - - Args: - bar: Dictionary containing 'time', 'close', and 'volume' data - """ - self.current_bar = bar - - # Add your strategy logic here - # For example: - # if self.current_bar['close'] > self.previous_close * (1 + self.threshold): - # self.last_signal = 'buy' - # elif self.current_bar['close'] < self.previous_close * (1 - self.threshold): - # self.last_signal = 'sell' - # else: - # self.last_signal = 'hold' - - def get_signal(self): - """ - Return the current trading signal. - Must return one of: 'buy', 'sell', 'hold' - """ - # Add your signal generation logic here - return 'hold' - def get_signals(self, df): """ Vectorized version of signal generation.