File size: 2,128 Bytes
5a8fb12
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
import pandas as pd
from indicators.sma import calculate_sma
from indicators.bollinger_bands import calculate_bollinger_bands

def generate_signals(data):
    """
    Analyzes technical indicators to generate buy and sell signals.

    Args:
        data (pd.DataFrame): DataFrame containing the historical price data and indicators.

    Returns:
        pd.DataFrame: The input DataFrame augmented with buy and sell signals.
    """
    # Ensure the necessary indicators are calculated and present in the DataFrame
    if 'SMA_21' not in data.columns or 'SMA_50' not in data.columns:
        data['SMA_21'] = calculate_sma(data, period=21)
        data['SMA_50'] = calculate_sma(data, period=50)
    
    if 'BB_Upper' not in data.columns:
        data = calculate_bollinger_bands(data)

    # Initialize columns for signals
    data['Buy_Signal'] = False
    data['Sell_Signal'] = False

    # Loop through the DataFrame to find buy and sell conditions
    for i in range(2, len(data)):
        # Buy condition: SMA_21 crosses above SMA_50, and has been below SMA_50 for at least 10 periods
        if data['SMA_21'].iloc[i] > data['SMA_50'].iloc[i] and data['SMA_21'].iloc[i-1] <= data['SMA_50'].iloc[i-1]:
            if data['SMA_50'].iloc[i-10:i-1].isnull().sum() < 1: # Ensure there's enough data
                if (data['SMA_21'].iloc[i-10:i-1] < data['SMA_50'].iloc[i-10:i-1]).all():
                    data.at[data.index[i], 'Buy_Signal'] = True

        # Sell condition: Price reaches or exceeds the upper Bollinger band for at least 3 periods after being below it for 5 or more periods
        if data['close'].iloc[i] >= data['BB_Upper'].iloc[i] and data['close'].iloc[i-1] < data['BB_Upper'].iloc[i-1] and data['close'].iloc[i-2] < data['BB_Upper'].iloc[i-2]:
            if (data['close'].iloc[i-5:i-1] < data['BB_Upper'].iloc[i-5:i-1]).all():
                data.at[data.index[i], 'Sell_Signal'] = True

    return data

# Example usage:
# Assuming `price_data` is a pandas DataFrame with columns including 'date', 'open', 'high', 'low', 'close', and 'volume':
# signals_data = generate_signals(price_data)