Пример #1
0
def generate_bear_bull_signal(position: pd.DataFrame, **kwargs) -> dict:
    """Generate Bear Bull Signal

    Arguments:
        position {pd.DataFrame} -- dataset

    Optional Args:
        interval {int} -- size of exponential moving average window (default: {13})
        plot_output {bool} -- (default: {True})
        name {str} -- (default: {''})
        p_bar {ProgressBar} -- (default: {None})

    Returns:
        dict -- [description]
    """
    interval = kwargs.get('interval', 13)
    plot_output = kwargs.get('plot_output', True)
    name = kwargs.get('name', '')
    p_bar = kwargs.get('p_bar')

    bb_signal = {'bulls': [], 'bears': []}
    ema = exponential_moving_avg(position, interval)

    for i, high in enumerate(position['High']):
        bb_signal['bulls'].append(high - ema[i])

    if p_bar is not None:
        p_bar.uptick(increment=0.1)

    for i, low in enumerate(position['Low']):
        bb_signal['bears'].append(low - ema[i])

    if p_bar is not None:
        p_bar.uptick(increment=0.1)

    x = dates_extractor_list(position)
    if plot_output:
        name3 = INDEXES.get(name, name)
        name2 = name3 + ' - Bull Power'
        bar_chart(bb_signal['bulls'], position=position, title=name2, x=x)
        name2 = name3 + ' - Bear Power'
        bar_chart(bb_signal['bears'], position=position, title=name2, x=x)

    return bb_signal
