如果您注意到有两个主要的思想流派可以决定何时买入和何时卖出股票,一个是技术分析📈,另一个是基本面分析。

技术分析着眼于标的股票或股票代码的价格走势,以确定一些模式,而在基本面分析中,正在研究现金流、收入、估值或行业趋势等指标。

许多人认为,企业的基本面捕获了形成投资决策所需的所有信息,但这并不完全正确;基本面因素并不总是反映在市场价格中。

当然,我不想卷入技术分析与基本面分析的古老争论;两者都有自己的优点和缺点。

通过技术分析,人们依赖于数字,主要是价格和数量,这在短期内是好的,但从长远来看,它本质上是业务将增加你的资金。

简而言之,技术分析涉及通过分析历史市场数据并通过统计数据对其进行评估来预测金融证券的价格,其假设包括历史往往会重演,价格捕获所有信息,并且时间序列数据总是有趋势。

技术分析构成了**算法/自动化/基于规则的交易的基础,**指标如RSI(相对强弱指数)、移动平均线、振荡器或蜡烛图模式用于检测/确定超买和超卖水平、趋势强度或趋势反转。

正在使用许多指标;在这篇博文中,我们将学习如何使用其中一些来生成买入和卖出信号。

在我们开始之前,只是一个快速的免责声明!

免责声明:本文中的材料纯属教育意义,不应被视为专业投资建议。

本文的前提不是要展示如何“快速致富”。本文的想法是帮助您入门并展示 Python 的可能性。

 使用的模块:

 熊猫助教:

pandas-ta: Pandas Technical Analysis (Pandas TA) 是一个易于使用的库,它利用了具有 130 多个指标和实用程序函数以及 60 多种烛台形态的 Pandas 软件包。

要安装库,只需打开终端,激活conda环境,然后做一个简单的。 pip install pandas-ta

Screenshot 2021-08-16 at 8.04.39 PM.png

1. 导入库

我们将使用多个包,例如 pandasnumpy 和其他包;如果您没有安装它们,则可以使用 pip

pip install <packagename>

<span>import</span> numpy <span>as</span> np
<span>import</span> pandas <span>as</span> pd
<span>import</span> yfinance <span>as</span> yf
<span>import</span> pandas_datareader.data <span>as</span> web
<span>import</span> pandas_ta <span>as</span> ta
<span>import</span> matplotlib.pyplot <span>as</span> plt
<span>from</span> datetime <span>import</span> date
plt.style.use(<span>'fivethirtyeight'</span>)
yf.pdr_override()

我们将分析 TATAMOTORS,因为它是一种高流动性的股票,可以使策略有效运作,因此为了提取相同的数据,我们将使用下面编写的代码。

stocksymbols = [<span>'TATAMOTORS.NS'</span>]
startdate = date(<span>2017</span>,<span>8</span>,<span>4</span>)
end_date = date.today()
print(end_date)
<span><span>def</span> <span>getMyPortfolio</span>(<span>stocks = stocksymbols ,start = startdate , end = end_date</span>):</span>
    data = web.get_data_yahoo(stocks , data_source=<span>'yahoo'</span> , start = start ,end= end )
    <span>return</span> data

因此,我们创建了开始日期和结束日期的变量来提取数据,并定义了一个函数来获取这些参数并返回数据。

data = getMyPortfolio(stocksymbols)
data

 输出:

Screenshot 2021-08-17 at 7.52.59 PM.png

3. 战略的实施

SMA:首先,我们将首先使用一个非常简单的指标,即简单移动平均线;同样的概念非常简单,我们取一定时期收盘价的平均值,以平滑趋势并描绘趋势流的大致方向。

 策略:

