削减企业价值/息税折旧及摊销前利润、出售购买股票和雅虎金融净借款

2024-06-16 11:50:25 发布

您现在位置:Python中文网/ 问答频道 /正文

我从Github上取了一个Python script来分析和排名股票。我终于开始运行了,但不幸的是,企业价值/息税折旧及摊销前利润和股东收益率正在填充它们的默认值,分别是1000&0。在

在过去的几天里,我一直在尝试故障排除,在这个过程中我学到了很多东西,但不幸的是没有运气。。我认为它试图从“Scraper”部分不存在的行中提取数据,或者引用不正确的HTML。我将粘贴这两个代码片段,我认为错误可能就在这两个代码片段中,尽管上面链接了其余的文件。在

Main文件

from sys import stdout

from Stock import Stock
import Pickler
import Scraper
import Rankings
import Fixer
import Writer

# HTML error code handler - importing data is a chore, and getting a connection
# error halfway through is horribly demotivating. Use a pickler to serialize
# imported data into a hot-startable database.
pklFileName = 'tmpstocks.pkl'
pickler = Pickler.Pickler()

# Check if a pickled file exists. Load it if the user requests. If no file
# loaded, stocks is an empty list.
stocks = pickler.loadPickledFile(pklFileName)

# Scrape data from FINVIZ. Certain presets have been established (see direct
# link for more details)
url = 'http://finviz.com/screener.ashx?v=152&f=cap_smallover&' + \
    'ft=4&c=0,1,2,6,7,10,11,13,14,45,65'
html = Scraper.importHtml(url)

# Parse the HTML for the number of pages from which we'll pull data
nPages = -1
for line in html:
    if line[0:40] == '<option selected="selected" value=1>Page':
        # Find indices
        b1 = line.index('/') + 1
        b2 = b1 + line[b1:].index('<')
        # Number of pages containing stock data
        nPages = int(line[b1:b2])
        break

# Parse data from table on the first page of stocks and store in the database,
# but only if no data was pickled
if pickler.source == Pickler.PickleSource.NOPICKLE:
    Scraper.importFinvizPage(html, stocks)

# The first page of stocks (20 stocks) has been imported. Now import the
# rest of them
source = Pickler.PickleSource.FINVIZ
iS = pickler.getIndex(source, 1, nPages + 1)

for i in range(iS, nPages + 1):
    try:
        # Print dynamic progress message
        print('Importing FINVIZ metrics from page ' + str(i) + ' of ' + \
            str(nPages) + '...', file=stdout, flush=True)

        # Scrape data as before
        url = 'http://finviz.com/screener.ashx?v=152&f=cap_smallover&ft=4&r=' + \
            str(i*20+1) + '&c=0,1,2,6,7,10,11,13,14,45,65'
        html = Scraper.importHtml(url)

        # Import stock metrics from page into a buffer
        bufferList = []
        Scraper.importFinvizPage(html, bufferList)

        # If no errors encountered, extend buffer to stocks list
        stocks.extend(bufferList)
    except:
        # Error encountered. Pickle stocks for later loading
        pickler.setError(source, i, stocks)
        break


# FINVIZ stock metrics successfully imported
print('\n')

# Store number of stocks in list
nStocks = len(stocks)

# Handle pickle file
source = Pickler.PickleSource.YHOOEV
iS = pickler.getIndex(source, 0, nStocks)

# Grab EV/EBITDA metrics from Yahoo! Finance
for i in range(iS, nStocks):
    try:
        # Print dynamic progress message
        print('Importing Key Statistics for ' + stocks[i].tick +
            ' (' + str(i) + '/' + str(nStocks - 1) + ') from Yahoo! Finance...', \
            file=stdout, flush=True)

        # Scrape data from Yahoo! Finance
        url = 'http://finance.yahoo.com/q/ks?s=' + stocks[i].tick + '+Key+Statistics'
        html = Scraper.importHtml(url)

        # Parse data
        for line in html:
            # Check no value
            if 'There is no Key Statistics' in line or \
            'Get Quotes Results for' in line or \
            'Changed Ticker Symbol' in line or \
            '</html>' in line:
                # Non-financial file (e.g. mutual fund) or
                # Ticker not located or
                # End of html page
                stocks[i].evebitda = 1000
                break
            elif 'Enterprise Value/EBITDA' in line:
                # Line contains EV/EBITDA data
                evebitda = Scraper.readYahooEVEBITDA(line)
                stocks[i].evebitda = evebitda
                break
    except:
        # Error encountered. Pickle stocks for later loading
        pickler.setError(source, i, stocks)
        break


# Yahoo! Finance EV/EBITDA successfully imported
print('\n')

# Handle pickle file
source = Pickler.PickleSource.YHOOBBY
iS = pickler.getIndex(source, 0, nStocks)

