基于 Python 和 FinBERT 的 AI 股票筛选器

2024年6月12日 462点热度 0人点赞 0条评论

寻找股票进行投资可能是一个漫长而乏味的过程。如果我们同时使用 AI 和 Python 来创建一个可以加快这一过程的程序会怎么样?在这篇博文中,我将探讨如何使用finvizfinance Python 库来查找“被低估”的股票。然后,我将介绍一种使用 FinBERT(一种预先训练的 NLP 模型)进行情绪分析的方法——可以对这些“被低估”的股票进行分析。

准备工作

首先,我们需要安装所需的库并导入它们。finviz.com是一个提供各种股票分析工具的网站,例如免费的股票筛选器 – 在这里,导入 finvizfinance 的筛选器对象,该对象返回筛选器结果“概述”部分的 Pandas 数据框。

from finvizfinance.screener.overview import Overview

然后,导入pandascsvos库。这些主要用于操作 csv 文件。

import pandas as pd
import csv
import os

筛选潜在股票

现在,按照价值投资方法,目标是整理一份可能被低估的股票清单以供研究。为此,创建一个使用 finvizfinance 库向在线股票筛选器发出请求的函数。以下函数将执行此操作:

def get_undervalued_stocks():
    """
    Returns a list of tickers with:
    
    - Positive Operating Margin
    - Debt-to-Equity ratio under 1
    - Low P/B (under 1)
    - Low P/E ratio (under 15)
    - Low PEG ratio (under 1)
    - Positive Insider Transactions
    """
    foverview = Overview()

作为价值投资者,我们一般寻找市净率 (P/B) 较低的股票。这表明股价低于公司资产的价值,意味着股票被低估——假设公司没有陷入财务困境。我们还可以查询营业利润率,这是一个很好的指标,可以表明一家公司的管理有多好,以及它从销售中赚取利润的效率有多高。此外,我们希望债务权益比低于 1,这意味着公司的风险较低。

另一个好的指标是最近的市盈率 (P/E) 低于平均水平。因此,我们需要低市盈率和低市盈率增长率 (PEG)。市盈率将公司的股价与其每股收益联系起来。因此,高市盈率可能意味着公司“估值过高”。

最后,我们还好寻找积极的内幕交易。积极的内幕交易是指内部人员购买自己公司的股票。经理和董事对他们经营的公司有独特的了解,因此,如果他们购买此类股票,那么可以合理地假设该公司的前景看好。

    filters_dict = {'Debt/Equity':'Under 1', 
                    'PEG':'Low (<1)', 
                    'Operating Margin':'Positive (>0%)', 
                    'P/B':'Low (<1)',
                    'P/E':'Low (<15)',
                    'InsiderTransactions':'Positive (>0%)'}

这些参数并不完全全面;它们可能针对特定行业,也可能过于严格,甚至在某些情况下过于宽泛。了解您想要投资的业务对于价值投资者来说也很重要,因此您可能需要定义自己的选股策略并研究更个性化的参数。以下是 FINVIZ.com 免费在线股票筛选器的所有可能参数列表:

parameters = ['Exchange', 'Index', 'Sector', 'Industry', 'Country', 'Market Cap.',
        'P/E', 'Forward P/E', 'PEG', 'P/S', 'P/B', 'Price/Cash', 'Price/Free Cash Flow',
        'EPS growththis year', 'EPS growthnext year', 'EPS growthpast 5 years', 'EPS growthnext 5 years',
        'Sales growthpast 5 years', 'EPS growthqtr over qtr', 'Sales growthqtr over qtr',
        'Dividend Yield', 'Return on Assets', 'Return on Equity', 'Return on Investment',
        'Current Ratio', 'Quick Ratio', 'LT Debt/Equity', 'Debt/Equity', 'Gross Margin',
        'Operating Margin', 'Net Profit Margin', 'Payout Ratio', 'InsiderOwnership', 'InsiderTransactions',
        'InstitutionalOwnership', 'InstitutionalTransactions', 'Float Short', 'Analyst Recom.',
        'Option/Short', 'Earnings Date', 'Performance', 'Performance 2', 'Volatility', 'RSI (14)',
        'Gap', '20-Day Simple Moving Average', '50-Day Simple Moving Average',
        '200-Day Simple Moving Average', 'Change', 'Change from Open', '20-Day High/Low',
        '50-Day High/Low', '52-Week High/Low', 'Pattern', 'Candlestick', 'Beta',
        'Average True Range', 'Average Volume', 'Relative Volume', 'Current Volume',
        'Price', 'Target Price', 'IPO Date', 'Shares Outstanding', 'Float']

现在已经设置了筛选器的过滤器,可以连接到 finviz 筛选器 API 并收集所需的数据。

    foverview.set_filter(filters_dict=filters_dict)
    df_overview = foverview.screener_view()
    if not os.path.exists('out'): #ensures you have an 'out' folder ready
        os.makedirs('out')
    df_overview.to_csv('out/Overview.csv', index=False)
    tickers = df_overview['Ticker'].to_list()
    return tickers

#print(get_undervalued_stocks())

