Life is self-reliant, and blessing is self-seeking. All misfortunes, blessings and guilt are in the hands of people, doing good will accumulate blessings, and doing evil will invite misfortunes.
Article Directory
What is the stock price gap
The existence of a gap in the K-line chart refers to a blank interval with no trading between two adjacent K-lines. When there is no overlap between today's lowest price and yesterday's highest price, it is called an upward gap; there is no overlap between today's highest price and yesterday's lowest price, which is called a downward gap.
Theoretically speaking, when there is no good or bad news in the market, the stock price should be flat the next day. However, if there is a good one the day before, then in the call auction that day, most investors will buy at a higher price because It may not be able to buy if it is favorable to peg low prices, thus forming an upward gap to open higher. On the contrary, it is gapped and opened low.
This gap left has a certain reference value for judging the ups and downs of the market outlook. However, it should be noted that if you open high and go low and fall within the highest price of yesterday, the gap is filled. It can only be called a gap high and cannot be called a gap. The gap means that the price of the day has not been reverse-covered.
However, we also need to note that if the gap is small, it may have no reference to the market outlook, and there will also be a gap on the ex-rights and ex-dividend date, which is not of reference. Of course, there are exceptions. For example, BYD has not covered the 50 gap. It is meaningless to look at a single stock data alone. This requires additional attention.
Calculate the gap value
In the previous section, we used Goertek as an example to analyze the parameters of various stocks. Today, we switched to a stock called Muyuan shares, because this stock has directly reached its daily limit of 99 due to the announcement of its performance, and now it has fallen to 82. The gap is obvious.
First, let's get the data of Muyuan shares in the past two months. The specific code is as follows:
df = ak.stock_zh_a_daily(symbol="sz002714", start_date="20201103", end_date="20210118",
adjust="qfq")
df.to_excel("牧原股份.xlsx")
Next, we define a function to calculate the gap value, the code is as follows:
def count_gap(cPriceUp, preLow, preHigh, low, high, threshold):
jump_value = 0
if (cPriceUp > 0) and (low - preHigh) > threshold:
# 向上跳空
jump_value = (low - preHigh) / threshold
elif (cPriceUp < 0) and (preLow - high) > threshold:
# 向下跳空
jump_value = (high - preLow) / threshold
return jump_value
The meaning of the parameters of the function is as follows:
cPriceUp: increase in closing price
preLow: the lowest price yesterday
preHigh: Yesterday’s highest price
low: lowest price
high: the highest price
threshold: gap threshold
The meaning of this function translated into text is as follows:
(1) Upward gap: When the increase cPriceUp is positive, and today's lowest price (low) minus yesterday's highest price (preHigh) is greater than the gap threshold.
(2) Downward gap: When the increase cPriceUp is negative, and yesterday's lowest price (preLow) minus today's highest price (high) is greater than the gap threshold.
Traverse stock data to obtain gaps
First, we need to customize a threshold for judging whether it meets the gap, the code is as follows:
jump_threshold = df["close"].median() * 0.01
Here define the median of closing price * 0.01 as the threshold.
Then, apply the formula to calculate the parameters in the above method, the specific code is as follows:
jump_threshold = df["close"].median() * 0.01
# 计算涨跌幅
df['changeRatio'] = df["close"].pct_change() * 100
# 增加昨日最低价序列
df["preLow"] = df["low"].shift(1)
# 增加昨日最高价序列
df['preHigh'] = df['high'].shift(1)
# 增加空白列jump
df = df.assign(jump=0)
# 计算所有跳空值
df['jump'] = df.apply(
lambda row: count_gap(row['changeRatio'], row['preLow'], row['preHigh'], row['low'], row['high'], jump_threshold),
axis=1)
The comment is very detailed, that is, to get all the gaps of the stock and assign them to the jump column, and the jump without the gap value is assigned the value 0. Here we have all the gaps, and then we need to distinguish whether it is an upward gap or a downward gap.
# 向上跳空
up_jump = df[(df["cPriceUp"] > 0) & df["jump"] > 0]
# 向下跳空
down_jump = df[(df["cPriceUp"] < 0) & df["jump"] < 0]
As shown in the code above, you only need to make judgments based on the concept of upward gaps and the concept of downward gaps above.
Draw gaps
After the above code calculation, we have got the gap. Below, we can draw a K-line chart based on these values and mark the position of the gap. The complete code is as follows:
import matplotlib.pyplot as plt
import pandas as pd
import matplotlib.ticker as ticker
import mpl_finance as mpf
def count_gap(cPriceUp, preLow, preHigh, low, high, threshold):
jump_value = 0
if (cPriceUp > 0) and ((low - preHigh) > threshold):
# 向上跳空
jump_value = (low - preHigh) / threshold
elif (cPriceUp < 0) and ((preLow - high) > threshold):
# 向下跳空
jump_value = (high - preLow) / threshold
return jump_value
df = pd.read_excel("牧原股份.xlsx")
df['date'] = pd.to_datetime(df['date'])
df['date'] = df['date'].apply(lambda x: x.strftime('%Y-%m-%d'))
jump_threshold = df["close"].median() * 0.01
# 计算涨跌幅
df['cPriceUp'] = df["close"].pct_change() * 100
# 增加昨日最低价序列
df["preLow"] = df["low"].shift(1)
# 增加昨日最高价序列
df['preHigh'] = df['high'].shift(1)
# 增加空白列jump
df = df.assign(jump=0)
# 计算所有跳空值
df['jump'] = df.apply(
lambda row: count_gap(row['cPriceUp'], row['preLow'], row['preHigh'], row['low'], row['high'], jump_threshold),
axis=1)
# 向上跳空
up_jump = df[(df["cPriceUp"] > 0) & df["jump"] > 0]
# 向下跳空
down_jump = df[(df["cPriceUp"] < 0) & df["jump"] < 0]
fig = plt.figure(figsize=(12, 8))
ax = fig.add_subplot(111)
plt.rcParams['font.sans-serif'] = ['SimHei']
#绘制K线图
mpf.candlestick2_ochl(ax, df["open"], df["close"], df["high"], df["low"], width=0.6, colorup='r',
colordown='green',
alpha=1.0)
#绘制向下跳空与向上跳空缺口指标
for key, val in df.items():
for index, today in up_jump.iterrows():
x_posit = df.index.get_loc(index)
ax.annotate("{}\n{}".format("向上跳空", today["date"]), xy=(x_posit, today["preHigh"]),
xytext=(-30, -up_jump["close"].mean() *0.5), xycoords="data",
fontsize=18, textcoords="offset points", arrowprops=dict(arrowstyle="simple", color="r"))
for key, val in df.items():
for index, today in down_jump.iterrows():
x_posit = df.index.get_loc(index)
ax.annotate("{}\n{}".format("向下跳空", today["date"]), xy=(x_posit, today["preLow"]),
xytext=(-30, down_jump["close"].mean() *0.5), xycoords="data",
fontsize=18, textcoords="offset points", arrowprops=dict(arrowstyle="simple", color="r"))
ax.xaxis.set_major_locator(ticker.MaxNLocator(20))
def format_date(x, pos=None):
if x < 0 or x > len(df['date']) - 1:
return ''
return df['date'][int(x)]
ax.xaxis.set_major_formatter(ticker.FuncFormatter(format_date))
plt.setp(plt.gca().get_xticklabels(), rotation=45, horizontalalignment='right')
After the operation, the effect obtained is as shown in the following figure:
We mentioned BYD earlier, and so far, it has not covered the 50 gap. What about such stocks? In fact, it's very simple. You set a filter condition, how much the increase exceeds, and ignore the gap. Generally speaking, like BYD, it will definitely not be able to go back, so if the increase is greater than a certain amount, don't record the gap.