# Grab BBY metrics from Yahoo! Finance
for i in range(iS, nStocks):
    try:
        # Print dynamic progress message
        print('Importing Cash Flow for ' + stocks[i].tick +
            ' (' + str(i) + '/' + str(nStocks - 1) + ') from Yahoo! Finance...', \
            file=stdout, flush=True)

        # Scrape data from Yahoo! Finance
        url = 'http://finance.yahoo.com/q/cf?s=' + stocks[i].tick + '&ql=1'
        html = Scraper.importHtml(url)

        # Parse data
        totalBuysAndSells = 0
        for line in html:
            # Check no value
            if 'There is no Cash Flow' in line or \
            'Get Quotes Results for' in line or \
            'Changed Ticker Symbol' in line or \
            '</html>' in line:
                # Non-financial file (e.g. mutual fund) or
                # Ticker not located or
                # End of html page
                break
            elif 'Sale Purchase of Stock' in line:
                # Line contains Sale/Purchase of Stock information
                totalBuysAndSells = Scraper.readYahooBBY(line)
                break

        # Calculate BBY as a percentage of current market cap
        bby = round(-totalBuysAndSells / stocks[i].mktcap * 100, 2)
        stocks[i].bby = bby
    except:
        # Error encountered. Pickle stocks for later loading
        pickler.setError(source, i, stocks)
        break


# Yahoo! Finance BBY successfully imported

if not pickler.hasErrorOccurred:
    # All data imported
    print('\n')
    print('Fixing screener errors...')

    # A number of stocks may have broken metrics. Fix these (i.e. assign out-of-
    # bounds values) before sorting
    stocks = Fixer.fixBrokenMetrics(stocks)

    print('Ranking stocks...')

    # Calculate shareholder Yield
    for i in range(nStocks):
        stocks[i].shy = stocks[i].div + stocks[i].bby

    # Time to rank! Lowest value gets 100
    rankPE = 100 * (1 - Rankings.rankByValue([o.pe for o in stocks]) / nStocks)
    rankPS = 100 * (1 - Rankings.rankByValue([o.ps for o in stocks]) / nStocks)
    rankPB = 100 * (1 - Rankings.rankByValue([o.pb for o in stocks]) / nStocks)
    rankPFCF = 100 * (1 - Rankings.rankByValue([o.pfcf for o in stocks]) / nStocks)
    rankEVEBITDA = 100 * (1 - Rankings.rankByValue([o.evebitda for o in stocks]) / nStocks)

    # Shareholder yield ranked with highest getting 100
    rankSHY = 100 * (Rankings.rankByValue([o.shy for o in stocks]) / nStocks)

    # Rank total stock valuation
    rankStock = rankPE + rankPS + rankPB + rankPFCF + rankEVEBITDA + rankSHY

    # Rank 'em
    rankOverall = Rankings.rankByValue(rankStock)
    # Calculate Value Composite - higher the better
    valueComposite = 100 * rankOverall / len(rankStock)
    # Reverse indices - lower index -> better score
    rankOverall = [len(rankStock) - 1 - x for x in rankOverall]

    # Assign to stocks
    for i in range(nStocks):
        stocks[i].rank = rankOverall[i]
        stocks[i].vc = round(valueComposite[i], 2)

    print('Sorting stocks...')

    # Sort all stocks by normalized rank
    stocks = [x for (y, x) in sorted(zip(rankOverall, stocks))]

    # Sort top decile by momentum factor. O'Shaughnessey historically uses 25
    # stocks to hold. The top decile is printed, and the user may select the top 25
    # (or any n) from the .csv file.
    dec = int(nStocks / 10)
    topDecile = []

    # Store temporary momentums from top decile for sorting reasons
    moms = [o.mom for o in stocks[:dec]]

    # Sort top decile by momentum
    for i in range(dec):
        # Get index of top momentum performer in top decile
        topMomInd = moms.index(max(moms))
        # Sort
        topDecile.append(stocks[topMomInd])
        # Remove top momentum performer from further consideration
        moms[topMomInd] = -100

    print('Saving stocks...')

    # Save momentum-weighted top decile
    topCsvPath = 'top.csv'
    Writer.writeCSV(topCsvPath, topDecile)

    # Save results to .csv
    allCsvPath = 'stocks.csv'
    Writer.writeCSV(allCsvPath, stocks)

    print('\n')
    print('Complete.')
    print('Top decile (sorted by momentum) saved to: ' + topCsvPath)
    print('All stocks (sorted by trending value) saved to: ' + allCsvPath)

刮刀

^{pr2}$

如果有人有任何意见或更好的方法,比如beauthoulsoup,我会非常感激的!我很乐意接受任何有帮助的教程。我的目的是提高我的编程能力和一个有效的股票筛选。在


Tags: oroftheinfromfordatahtml
1条回答
网友
1楼 · 发布于 2024-06-16 11:50:25

在Python和Matlab中,我也遇到了同样的问题。为了解决这个问题,我在VBA中编写了一个宏,通过访问每个股票的关键统计页面来获取雅虎的所有EV/EBITDA数据。然而,市值超过2亿美元的3000多只股票要花上大约一天的时间,这并不实际。在

我试着在网上的各种股票筛选工具上找到企业价值/息税折旧及摊销前利润,但他们要么不报告,要么只让你免费下载几百只股票的数据。Busy Stock的筛选程序在这方面似乎是最好的,但他们的企业价值/息税折旧及摊销前利润(EV/EBITDA)数据与雅虎的不一致,这让我担心他们使用的方法不同。在

一个解决方案和我给你的建议是使用Quantopian中的趋势值算法,它是免费的。您可以在这里找到代码:https://www.quantopian.com/posts/oshaugnessy-what-works-on-wall-street Quantopian将允许您将算法回溯到2002年,并对其进行实时测试。在

相关问题 更多 >