Untitled

 avatar
unknown
plain_text
9 days ago
4.7 kB
1
Indexable
def main():
    # --------------------------------------------------------
    # A) Read the pickled data from disk
    # --------------------------------------------------------
    logger.info("Reading pickle files...")

    pcr_df = pd.read_pickle("data/MAIN_NIFTY50_PCR.pkl")         # (Date, Time, PCR)
    expiry_df = pd.read_pickle("data/MAIN_NIFTY50_EXPIRIES.pkl")   # (Expiries, Status)
    options_df = pd.read_pickle("data/MAIN_NIFTY50_OPTIONS_2021_NIFTY50_2021_01_07_OptionChain.pkl") # (Date, Time, Open, ..., ExpiryDate)

    logger.info(f"PCR DF shape: {pcr_df.shape}, columns: {pcr_df.columns}")
    logger.info(f"Expiry DF shape: {expiry_df.shape}, columns: {expiry_df.columns}")
    logger.info(f"Options DF shape: {options_df.shape}, columns: {options_df.columns}")

    # --------------------------------------------------------
    # B) Select the first expiry for demonstration
    #    (once working, you can loop over all expiries)
    # --------------------------------------------------------
    first_expiry = '2021-01-07'
    first_expiry_datetime = datetime.strptime(first_expiry, "%Y-%m-%d")
    first_expiry = first_expiry_datetime.strftime("%d-%m-%Y")
    logger.info(f"Selected expiry for test: {first_expiry}")

    # Filter options data for that expiry
    mask = (options_df['ExpiryDate'] == first_expiry)
    df_expiry = options_df[mask].copy()

    # Sort by Date, Time (important for time-series)
    df_expiry.sort_values(['Date','Time'], inplace=True)

    logger.info(f"Filtered option data shape: {df_expiry.shape}")

    # --------------------------------------------------------
    # C) Merge with PCR Data on (Date, Time)
    #    This ensures we have a PCR value for each row
    # --------------------------------------------------------
    df_merged = pd.merge(df_expiry, pcr_df, on=['Date','Time'], how='left')
    df_merged.sort_values(['Date','Time'], inplace=True)
    # Now df_merged has columns:
    #  [Date, Time, Open, High, Low, Close, Volume, OI, OptionType,
    #   StrikePrice, Ticker, Delta, Close_Index, ExpiryDate, PCR]
    logger.info(f"Merged shape: {df_merged.shape}")

    # For the GPU backtest, we'll just need:
    #   - pcr array
    #   - close prices array
    # In a real strategy, you might need Delta or other columns.

    # Drop rows with missing PCR if it happens
    df_merged = df_merged.dropna(subset=['PCR']).reset_index(drop=True)
    n_rows = len(df_merged)

    # --------------------------------------------------------
    # D) Prepare NumPy arrays for GPU
    # --------------------------------------------------------
    pcr_np = df_merged['PCR'].values.astype(np.float32)
    close_np = df_merged['Close'].values.astype(np.float32)

    # Copy to GPU
    pcr_gpu = cuda.to_device(pcr_np)
    close_gpu = cuda.to_device(close_np)

    # We'll store the result in a small array of length 1 (for one variant)
    # If you had multiple variants, you'd create a larger array: length = #variants
    pnl_gpu = cuda.device_array(1, dtype=np.float32)

    # --------------------------------------------------------
    # E) Launch the GPU kernel
    # --------------------------------------------------------
    # We use 1 block, 1 thread for demonstration (since we only do 1 variant)
    threads_per_block = 1
    blocks = 1

    logger.info("Launching GPU kernel for single-expiry demonstration...")

    backtest_single_expiry_kernel[blocks, threads_per_block](
        pcr_gpu, 
        close_gpu,
        # JSON thresholds
        BULLISH_ENTRY_PCR,
        HEAVILY_BULLISH_PCR,
        BEARISH_ENTRY_PCR,
        HEAVILY_BEARISH_PCR,
        # UNIVERSAL_STOP_LOSS,
        # UNIVERSAL_TARGET,
        # Output
        pnl_gpu
    )

    # Synchronize
    cuda.synchronize()

    # --------------------------------------------------------
    # F) Retrieve the result
    # --------------------------------------------------------
    pnl_result = pnl_gpu.copy_to_host()[0]
    logger.info(f"Backtest completed. Final PnL: {pnl_result:.2f}")

    # --------------------------------------------------------
    # G) Next Steps
    # --------------------------------------------------------
    # - If this works for the first expiry, you can loop over all expiries in expiry_df.
    # - If you have multiple variants (param sets), you can create bigger arrays for
    #   your thresholds, launch more threads, and do "thread_id = cuda.grid(1)"
    #   indexing inside the kernel.
    # - Ensure your memory usage and performance are tested for large data.

Leave a Comment