Spaces:
Runtime error
Runtime error
Create strategy.py
Browse files- signals/strategy.py +86 -0
signals/strategy.py
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import pandas as pd
|
| 2 |
+
from indicators.sma import calculate_21_50_sma
|
| 3 |
+
from indicators.bollinger_bands import calculate_bollinger_bands
|
| 4 |
+
|
| 5 |
+
def calculate_standard_deviation(data):
|
| 6 |
+
"""
|
| 7 |
+
Calculate the standard deviation of the closing prices over a 21-period window.
|
| 8 |
+
|
| 9 |
+
Parameters:
|
| 10 |
+
- data (pd.DataFrame): The stock data with 'Close' column.
|
| 11 |
+
|
| 12 |
+
Returns:
|
| 13 |
+
- pd.DataFrame: The stock data with an added 'SD_21' column for the standard deviation.
|
| 14 |
+
"""
|
| 15 |
+
data['SD_21'] = data['Close'].rolling(window=21).std()
|
| 16 |
+
return data
|
| 17 |
+
|
| 18 |
+
def check_buy_signal(data):
|
| 19 |
+
"""
|
| 20 |
+
Analyzes stock data to identify buy signals based on enhanced criteria:
|
| 21 |
+
- On the 1 day time frame, the 21-period SMA is above the 50-period SMA.
|
| 22 |
+
- The 21-period SMA has been above the 50-period SMA for more than 1 day.
|
| 23 |
+
- On the 1-hour time frame, the 21-period SMA has just crossed above the 50-period SMA from below.
|
| 24 |
+
- On the 1-day time frame, the price is either below the 21-period SMA or less than 0.25 SD above the 21-period SMA.
|
| 25 |
+
|
| 26 |
+
Parameters:
|
| 27 |
+
- data (pd.DataFrame): The stock data with 'Close', 'SMA_21', 'SMA_50', 'SD_21' columns.
|
| 28 |
+
|
| 29 |
+
Returns:
|
| 30 |
+
- pd.Series: A boolean series indicating buy signals.
|
| 31 |
+
"""
|
| 32 |
+
price_position = data['Close'] - data['SMA_21']
|
| 33 |
+
within_sd_limit = (price_position > 0) & (price_position <= 0.25 * data['SD_21'])
|
| 34 |
+
buy_signal = ((data['SMA_21'] > data['SMA_50']) &
|
| 35 |
+
(data['SMA_21'].shift(1) > data['SMA_50'].shift(1)) &
|
| 36 |
+
((data['Close'] < data['SMA_21']) | within_sd_limit))
|
| 37 |
+
return buy_signal
|
| 38 |
+
|
| 39 |
+
def check_sell_signal(data):
|
| 40 |
+
"""
|
| 41 |
+
Analyzes stock data to identify sell signals based on the criteria:
|
| 42 |
+
- The price has crossed above the upper band of the 1.7SD Bollinger Band on the 21-period SMA.
|
| 43 |
+
|
| 44 |
+
Parameters:
|
| 45 |
+
- data (pd.DataFrame): The stock data with 'Close', 'BB_Upper' columns.
|
| 46 |
+
|
| 47 |
+
Returns:
|
| 48 |
+
- pd.Series: A boolean series indicating sell signals.
|
| 49 |
+
"""
|
| 50 |
+
sell_signal = data['Close'] > data['BB_Upper']
|
| 51 |
+
return sell_signal
|
| 52 |
+
|
| 53 |
+
def generate_signals(stock_data):
|
| 54 |
+
"""
|
| 55 |
+
Main function to generate buy and sell signals for a given stock.
|
| 56 |
+
|
| 57 |
+
Parameters:
|
| 58 |
+
- stock_data (pd.DataFrame): The stock data.
|
| 59 |
+
|
| 60 |
+
Returns:
|
| 61 |
+
- pd.DataFrame: The stock data with additional columns 'Buy_Signal' and 'Sell_Signal'.
|
| 62 |
+
"""
|
| 63 |
+
# Ensure the necessary SMA, Bollinger Bands, and standard deviation calculations are performed
|
| 64 |
+
stock_data = calculate_21_50_sma(stock_data)
|
| 65 |
+
stock_data = calculate_bollinger_bands(stock_data)
|
| 66 |
+
stock_data = calculate_standard_deviation(stock_data)
|
| 67 |
+
|
| 68 |
+
# Generate buy and sell signals
|
| 69 |
+
stock_data['Buy_Signal'] = check_buy_signal(stock_data)
|
| 70 |
+
stock_data['Sell_Signal'] = check_sell_signal(stock_data)
|
| 71 |
+
|
| 72 |
+
return stock_data
|
| 73 |
+
|
| 74 |
+
if __name__ == "__main__":
|
| 75 |
+
# Example usage
|
| 76 |
+
dates = pd.date_range(start='2023-01-01', periods=100, freq='D')
|
| 77 |
+
close_prices = pd.Series((100 + pd.np.random.randn(100).cumsum()), index=dates)
|
| 78 |
+
sample_data = pd.DataFrame({'Close': close_prices})
|
| 79 |
+
|
| 80 |
+
# Simulating the adding of SMA and SD columns for the example
|
| 81 |
+
sample_data = calculate_21_50_sma(sample_data)
|
| 82 |
+
sample_data = calculate_bollinger_bands(sample_data)
|
| 83 |
+
sample_data = calculate_standard_deviation(sample_data)
|
| 84 |
+
|
| 85 |
+
signals_data = generate_signals(sample_data)
|
| 86 |
+
print(signals_data[['Buy_Signal', 'Sell_Signal']].tail())
|