Пример #2
0
def bear_bull_feature_detection(bear_bull: dict, position: pd.DataFrame, **kwargs) -> dict:
    """Bear Bull Feature Detection

    Arguments:
        bear_bull {dict} -- bull bear data object
        position {pd.DataFrame} -- dataset

    Optional Args:
        interval {int} -- size of exponential moving average window (default: {13})
        bb_interval {list} -- list of sizes of bear and bull windows (default: {[4, 5, 6, 7, 8]})
        plot_output {bool} -- (default: {True})
        name {str} -- (default: {''})
        p_bar {ProgressBar} -- (default {None})
        view {str} -- (default: {''})

    Returns:
        dict -- [description]
    """
    interval = kwargs.get('interval', 13)
    bb_interval = kwargs.get('bb_interval', [4, 5, 6, 7, 8])
    plot_output = kwargs.get('plot_output', True)
    name = kwargs.get('name', '')
    p_bar = kwargs.get('p_bar')
    view = kwargs.get('view')

    # Determine the slope of the ema at given points
    ema = exponential_moving_avg(position, interval)

    ema_slopes = [0.0] * (interval-1)
    for i in range(interval-1, len(ema)):
        x = list(range(i-(interval-1), i))
        y = ema[i-(interval-1): i]
        reg = linregress(x, y=y)
        ema_slopes.append(reg[0])

    if p_bar is not None:
        p_bar.uptick(increment=0.1)

    incr = 0.6 / float(len(bb_interval))

    state = [0.0] * len(ema)
    features = []

    for bb in bb_interval:
        # Determine the slope of the bear power signal at given points
        bear_slopes = [0.0] * (bb-1)
        for i in range(bb-1, len(ema)):
            x = list(range(i-(bb-1), i))
            y = bear_bull['tabular']['bears'][i-(bb-1): i]
            reg = linregress(x, y=y)
            bear_slopes.append(reg[0])

        # Determine the slope of the bull power signal at given points
        bull_slopes = [0.0] * (bb-1)
        for i in range(bb-1, len(ema)):
            x = list(range(i-(bb-1), i))
            y = bear_bull['tabular']['bulls'][i-(bb-1): i]
            reg = linregress(x, y=y)
            bull_slopes.append(reg[0])

        for i in range(1, len(ema)):
            data = None
            date = position.index[i].strftime("%Y-%m-%d")

            if ema_slopes[i] > 0.0:
                if bear_bull['tabular']['bears'][i] < 0.0:
                    if bear_slopes[i] > 0.0:
                        # Determine the basic (first 2 conditions) bullish state (+1)
                        state[i] += 1.0
                        if bear_bull['tabular']['bulls'][i] > bear_bull['tabular']['bulls'][i-1]:
                            state[i] += 0.5
                            if position['Close'][i] < position['Close'][i-1]:
                                # Need to find bullish divergence!
                                state[i] += 1.0
                                data = {
                                    "type": 'bullish',
                                    "value": f'bullish divergence: {bb}d interval',
                                    "index": i,
                                    "date": date
                                }

            if ema_slopes[i] < 0.0:
                if bear_bull['tabular']['bulls'][i] > 0.0:
                    if bull_slopes[i] < 0.0:
                        # Determine the basic (first 2 conditions) bearish state (+1)
                        state[i] += -1.0
                        if bear_bull['tabular']['bears'][i] < bear_bull['tabular']['bears'][i-1]:
                            state[i] += -0.5
                            if position['Close'][i] > position['Close'][i-1]:
                                # Need to find bearish divergence!
                                state[i] += -1.0
                                data = {
                                    "type": 'bearish',
                                    "value": f'bearish divergence: {bb}d interval',
                                    "index": i,
                                    "date": date
                                }

            if data is not None:
                features.append(data)

        if p_bar is not None:
            p_bar.uptick(increment=incr)

    bear_bull['signals'] = filter_features(features, plot_output=plot_output)
    bear_bull['length_of_data'] = len(bear_bull['tabular']['bears'])

    weights = [1.0, 0.75, 0.45, 0.1]

    state2 = [0.0] * len(state)
    for ind, s in enumerate(state):
        if s != 0.0:
            state2[ind] += s

            # Smooth the curves
            if ind - 1 >= 0:
                state2[ind-1] += s * weights[1]
            if ind + 1 < len(state):
                state2[ind+1] += s * weights[1]
            if ind - 2 >= 0:
                state2[ind-2] += s * weights[2]
            if ind + 2 < len(state):
                state2[ind+2] += s * weights[2]
            if ind - 3 >= 0:
                state2[ind-3] += s * weights[3]
            if ind + 3 < len(state):
                state2[ind+3] += s * weights[3]

    state3 = exponential_moving_avg(state2, 7, data_type='list')
    norm = normalize_signals([state3])
    state4 = norm[0]

    title = 'Bear Bull Power Metrics'
    if plot_output:
        dual_plotting(position['Close'], state4, 'Price',
                      'Bear Bull Power', title=title)
    else:
        filename = os.path.join(name, view, f"bear_bull_power_{name}.png")
        dual_plotting(position['Close'], state4, 'Price', 'Metrics', title=title,
                      saveFig=True, filename=filename)

    bear_bull['metrics'] = state4

    if p_bar is not None:
        p_bar.uptick(increment=0.1)

    return bear_bull
