♟️Available Strategies

Our Telegram bot offers a variety of pre-defined trading strategies suitable for different trading styles and market conditions.

1. RSI (Relative Strength Index)

  • Overview: RSI is a momentum oscillator that measures the speed and change of price movements.

  • Ideal For: Identifying overbought or oversold conditions in a trading asset.

  • Usage: Typically, an RSI above 70 indicates an asset is overbought, while below 30 suggests it is oversold.

def compute_rsi(data, period=14):
    """Compute the RSI for a given data set and RSI period."""
    delta = data['close'].diff()
    gain = (delta.where(delta > 0, 0)).fillna(0)
    loss = (-delta.where(delta < 0, 0)).fillna(0)

    avg_gain = gain.rolling(window=period).mean()
    avg_loss = loss.rolling(window=period).mean()

    rs = avg_gain / avg_loss
    rsi = 100 - (100 / (1 + rs))
    return rsi

def generate_rsi_signals(data, rsi):
    """Generate buy and sell signals based on RSI."""
    data['buy_signal'] = rsi < 30   # RSI below 30 indicates oversold conditions
    data['sell_signal'] = rsi > 70  # RSI above 70 indicates overbought conditions
    return data

def get_current_rsi_trade_signal(df):
    """
    Determine the current trade signal based on the RSI strategy.

    Args:
    df (pandas.DataFrame): The DataFrame containing the price data and RSI values.

    Returns:
    str: 'BUY' if buying conditions are met, 'SELL' if selling conditions are met, 
         or None if conditions for neither are met.
    """
    if df.empty:
        return None

    current_rsi = df['rsi'].iloc[-1]
    rsi_buy_threshold = 30
    rsi_sell_threshold = 70

    if current_rsi < rsi_buy_threshold:
        return 'BUY'
    elif current_rsi > rsi_sell_threshold:
        return 'SELL'
    else:
        return None

2. MACD (Moving Average Convergence Divergence)

  • Overview: MACD is a trend-following momentum indicator that shows the relationship between two moving averages of an asset's price.

  • Ideal For: Spotting changes in the strength, direction, momentum, and duration of a trend.

  • Usage: Traders look for signal line crossovers, centerline crossovers, and divergences to identify potential trading opportunities.


def compute_macd(data, short_window=12, long_window=26, signal_window=9):
    """Compute the MACD (Moving Average Convergence Divergence)."""
    short_ema = data['close'].ewm(span=short_window, adjust=False).mean()
    long_ema = data['close'].ewm(span=long_window, adjust=False).mean()
    macd = short_ema - long_ema
    signal = macd.ewm(span=signal_window, adjust=False).mean()
    return macd, signal

def generate_macd_signals(data, macd, signal):
    """Generate buy and sell signals based on MACD."""
    data['macd'] = macd
    data['signal_line'] = signal
    data['buy_signal'] = (macd > signal) & (macd.shift(1) <= signal.shift(1))  # MACD crosses above signal line
    data['sell_signal'] = (macd < signal) & (macd.shift(1) >= signal.shift(1))  # MACD crosses below signal line
    return data

def get_current_macd_trade_signal(df):
    """
    Determine the current trade signal based on the MACD strategy.

    Args:
    df (pandas.DataFrame): The DataFrame containing the price data and MACD values.

    Returns:
    str: 'BUY' if buying conditions are met, 'SELL' if selling conditions are met, 
         or None if conditions for neither are met.
    """
    if df.empty:
        return None

    if df['buy_signal'].iloc[-1]:
        return 'BUY'
    elif df['sell_signal'].iloc[-1]:
        return 'SELL'
    else:
        return None

3. Guppy Multiple Moving Average (GMMA)

  • Overview: Guppy is an indicator used to identify trends, changes in trends, and the strength of these trends.

  • Ideal For: Understanding both short-term and long-term trends and their convergence.

  • Usage: The GMMA consists of two sets of moving averages – a short-term set and a long-term set. The interaction between the two sets is used for trading signals.

def compute_gmma(data):
    # Short-term EMAs
    short_term_periods = [3, 5, 8, 10, 12, 15]
    for period in short_term_periods:
        data[f'Ema_{period}'] = data['close'].ewm(span=period, adjust=False).mean()

    # Long-term EMAs
    long_term_periods = [30, 35, 40, 45, 50, 60]
    for period in long_term_periods:
        data[f'Ema_{period}'] = data['close'].ewm(span=period, adjust=False).mean()

    return data

