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())
|