def generate_total_power_signal(position: pd.DataFrame, **kwargs) -> dict:
    """Generate Total Power Signal

    Arguments:
        position {pd.DataFrame} -- fund dataset

    Optional Args:
        lookback {int} -- period for total power signal (default: {45})
        powerback {int} -- period for ema (default: {10})
        plot_output {bool} -- (default: {True})
        name {str} -- (default: {''})
        p_bar {ProgressBar} -- (default: {None})
        view {str} -- (default: {''})

    Returns:
        dict -- cumulative signals bear, bull, total
    """
    lookback = kwargs.get('lookback', 45)
    powerback = kwargs.get('powerback', 10)
    plot_output = kwargs.get('plot_output', True)
    name = kwargs.get('name', '')
    p_bar = kwargs.get('p_bar')
    view = kwargs.get('view')

    signals = {
        "bears_raw": [],
        "bulls_raw": [],
        "total": [],
        "bears": [],
        "bulls": []
    }

    ema = exponential_moving_avg(position, powerback)

    if p_bar is not None:
        p_bar.uptick(increment=0.1)

    for i, high in enumerate(position['High']):
        if high - ema[i] > 0.0:
            signals['bulls_raw'].append(1.0)
        else:
            signals['bulls_raw'].append(0.0)
    for i, low in enumerate(position['Low']):
        if low - ema[i] < 0.0:
            signals['bears_raw'].append(1.0)
        else:
            signals['bears_raw'].append(0.0)

    if p_bar is not None:
        p_bar.uptick(increment=0.1)

    # Create look back period signals
    for i in range(lookback-1):
        signals['bulls'].append(sum(signals['bulls_raw'][0:i+1]))
        signals['bears'].append(sum(signals['bears_raw'][0:i+1]))

    if p_bar is not None:
        p_bar.uptick(increment=0.1)

    for i in range(lookback-1, len(ema)):
        summer = sum(signals['bulls_raw'][i-(lookback-1): i])
        signals['bulls'].append(summer)
        summer = sum(signals['bears_raw'][i-(lookback-1): i])
        signals['bears'].append(summer)

    if p_bar is not None:
        p_bar.uptick(increment=0.1)

    # Compute the total power signal
    for i, bull in enumerate(signals['bulls']):
        total = np.abs(bull - signals['bears'][i])
        signals['total'].append(total)

    if p_bar is not None:
        p_bar.uptick(increment=0.1)

    # Adjust the signals, pop the 'raw' lists
    signals.pop('bulls_raw')
    signals.pop('bears_raw')

    for i, tot in enumerate(signals['total']):
        signals['total'][i] = 100.0 * tot / float(lookback)

    if p_bar is not None:
        p_bar.uptick(increment=0.1)

    for i, bull in enumerate(signals['bulls']):
        signals['bulls'][i] = 100.0 * bull / float(lookback)
    for i, bear in enumerate(signals['bears']):
        signals['bears'][i] = 100.0 * bear / float(lookback)

    if p_bar is not None:
        p_bar.uptick(increment=0.1)

    name2 = INDEXES.get(name, name)
    title = name2 + ' - Total Power'
    if plot_output:
        dual_plotting(position['Close'],
                      [signals['bears'], signals['bulls'], signals['total']],
                      'Price',
                      ['Bear', 'Bull', 'Total'],
                      title=title)

    else:
        filename = os.path.join(name, view, f"total_power_{name}.png")
        dual_plotting(position['Close'],
                      [signals['bears'], signals['bulls'], signals['total']],
                      'Price',
                      ['Bear', 'Bull', 'Total'],
                      title=title,
                      saveFig=True,
                      filename=filename)

    if p_bar is not None:
        p_bar.uptick(increment=0.1)

    return signals