def generate_gmma_signals(data):
    short_term = data[['Ema_3', 'Ema_5', 'Ema_8', 'Ema_10', 'Ema_12', 'Ema_15']].mean(axis=1)
    long_term = data[['Ema_30', 'Ema_35', 'Ema_40', 'Ema_45', 'Ema_50', 'Ema_60']].mean(axis=1)

    # Generate signals
    data['buy_signal'] = short_term > long_term
    data['sell_signal'] = short_term < long_term

    return data

def get_current_gmma_trade_signal(df):
    if df.empty:
        return None

    if df['buy_signal'].iloc[-1] and not df['buy_signal'].iloc[-2]:
        return 'BUY'
    elif df['sell_signal'].iloc[-1] and not df['sell_signal'].iloc[-2]:
        return 'SELL'
    else:
        return None

4. Bollinger Bands

Bollinger Bands are a type of price envelope developed by John Bollinger. They consist of two volatility bands placed above and below a moving average. Volatility is based on the standard deviation, which changes as volatility increases or decreases.

Ideal For: Bollinger Bands are particularly effective in trending markets where they can provide insights into potential highs and lows of an asset's price. They are used to identify overbought and oversold conditions, market volatility, and potential price breakouts.

Usage:

  • Overbought Condition: When the price moves above the upper band, the asset may be considered overbought, suggesting a possible selling opportunity or a potential pullback in the price.

  • Oversold Condition: Conversely, if the price drops below the lower band, the asset might be considered oversold, indicating a potential buying opportunity or a price increase.

  • Volatility Analysis: The width of the bands is also used to gauge volatility. A narrow "squeeze" of the bands can indicate a period of low volatility and hint at a potential future increase in volatility and the likelihood of a significant price movement.

  • Trend Identification: In a strong uptrend, prices might consistently ride the upper band, and during a downtrend, they could cling to the lower band.

def compute_bollinger(data, window=14, num_std_dev=2.5):
    """Compute Bollinger Bands for a given DataFrame."""
    rolling_mean = data['close'].rolling(window=window).mean()
    rolling_std = data['close'].rolling(window=window).std()
    upper_band = rolling_mean + (rolling_std * num_std_dev)
    lower_band = rolling_mean - (rolling_std * num_std_dev)
    return upper_band, lower_band

def generate_bollinger_signals(data, upper_band, lower_band):
    """Generate buy and sell signals based on Bollinger Bands."""
    data['upper_band'] = upper_band
    data['lower_band'] = lower_band
    data['buy_signal'] = data['close'] < data['lower_band']  # Close price crosses below lower band
    data['sell_signal'] = data['close'] > data['upper_band']  # Close price crosses above upper band
    return data

def get_current_bollinger_trade_signal(df):
    """
    Determine the current trade signal based on the Bollinger Bands strategy.

    Args:
    df (pandas.DataFrame): The DataFrame containing the price data and Bollinger Band values.

    Returns:
    str: 'BUY' if buying conditions are met, 'SELL' if selling conditions are met,
         or None if conditions for neither are met.
    """
    if df.empty:
        return None

    if df['buy_signal'].iloc[-1]:
        return 'BUY'
    elif df['sell_signal'].iloc[-1]:
        return 'SELL'
    else:
        return None

5. VWAP

