Search code examples
dataframeiterationpython-polarscandlesticks

How to access prev row values on select in Polars Dataframe? Heikin-Ashi candle calculation


I have DF = { open: [], high:[], low:[], close[] )

and formula to aggregate current DF:

# OPEN = (Open_n-1 + Close_n-1) / 2.0
# HIGH = Max(High_n, Open_n, Close_n)
# LOW = Min(Low_n, Open_n, Close_n)
# CLOSE = (Open_n + High_n + Low_n + Close_n) / 4.0

Having issue with OPEN = (Open_n-1 + Close_n-1) / 2.0 part. No idea how to access previous row values... Maybe iterate through rows, generate prev row placeholder with another select query but it seems quite hacky.

Does anybody have suggestions to solve this one?

At the moment I have this:

self.candle_data_ctx.price_candle_df.
select([
    # OPEN = (Open_n-1 + Close_n-1) / 2.0
    #     TODO - implement
    # HIGH = Max(High_n, Open_n, Close_n)
    pl.max([pl.col('high_price'), pl.col('open_price'), pl.col('close_price')
                ]).alias('high_price'),
    # LOW = Min(Low_n, Open_n, Close_n)
    pl.min([pl.col('low_price'), pl.col('open_price'), pl.col('close_price')
                ]).alias('low_price'),
    # CLOSE = (Open_n + High_n + Low_n + Close_n) / 4.0
    (
       (
          pl.col('open_price') + pl.col('high_price') + pl.col('low_price') + pl.col('close_price')
        ) / 4.0
    ).alias('close_price'),
])

Solution

  • SOLVED - Heikin-Ashi candle calculation:

    price_candle_df
    .select([
        # OPEN_n = (Open_n-1 + Close_n-1) / 2.0
        (
            (
                pl.col('open_price').shift(periods=1) + pl.col('close_price').shift(periods=1)
            ) / 2.0
        ).fill_null(pl.col('open_price')).alias('open_price'),
    
        # HIGH_n = Max(High_n, Open_n, Close_n)
        pl.max([
            pl.col('high_price'),
            pl.col('open_price'),
            pl.col('close_price')
        ]).alias('high_price'),
    
        # LOW_n = Min(Low_n, Open_n, Close_n)
        pl.min([
            pl.col('low_price'),
            pl.col('open_price'),
            pl.col('close_price')
        ]).alias('low_price'),
    
        # CLOSE_n = (Open_n + High_n + Low_n + Close_n) / 4.0
        (
            (
                pl.col('open_price') + pl.col('high_price') + 
                pl.col('low_price') + pl.col('close_price')
            ) / 4.0
         ).alias('close_price')
    ])