data[<span>'SMA 30'</span>] = ta.sma(data[<span>'Close'</span>],<span>30</span>)
data[<span>'SMA 100'</span>] = ta.sma(data[<span>'Close'</span>],<span>100</span>)
<span>#SMA BUY SELL</span>
<span>#Function for buy and sell signal</span>
<span><span>def</span> <span>buy_sell</span>(<span>data</span>):</span>
    signalBuy = []
    signalSell = []
    position = <span>False</span> 

    <span>for</span> i <span>in</span> range(len(data)):
        <span>if</span> data[<span>'SMA 30'</span>][i] &gt; data[<span>'SMA 100'</span>][i]:
            <span>if</span> position == <span>False</span> :
                signalBuy.append(data[<span>'Adj Close'</span>][i])
                signalSell.append(np.nan)
                position = <span>True</span>
            <span>else</span>:
                signalBuy.append(np.nan)
                signalSell.append(np.nan)
        <span>elif</span> data[<span>'SMA 30'</span>][i] &lt; data[<span>'SMA 100'</span>][i]:
            <span>if</span> position == <span>True</span>:
                signalBuy.append(np.nan)
                signalSell.append(data[<span>'Adj Close'</span>][i])
                position = <span>False</span>
            <span>else</span>:
                signalBuy.append(np.nan)
                signalSell.append(np.nan)
        <span>else</span>:
            signalBuy.append(np.nan)
            signalSell.append(np.nan)
    <span>return</span> pd.Series([signalBuy, signalSell])

我们有两个 SMA,一个是短期的;另一种是长期的。我们编写了一个简单的函数,当空头均线大于多头时买入,当多头均线大于空头时卖出。因此,我们首先创建了两个列表,分别名为 signalBuy 和 signalSell;每当满足买入条件时,我们都会将收盘价附加到列表中;否则,我们附加了 NaN,然后在数据中存储了相同的列表。

我们还创建了一个名为 position 的变量,它确保我们在前一笔交易之后进行相反的交易,因此如果前一笔交易是“买入”,那么下一笔交易只会是“卖出”,因为头寸设置为 true。

data['Buy_Signal_price'], data['Sell_Signal_price'] = buy_sell(data)
data

我们调用了函数 & 将结果存储在我们的数据帧中。现在我们将绘制买入和卖出信号。

 输出:

Screenshot 2021-08-17 at 9.34.02 PM.png

 可视化:

fig, ax = plt.subplots(figsize=(<span>14</span>,<span>8</span>))
ax.plot(data[<span>'Adj Close'</span>] , label = stocksymbols[<span>0</span>] ,linewidth=<span>0.5</span>, color=<span>'blue'</span>, alpha = <span>0.9</span>)
ax.plot(data[<span>'SMA 30'</span>], label = <span>'SMA30'</span>, alpha = <span>0.85</span>)
ax.plot(data[<span>'SMA 100'</span>], label = <span>'SMA100'</span> , alpha = <span>0.85</span>)
ax.scatter(data.index , data[<span>'Buy_Signal_price'</span>] , label = <span>'Buy'</span> , marker = <span>'^'</span>, color = <span>'green'</span>,alpha =<span>1</span> )
ax.scatter(data.index , data[<span>'Sell_Signal_price'</span>] , label = <span>'Sell'</span> , marker = <span>'v'</span>, color = <span>'red'</span>,alpha =<span>1</span> )
ax.set_title(stocksymbols[<span>0</span>] + <span>" Price History with buy and sell signals"</span>,fontsize=<span>10</span>, backgroundcolor=<span>'blue'</span>, color=<span>'white'</span>)
ax.set_xlabel(<span>f'<span>{startdate}</span> - <span>{end_date}</span>'</span> ,fontsize=<span>18</span>)
ax.set_ylabel(<span>'Close Price INR (₨)'</span> , fontsize=<span>18</span>)
legend = ax.legend()
ax.grid()
plt.tight_layout()
plt.show()

 输出:

filename.png

在上面的代码中,我们基本上可视化了我们的买入和卖出水平,这表明移动平均线非常擅长捕捉长期趋势,可以据此决定是买入、卖出还是持有。

MACD:移动平均收敛散度指标 (MACD) 使用两个指数移动平均线 (EMA) - 短期和长期计算。MACD 的指数移动平均线用作信号线来指示向上或向下的动量。指数移动平均线只不过是一条移动平均线,它赋予了最近数据更多的权重。

所以现在我们将用 pandas-ta 计算 MACD;它将给我们三列,一列是两个称为 MACD 的 EMA 之间的差异,一列是称为信号的 MACD 值的 EMA,最后一列是称为 MACD 直方图的 MACD 和信号之间的差异。

macd = ta.macd(data[<span>'Close'</span>])
macd

 输出:

Screenshot 2021-08-23 at 8.08.35 PM.png