def total_power_feature_detection(tp: dict, position: pd.DataFrame, **kwargs) -> dict:
    """Total Power Feature Detection / Metrics

    Arguments:
        tp {dict} -- total power data object
        position {pd.DataFrame} -- dataset

    Optional Args:
        adj_level {float} -- threshold level of indicators (default: {72.0})
        plot_output {bool} -- (default: {True})
        name {str} -- (default: {''})
        p_bar {ProgressBar} -- (default: {None})
        view {str} -- (default: {''})

    Returns:
        dict -- tp
    """
    adj_level = kwargs.get('adj_level', 72.0)
    plot_output = kwargs.get('plot_output', True)
    name = kwargs.get('name', '')
    p_bar = kwargs.get('p_bar')
    view = kwargs.get('view')

    tab = tp['tabular']
    metrics = [0.0] * len(tab['total'])
    features = []

    if tab['bulls'][0] > tab['bears'][0]:
        on_top = 'bull'
    else:
        on_top = 'bear'

    tot_above = ''
    for i, tot in enumerate(tab['total']):
        date = position.index[i].strftime("%Y-%m-%d")

        if (tot >= 99.0) and (tab['bulls'][i] >= 99.0):
            metrics[i] += 3.0
            data = {
                "type": 'bullish',
                "value": 'full bullish signal: 100%',
                "index": i,
                "date": date
            }
            features.append(data)

        if (tot >= 99.0) and (tab['bears'][i] >= 99.0):
            metrics[i] += -3.0
            data = {
                "type": 'bearish',
                "value": 'full bearish signal: 100%',
                "index": i,
                "date": date
            }
            features.append(data)

        if (on_top == 'bull') and (tab['bears'][i] > tab['bulls'][i]):
            metrics[i] += -1.0
            on_top = 'bear'
            data = {
                "type": 'bearish',
                "value": 'bear-bull crossover',
                "index": i,
                "date": date
            }
            features.append(data)

        if (on_top == 'bear') and (tab['bulls'][i] > tab['bears'][i]):
            metrics[i] += -1.0
            on_top = 'bull'
            data = {
                "type": 'bullish',
                "value": 'bear-bull crossover',
                "index": i,
                "date": date
            }
            features.append(data)

        if tot > tab['bulls'][i]:
            tot_above = 'bull'

        if tot > tab['bears'][i]:
            tot_above = 'bear'

        if (tot_above == 'bull') and (tab['bulls'][i] > tot):
            tot_above = ''
            metrics[i] += 1.0
            data = {
                "type": 'bullish',
                "value": 'bull-total crossover',
                "index": i,
                "date": date
            }
            features.append(data)

        if (tot_above == 'bear') and (tab['bears'][i] > tot):
            tot_above = ''
            metrics[i] += -1.0
            data = {
                "type": 'bearish',
                "value": 'bear-total crossover',
                "index": i,
                "date": date
            }
            features.append(data)

        if i > 0:
            if (tab['bulls'][i-1] < adj_level) and (tab['bulls'][i] > adj_level):
                metrics[i] += 1.0
                data = {
                    "type": 'bullish',
                    "value": 'bull-adjustment level crossover',
                    "index": i,
                    "date": date
                }
                features.append(data)

            if (tab['bears'][i-1] < adj_level) and (tab['bears'][i] > adj_level):
                metrics[i] += -1.0
                data = {
                    "type": 'bearish',
                    "value": 'bear-adjustment level crossover',
                    "index": i,
                    "date": date
                }
                features.append(data)

    if p_bar is not None:
        p_bar.uptick(increment=0.1)

    weights = [1.0, 0.85, 0.6, 0.25]

    state2 = [0.0] * len(metrics)
    for ind, s in enumerate(metrics):
        if s != 0.0:
            state2[ind] += s

            # Smooth the curves
            if ind - 1 >= 0:
                state2[ind-1] += s * weights[1]
            if ind + 1 < len(metrics):
                state2[ind+1] += s * weights[1]
            if ind - 2 >= 0:
                state2[ind-2] += s * weights[2]
            if ind + 2 < len(metrics):
                state2[ind+2] += s * weights[2]
            if ind - 3 >= 0:
                state2[ind-3] += s * weights[3]
            if ind + 3 < len(metrics):
                state2[ind+3] += s * weights[3]

    metrics = exponential_moving_avg(state2, 7, data_type='list')
    norm = normalize_signals([metrics])
    metrics = norm[0]

    name2 = INDEXES.get(name, name)
    title = name2 + ' - Total Power Metrics'
    if plot_output:
        dual_plotting(position['Close'], metrics, 'Price', 'Metrics')
        for feat in features:
            print(f"Total Power: {feat}")

    else:
        filename = os.path.join(name, view, f"total_pwr_metrics_{name}.png")
        dual_plotting(position['Close'], metrics, 'Price',
                      'Metrics', title=title, saveFig=True, filename=filename)

    tp['metrics'] = metrics
    tp['signals'] = features
    tp['length_of_data'] = len(tp['tabular']['bears'])

    if p_bar is not None:
        p_bar.uptick(increment=0.1)

    return tp