Untitled

mail@pastecode.io avatar
unknown
plain_text
a month ago
55 kB
3
Indexable
Never
@jit(nopython=True)
def simple_backtest_opposite(sig, item_id_changed, signal_times, bidprice, askprice,
                             loss_thres, serial_incr, timelimit, quantity_risk, risk, reward, initial_nav, quantity_maxrisk, ls, minq = 5, fixed_quantity = False):
    """
    Performs a simple financial backtesting simulation based on given trading signals and prices, 
    adjusting positions according to specified trading rules, loss thresholds, and profit targets.

    Parameters:
    sig (numpy.ndarray): Array of trading signals where 1 indicates a long signal and -1 indicates a short signal.
    item_id_changed (numpy.ndarray): Array indicating whether the item ID has changed, triggering a closeout of positions.
    signal_times (numpy.ndarray): Array of timestamps for each trading signal.
    bidprice (numpy.ndarray): Array of bid prices for the trading instrument.
    askprice (numpy.ndarray): Array of ask prices for the trading instrument.
    loss_thres (float): Threshold for loss at which positions should be closed to stop further loss.
    serial_incr (int): Increment value for the serial number used in tracking trades.
    timelimit (int): Time limit after which positions should be closed if no other conditions are met.
    stop_loss (float): Stop loss level at which a position should be closed to limit losses.
    profit_target (float): Target profit level at which a position should be closed to realize gains.
    initial_quantity (int): Initial quantity of the instrument to be traded on receiving a trading signal.

    Returns:
    tuple: Contains multiple arrays including:
        - signal (numpy.ndarray): Updated signals after processing.
        - sig (numpy.ndarray): Original signals received.
        - quantity (numpy.ndarray): Array showing the quantity of instrument held over time.
        - tradeprice_leg1 (numpy.ndarray): Trading price for the first leg.
        - case (numpy.ndarray): Array of integers indicating the case scenario applied at each step.
        - return_since_signal (numpy.ndarray): Returns calculated since the last signal.
        - serial (numpy.ndarray): Serial numbers for trades.
        - traded_price_leg1 (numpy.ndarray): Actual traded prices after including transaction costs.
        - compounded_return_since_signal (numpy.ndarray): Compounded returns since the last trading signal.
        - time_since_signal (numpy.ndarray): Time elapsed since the last trading signal.
        - total_nav (numpy.ndarray): Net asset value over time.
        - crystallised_return (numpy.ndarray): Realized returns over the trading period.
        - short_signal_on_array (numpy.ndarray): Array indicating periods with active short positions.
        - long_signal_on_array (numpy.ndarray): Array indicating periods with active long positions.

    """

    
    time_limit = timelimit
    loss_threshold = loss_thres
    serial_incr = serial_incr
    lotsize1 = ls
    txn_cost = 0.0  # 833

    case = np.empty(bidprice.shape)
    signal = np.empty(bidprice.shape)
    short_signal_on_array = np.empty(bidprice.shape)
    long_signal_on_array = np.empty(bidprice.shape)

    quantity = np.empty(bidprice.shape)
    maxquantity = np.empty(bidprice.shape)
    serial = np.empty(bidprice.shape)
    q1 = np.empty(bidprice.shape)
    sl = np.empty(bidprice.shape)
    tp = np.empty(bidprice.shape)

    signal_price_leg1 = np.empty(bidprice.shape)
    tradeprice_leg1 = np.empty(bidprice.shape)
    traded_price_leg1 = np.empty(bidprice.shape)

    time_since_signal = np.empty(bidprice.shape)
    return_since_signal = np.empty(bidprice.shape)
    compounded_return_since_signal = np.empty(bidprice.shape)
    crystallised_quantity = np.empty(bidprice.shape)
    crystallised_return = np.empty(bidprice.shape)
    total_nav = np.empty(bidprice.shape)
    traded_nav1 = np.empty(bidprice.shape)

    short_signal_on = False
    long_signal_on = False
    short_signal_on_array[0] = 0
    long_signal_on_array[0] = 0

    signal[0] = 0
    quantity[0] = 0
    maxquantity[0] = 0
    q1[0]=0
    tp[0] = 0
    sl[0] = 0

    time_since_signal[0] = 0
    return_since_signal[0] = 0
    compounded_return_since_signal[0] = 0
    crystallised_quantity[0] = 0
    crystallised_return[0] = 0
    total_nav[0] = initial_nav
    traded_nav1[0] = 0

    if bidprice[0] != 0:
        tradeprice_leg1[0] = bidprice[0]
        signal_price_leg1[0] = bidprice[0]
        traded_price_leg1[0] = bidprice[0]
    else:
        tradeprice_leg1[0] = 0
        signal_price_leg1[0] = 0
        traded_price_leg1[0] = 0

    
    for i in range(1,len(bidprice)):

        case1long = (sig[i] == 1 and long_signal_on==False and short_signal_on==False)
        case2long = (sig[i] == 1 and long_signal_on==True and short_signal_on==False)
        case1short = (sig[i] == -1 and long_signal_on==False and short_signal_on==False) 
        case2short = (sig[i] == -1 and long_signal_on==False and short_signal_on==True)

        if long_signal_on:
            casecloseloss = (bidprice[i] <= sl[i-1]) 
            caseclosetp = (bidprice[i] >= tp[i-1])

        elif short_signal_on:
            casecloseloss = (askprice[i] >= sl[i-1]) 
            caseclosetp = (askprice[i] <= tp[i-1])

        closingbeforeexpiry = (item_id_changed[i] == 1)

        if signal_times[i] == 1:

            if case1long:
                    
                if quantity[i-1] == 0:

                    case[i] = 5
                    signal[i] = 1
                    long_signal_on = True
                    short_signal_on = False

                    serial[i] = 1
                    time_since_signal[i] = 1
                    signal_price_leg1[i] = askprice[i]
                    traded_price_leg1[i] = askprice[i] * (1 + txn_cost)
                    tradeprice_leg1[i] = traded_price_leg1[i]

                    if fixed_quantity:
                        quantity[i] = minq
                        maxquantity[i] = minq
                    else:
                        quantity[i], maxquantity[i], tp[i], sl[i] = define_q_and_tp(1, askprice[i], quantity_risk, risk, reward, total_nav[i-1], quantity_maxrisk, minq)

                    return_since_signal[i] = (quantity[i]*((bidprice[i] - traded_price_leg1[i]))*lotsize1) 
                    traded_nav1[i] = total_nav[i-1]
                    crystallised_return[i] = 0
                    compounded_return_since_signal[i] = crystallised_return[i] + return_since_signal[i]
                    total_nav[i] = total_nav[i-1] + crystallised_return[i] + return_since_signal[i] - return_since_signal[i-1]
                    short_signal_on_array[i] = np.where(short_signal_on == False, 0, 1)
                    long_signal_on_array[i] = np.where(long_signal_on == False, 0, 1)

                elif quantity[i-1] > 0:
                    raise KeyError

                    if ((askprice[i] - traded_price_leg1[i-1])/traded_price_leg1[i-1]) < -loss_threshold:

                        signal_price_leg1[i] = askprice[i]
                        traded_price_leg1[i] = askprice[i] * (1 + txn_cost)
                        tradeprice_leg1[i] = traded_price_leg1[i]
                        traded_nav1[i] = traded_nav1[i-1]

                        
                        serial[i] = serial[i-1] + serial_incr
                        time_since_signal[i] = time_since_signal[i-1] + 1
                        q1[i] = 5
                        if abs(quantity[i-1]) >= maxquantity:
                            quantity[i] = quantity[i-1]
                        else:
                            quantity[i] = quantity[i-1] + q1[i] 
                        case[i] = 6
                        crystallised_return[i] = (quantity[i-1]*((traded_price_leg1[i] - traded_price_leg1[i-1]))*lotsize1) 
                        short_signal_on = False
                        long_signal_on = True
                        signal[i] = 1

                        return_since_signal[i] = (quantity[i]*((bidprice[i] - traded_price_leg1[i]))*lotsize1)
                        compounded_return_since_signal[i] = crystallised_return[i] +  return_since_signal[i]
                        total_nav[i] = total_nav[i-1] + crystallised_return[i] + return_since_signal[i] - return_since_signal[i-1]
                        short_signal_on_array[i] = np.where(short_signal_on == False, 0, 1)
                        long_signal_on_array[i] = np.where(long_signal_on == False, 0, 1)

                    else:
                        
                        serial[i] = serial[i-1]
                        time_since_signal[i] = time_since_signal[i-1] + 1
                        quantity[i] = quantity[i-1]
                        traded_nav1[i] = traded_nav1[i-1]

                        signal_price_leg1[i] = signal_price_leg1[i-1] 
                        traded_price_leg1[i] = traded_price_leg1[i-1] 
                        tradeprice_leg1[i] = askprice[i]
                        short_signal_on = False
                        long_signal_on = True
                        signal[i] = 1
                        case[i] = 7

                        return_since_signal[i] = (quantity[i]*((bidprice[i] - traded_price_leg1[i]))*lotsize1)
                        crystallised_return[i] = 0 
                        compounded_return_since_signal[i] = crystallised_return[i] + return_since_signal[i]
                        total_nav[i] = total_nav[i-1] + crystallised_return[i] + return_since_signal[i] - return_since_signal[i-1]
                        short_signal_on_array[i] = np.where(short_signal_on == False, 0, 1)
                        long_signal_on_array[i] = np.where(long_signal_on == False, 0, 1)
    
                else:
                    raise KeyError
                    serial[i] = serial[i-1]
                    time_since_signal[i] = time_since_signal[i-1] + 1

                    quantity[i] = quantity[i-1]
                    traded_nav1[i] = traded_nav1[i-1]


                    signal_price_leg1[i] = signal_price_leg1[i-1] 
                    traded_price_leg1[i] = traded_price_leg1[i-1] 
                    tradeprice_leg1[i] = askprice[i]
                    short_signal_on = False
                    long_signal_on = True
                    signal[i] = 0
                    case[i] = 8

                    return_since_signal[i] = (quantity[i]*((bidprice[i] - traded_price_leg1[i]))*lotsize1)
                    crystallised_return[i] = 0 
                    compounded_return_since_signal[i] = crystallised_return[i] + return_since_signal[i]
                    total_nav[i] = total_nav[i-1] + crystallised_return[i] + return_since_signal[i] - return_since_signal[i-1]
                    short_signal_on_array[i] = np.where(short_signal_on == False, 0, 1)
                    long_signal_on_array[i] = np.where(long_signal_on == False, 0, 1)

            elif case2long:

                if quantity[i-1] == 0:
                    raise KeyError
                    
                    long_signal_on = True
                    short_signal_on = False
                    serial[i] = 1

                    time_since_signal[i] = 1
                    quantity[i] = initial_quantity
                    traded_nav1[i] = total_nav[i-1]

                    signal_price_leg1[i] = askprice[i]
                    traded_price_leg1[i] = askprice[i] * (1 + txn_cost)
                    tradeprice_leg1[i] = traded_price_leg1[i]
                    signal[i] = 1
                    case[i] = 5
                    return_since_signal[i] = (quantity[i]*((bidprice[i] - traded_price_leg1[i]))*lotsize1) # lotsize?
                    crystallised_return[i] = 0
                    compounded_return_since_signal[i] = crystallised_return[i] + return_since_signal[i]
                    total_nav[i] = total_nav[i-1] + crystallised_return[i] + return_since_signal[i] - return_since_signal[i-1]
                    short_signal_on_array[i] = np.where(short_signal_on == False, 0, 1)
                    long_signal_on_array[i] = np.where(long_signal_on == False, 0, 1)

                elif quantity[i-1] > 0:
                    
                    if casecloseloss or caseclosetp:

                        case[i]=34
                        signal[i] = 0
                        short_signal_on = False
                        long_signal_on = False

                        serial[i] = 0
                        time_since_signal[i] = 0

                        signal_price_leg1[i] = signal_price_leg1[i-1] 
                        traded_price_leg1[i] = bidprice[i]*(1-txn_cost)
                        tradeprice_leg1[i] = traded_price_leg1[i]
                        traded_nav1[i] = traded_nav1[i - 1]

                        quantity[i] = 0
                        maxquantity[i] = 0

                        sl[i] = 0
                        tp[i] = 0

                        return_since_signal[i] = 0
                        crystallised_return[i] = (quantity[i-1]*((traded_price_leg1[i] - traded_price_leg1[i-1]))*lotsize1) 
                        compounded_return_since_signal[i] = crystallised_return[i] + return_since_signal[i]     
                        total_nav[i] = total_nav[i-1] + crystallised_return[i] + return_since_signal[i] - return_since_signal[i-1]
                        short_signal_on_array[i] = np.where(short_signal_on == False, 0, 1)
                        long_signal_on_array[i] = np.where(long_signal_on == False, 0, 1)
                    
                    elif (((bidprice[i] - traded_price_leg1[i-1])/traded_price_leg1[i-1])) < -loss_threshold:
                        
                        case[i] = 6
                        signal[i] = 1
                        short_signal_on = False
                        long_signal_on = True

                        signal_price_leg1[i] = askprice[i]
                        traded_price_leg1[i] = askprice[i] * (1 + txn_cost)
                        tradeprice_leg1[i] = traded_price_leg1[i]
                        traded_nav1[i] = traded_nav1[i-1]
                        
                        serial[i] = serial[i-1] + serial_incr
                        time_since_signal[i] = time_since_signal[i-1] + 1
                        q1[i] = minq
                        if abs(quantity[i-1]) >= maxquantity[i-1]:
                            quantity[i] = quantity[i-1]
                        else:
                            quantity[i] = quantity[i-1] + q1[i]

                        sl[i] = sl[i - 1]
                        tp[i] = tp[i - 1]
                        maxquantity[i] = maxquantity[i - 1]

                        crystallised_return[i] = (quantity[i-1]*((traded_price_leg1[i] - traded_price_leg1[i-1]))*lotsize1)
                        return_since_signal[i] = (quantity[i]*((bidprice[i] - traded_price_leg1[i]))*lotsize1)
                        compounded_return_since_signal[i] = crystallised_return[i] +  return_since_signal[i]
                        total_nav[i] = total_nav[i-1] + crystallised_return[i] + return_since_signal[i] - return_since_signal[i-1]
                        short_signal_on_array[i] = np.where(short_signal_on == False, 0, 1)
                        long_signal_on_array[i] = np.where(long_signal_on == False, 0, 1)

                    else:
                        
                        serial[i] = serial[i-1]
                        time_since_signal[i] = time_since_signal[i-1] + 1
                        quantity[i] = quantity[i-1]
                        traded_nav1[i] = traded_nav1[i-1]
                        sl[i] = sl[i-1]
                        tp[i] = tp[i-1]
                        maxquantity[i] =maxquantity[i-1]

                        signal_price_leg1[i] = signal_price_leg1[i-1] 
                        traded_price_leg1[i] = traded_price_leg1[i-1] 
                        tradeprice_leg1[i] = bidprice[i]
                        short_signal_on = False
                        long_signal_on = True
                        signal[i] = 1
                        case[i] = 7

                        return_since_signal[i] = (quantity[i]*((bidprice[i] - traded_price_leg1[i]))*lotsize1)
                        crystallised_return[i] = 0 
                        compounded_return_since_signal[i] = crystallised_return[i] + return_since_signal[i]
                        total_nav[i] = total_nav[i-1] + crystallised_return[i] + return_since_signal[i] - return_since_signal[i-1]
                        short_signal_on_array[i] = np.where(short_signal_on == False, 0, 1)
                        long_signal_on_array[i] = np.where(long_signal_on == False, 0, 1)
    
                else:
                    raise KeyError
                    serial[i] = serial[i-1]
                    time_since_signal[i] = time_since_signal[i-1] + 1
                    traded_nav1[i] = traded_nav1[i-1]

                    quantity[i] = quantity[i-1]

                    signal_price_leg1[i] = signal_price_leg1[i-1] 
                    traded_price_leg1[i] = traded_price_leg1[i-1] 
                    tradeprice_leg1[i] = askprice[i]
                    short_signal_on = False
                    long_signal_on = True
                    signal[i] = 0
                    case[i] = 8

                    return_since_signal[i] = (quantity[i]*((bidprice[i] - traded_price_leg1[i]))*lotsize1)
                    crystallised_return[i] = 0 
                    compounded_return_since_signal[i] = crystallised_return[i] + return_since_signal[i]
                    total_nav[i] = total_nav[i-1] + crystallised_return[i] + return_since_signal[i] - return_since_signal[i-1]
                    short_signal_on_array[i] = np.where(short_signal_on == False, 0, 1)
                    long_signal_on_array[i] = np.where(long_signal_on == False, 0, 1)

            elif case1short:

                if quantity[i-1] == 0:
                    temp_signal[i] = 0   
                    serial[i] = 1
                    time_since_signal[i] = 1
                    q1[i] = 5

                    traded_nav1[i] = total_nav[i-1]

                    signal_price_leg1[i] = bidprice[i]
                    traded_price_leg1[i] = bidprice[i]*(1-txn_cost)
                    tradeprice_leg1[i] = traded_price_leg1[i]
                    short_signal_on = True
                    long_signal_on = False
                    signal[i] = -1
                    if fixed_quantity:
                        quantity[i] = -5
                        maxquantity[i] = -minq
                    else:
                        quantity[i], maxquantity[i], tp[i], sl[i] = define_q_and_tp(-1, bidprice[i], quantity_risk, risk, reward, total_nav[i-1], quantity_maxrisk, minq)

                    return_since_signal[i] = (quantity[i]*((askprice[i] - traded_price_leg1[i]))*lotsize1) 
                    crystallised_return[i] = 0
                    compounded_return_since_signal[i] = crystallised_return[i] + return_since_signal[i]
                    case[i] = 13
                    total_nav[i] = total_nav[i-1] + crystallised_return[i] + return_since_signal[i] - return_since_signal[i-1]
                    short_signal_on_array[i] = np.where(short_signal_on == False, 0, 1)
                    long_signal_on_array[i] = np.where(long_signal_on == False, 0, 1)

                elif quantity[i-1] < 0:
                    raise KeyError

                    if (((bidprice[i] - traded_price_leg1[i-1])/traded_price_leg1[i-1])*-1) < -loss_threshold:
                        signal_price_leg1[i] = bidprice[i]
                        traded_price_leg1[i] = bidprice[i]*(1-txn_cost)
                        tradeprice_leg1[i] = traded_price_leg1[i]
                        temp_signal[i] = 0
                        traded_nav1[i] = traded_nav1[i-1]
                        
                        serial[i] = serial[i-1] + serial_incr
                        time_since_signal[i] = time_since_signal[i-1] + 1
                        q1[i] = -5 
                        if abs(quantity[i-1]) >= maxquantity:
                            quantity[i] = quantity[i-1]
                        else:
                            quantity[i] = quantity[i-1] + q1[i] 
                        case[i] = 14
                        crystallised_return[i] = (quantity[i-1]*((traded_price_leg1[i] - traded_price_leg1[i-1]))*lotsize1) 
                        short_signal_on = True
                        long_signal_on = False
                        signal[i] = -1
                        return_since_signal[i] = (quantity[i]*((askprice[i] - traded_price_leg1[i]))*lotsize1)
                        compounded_return_since_signal[i] = crystallised_return[i] +  return_since_signal[i]
                        total_nav[i] = total_nav[i-1] + crystallised_return[i] + return_since_signal[i] - return_since_signal[i-1]
                        short_signal_on_array[i] = np.where(short_signal_on == False, 0, 1)
                        long_signal_on_array[i] = np.where(long_signal_on == False, 0, 1)


                    else:
                        serial[i] = serial[i-1]
                        time_since_signal[i] = time_since_signal[i-1] + 1
                        quantity[i] = quantity[i-1]
                        temp_signal[i] = 0
                        traded_nav1[i] = traded_nav1[i-1]

                        signal_price_leg1[i] = signal_price_leg1[i-1] 
                        traded_price_leg1[i] = traded_price_leg1[i-1] 
                        tradeprice_leg1[i] = bidprice[i]
                        short_signal_on = True
                        long_signal_on = False
                        signal[i] = -1
                        case[i] = 15
                        return_since_signal[i] = (quantity[i]*((askprice[i] - traded_price_leg1[i]))*lotsize1)
                        crystallised_return[i] = 0
                        compounded_return_since_signal[i] = crystallised_return[i] + return_since_signal[i]
                        total_nav[i] = total_nav[i-1] + crystallised_return[i] + return_since_signal[i] - return_since_signal[i-1]
                        short_signal_on_array[i] = np.where(short_signal_on == False, 0, 1)
                        long_signal_on_array[i] = np.where(long_signal_on == False, 0, 1)

                else:
                    raise KeyError
                    serial[i] = 0
                    time_since_signal[i] = 0
                    quantity[i] = 0
                    temp_signal[i] = -1
                    traded_nav1[i] = traded_nav1[i-1]


                    signal_price_leg1[i] = 0
                    traded_price_leg1[i] = 0
                    tradeprice_leg1[i] = 0
                    short_signal_on = False
                    long_signal_on = False  
                    signal[i] = 0 
                    case[i] = 16
                    return_since_signal[i] = 0
                    crystallised_return[i] = 0
                    compounded_return_since_signal[i] = 0  
                    total_nav[i] = total_nav[i-1] + crystallised_return[i] + return_since_signal[i] - return_since_signal[i-1]
                    short_signal_on_array[i] = np.where(short_signal_on == False, 0, 1)
                    long_signal_on_array[i] = np.where(long_signal_on == False, 0, 1)

            elif case2short:

                if quantity[i-1] == 0:
                    raise KeyError
                    temp_signal[i] = 0   
                    serial[i] = 1
                    time_since_signal[i] = 1
                    q1[i] = 5
                    quantity[i] = initial_quantity * -1 

                    traded_nav1[i] = total_nav[i-1]

                    signal_price_leg1[i] = bidprice[i]
                    traded_price_leg1[i] = bidprice[i]*(1-txn_cost)
                    tradeprice_leg1[i] = traded_price_leg1[i]
                    short_signal_on = True
                    long_signal_on = False
                    signal[i] = -1
                    return_since_signal[i] = (quantity[i]*((askprice[i] - traded_price_leg1[i]))*lotsize1) 
                    crystallised_return[i] = 0
                    compounded_return_since_signal[i] = crystallised_return[i] + return_since_signal[i]
                    case[i] = 13
                    total_nav[i] = total_nav[i-1] + crystallised_return[i] + return_since_signal[i] - return_since_signal[i-1]
                    short_signal_on_array[i] = np.where(short_signal_on == False, 0, 1)
                    long_signal_on_array[i] = np.where(long_signal_on == False, 0, 1)

                elif quantity[i-1] < 0:

                    if casecloseloss or caseclosetp:
                        serial[i] = 0
                        time_since_signal[i] = 0
                        temp_signal[i] = 0
                        traded_nav1[i] = traded_nav1[i-1]
                        
                        quantity[i] = 0
                        signal_price_leg1[i] = signal_price_leg1[i-1] 
                        traded_price_leg1[i] = askprice[i]*(1+txn_cost)
                        tradeprice_leg1[i] = traded_price_leg1[i]
                        short_signal_on = False
                        long_signal_on = False
                        signal[i] = 0
                        case[i] = 38
                        return_since_signal[i] = 0
                        sl[i] = 0
                        tp[i] = 0
                        maxquantity[i] = 0
                        crystallised_return[i] = (quantity[i-1]*((traded_price_leg1[i] - traded_price_leg1[i-1]))*lotsize1)
                        compounded_return_since_signal[i] = crystallised_return[i] + return_since_signal[i]
                        total_nav[i] = total_nav[i-1] + crystallised_return[i] + return_since_signal[i] - return_since_signal[i-1]
                        short_signal_on_array[i] = np.where(short_signal_on == False, 0, 1)
                        long_signal_on_array[i] = np.where(long_signal_on == False, 0, 1)

                    elif (((askprice[i] - traded_price_leg1[i-1])/traded_price_leg1[i-1])*-1) < -loss_threshold:
                        signal_price_leg1[i] = bidprice[i]
                        traded_price_leg1[i] = bidprice[i]*(1-txn_cost)
                        tradeprice_leg1[i] = traded_price_leg1[i]
                        temp_signal[i] = 0
                        traded_nav1[i] = traded_nav1[i-1]
                        tp[i],
                        
                        serial[i] = serial[i-1] + serial_incr
                        time_since_signal[i] = time_since_signal[i-1] + 1
                        q1[i] = -5 
                        if abs(quantity[i-1]) >= maxquantity:
                            quantity[i] = quantity[i-1]
                        else:
                            quantity[i] = quantity[i-1] + q1[i] 
                        case[i] = 14
                        sl[i] = sl[i-1]
                        tp[i] = tp[i-1]
                        maxquantity[i] =maxquantity[i-1]
                        crystallised_return[i] = (quantity[i-1]*((traded_price_leg1[i] - traded_price_leg1[i-1]))*lotsize1) 
                        short_signal_on = True
                        long_signal_on = False
                        signal[i] = -1
                        return_since_signal[i] = (quantity[i]*((askprice[i] - traded_price_leg1[i]))*lotsize1)
                        compounded_return_since_signal[i] = crystallised_return[i] +  return_since_signal[i]
                        total_nav[i] = total_nav[i-1] + crystallised_return[i] + return_since_signal[i] - return_since_signal[i-1]
                        short_signal_on_array[i] = np.where(short_signal_on == False, 0, 1)
                        long_signal_on_array[i] = np.where(long_signal_on == False, 0, 1)

                    else:
                        serial[i] = serial[i-1]
                        time_since_signal[i] = time_since_signal[i-1] + 1
                        quantity[i] = quantity[i-1]
                        temp_signal[i] = 0
                        signal_price_leg1[i] = signal_price_leg1[i-1] 
                        traded_price_leg1[i] = traded_price_leg1[i-1] 
                        tradeprice_leg1[i] = askprice[i]
                        short_signal_on = True
                        long_signal_on = False
                        signal[i] = -1
                        traded_nav1[i] = traded_nav1[i-1]

                        sl[i] = sl[i-1]
                        tp[i] = tp[i-1]
                        maxquantity[i] =maxquantity[i-1]

                        case[i] = 15
                        return_since_signal[i] = (quantity[i]*((askprice[i] - traded_price_leg1[i]))*lotsize1)
                        crystallised_return[i] = 0
                        compounded_return_since_signal[i] = crystallised_return[i] + return_since_signal[i]
                        total_nav[i] = total_nav[i-1] + crystallised_return[i] + return_since_signal[i] - return_since_signal[i-1]
                        short_signal_on_array[i] = np.where(short_signal_on == False, 0, 1)
                        long_signal_on_array[i] = np.where(long_signal_on == False, 0, 1)

                else:
                    raise KeyError
                    serial[i] = 0
                    time_since_signal[i] = 0
                    quantity[i] = 0
                    temp_signal[i] = -1
                    traded_nav1[i] = traded_nav1[i-1]

                    signal_price_leg1[i] = 0
                    traded_price_leg1[i] = 0
                    tradeprice_leg1[i] = 0
                    short_signal_on = False
                    long_signal_on = False  
                    signal[i] = 0 
                    case[i] = 16
                    return_since_signal[i] = 0
                    crystallised_return[i] = 0
                    compounded_return_since_signal[i] = 0  
                    total_nav[i] = total_nav[i-1] + crystallised_return[i] + return_since_signal[i] - return_since_signal[i-1]
                    short_signal_on_array[i] = np.where(short_signal_on == False, 0, 1)
                    long_signal_on_array[i] = np.where(long_signal_on == False, 0, 1)

            else:
                
                if long_signal_on:
                    if sig[i] == -1:
                        case[i] = 13
                        signal[i] = -1
                        short_signal_on = True
                        long_signal_on = False
                        serial[i] = 1
                        time_since_signal[i] = 1
                        # q1[i] = -minq
                        signal_price_leg1[i] = bidprice[i]
                        traded_price_leg1[i] = bidprice[i]*(1-txn_cost)
                        tradeprice_leg1[i] = traded_price_leg1[i]

                        crystallised_return[i] = (quantity[i - 1] * ((traded_price_leg1[i] - traded_price_leg1[i - 1])) * lotsize1)
                        traded_nav1[i] = total_nav[i-1] + crystallised_return[i]

                        if fixed_quantity:
                            quantity[i] = -minq
                            maxquantity[i] = -minq
                        else:
                            quantity[i], maxquantity[i],  tp[i], sl[i] = define_q_and_tp(-1, bidprice[i], quantity_risk, risk, reward, traded_nav1[i], quantity_maxrisk, minq)

                        return_since_signal[i] = (quantity[i]*((askprice[i] - traded_price_leg1[i]))*lotsize1)
                        compounded_return_since_signal[i] = crystallised_return[i] + return_since_signal[i]
                        total_nav[i] = total_nav[i-1] + crystallised_return[i] + return_since_signal[i] - return_since_signal[i-1]
                        short_signal_on_array[i] = np.where(short_signal_on == False, 0, 1)
                        long_signal_on_array[i] = np.where(long_signal_on == False, 0, 1)

                    elif casecloseloss or caseclosetp:
                        raise KeyError
                        serial[i] = 0
                        time_since_signal[i] = 0                    
                        quantity[i] = 0
                        traded_nav1[i] = traded_nav1[i-1]

                        signal_price_leg1[i] = signal_price_leg1[i-1] 
                        traded_price_leg1[i] = bidprice[i]*(1-txn_cost)
                        tradeprice_leg1[i] = traded_price_leg1[i]
                        short_signal_on = False
                        long_signal_on = False
                        signal[i] = 0
                        case[i] = 26
                        sl[i] = 0
                        tp[i] = 0
                        maxquantity[i] =0
                        
                        return_since_signal[i] = 0
                        crystallised_return[i] = (quantity[i-1]*((traded_price_leg1[i] - traded_price_leg1[i-1]))*lotsize1) 
                        compounded_return_since_signal[i] = crystallised_return[i] + return_since_signal[i]     
                        total_nav[i] = total_nav[i-1] + crystallised_return[i] + return_since_signal[i] - return_since_signal[i-1]
                        short_signal_on_array[i] = np.where(short_signal_on == False, 0, 1)
                        long_signal_on_array[i] = np.where(long_signal_on == False, 0, 1)

                    else:
                        raise KeyError
                        serial[i] = serial[i-1]
                        time_since_signal[i] = time_since_signal[i-1] + 1
                        traded_nav1[i] = traded_nav1[i-1]

                        quantity[i] = quantity[i-1]

                        signal_price_leg1[i] = signal_price_leg1[i-1] 
                        traded_price_leg1[i] = traded_price_leg1[i-1] 
                        tradeprice_leg1[i] = askprice[i]
                        short_signal_on = False
                        long_signal_on = True
                        signal[i] = 1
                        case[i] = 27
                        return_since_signal[i] = (quantity[i]*((bidprice[i] - traded_price_leg1[i]))*lotsize1) 
                        crystallised_return[i] = 0
                        compounded_return_since_signal[i] = crystallised_return[i] + return_since_signal[i]   
                        total_nav[i] = total_nav[i-1] + crystallised_return[i] + return_since_signal[i] - return_since_signal[i-1]
                        short_signal_on_array[i] = np.where(short_signal_on == False, 0, 1)
                        long_signal_on_array[i] = np.where(long_signal_on == False, 0, 1)

                elif short_signal_on:
                    
                    if sig[i] == 1:
                        case[i] = 30
                        signal[i] = 1
                        long_signal_on = True
                        short_signal_on = False
                        serial[i] = 1
                        time_since_signal[i] = 1

                        signal_price_leg1[i] = askprice[i]
                        traded_price_leg1[i] = askprice[i] * (1 + txn_cost)
                        tradeprice_leg1[i] = traded_price_leg1[i]

                        crystallised_return[i] = (quantity[i - 1] * ((traded_price_leg1[i] - traded_price_leg1[i - 1])) * lotsize1)
                        traded_nav1[i] = total_nav[i-1] + crystallised_return[i]

                        if fixed_quantity:
                            quantity[i] = minq
                            maxquantity[i] = minq
                        else:
                            quantity[i], maxquantity[i], tp[i], sl[i] = define_q_and_tp(1, askprice[i], quantity_risk, risk, reward, traded_nav1[i], quantity_maxrisk, minq)

                        return_since_signal[i] = (quantity[i]*((bidprice[i] - traded_price_leg1[i]))*lotsize1)
                        compounded_return_since_signal[i] = crystallised_return[i] + return_since_signal[i]
                        total_nav[i] = total_nav[i-1] + crystallised_return[i] + return_since_signal[i] - return_since_signal[i-1]
                        short_signal_on_array[i] = np.where(short_signal_on == False, 0, 1)
                        long_signal_on_array[i] = np.where(long_signal_on == False, 0, 1)

                    elif casecloseloss or caseclosetp:
                        raise KeyError
                        serial[i] = 0
                        time_since_signal[i] = 0
                        temp_signal[i] = 0
                        traded_nav1[i] = traded_nav1[i-1]
                        
                        quantity[i] = 0
                        signal_price_leg1[i] = signal_price_leg1[i-1] 
                        traded_price_leg1[i] = askprice[i]*(1+txn_cost)
                        tradeprice_leg1[i] = traded_price_leg1[i]
                        short_signal_on = False
                        long_signal_on = False
                        signal[i] = 0
                        case[i] = 29
                        return_since_signal[i] = 0
                        sl[i] = 0
                        tp[i] = 0
                        maxquantity[i] =0
                        

                        crystallised_return[i] = (quantity[i-1]*((traded_price_leg1[i] - traded_price_leg1[i-1]))*lotsize1)
                        compounded_return_since_signal[i] = crystallised_return[i] + return_since_signal[i]
                        total_nav[i] = total_nav[i-1] + crystallised_return[i] + return_since_signal[i] - return_since_signal[i-1]
                        short_signal_on_array[i] = np.where(short_signal_on == False, 0, 1)
                        long_signal_on_array[i] = np.where(long_signal_on == False, 0, 1)

                    else:
                        raise KeyError
                        serial[i] = serial[i-1]
                        time_since_signal[i] = time_since_signal[i-1] + 1
                        traded_nav1[i] = traded_nav1[i-1]

                        quantity[i] = quantity[i-1]
                        temp_signal[i] =  temp_signal[i-1]

                        signal_price_leg1[i] = signal_price_leg1[i-1] 
                        traded_price_leg1[i] = traded_price_leg1[i-1] 
                        tradeprice_leg1[i] = bidprice[i]
                        short_signal_on = True
                        long_signal_on = False
                        signal[i] = -1
                        case[i] = 30
                        return_since_signal[i] = (quantity[i]*((askprice[i] - traded_price_leg1[i]))*lotsize1)

                        crystallised_return[i] = 0
                        compounded_return_since_signal[i] = crystallised_return[i] + return_since_signal[i]    
                        total_nav[i] = total_nav[i-1] + crystallised_return[i] + return_since_signal[i] - return_since_signal[i-1]
                        short_signal_on_array[i] = np.where(short_signal_on == False, 0, 1)
                        long_signal_on_array[i] = np.where(long_signal_on == False, 0, 1)

                else:
                    raise KeyError
                    serial[i] = 0
                    time_since_signal[i] = 0
                    quantity[i] = 0
                    traded_nav1[i] = traded_nav1[i-1]
                    sl[i] = 0
                    tp[i] = 0
                    maxquantity[i] =0
                        
                    signal_price_leg1[i] = 0
                    traded_price_leg1[i] = 0
                    tradeprice_leg1[i] = 0
                    short_signal_on = False
                    long_signal_on = False  
                    signal[i] = 0 
                    case[i] = 31
                    return_since_signal[i] = 0
                    crystallised_return[i] = 0
                    compounded_return_since_signal[i] = 0  
                    total_nav[i] = total_nav[i-1] + crystallised_return[i] + return_since_signal[i] - return_since_signal[i-1]
                    short_signal_on_array[i] = np.where(short_signal_on == False, 0, 1)
                    long_signal_on_array[i] = np.where(long_signal_on == False, 0, 1)


            if (time_since_signal[i] >= time_limit ) or closingbeforeexpiry:
                if long_signal_on:
                    traded_price_leg1[i] = bidprice[i]*(1-txn_cost)
                    signal_price_leg1[i] = signal_price_leg1[i-1] 
                    tradeprice_leg1[i] = traded_price_leg1[i]
                    case[i] = 32
                    serial[i] = 0
                    time_since_signal[i] = 0
                    temp_signal[i] = 0
                    traded_nav1[i] = 0
                    sl[i] = 0
                    tp[i] = 0
                    maxquantity[i] = 0
                    
                    quantity[i] = 0

                    short_signal_on = False
                    long_signal_on = False 
                    signal[i] = 0 
                    return_since_signal[i] = 0

                    crystallised_return[i] = (quantity[i-1]*((traded_price_leg1[i] - traded_price_leg1[i-1]))*lotsize1) 
                    compounded_return_since_signal[i] = crystallised_return[i] + return_since_signal[i]  
                    total_nav[i] = total_nav[i-1] + crystallised_return[i] + return_since_signal[i] - return_since_signal[i-1]
                    short_signal_on_array[i] = np.where(short_signal_on == False, 0, 1)
                    long_signal_on_array[i] = np.where(long_signal_on == False, 0, 1)

                elif short_signal_on:
                    traded_price_leg1[i] = askprice[i]*(1+txn_cost)
                    signal_price_leg1[i] = signal_price_leg1[i-1] 
                    temp_signal[i] = 0

                    tradeprice_leg1[i] = traded_price_leg1[i]
                    traded_nav1[i] = 0
                    sl[i] = 0
                    tp[i] = 0
                    maxquantity[i] =0
                    case[i] = 33
                    serial[i] = 0
                    time_since_signal[i] = 0
                    
                    quantity[i] = 0

                    short_signal_on = False
                    long_signal_on = False 
                    signal[i] = 0 
                    return_since_signal[i] = 0

                    crystallised_return[i] = (quantity[i-1]*((traded_price_leg1[i] - traded_price_leg1[i-1]))*lotsize1)
            
                    compounded_return_since_signal[i] = crystallised_return[i] + return_since_signal[i]  
                    total_nav[i] = total_nav[i-1] + crystallised_return[i] + return_since_signal[i] - return_since_signal[i-1]
                    short_signal_on_array[i] = np.where(short_signal_on == False, 0, 1)
                    long_signal_on_array[i] = np.where(long_signal_on == False, 0, 1)

                else:
                    traded_price_leg1[i] = 0
                    signal_price_leg1[i] = 0
                    temp_signal[i] = 0
                    traded_nav1[i] =  0
                    sl[i] = 0
                    tp[i] = 0
                    maxquantity[i] = 0
                    tradeprice_leg1[i] = 0
                    crystallised_return[i] = 0
                    serial[i] = 0
                    time_since_signal[i] = 0
                    
                    quantity[i] = 0

                    short_signal_on = False
                    long_signal_on = False 
                    signal[i] = 0 
                    return_since_signal[i] = 0
                    compounded_return_since_signal[i] = 0
                    case[i] = 34
                    total_nav[i] = total_nav[i-1] + crystallised_return[i] + return_since_signal[i] - return_since_signal[i-1]
                    short_signal_on_array[i] = np.where(short_signal_on == False, 0, 1)
                    long_signal_on_array[i] = np.where(long_signal_on == False, 0, 1)

        elif signal_times[i] == 0:

            if long_signal_on:
                if casecloseloss or caseclosetp:
                    serial[i] = 0
                    time_since_signal[i] = 0                    
                    quantity[i] = 0
                    temp_signal[i] = 0
                    sl[i] = 0
                    tp[i] = 0
                    maxquantity[i] =0
                    signal_price_leg1[i] = signal_price_leg1[i-1] 
                    traded_price_leg1[i] = bidprice[i]*(1-txn_cost)
                    tradeprice_leg1[i] = traded_price_leg1[i]
                    short_signal_on = False
                    long_signal_on = False
                    signal[i] = 0
                    case[i] = 26
                    traded_nav1[i] = traded_nav1[i-1]
                    
                    return_since_signal[i] = 0
                    crystallised_return[i] = (quantity[i-1]*((traded_price_leg1[i] - traded_price_leg1[i-1]))*lotsize1) 
                    compounded_return_since_signal[i] = crystallised_return[i] + return_since_signal[i]     
                    total_nav[i] = total_nav[i-1] + crystallised_return[i] + return_since_signal[i] - return_since_signal[i-1]
                    short_signal_on_array[i] = np.where(short_signal_on == False, 0, 1)
                    long_signal_on_array[i] = np.where(long_signal_on == False, 0, 1)
                
                else:
                    serial[i] = serial[i-1]
                    time_since_signal[i] = time_since_signal[i-1] + 1

                    quantity[i] = quantity[i-1]
                    temp_signal[i] = temp_signal[i-1]
                    traded_nav1[i] = traded_nav1[i-1]
                    sl[i] = sl[i-1]
                    tp[i] = tp[i-1]
                    maxquantity[i] = maxquantity[i-1]

                    signal_price_leg1[i] = signal_price_leg1[i-1] 
                    traded_price_leg1[i] = traded_price_leg1[i-1] 
                    tradeprice_leg1[i] = bidprice[i]
                    short_signal_on = False
                    long_signal_on = True
                    signal[i] = 1
                    case[i] = 27
                    return_since_signal[i] = (quantity[i]*((bidprice[i] - traded_price_leg1[i]))*lotsize1) 
                    crystallised_return[i] = 0
                    compounded_return_since_signal[i] = crystallised_return[i] + return_since_signal[i]   
                    total_nav[i] = total_nav[i-1] + crystallised_return[i] + return_since_signal[i] - return_since_signal[i-1]
                    short_signal_on_array[i] = np.where(short_signal_on == False, 0, 1)
                    long_signal_on_array[i] = np.where(long_signal_on == False, 0, 1)

            elif short_signal_on:
                if casecloseloss or caseclosetp:
                    serial[i] = 0
                    time_since_signal[i] = 0
                    temp_signal[i] = 0
                    traded_nav1[i] = traded_nav1[i-1]
                    sl[i] = 0
                    tp[i] = 0
                    maxquantity[i] =0
                    quantity[i] = 0
                    signal_price_leg1[i] = signal_price_leg1[i-1] 
                    traded_price_leg1[i] = askprice[i]*(1+txn_cost)
                    tradeprice_leg1[i] = traded_price_leg1[i]
                    short_signal_on = False
                    long_signal_on = False
                    signal[i] = 0
                    case[i] = 29
                    return_since_signal[i] = 0

                    crystallised_return[i] = (quantity[i-1]*((traded_price_leg1[i] - traded_price_leg1[i-1]))*lotsize1)
                    compounded_return_since_signal[i] = crystallised_return[i] + return_since_signal[i]
                    total_nav[i] = total_nav[i-1] + crystallised_return[i] + return_since_signal[i] - return_since_signal[i-1]
                    short_signal_on_array[i] = np.where(short_signal_on == False, 0, 1)
                    long_signal_on_array[i] = np.where(long_signal_on == False, 0, 1)

                else:
                    serial[i] = serial[i-1]
                    time_since_signal[i] = time_since_signal[i-1] + 1

                    quantity[i] = quantity[i-1]
                    temp_signal[i] =  temp_signal[i-1]
                    traded_nav1[i] = total_nav[i-1]
                    sl[i] = sl[i-1]
                    tp[i] = tp[i-1]
                    maxquantity[i] =maxquantity[i-1]

                    signal_price_leg1[i] = signal_price_leg1[i-1] 
                    traded_price_leg1[i] = traded_price_leg1[i-1] 
                    tradeprice_leg1[i] = askprice[i]
                    short_signal_on = True
                    long_signal_on = False
                    signal[i] = -1
                    case[i] = 30
                    return_since_signal[i] = (quantity[i]*((askprice[i] - traded_price_leg1[i]))*lotsize1)

                    crystallised_return[i] = 0
                    compounded_return_since_signal[i] = crystallised_return[i] + return_since_signal[i]    
                    total_nav[i] = total_nav[i-1] + crystallised_return[i] + return_since_signal[i] - return_since_signal[i-1]
                    short_signal_on_array[i] = np.where(short_signal_on == False, 0, 1)
                    long_signal_on_array[i] = np.where(long_signal_on == False, 0, 1)

            else:
                serial[i] = 0
                time_since_signal[i] = 0
                quantity[i] = 0
                temp_signal[i] = 0
                traded_nav1[i] = total_nav[i-1]
                sl[i] = 0
                tp[i] = 0
                maxquantity[i] =0
                signal_price_leg1[i] = 0
                traded_price_leg1[i] = 0
                tradeprice_leg1[i] = 0
                short_signal_on = False
                long_signal_on = False  
                signal[i] = 0 
                case[i] = 31
                return_since_signal[i] = 0
                crystallised_return[i] = 0
                compounded_return_since_signal[i] = 0  
                total_nav[i] = total_nav[i-1] + crystallised_return[i] + return_since_signal[i] - return_since_signal[i-1]
                short_signal_on_array[i] = np.where(short_signal_on == False, 0, 1)
                long_signal_on_array[i] = np.where(long_signal_on == False, 0, 1)


            if (time_since_signal[i] >= time_limit) or closingbeforeexpiry:
                if long_signal_on:
                    traded_price_leg1[i] = bidprice[i]*(1-txn_cost)
                    signal_price_leg1[i] = signal_price_leg1[i-1] 
                    tradeprice_leg1[i] = traded_price_leg1[i]
                    serial[i] = 0
                    time_since_signal[i] = 0
                    traded_nav1[i] = 0
                    sl[i] = 0
                    tp[i] = 0
                    maxquantity[i] =0
                    quantity[i] = 0
                    temp_signal[i] = 0
                    short_signal_on = False
                    long_signal_on = False 
                    signal[i] = 0 
                    return_since_signal[i] = 0 
                    crystallised_return[i] = (quantity[i-1]*((traded_price_leg1[i] - traded_price_leg1[i-1]))*lotsize1)
                    compounded_return_since_signal[i] = crystallised_return[i] + return_since_signal[i]  
                    case[i] = 60
                    total_nav[i] = total_nav[i-1] + crystallised_return[i] + return_since_signal[i] - return_since_signal[i-1]
                    short_signal_on_array[i] = np.where(short_signal_on == False, 0, 1)
                    long_signal_on_array[i] = np.where(long_signal_on == False, 0, 1)

                elif short_signal_on:
                    traded_price_leg1[i] = askprice[i]*(1+txn_cost)
                    signal_price_leg1[i] = signal_price_leg1[i-1] 

                    tradeprice_leg1[i] = traded_price_leg1[i]
                    serial[i] = 0
                    time_since_signal[i] = 0
                    traded_nav1[i] = 0
                    sl[i] = 0
                    tp[i] = 0
                    maxquantity[i] =0
                    quantity[i] = 0
                    temp_signal[i] = 0

                    short_signal_on = False
                    long_signal_on = False 
                    signal[i] = 0 

                    return_since_signal[i] = 0

                    crystallised_return[i] = (quantity[i-1]*((traded_price_leg1[i] - traded_price_leg1[i-1]))*lotsize1) 
                    
                    compounded_return_since_signal[i] = crystallised_return[i] + return_since_signal[i]  
                    case[i] = 61
                    total_nav[i] = total_nav[i-1] + crystallised_return[i] + return_since_signal[i] - return_since_signal[i-1]
                    short_signal_on_array[i] = np.where(short_signal_on == False, 0, 1)
                    long_signal_on_array[i] = np.where(long_signal_on == False, 0, 1)
                
                else:
                    traded_price_leg1[i] = 0
                    signal_price_leg1[i] = 0
                    tradeprice_leg1[i] = 0
                    crystallised_return[i] = 0
                    serial[i] = 0
                    time_since_signal[i] = 0
                    temp_signal[i] = 0
                    traded_nav1[i] = 0
                    sl[i] = 0
                    tp[i] = 0
                    maxquantity[i] =0
                    quantity[i] = 0

                    short_signal_on = False
                    long_signal_on = False 
                    signal[i] = 0 
                    return_since_signal[i] = 0
                    compounded_return_since_signal[i] = 0
                    case[i] = 62
                    total_nav[i] = total_nav[i-1] + crystallised_return[i] + return_since_signal[i] - return_since_signal[i-1]
                    short_signal_on_array[i] = np.where(short_signal_on == False, 0, 1)
                    long_signal_on_array[i] = np.where(long_signal_on == False, 0, 1)
        
        if total_nav[i] <= 0:
            break

    return signal, sig, quantity, maxquantity, tradeprice_leg1, case, return_since_signal,serial, traded_price_leg1, compounded_return_since_signal, time_since_signal, total_nav, crystallised_return, short_signal_on_array, long_signal_on_array




@jit(nopython=True)
def define_q_and_tp(buy_sell, closeprice, quantity_risk, risk, reward, initial_nav, quantity_maxrisk, min_q):
    q = (initial_nav * quantity_risk) / closeprice
    maxquantity = (initial_nav * quantity_maxrisk) / closeprice

    q = (q // min_q) * min_q
    maxquantity = (maxquantity // min_q) * min_q

    if q < min_q:
        q = min_q
    if maxquantity < min_q:
        maxquantity = min_q

    q = q * buy_sell
    maxquantity = maxquantity * buy_sell

    tp = closeprice * (1 + buy_sell * reward)
    sl = closeprice * (1 - buy_sell * risk)

    return float(q), float(maxquantity), float(tp), float(sl)
Leave a Comment