现在我们已经有了 MACD 列,我们将将它们与主数据帧合并。

data = pd.concat([data, macd], axis=<span>1</span>).reindex(data.index)
data

 输出:

Screenshot 2021-08-23 at 8.09.31 PM.png

如果 MACD 线越过信号线(MACD 线的移动平均线),我们将持有多头头寸。相反,如果 MACD 线穿过信号线下方,则更明智的做法是持有该股的空头头寸,因为预计趋势会反转。

 策略:

<span><span>def</span> <span>MACD_Strategy</span>(<span>df, risk</span>):</span>
    MACD_Buy=[]
    MACD_Sell=[]
    position=<span>False</span>

    <span>for</span> i <span>in</span> range(<span>0</span>, len(df)):
        <span>if</span> df[<span>'MACD_12_26_9'</span>][i] &gt; df[<span>'MACDs_12_26_9'</span>][i] :
            MACD_Sell.append(np.nan)
            <span>if</span> position ==<span>False</span>:
                MACD_Buy.append(df[<span>'Adj Close'</span>][i])
                position=<span>True</span>
            <span>else</span>:
                MACD_Buy.append(np.nan)
        <span>elif</span> df[<span>'MACD_12_26_9'</span>][i] &lt; df[<span>'MACDs_12_26_9'</span>][i] :
            MACD_Buy.append(np.nan)
            <span>if</span> position == <span>True</span>:
                MACD_Sell.append(df[<span>'Adj Close'</span>][i])
                position=<span>False</span>
            <span>else</span>:
                MACD_Sell.append(np.nan)
        <span>elif</span> position == <span>True</span> <span>and</span> df[<span>'Adj Close'</span>][i] &lt; MACD_Buy[<span>-1</span>] * (<span>1</span> - risk):
            MACD_Sell.append(df[<span>"Adj Close"</span>][i])
            MACD_Buy.append(np.nan)
            position = <span>False</span>
        <span>elif</span> position == <span>True</span> <span>and</span> df[<span>'Adj Close'</span>][i] &lt; df[<span>'Adj Close'</span>][i - <span>1</span>] * (<span>1</span> - risk):
            MACD_Sell.append(df[<span>"Adj Close"</span>][i])
            MACD_Buy.append(np.nan)
            position = <span>False</span>
        <span>else</span>:
            MACD_Buy.append(np.nan)
            MACD_Sell.append(np.nan)

    data[<span>'MACD_Buy_Signal_price'</span>] = MACD_Buy
    data[<span>'MACD_Sell_Signal_price'</span>] = MACD_Sell

我们还在策略中加入了风险因素。如果当前价格超出可接受的限制,或者当前价格超过指定的百分比,我们将出售。简单来说,我们在策略中添加了止损和追踪止损。

MACD_strategy = MACD_Strategy(data, <span>0.025</span>)
MACD_strategy

 输出:

Screenshot 2021-08-23 at 8.11.30 PM.png

我们已将风险承受能力水平设置为 2.5%,因此,例如,如果我们以 100 买入并且价格超过 97.5 (100 * (1 - 0.025)),我们将卖出。我们将跟踪止损,这意味着如果我们在 100 买入并且价格升至 110,我们的止损将是 107.25 (110 * (1 - 0.025))。

为了可视化 MACD 直方图,我们创建了一个简单的函数来插入布尔列。

<span><span>def</span> <span>MACD_color</span>(<span>data</span>):</span>
    MACD_color = []
    <span>for</span> i <span>in</span> range(<span>0</span>, len(data)):
        <span>if</span> data[<span>'MACDh_12_26_9'</span>][i] &gt; data[<span>'MACDh_12_26_9'</span>][i - <span>1</span>]:
            MACD_color.append(<span>True</span>)
        <span>else</span>:
            MACD_color.append(<span>False</span>)
    <span>return</span> MACD_color

data[<span>'positive'</span>] = MACD_color(data)
data

 可视化:

plt.rcParams.update({<span>'font.size'</span>: <span>10</span>})
fig, ax1 = plt.subplots(figsize=(<span>14</span>,<span>8</span>))
fig.suptitle(stocksymbols[<span>0</span>], fontsize=<span>10</span>, backgroundcolor=<span>'blue'</span>, color=<span>'white'</span>)
ax1 = plt.subplot2grid((<span>14</span>, <span>8</span>), (<span>0</span>, <span>0</span>), rowspan=<span>8</span>, colspan=<span>14</span>)
ax2 = plt.subplot2grid((<span>14</span>, <span>12</span>), (<span>10</span>, <span>0</span>), rowspan=<span>6</span>, colspan=<span>14</span>)
ax1.set_ylabel(<span>'Price in ₨'</span>)
ax1.plot(<span>'Adj Close'</span>,data=data, label=<span>'Close Price'</span>, linewidth=<span>0.5</span>, color=<span>'blue'</span>)
ax1.scatter(data.index, data[<span>'MACD_Buy_Signal_price'</span>], color=<span>'green'</span>, marker=<span>'^'</span>, alpha=<span>1</span>)
ax1.scatter(data.index, data[<span>'MACD_Sell_Signal_price'</span>], color=<span>'red'</span>, marker=<span>'v'</span>, alpha=<span>1</span>)
ax1.legend()
ax1.grid()
ax1.set_xlabel(<span>'Date'</span>, fontsize=<span>8</span>)

ax2.set_ylabel(<span>'MACD'</span>, fontsize=<span>8</span>)
ax2.plot(<span>'MACD_12_26_9'</span>, data=data, label=<span>'MACD'</span>, linewidth=<span>0.5</span>, color=<span>'blue'</span>)
ax2.plot(<span>'MACDs_12_26_9'</span>, data=data, label=<span>'signal'</span>, linewidth=<span>0.5</span>, color=<span>'red'</span>)
ax2.bar(data.index,<span>'MACDh_12_26_9'</span>, data=data, label=<span>'Volume'</span>, color=data.positive.map({<span>True</span>: <span>'g'</span>, <span>False</span>: <span>'r'</span>}),width=<span>1</span>,alpha=<span>0.8</span>)
ax2.axhline(<span>0</span>, color=<span>'black'</span>, linewidth=<span>0.5</span>, alpha=<span>0.5</span>)
ax2.grid()
plt.show()

filename.png

BB:布林带是交易世界中最常用的指标之一,因为它非常强大,但又非常简单。

它们由三行组成,

上布林带、中布林带、下布林带。布林带上轨线和下轨线绘制了与收盘价平均值相差两个标准差的图。这两个波段占价格行为的 80% 以上,因此任何高于或低于波段的价格都非常重要。

 策略:

<span><span>def</span> <span>bb_strategy</span>(<span>data</span>):</span>
    bbBuy = []
    bbSell = []
    position = <span>False</span>
    bb = ta.bbands(data[<span>'Adj Close'</span>], length=<span>20</span>,std=<span>2</span>)
    data = pd.concat([data, bb], axis=<span>1</span>).reindex(data.index)

    <span>for</span> i <span>in</span> range(len(data)):
        <span>if</span> data[<span>'Adj Close'</span>][i] &lt; data[<span>'BBL_20_2.0'</span>][i]:
            <span>if</span> position == <span>False</span> :
                bbBuy.append(data[<span>'Adj Close'</span>][i])
                bbSell.append(np.nan)
                position = <span>True</span>
            <span>else</span>:
                bbBuy.append(np.nan)
                bbSell.append(np.nan)
        <span>elif</span> data[<span>'Adj Close'</span>][i] &gt; data[<span>'BBU_20_2.0'</span>][i]:
            <span>if</span> position == <span>True</span>:
                bbBuy.append(np.nan)
                bbSell.append(data[<span>'Adj Close'</span>][i])
                position = <span>False</span> <span>#To indicate that I actually went there</span>
            <span>else</span>:
                bbBuy.append(np.nan)
                bbSell.append(np.nan)
        <span>else</span> :
            bbBuy.append(np.nan)
            bbSell.append(np.nan)

    data[<span>'bb_Buy_Signal_price'</span>] = bbBuy
    data[<span>'bb_Sell_Signal_price'</span>] = bbSell

    <span>return</span> data

在上面的函数中,我们调用了 pandas_ta 的“bbbands”函数,然后用我们的原始数据联系生成的数据帧。