运行上述程序(如果取消注释最后一行)会输出一个股票代码列表,如果进行进一步分析,该列表可以帮助您形成关注列表。建议在匆忙得出结论之前,您可能希望花一些时间手动查看这些公司 – 例如,重点关注损益表或资产负债表。

['AMPY', 'BOOM', 'BWB', 'CAAS', 'CNX', 'HAFC', 'HTLF', 'SASR', 'SPNT', 'TCBX']

另外还会在“out”文件夹中找到一个 csv 文件,其中包含这些股票的概览。

使用金融 BERT 进行情绪分析(Sentiment Analysis)

现在,我们有了一份“被低估”的股票清单,可以投资。但是,了解媒体对公司的看法也很重要,最重要的是,了解其股票本身。虽然优秀的价值投资者不应该随波逐流,但了解股票的观点是明智的——因为这有助于评估其价值的根本原因,无论是高估还是低估。

因此,我们需要编写一个程序,以便获取股票筛选器提供的与每只股票相关的最新新闻文章列表。该程序将输出文章的标题、发布日期以及文章中传达的总体情绪——让您可以轻松概览对股票的总体情绪。

准备工作

首先,需要安装并导入所需的依赖项。

Transformers库提供了数千个预先训练的模型,用于对文本、视觉和音频等不同模态执行任务。为了对金融新闻文章进行情感分析,我们将使用ProsusAI训练模型FinBERT。该模型是通过在金融领域进一步训练 Google 的语言模型 BERT 而建立的。

from transformers import pipeline

要从 Yahoo! 下载市场数据新闻,财经API 我们将使用yfinance Python 库。

import yfinance as yf

接下来,我们导入Goose(一个 Html 内容/文章提取器,适用于 Python3 的网页抓取工具),以及 requests 库的 get 方法来发送 HTTP 请求并获取财经新闻文章数据。

from goose3 import Goose
from requests import get

获取财经新闻文章数据

我们定义一个函数,以股票行情机作为输入,并返回一个包含 3 列的 Pandas 数据框:发布日期、文章标题、文章情感。

Ticker模块将允许您 获取给定股票的最新财经新闻列表。接下来,实例化 Goose 文章提取器和预训练 NLP 模型的管道。

def get_ticker_news_sentiment(ticker):
    """
    Returns a Pandas dataframe of the given ticker's most recent news article headlines,
    with the overal sentiment of each article.

    Args:
        ticker (string)

    Returns:
        pd.DataFrame: {'Date', 'Article title', Article sentiment'}
    """
    ticker_news = yf.Ticker(ticker)
    news_list = ticker_news.get_news()
    extractor = Goose()
    pipe = pipeline("text-classification", model="ProsusAI/finbert")

调用 get_news() 方法会返回一个字典列表。每个字典都包含有关新闻文章的信息,例如文章的链接和标题。对于列表中的每个字典(文章),在使用 Goose 提取器提取其文本和日期之前,先向文章的链接发送请求。

如果文章的文本超过 512 个单词,则标记索引序列长度将长于FinBERT模型指定的最大序列长度。通过模型运行这样的序列将导致索引错误。虽然有一种方法可以对超过 512 个标记的长文本进行情感分析,但由于本文的重点,这种方法将不作详细说明。

通过将文本传递到管道,模型将为三个标签提供 softmax 输出:正面、负面或中性。概率最大的“标签”将被返回。这将描述给定文本的整体主导情绪。

最后,此函数将“数据”列表转换为 Pandas 数据框并返回它:

    data = []
    for dic in news_list:
        title = dic['title']
        response = get(dic['link'])
        article = extractor.extract(raw_html=response.content)
        text = article.cleaned_text
        date = article.publish_date
        if len(text) > 512:
            data.append({'Date':f'{date}',
                         'Article title':f'{title}',
                         'Article sentiment':'NaN too long'})
        else:
            results = pipe(text)
            #print(results)
            data.append({'Date':f'{date}',
                         'Article title':f'{title}',
                         'Article sentiment':results[0]['label']})
    df = pd.DataFrame(data)
    return df

现在,让我们将这个新函数用于之前获得的股票行情。首先,您需要一个小的辅助函数,它将股票行情的新闻情绪 Pandas DataFrame转换为存储在 out 目录中的 csv 文件。

def generate_csv(ticker):
    get_ticker_news_sentiment(ticker).to_csv(f'out/{ticker}.csv', index=False)

最后,我们对之前获得的每个股票代码调用此函数:

undervalued = get_undervalued_stocks()
for ticker in undervalued:
    generate_csv(ticker)

这将创建或更新您的输出目录,其中包含一个概览文件,其中包含所有“被低估”股票的一般数据,以及一个 csv 文件,其中包含对股票的近期情绪的简单概览。

例如,仅通过查看Amplify Energy Insiders (AMPY)上的最新金融文章标题,似乎其他人也同意该股票“被低估了”。

这样,我们的目标就完成了。通过运行这个程序,我们获得了“被低估”股票的列表、这些股票的概述以及最近的财经新闻文章列表——以及它们的整体情绪。通过这些信息,我们可以评估某支股票是否值得买入。

予人玫瑰,手有余香。如果您觉得本文对您有帮助,请点赞或打赏。

文章评论

您需要 登录 之后才可以评论