簡體   English   中英

Matplotlib 在刻度之間繪制市場(X 軸)

[英]Matplotlib plot market between ticks (X axis)

我正在根據股票價格計算 2 條移動平均線,並確定它們是否交叉。 當他們交叉時,我想在圖表中顯示一個位於其頂部的標記。

為了找到交叉點,我正在使用以下代碼:

idxs = np.argwhere(np.diff(df_status)).flatten()

其中 df_status 是一個列表,其中包含來自兩個移動平均線的 -1、0 和 1。 idxs 為我提供了 df_status 中發生交叉的索引位置。

問題是當交叉在兩個日期之間時,如下圖所示: SMA 10 和 100 之間的交叉。藍線是股價

如何將標記移動到交叉點的中心而不是檢測到的日期?

重現代碼:

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.image as mpimg

data = [
    ["2019-12-16", 4.39, 4.02, 5.11],
    ["2019-12-17", 4.42, 4.08, 5.09],
    ["2019-12-18", 4.2, 4.11, 5.06],
    ["2019-12-19", 4.57, 4.18, 5.04],
    ["2019-12-20", 4.85, 4.27, 5.03],
    ["2019-12-23", 4.95, 4.36, 5.01],
    ["2019-12-26", 5.8, 4.54, 5.01],
    ["2019-12-27", 6.0, 4.74, 5.01],
    ["2019-12-30", 5.9, 4.92, 5.0],
    ["2020-01-02", 6.02, 5.11, 5.00]
]
columns = ["day", "price", "SMA_10", "SMA_100"]

df = pd.DataFrame(data, columns=columns)
df['status_SMA_10_SMA_100'] = np.sign(df['SMA_10'] - df['SMA_100'])
idxs = np.argwhere(np.diff(df['status_SMA_10_SMA_100'])).flatten() # get crossovers

fig = plt.figure(figsize=[15, 8])
ax = fig.gca()
plt.grid(True)
plt.plot(df['day'], df['price'])
plt.plot(df['day'], df['SMA_10'])
plt.plot(df['day'], df['SMA_100'])
for marker in idxs:
    ax.plot(df['day'][marker], df['SMA_100'][marker], marker='o', markersize=35, alpha=.5)
    ax.plot(df['day'][marker + 1], df['SMA_100'][marker], marker='o', markersize=35, alpha=.5)
plt.show()

在此代碼中,交叉位於索引 8,但交叉發生在索引 8 和 9 之間的圖中。如何在兩個 X 刻度之間定位標記?

IIUC,要找到交叉“SMA_10”和“SMA_100”,試試這個:

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.image as mpimg

data = [
    ["2019-12-16", 4.39, 4.02, 5.11],
    ["2019-12-17", 4.42, 4.08, 5.09],
    ["2019-12-18", 4.2, 4.11, 5.06],
    ["2019-12-19", 4.57, 4.18, 5.04],
    ["2019-12-20", 4.85, 4.27, 5.03],
    ["2019-12-23", 4.95, 4.36, 5.01],
    ["2019-12-26", 5.8, 4.54, 5.01],
    ["2019-12-27", 6.0, 4.74, 5.01],
    ["2019-12-30", 5.9, 4.92, 5.0],
    ["2020-01-02", 6.02, 5.11, 5.00]
]
columns = ["day", "price", "SMA_10", "SMA_100"]

df = pd.DataFrame(data, columns=columns)
df['status_SMA_10_SMA_100'] = np.sign(df['SMA_10'] - df['SMA_100'])
idxs = np.argwhere(np.diff(df['status_SMA_10_SMA_100'])).flatten() # get crossovers

fig = plt.figure(figsize=[15, 8])
ax = fig.gca()
plt.grid(True)
plt.plot(df['day'], df['price'])
plt.plot(df['day'], df['SMA_10'])
plt.plot(df['day'], df['SMA_100'])
s = (df['SMA_10'] - df['SMA_100']).reset_index().set_index(0)
xmarker = s.reindex(s.index.union([0])).interpolate(method='index').loc[0.00].values
ymarker = df['SMA_10'].reindex(df.index.union(xmarker)).interpolate(method='index').loc[xmarker].values
ax.plot(xmarker, ymarker, marker='o', markersize='35', alpha=.5)
# for marker in idxs:
#     ax.plot(df['day'][marker], df['SMA_100'][marker], marker='o', markersize=35, alpha=.5)
#     ax.plot(df['day'][marker + 1], df['SMA_100'][marker], marker='o', markersize=35, alpha=.5)
plt.show()

輸出:

在此處輸入圖片說明

使用@ScottBoston 的建議,我想出了這個適用於單個和多個交叉的解決方案:

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.image as mpimg


def getAxisPositionForCrosses(index_position, df):
    qtt_points = 10
    ma1 = [np.nan] * qtt_points
    ma1[0] = df.loc[index_position]['SMA_10']
    ma1[qtt_points - 1] = df.loc[index_position + 1]['SMA_10']
    ma2 = [np.nan] * qtt_points
    ma2[0] = df.loc[index_position]['SMA_100']
    ma2[qtt_points - 1] = df.loc[index_position + 1]['SMA_100']

    df_cross = pd.DataFrame({'ma1': ma1, 'ma2': ma2})
    df_cross = df_cross.interpolate(method='index')
    df_cross['diff'] = df_cross['ma1'] >= df_cross['ma2']
    idxs_crosses = np.argwhere(np.diff(df_cross['diff'])).flatten()
    x_cross = index_position + 1/idxs_crosses[0]
    return {'x': x_cross, 'y': df_cross.loc[idxs_crosses[0]]['ma2']}

data = [
    ["2019-12-17", 8.54, 8.73, 8.68],
    ["2019-12-18", 8.4, 8.69, 8.66],
    ["2019-12-19", 8.41, 8.66, 8.65],
    ["2019-12-20", 8.09, 8.6, 8.62],
    ["2019-12-23", 8.4, 8.58, 8.61],
    ["2019-12-26", 8.25, 8.54, 8.58],
    ["2019-12-27", 8.42, 8.53, 8.58],
    ["2019-12-30", 8.78, 8.55, 8.59],
    ["2020-01-02", 8.97, 8.6, 8.61],
    ["2020-01-03", 9.27, 8.68, 8.65]
]
columns = ["day", "price", "SMA_10", "SMA_100"]

df = pd.DataFrame(data, columns=columns)
df['status_SMA_10_SMA_100'] = np.sign(df['SMA_10'] - df['SMA_100'])
# get crossovers
idxs = np.argwhere(np.diff(df['status_SMA_10_SMA_100'])).flatten()
cross_x = []
cross_y = []
for index in idxs:
    cross = getAxisPositionForCrosses(index, df)
    cross_x.append(cross['x'])
    cross_y.append(cross['y'])

fig = plt.figure(figsize=[15, 8])
ax = fig.gca()
plt.grid(True)
plt.plot(df['day'], df['price'])
plt.plot(df['day'], df['SMA_10'])
plt.plot(df['day'], df['SMA_100'])
ax.plot([cross_x], [cross_y], marker='o', markersize='35', alpha=.5)
plt.show()

多個交叉 單交叉

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM