-
-
Notifications
You must be signed in to change notification settings - Fork 288
Renko charts
bellow I've used renko charts and your api to show me better analyses.
let me share the code:
first of all create a folder create file called pyrenko.py:
this is based on: https://github.com/quantroom-pro/pyrenko/blob/master/pyrenko.py
with little changes I added ema 22 periods.
TODO: this renko has no wicks so it need be developed. To see renko with wicks look at tradingview site.
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.patches as patches
import talib
class renko:
def __init__(self):
self.source_prices = []
self.renko_prices = []
self.renko_directions = []
# 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:
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):
# 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))
#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))
return num_new_bars
# Getting renko on history
def build_history(self, prices):
if len(prices) > 0:
# Init by start values
self.source_prices = prices
self.renko_prices.append(prices.iloc[0])
self.renko_directions.append(0)
# For each price in history
for p in self.source_prices[1:]:
self.__renko_rule(p)
return len(self.renko_prices)
# Getting next renko value for last price
def do_next(self, last_price):
if len(self.renko_prices) == 0:
self.source_prices.append(last_price)
self.renko_prices.append(last_price)
self.renko_directions.append(0)
return 1
else:
self.source_prices.append(last_price)
return self.__renko_rule(last_price)
# Simple method to get optimal brick size based on ATR
def __get_optimal_brick_size(self, HLC_history, atr_timeperiod = 14):
brick_size = 0.0
# If we have enough of data
if HLC_history.shape[0] > atr_timeperiod:
brick_size = np.median(talib.ATR(high = np.double(HLC_history.iloc[:, 0]),
low = np.double(HLC_history.iloc[:, 1]),
close = np.double(HLC_history.iloc[:, 2]),
timeperiod = atr_timeperiod)[atr_timeperiod:])
return brick_size
def evaluate(self, method = 'simple'):
balance = 0
sign_changes = 0
leng = len(self.renko_prices)
price_ratio = len(self.source_prices) / leng if leng else 0
if method == 'simple':
for i in range(2, len(self.renko_directions)):
if self.renko_directions[i] == self.renko_directions[i - 1]:
balance = balance + 1
else:
balance = balance - 2
sign_changes = sign_changes + 1
if sign_changes == 0:
sign_changes = 1
score = balance / sign_changes
if score >= 0 and price_ratio >= 1:
score = np.log(score + 1) * np.log(price_ratio)
else:
score = -1.0
return {'balance': balance, 'sign_changes:': sign_changes,
'price_ratio': price_ratio, 'score': score}
def get_renko_prices(self):
return self.renko_prices
def get_renko_directions(self):
return self.renko_directions
def plot_renko(self, col_up = 'g', col_down = 'r'):
fig, ax = plt.subplots(1, figsize=(20, 10))
ax.set_title('Renko chart')
ax.set_xlabel('Renko bars')
ax.set_ylabel('Price')
# Calculate the limits of axes
ax.set_xlim(0.0,
len(self.renko_prices) + 1.0)
ax.set_ylim(np.min(self.renko_prices) - 3.0 * self.brick_size,
np.max(self.renko_prices) + 3.0 * self.brick_size)
# exponential
ema = talib.EMA(np.array(self.renko_prices,dtype='f8'),timeperiod=22)
ax.plot(ema, color='blue', lw=2, label='EMA (22)')
# Plot each renko bar
for i in range(1, len(self.renko_prices)):
# Set basic params for patch rectangle
col = col_up if self.renko_directions[i] == 1 else col_down
x = i
y = self.renko_prices[i] - self.brick_size if self.renko_directions[i] == 1 else self.renko_prices[i]
height = self.brick_size
# Draw bar with params
ax.add_patch(
patches.Rectangle(
(x, y), # (x,y)
1.0, # width
self.brick_size, # height
facecolor = col
)
)
plt.show()
then create new file called userdata.py and set your credentials
mainUser = {
'username': '',
'password': ''
}
After that create new file called renko.py:
then just paste this code
import time
import os
import json
import datetime as dt
from iqoptionapi.stable_api import IQ_Option
from argparse import ArgumentParser
import pandas as pd
import userdata
import pyrenko
## How to use python renko.py -a USDJPY -i 300
parser = ArgumentParser()
parser.add_argument("-a", "--asset", dest="asset", required=True,
help="Pass the asset:(EURUSD, AUDUSD, XEMUSD-l ...)", metavar="ASSET")
parser.add_argument("-i", "--interval", dest="interval", required=False,
help="Pass interval in seconds: [1,5,10,15,30,60,120,300,600,900,1800,3600,7200,14400,28800,43200,86400,604800,2592000,'all']", metavar="TIME")
parser.add_argument("-f", "--file-sufix", dest="filesufix", required=False,
help="Pass sufix to file ", metavar="SUFIX")
args = parser.parse_args()
asset = args.asset or "USDJPY"
interval = args.interval or 60
sufix = args.filesufix or ""
## AUTH
user = userdata.mainUser
Iq= IQ_Option(user["username"],user["password"])
end_from_time=time.time()
ANS=[]
for i in range(3):
candles=[]
candles=Iq.get_candles(asset, int(interval), 1000, end_from_time)
cds = []
for candle in candles:
cd_handle = {}
if candle["open"]:
cd_handle['open'] = candle["open"]
cd_handle['high'] = candle["max"]
cd_handle['low'] = candle["min"]
cd_handle['close'] = candle["close"]
cd_handle['created_at'] = dt.datetime.fromtimestamp(candle["from"]).isoformat()
cd_handle['timestamp'] = candle["from"]
cd_handle['volume'] = candle["volume"]
cds.append(cd_handle)
ANS =cds+ANS
end_from_time=int(cds[0]["timestamp"])-1
try:
df = pd.DataFrame(ANS)
optimal_brick = pyrenko.renko().set_brick_size(auto = True, HLC_history = df[["high", "low", "close"]])
# Build Renko chart
renko_obj_atr = pyrenko.renko()
renko_obj_atr.set_brick_size(auto = False, brick_size = optimal_brick)
renko_obj_atr.build_history(prices = df.close)
if len(renko_obj_atr.get_renko_prices()) > 1:
renko_obj_atr.plot_renko()
except IOError:
print("I/O error")
Don't forget to install all depencies in renko.py
after all just run
python renko.py -a USDJPY -i 300
It means you are running with USDJPY and it will get 5 minutes per candles
It is not so accurate because to create renko you need each price change and not just closes
but it create an chart with a better precision then only candles
I hope it can contribute to raise up this project.