```python
import pandas as pd

def compute_vwap(data, short_window=13, long_window=26, signal_window=9):
    """Compute the MACD (Moving Average Convergence Divergence)."""
    short_ema = data['close'].ewm(span=short_window, adjust=False).mean()
    long_ema = data['close'].ewm(span=long_window, adjust=False).mean()
    macd = short_ema - long_ema
    signal = macd.ewm(span=signal_window, adjust=False).mean()
    return macd, signal

def generate_vwap_signals(data, macd, signal):
    """Generate buy and sell signals based on MACD."""
    data['macd'] = macd
    data['signal_line'] = signal
    data['buy_signal'] = (macd > signal) & (macd.shift(1) <= signal.shift(1))  # MACD crosses above signal line
    data['sell_signal'] = (macd < signal) & (macd.shift(1) >= signal.shift(1))  # MACD crosses below signal line
    return data

def get_current_vwap_trade_signal(df):
    """
    Determine the current trade signal based on the MACD strategy.

    Args:
    df (pandas.DataFrame): The DataFrame containing the price data and MACD values.

    Returns:
    str: 'BUY' if buying conditions are met, 'SELL' if selling conditions are met, 
         or None if conditions for neither are met.
    """
    if df.empty:
        return None

    if df['buy_signal'].iloc[-1]:
        return 'BUY'
    elif df['sell_signal'].iloc[-1]:
        return 'SELL'
    else:
        return None

def execute_vwap(df, user_strategy_data):
    # Compute MACD and signal line
    macd, signal = compute_vwap(df)
    signals = generate_vwap_signals(df, macd, signal)

    #print(signals)
    current_trade_signal = get_current_vwap_trade_signal(df)
    #print(current_trade_signal)

    # Return both the signals and the current trade signal
    return signals, current_trade_signal
```+

6. MA Crossover

````python
import pandas as pd

def compute_ma_crossover(data):
    # Moving Averages
    data['Short_MA'] = data['close'].rolling(window=5).mean()
    data['Long_MA'] = data['close'].rolling(window=20).mean()
    return data

def generate_ma_crossover_signals(data):
    data['buy_signal'] = False
    data['sell_signal'] = False

    for i in range(1, len(data)):
        if data['Short_MA'].iloc[i] > data['Long_MA'].iloc[i] and data['Short_MA'].iloc[i-1] <= data['Long_MA'].iloc[i-1]:
            data.at[i, 'buy_signal'] = True
        elif data['Short_MA'].iloc[i] < data['Long_MA'].iloc[i] and data['Short_MA'].iloc[i-1] >= data['Long_MA'].iloc[i-1]:
            data.at[i, 'sell_signal'] = True

    return data

def get_current_ma_crossover_signal(df):
    if df.empty:
        return None

    last_buy_index = df[df['buy_signal']].index.max()
    last_sell_index = df[df['sell_signal']].index.max()

    if pd.isna(last_buy_index) and pd.isna(last_sell_index):
        return None
    elif pd.isna(last_sell_index) or (last_buy_index > last_sell_index):
        return 'BUY'
    elif pd.isna(last_buy_index) or (last_sell_index > last_buy_index):
        return 'SELL'
    else:
        return None

def execute_ma_crossover(df):
    df = compute_ma_crossover(df)
    signals = generate_ma_crossover_signals(df)

    current_trade_signal = get_current_ma_crossover_signal(df)
    return signals, current_trade_signal
```

7. Ichimoku Cloud

```python
import pandas as pd

def compute_ichimoku_cloud(data):
    """
    Calculate the Ichimoku Cloud
    :param data: DataFrame with 'high', 'low', and 'close' columns
    :return: DataFrame with Ichimoku Cloud components
    """
    high_prices = data['high']
    low_prices = data['low']
    close_prices = data['close']

    # Tenkan-sen (Conversion Line)
    data['tenkan_sen'] = (high_prices.rolling(window=9).max() + low_prices.rolling(window=9).min()) / 2

    # Kijun-sen (Base Line)
    data['kijun_sen'] = (high_prices.rolling(window=26).max() + low_prices.rolling(window=26).min()) / 2

    # Senkou Span A (Leading Span A)
    data['senkou_span_a'] = ((data['tenkan_sen'] + data['kijun_sen']) / 2).shift(26)

    # Senkou Span B (Leading Span B)
    data['senkou_span_b'] = ((high_prices.rolling(window=52).max() + low_prices.rolling(window=52).min()) / 2).shift(26)

    # Chikou Span (Lagging Span)
    data['chikou_span'] = close_prices.shift(-26)

    return data

def generate_ichimoku_signals(data):
    """
    Generate buy and sell signals based on Ichimoku Cloud
    :param data: DataFrame with Ichimoku Cloud components
    :return: DataFrame with 'buy_signal' and 'sell_signal'
    """
    data['buy_signal'] = False
    data['sell_signal'] = False
    
    last_signal = ''  # This variable will track the last signal

    for i in range(26, len(data)):
        # Buy condition
        if data['close'].iloc[i] > max(data['senkou_span_a'].iloc[i], data['senkou_span_b'].iloc[i]) and last_signal != 'buy':
            data.at[i, 'buy_signal'] = True
            data.at[i, 'sell_signal'] = False
            last_signal = 'buy'
        # Sell condition
        elif data['close'].iloc[i] < min(data['senkou_span_a'].iloc[i], data['senkou_span_b'].iloc[i]) and last_signal != 'sell':
            data.at[i, 'sell_signal'] = True
            data.at[i, 'buy_signal'] = False
            last_signal = 'sell'

    return data

