def weighted_avg_forecast(source: list, window_size: int, num: int, weight: float=1.0):
    """
    Forecast new values from a list of existing values using a weighted average delta formula.

    Noticeably faster than linear regression while producing similar results.

    Arguments:
        source:       List of data to forecast from (integer or floating point).
        window_size:  The number of elements to use from the end of 'source' for prediction.
        num:          The number of elements to forecast.
        weight:       Amount of weight to give to the elements closest to the predicted data. Values less than 1.0 will
                      give the most weight to the farthest elements. Values exceeding 2.0 or -2.0 will increasingly
                      give no weight to the farthest and nearest elements, respectively.

    Returns:
        list(float):  A list of the additional predicted data.
    """

    assert num <= window_size, "Cannot forecast more elements than window size."
    assert len(source) >= window_size, ("Source data length {} is less than window size {}."
                                        .format(len(source), window_size))

    result = []
    weight_step = (weight - (1.0 + (1.0 - weight))) / window_size

    for index in range(num):
        delta_avg = 0.0

        # Include any previously forecasted data.
        for window_index in range(index):
            if window_index == 0:
                sample_2 = source[-1]
                sample_1 = result[0]
            else:
                sample_2 = result[-(window_index + 1)]
                sample_1 = result[-(window_index)]

            sample_delta = sample_1 - sample_2
            weight_amount = (weight - (weight_step * window_index))
            if (weight_amount) < 0: weight_amount = 0
            delta_avg += sample_delta * weight_amount

        # Include remaining source data.
        for window_index in range(window_size - index):
            sample_delta = (source[-(window_index + 1)] - source[-(window_index + 2)])
            weight_amount = (weight - (weight_step * (window_index + index)))
            if (weight_amount) < 0: weight_amount = 0
            delta_avg += sample_delta * weight_amount

        last_sample = source[-1] if index == 0 else result[-1]
        delta_avg /= window_size
        result.append(last_sample + delta_avg)

    return result