Discover more from All About Trading!
Color-Coding Bar Charts Based on Technical Signals.
Chart Manipulation in Python to Account for Technical Signals.
Color-coding is very helpful for noise reduction in technical analysis as well as for visual quick interpretation of the signals. In this article, we will develop this method with the stochastic oscillator. The aim is to create a visually comprehensible chart that uses colors to refer to a certain condition.
I have just released a new book after the success of my previous one “The Book of Trading Strategies”. It features advanced trend-following indicators and strategies with a GitHub page dedicated to the continuously updated code. Also, this book features the original colors after having optimized for printing costs. If you feel that this interests you, feel free to visit the below Amazon link, or if you prefer to buy the PDF version, you could contact me on LinkedIn.
Developing an OHLC Candlestick Chart
Candlestick charts are among the most famous ways to analyze the time series visually. They contain more information than a simple line chart and have more visual interpretability than bar charts. Many libraries in Python offer charting functions but being someone who suffers from malfunctioning import of libraries and functions alongside their fogginess, I have created my own simple function that charts candlesticks manually with no exogenous help needed.
OHLC data is an abbreviation for open, high, low, and close price. They are the four main ingredients for a timestamp. It is always better to have these four values together so that our analysis reflects more the reality. Here is a table that summarizes the OHLC data of a hypothetical security:
Our job now is to plot the data so that we can visually interpret what kind of trend is the price following. We will start with the basic line plot before we move on to candlestick plotting.
Note that you can download the data manually or using Python. In case you have an excel file that has OHLC only data starting from the first row and column, you can import it using the below code snippet:
import numpy as np import pandas as pd
# Importing the Data my_ohlc_data = pd.read_excel('my_ohlc_data.xlsx')
# Converting to Array my_ohlc_data = np.array(my_ohlc_data)
Plotting basic line plots is extremely easy in Python and requires only one line of code. We have to make sure that we have imported a library called matplotlib and then we will call a function that plots the data for us.
# Importing the necessary charting library import matplotlib.pyplot as plt
# The syntax to plot a line chart plt.plot(my_ohlc_data, color = 'black', label = 'EURUSD')
# The syntax to add the label created above plt.legend()
# The syntax to add a grid plt.grid()
Now that we have seen how to create normal line charts, it is time to take it to the next level with candlestick charts. The way to do this with no complications is to think about vertical lines. Here is the intuition (followed by an application of the function below):
Select a lookback period. This is the number of values you want to appear on the chart.
Plot vertical lines for each row representing the highs and lows. For example, on OHLC data, we will use a matplotlib function called vlines which plots a vertical line on the chart using a minimum (low) value and a maximum (high value).
Make a color condition which states that if the closing price is greater than the opening price, then execute the selected block of code (which naturally contains the color green). Do this with the color red (bearish candle) and the color black (Doji candle).
Plot vertical lines using the conditions with the min and max values representing closing prices and opening prices. Make sure to make the line’s width extra big so that the body of the candle appears sufficiently enough that the chart is deemed a candlestick chart.
def ohlc_plot_candles(data, window): sample = data[-window:, ] for i in range(len(sample)): plt.vlines(x = i, ymin = sample[i, 2], ymax = sample[i, 1], color = 'black', linewidth = 1) if sample[i, 3] > sample[i, 0]: plt.vlines(x = i, ymin = sample[i, 0], ymax = sample[i, 3], color = 'green', linewidth = 3)
if sample[i, 3] < sample[i, 0]: plt.vlines(x = i, ymin = sample[i, 3], ymax = sample[i, 0], color = 'red', linewidth = 3) if sample[i, 3] == sample[i, 0]: plt.vlines(x = i, ymin = sample[i, 3], ymax = sample[i, 0] + 0.00003, color = 'black', linewidth = 1.00) plt.grid()
Creating a Trading Signal or Condition
The trading signal or condition we will create is based on the stochastic oscillator which we will define now. The basic idea is that we will look at the candlestick (or bar) charts while knowing when the signals from the indicators occurred. This is without the need to display the oscillator. The stochastic oscillator seeks to find oversold and overbought zones by incorporating the highs and lows using a normalization formula as shown below:
An overbought level is an area where the market is perceived to be extremely bullish and is bound to consolidate. An oversold level is an area where market is perceived to be extremely bearish and is bound to bounce. Hence, the stochastic oscillator is a contrarian indicator that seeks to signal reactions of extreme movements.
def stochastic_oscillator(data, lookback, high, low, close, where, slowing = False, smoothing = False, slowing_period = 1, smoothing_period = 1): data = adder(data, 1) for i in range(len(data)): try: data[i, where] = (data[i, close] - min(data[i - lookback + 1:i + 1, low])) / (max(data[i - lookback + 1:i + 1, high]) - min(data[i - lookback + 1:i + 1, low])) except ValueError: pass data[:, where] = data[:, where] * 100 if slowing == True and smoothing == False: data = ma(data, slowing_period, where, where + 1) if smoothing == True and slowing == False: data = ma(data, smoothing_period, where, where + 1) if smoothing == True and slowing == True: data = ma(data, slowing_period, where, where + 1) data = ma(data, smoothing_period, where, where + 2) data = jump(data, lookback)
Let us consider the following conditions:
A value above 95 on the 100-period stochastic oscillator colors the bars in red as a bearish reaction is to be expected soon.
A value below 5 on the 100-period stochastic oscillator colors the bars in green as a bullish reaction is to be expected soon.
def ohlc_plot_bars(data, window): sample = data[-window:, ] for i in range(len(sample)): plt.vlines(x = i, ymin = sample[i, 2], ymax = sample[i, 1], color = 'black', linewidth = 1) if sample[i, 4] > 95: plt.vlines(x = i, ymin = sample[i, 0], ymax = sample[i, 3], color = 'red', linewidth = 3)
if sample[i, 4] < 5: plt.vlines(x = i, ymin = sample[i, 3], ymax = sample[i, 0], color = 'green', linewidth = 3) if sample[i, 4] == sample[i, 0]: plt.vlines(x = i, ymin = sample[i, 3], ymax = sample[i, 0] + 0.00003, color = 'black', linewidth = 1.00) plt.grid()
If you are also interested by more technical indicators and strategies, then my book might interest you:
Remember to always do your back-tests. You should always believe that other people are wrong. My indicators and style of trading may work for me but maybe not for you.
I am a firm believer of not spoon-feeding. I have learnt by doing and not by copying. You should get the idea, the function, the intuition, the conditions of the strategy, and then elaborate (an even better) one yourself so that you back-test and improve it before deciding to take it live or to eliminate it. My choice of not providing specific Back-testing results should lead the reader to explore more herself the strategy and work on it more.
To sum up, are the strategies I provide realistic? Yes, but only by optimizing the environment (robust algorithm, low costs, honest broker, proper risk management, and order management). Are the strategies provided only for the sole use of trading? No, it is to stimulate brainstorming and getting more trading ideas as we are all sick of hearing about an oversold RSI as a reason to go short or a resistance being surpassed as a reason to go long. I am trying to introduce a new field called Objective Technical Analysis where we use hard data to judge our techniques rather than rely on outdated classical methods.