quantroom-pro / pyrenko

125 stars 49 forks source link

Date time stamps? #8

Open geofract opened 11 months ago

geofract commented 11 months ago

I appreciate Renko is a representation of price without time, but I would like to record datetime values from my data so I can tell when each brick closes.

Which part of the code should I look at to implement this - or where might I start?

lamres commented 11 months ago

Hey @Geofract, thanks for you feedback!

We plan to share an ultimate package for Renko in the next few months. This will be implemented inside it as the one of enhancements.

As for this package, the first you have to declare a list of date in init function. The second part is to add a new element with the current date when the new Renko bar is build in __renko_rule function beside of self.renko_prices variable.

geofract commented 11 months ago

That's great news, I really look forward to the next package!

Thank you for the coding tips too. I will see if I can add date time to your script.

geofract commented 7 months ago

Hi @lamres

There was a future warning which I think related to the build_history method, so I have edited my local version as follows:

FutureWarning: The behavior ofseries[i:j]with an integer-dtype index is deprecated. In a future version, this will be treated as *label-based* indexing, consistent with e.g.series[i]lookups. To retain the old behavior, useseries.iloc[i:j]. To get the future behavior, useseries.loc[i:j]``

# Getting renko on history
`def build_history(self, prices, dates):
    if len(prices) > 0:
        # Init by start values
        self.source_prices = prices
        self.renko_prices.append(prices.iloc[0])
        self.renko_datetime.append(dates.iloc[0])
        self.renko_directions.append(0)

        for p in range(len(self.source_prices)):
            date = dates.iloc[p]
            price = prices.iloc[p]
            self.__renko_rule(price, date)

    return len(self.renko_prices)`

I'm new to coding, so maybe my code is not ideal? I added date functionality too - I'll post those changes separately.

Thanks G

geofract commented 7 months ago

In case this is of interest to others, here's my attempt to add date functionality; nb. I'm just posting the areas changed, not the entire class.

 class renko:      
    def __init__(self):
        self.source_prices = []
        self.renko_prices = []
        self.renko_directions = []
        self.renko_datetime = []

    # Setting brick size. Auto mode is preferred, it uses history
    def set_brick_size(self, HLC_history = None, auto = True, brick_size = 10.0):
        if auto == True:
            # this option is disabled
            self.brick_size = self.__get_optimal_brick_size(HLC_history.iloc[:, [0, 1, 2]])
        else:
            self.brick_size = brick_size
        return self.brick_size

    def __renko_rule(self, last_price, date):
        # Get the gap between two prices
        gap_div = int(float(last_price - self.renko_prices[-1]) / self.brick_size)
        is_new_brick = False
        start_brick = 0
        num_new_bars = 0

        # When we have some gap in prices
        if gap_div != 0:
            # Forward any direction (up or down)
            if (gap_div > 0 and (self.renko_directions[-1] > 0 or self.renko_directions[-1] == 0)) or (gap_div < 0 and 
                (self.renko_directions[-1] < 0 or self.renko_directions[-1] == 0)):
                num_new_bars = gap_div
                is_new_brick = True
                start_brick = 0
            # Backward direction (up -> down or down -> up)
            elif np.abs(gap_div) >= 2: # Should be double gap at least
                num_new_bars = gap_div
                num_new_bars -= np.sign(gap_div)
                start_brick = 2
                is_new_brick = True
                self.renko_prices.append(self.renko_prices[-1] + 2 * self.brick_size * np.sign(gap_div))
                self.renko_directions.append(np.sign(gap_div))
                self.renko_datetime.append(date)
            #else:
                #num_new_bars = 0

            if is_new_brick:
                # Add each brick
                for d in range(start_brick, np.abs(gap_div)):
                    self.renko_prices.append(self.renko_prices[-1] + self.brick_size * np.sign(gap_div))
                    self.renko_directions.append(np.sign(gap_div))
                    self.renko_datetime.append(date)

        return num_new_bars

    # Getting renko on history
    def build_history(self, prices, dates):
        if len(prices) > 0:
            # Init by start values
            self.source_prices = prices
            self.renko_prices.append(prices.iloc[0])
            self.renko_datetime.append(dates.iloc[0])
            self.renko_directions.append(0)

            for p in range(len(self.source_prices)):
                date = dates.iloc[p]
                price = prices.iloc[p]
                self.__renko_rule(price, date)

        return len(self.renko_prices)