def get_current_ichimoku_trade_signal(data):
    """
    Get the current trade signal based on the Ichimoku Cloud
    :param data: DataFrame with Ichimoku Cloud components and signals
    :return: The current trade signal ('buy', 'sell', or 'hold')
    """
    # Ensure there is data to analyze
    if data.empty:
        return 'hold'

    # Access the most recent row in the DataFrame
    latest_data = data.iloc[-1]

    # Determine the trade signal
    if latest_data['buy_signal']:
        return 'buy'
    elif latest_data['sell_signal']:
        return 'sell'
    else:
        return 'hold'

def execute_ichimoku_strategy(df):
    df = compute_ichimoku_cloud(df)
    signals = generate_ichimoku_signals(df)
    return signals

```
  1. ATR

```python
import pandas as pd

def compute_atr(data, atr_period=14):
    """
    Calculate the Average True Range (ATR)
    :param data: DataFrame with 'high', 'low', and 'close' columns
    :param atr_period: The period over which to calculate ATR
    :return: DataFrame with 'ATR' column
    """
    data['high-low'] = data['high'] - data['low']
    data['high-close'] = abs(data['high'] - data['close'].shift())
    data['low-close'] = abs(data['low'] - data['close'].shift())
    tr = data[['high-low', 'high-close', 'low-close']].max(axis=1)
    atr = tr.rolling(window=atr_period).mean()

    data['ATR'] = atr
    return data.drop(['high-low', 'high-close', 'low-close'], axis=1)

def generate_atr_breakout_signals(data, atr_multiplier=2):
    """
    Generate buy and sell signals based on ATR Breakout
    :param data: DataFrame with 'close' and 'ATR' columns
    :param atr_multiplier: Multiplier for ATR to define breakout range
    :return: DataFrame with 'buy_signal' and 'sell_signal'
    """
    data['buy_signal'] = False
    data['sell_signal'] = False

    # Define breakout range
    data['upper_band'] = data['close'].rolling(window=20).mean() + atr_multiplier * data['ATR']
    data['lower_band'] = data['close'].rolling(window=20).mean() - atr_multiplier * data['ATR']

    for i in range(1, len(data)):
        # Buy signal: price breaks above upper band
        if data['close'].iloc[i] > data['upper_band'].iloc[i] and data['close'].iloc[i-1] <= data['upper_band'].iloc[i-1]:
            data.at[i, 'buy_signal'] = True
        # Sell signal: price breaks below lower band
        elif data['close'].iloc[i] < data['lower_band'].iloc[i] and data['close'].iloc[i-1] >= data['lower_band'].iloc[i-1]:
            data.at[i, 'sell_signal'] = True

    return data.drop(['upper_band', 'lower_band'], axis=1)

def get_current_atr_breakout_signal(data):
    """
    Get the current trade signal based on the latest ATR Breakout values
    :param data: DataFrame with 'buy_signal' and 'sell_signal'
    :return: Current trade signal ('BUY', 'SELL', or None)
    """
    if data.empty:
        return None

    last_buy_index = data[data['buy_signal']].index.max()
    last_sell_index = data[data['sell_signal']].index.max()

    if pd.isna(last_buy_index) and pd.isna(last_sell_index):
        return None
    elif pd.isna(last_sell_index) or (last_buy_index > last_sell_index):
        return 'BUY'
    elif pd.isna(last_buy_index) or (last_sell_index > last_buy_index):
        return 'SELL'
    else:
        return None

def execute_atr_breakout(df):
    df = compute_atr(df)
    signals = generate_atr_breakout_signals(df)

    current_trade_signal = get_current_atr_breakout_signal(df)
    return signals, current_trade_signal

```

We are continuously working to expand our range of strategies to cater to a broader range of trading preferences and market conditions.

Last updated