Skip to main content
How Can We Help?

Search for answers or browse our knowledge base.

Return to Support Front Page

Categories
Print

N-PX Data (Institutional Votes)

We have processed all N-PX filings filed in 2024 since 6/1 – the date of the latest EDGAR update for these filings. This database has over 24 million recorded vote actions taken by institutional investors on shares for which they control the voting rights. The table below lists the fields in the database and a description of the content of the field. Below the table is an example Python script to more precisely filter and select relevant data.

Most of this data seems reasonable. However there are some clear anomalies. Please consider reading this blog post about how we handled the rows we identified as possibly reporting faulty data (Blog Post N-PX)

Path

S:/directEDGAR_DATA/npxdata.db

Table Name

npxdata

Field

Description

FILER_CIK

Central Index Key of the entity that made the filing

ACCESSION

ACCESSION number of the filing the data was pulled from - primarily used internally to allow us to identify data to be pulled from the db when an amended filing is made (N-PX/A)

FORM

N-PX ot N-PX/A

issuerName

The name of the subject company as reported by the filer - these have not been normalized

cusip

The CUSIP number of the issuer as reported by the filer

meetingDate

The date of the meeting when the proposal was put to a vote.

voteDescription

The proposal as reported by the issuer - generally this should match the language used on the voting card - however, if for example the voting card combines the votes for directors into one item - the filer is to separately report on the votes for each individual director.

sharesVoted

This represents the number of shares that were reported as voted on the proposal.  This value is a real number.

sharesVoted_ORG

The data is initially read as text - this is the original text string that was transformed to the sharesVoted.  We use this value in conjunction with the real version (SharesVoted) for testing purposes to evaluate the quality of the source data.

sharesOnLoan

The number of shares of this issuer the filer has loaned out - this is stored as a real number in the database.

sharesOnLoan_ORG

sharesOnLoan - this is the original text value as parsed from the filing.

voteSource

ISSUER/SECURITY HOLDER - the instigator/originator for the proposal

directorElections

1/0 - based on filer classification

section14ASayOnPayVotes

1/0 - based on filer classification

auditRelated

1/0 - based on filer classification

investmentCompanyMatters

1/0 - based on filer classification

shareholderRightsAndDefenses

1/0 - based on filer classification

extraordinaryTransactions

1/0 - based on filer classification

capitalStructure

1/0 - based on filer classification

compensation

1/0 - based on filer classification

corporateGovernance

1/0 - based on filer classification

environmentOrClimate

1/0 - based on filer classification

humanRightsOrHumanCapitalWorkforce

1/0 - based on filer classification

diversityEquityandInclusion

1/0 - based on filer classification

otherSocialIssues

1/0 - based on filer classification

otherVoteDescription

Filer determined clarification of the voting issue

voteRecord_howVoted

FOR/AGAINST/ABSTAIN

voteRecord_sharesVoted

Number of shares in this tranche voted in the manner of howVoted - this value is a real number.

voteRecord_sharesVoted_ORG

This is the as originally reported text version of the originally reported sharesVoted.

voteRecord_managementRecommendation

FOR/AGAINST/NONE to reflect the position taken by the filer relative to the recommendation by management.  A FOR value indicates that the vote by the filer (FOR/AGAINST) matched the recommendation of management. The SEC guidance explicitly states that the value should be NONE when management has not taken a position.

This code sample selects all rows from the table where the vote was classified as relating to a Say-On-Pay issue and where the filer (institutional investor) voted against management. The results are saved in a csv file to then compress and download and explore as needed. There are over 200K rows in this file.

import sqlite3
import csv

# Define the database path and output CSV file
db_path = r"S:\directEDGAR_DATA\npxdata.db"
output_csv = r"D:\PhotonUser\My Files\Temporary Files\filtered_data.csv"

try:
    # Connect to the SQLite database
    conn = sqlite3.connect(db_path)
    cursor = conn.cursor()

    # Execute the query to select rows with the specified conditions
    query = """
    SELECT * FROM npxdata 
    WHERE section14ASayOnPayVotes = 1 
    AND voteRecord_howVoted = 'AGAINST'
    """
    cursor.execute(query)

    # Fetch all matching rows
    rows = cursor.fetchall()

    # Get the column names from the cursor description
    column_names = [description[0] for description in cursor.description]

    # Open the CSV file for writing
    with open(output_csv, mode='w', newline='', encoding='utf-8') as csvfile:
        writer = csv.DictWriter(csvfile, fieldnames=column_names)
        writer.writeheader()

        for row in rows:
            try:
                # Create a dictionary mapping column names to row values
                row_dict = dict(zip(column_names, row))
                # Write the row to the CSV file
                writer.writerow(row_dict)
            except Exception as e:
                print(f"Error writing row: {row_dict} - {e}")

    print(f"Data successfully written to {output_csv}")

except sqlite3.Error as e:
    print(f"Database error: {e}")
except Exception as e:
    print(f"Error: {e}")
finally:
    # Close the database connection
    if conn:
        conn.close()

Table of Contents