我们构建了策略逻辑,当收盘价触及下轨线(BBL_ length_standard偏差)表示超卖情况时买入,当收盘价触及表示超买情景的上轨线(BBU_ length_standard偏差)时卖出。

存储上述功能:

<span>#storing the function</span>
data = bb_strategy(data)
data

 输出:

Screenshot 2021-08-17 at 10.26.38 PM.png

 可视化:

<span>#plot</span>
fig, ax1 = plt.subplots(figsize=(<span>14</span>,<span>8</span>))
fig.suptitle(stocksymbols[<span>0</span>], fontsize=<span>10</span>, backgroundcolor=<span>'blue'</span>, color=<span>'white'</span>)
ax1 = plt.subplot2grid((<span>14</span>, <span>8</span>), (<span>0</span>, <span>0</span>), rowspan=<span>8</span>, colspan=<span>14</span>)
ax2 = plt.subplot2grid((<span>14</span>, <span>12</span>), (<span>10</span>, <span>0</span>), rowspan=<span>6</span>, colspan=<span>14</span>)
ax1.set_ylabel(<span>'Price in ₨'</span>)
ax1.plot(data[<span>'Adj Close'</span>],label=<span>'Close Price'</span>, linewidth=<span>0.5</span>, color=<span>'blue'</span>)
ax1.scatter(data.index, data[<span>'bb_Buy_Signal_price'</span>], color=<span>'green'</span>, marker=<span>'^'</span>, alpha=<span>1</span>)
ax1.scatter(data.index, data[<span>'bb_Sell_Signal_price'</span>], color=<span>'red'</span>, marker=<span>'v'</span>, alpha=<span>1</span>)
ax1.legend()
ax1.grid()
ax1.set_xlabel(<span>'Date'</span>, fontsize=<span>8</span>)

ax2.plot(data[<span>'BBM_20_2.0'</span>], label=<span>'Middle'</span>, color=<span>'blue'</span>, alpha=<span>0.35</span>) <span>#middle band</span>
ax2.plot(data[<span>'BBU_20_2.0'</span>], label=<span>'Upper'</span>, color=<span>'green'</span>, alpha=<span>0.35</span>) <span>#Upper band</span>
ax2.plot(data[<span>'BBL_20_2.0'</span>], label=<span>'Lower'</span>, color=<span>'red'</span>, alpha=<span>0.35</span>) <span>#lower band</span>
ax2.fill_between(data.index, data[<span>'BBL_20_2.0'</span>], data[<span>'BBU_20_2.0'</span>], alpha=<span>0.1</span>)
ax2.legend(loc=<span>'upper left'</span>)
ax2.grid()
plt.show()

 输出:

filename.png

我们的策略基于这样的假设,即每当收盘价低于或高于布林带时,价格回归的可能性就很高,因此它可以用作信号,但不能完全依赖,因为可能存在推动股票的潜在事件。

 4. 结束语

这样一来,它就结束了!

技术分析领域本身非常广阔,因为指标太多了。

人们必须了解构建这些指标背后的基本概念/意图,才能通过组合其中一些指标或完全构建一个全新的指标来构建成功的交易策略。

随着我们在技术指标📉的帮助下深入研究算法交易领域,复杂性本身将在未来以微妙的幅度增加。不过,我希望你喜欢这篇文章!

您还可以在此处访问 GitHub 链接,直接在一个文件中查看整个代码。

感谢您的阅读;如果您到目前为止已经达到它,请喜欢这篇文章;它会鼓励我写更多的文章。请分享您的宝贵建议;我非常感谢您的诚实反馈!🙂

如果您对此有任何疑问或需要任何进一步的信息,请随时发表评论并联系。考虑订阅我的邮件列表,以便自动更新未来的文章。📬

💡

请注意,自 2021 年 11 月以来,我们没有在此博客上发表任何新帖子,您可以自由订阅邮件列表,但是,您也会被自动添加到新博客的 (thealtinvestor.in) 邮件列表中。

我很想通过邮件与您联系,或者您也可以在LinkedIn上找到我

如果您喜欢这篇文章,请考虑通过单击此处或下面的按钮为我买一本书📖。

订阅我们的时事通讯

直接在收件箱中阅读 Trade With Python 中的文章。订阅时事通讯,不要错过。

Written by

Utkarsh singhal

Published on

Trade With Python