Example #1
0
def test_extract_report_owner_form3_collection(test_form3_collection,
                                               doc_num: int):
    """
    Validate Form3 extraction code against a random sample of documents
    :param test_form3_collection:
    :return:
    """
    file = list(test_form3_collection.glob("*.txt"))[doc_num]
    doc = Form3(file)
    assert doc.filename == file.name
    fields_list = doc.report_owners
    assert len(fields_list) > 0
    for idx, fields in enumerate(fields_list):
        assert (len(fields)) == 19
        assert fields["filename"] == file.name
        assert fields["order"] == f"{idx+1}"
        assert fields["type"] == "reportingOwner"
        assert fields["index"] == f"reportingOwner{idx+1}"

        assert validate(file, fields["rpt_owner_cik"], r"\d{10}")
        assert validate(file, fields["rpt_owner_name"], r".+")
        assert validate(file, fields["rpt_owner_city"], r".+")
        assert validate(file,
                        fields["is_director"],
                        r"[10]",
                        none_allowed=True)
        assert validate(file, fields["is_officer"], r"[10]", none_allowed=True)
        assert validate(file,
                        fields["is_ten_percent_owner"],
                        r"[10]",
                        none_allowed=True)
        assert validate(file, fields["is_other"], r"[10]", none_allowed=True)
Example #2
0
def test_extract_report_owner_form3(test_form3):
    """
    Validate Form3 extraction code against a single detailed example
    :param test_form3:
    :return:
    """
    doc = Form3(test_form3)

    assert doc.accession_num == "0001209191-20-054135"
    assert doc.filename == test_form3.name

    fields_list = doc.report_owners
    assert len(fields_list) == 1
    assert len(fields_list[0]) == 19

    assert fields_list[0]["filename"] == test_form3.name
    assert fields_list[0]["accession_num"] == doc.accession_num
    assert fields_list[0]["order"] == "1"
    assert fields_list[0]["type"] == "reportingOwner"
    assert fields_list[0]["index"] == "reportingOwner1"
    assert fields_list[0]["rpt_owner_cik"] == "0001676526"
    assert fields_list[0]["rpt_owner_name"] == "Lawler John T."
    assert fields_list[0]["rpt_owner_street1"] == "ONE AMERICAN ROAD"
    assert fields_list[0]["rpt_owner_street2"] is None
    assert fields_list[0]["rpt_owner_city"] == "DEARBORN"
    assert fields_list[0]["rpt_owner_state"] == "MI"
    assert fields_list[0]["rpt_owner_zip_code"] == "48126"
    assert fields_list[0]["rpt_owner_state_descr"] is None
    assert fields_list[0]["is_director"] == "0"
    assert fields_list[0]["is_officer"] == "1"
    assert fields_list[0]["is_ten_percent_owner"] == "0"
    assert fields_list[0]["is_other"] == "0"
    assert fields_list[0]["officer_title"] == "Vice President, CFO"
    assert fields_list[0]["other_text"] is None
Example #3
0
def test_extract_derivative_trans_form3_collection(test_form3_collection, doc_num: int):
    """
    Validate Form3 extraction code against a random sample of documents
    :param test_form3_collection:
    :return:
    """

    file = list(test_form3_collection.glob("*.txt"))[doc_num]
    doc = Form3(file)
    assert doc.filename == file.name
    fields_list = doc.derivatives
    assert len(fields_list) >= 0
    for idx, fields in enumerate(fields_list):
        assert (len(fields)) == 12
        assert fields["filename"] == file.name
        assert fields["accession_num"] == doc.accession_num
        assert fields["order"] == f"{idx+1}"
        assert fields["type"] == "derivHolding"
        assert fields["index"] == f"derivHolding{idx+1}"

        assert validate(file, fields["accession_num"], r"[\d-]+")
        assert validate(file, fields["security_title"], r".+")
        assert validate(file, fields["conversion_or_exercise_price"], r"[\d+\.]*")
        assert validate(file, fields["exercise_date"], r"(\d\d\d\d-\d\d-\d\d)?")
        assert validate(file, fields["expiration_date"], r"(\d\d\d\d-\d\d-\d\d)?")
        assert validate(file, fields["underlying_security_title"], r".+")
        assert validate(file, fields["underlying_security_shares"], r"[\d+\.]+")
        assert validate(file, fields["direct_or_indirect_ownership"], r"[DI]")
Example #4
0
def test_extract_doclevel_form3_collection(test_form3_collection):
    """
    Validate Form3 extraction code against a random sample of documents
    :param test_form3_collection:
    :return:
    """
    for file in test_form3_collection.glob("*.txt"):
        doc = Form3(file)
        assert doc.filename == file.name
        fields = doc.doc_info
        assert len(fields) == 19
        assert fields["filename"] == file.name
        assert fields["schema_version"] == "X0206"
        assert fields["document_type"] == "3"

        assert validate(file, fields["accession_num"], r"[\d-]+")
        assert validate(file, fields["sec_accept_datetime"], r"\d{14,14}")
        assert validate(file, fields["sec_file_num"], r"[\d-]+")
        assert validate(file, fields["doc_count"], r"\d+")
        assert validate(file, fields["filed_date"], r"\d{8,8}")
        assert validate(file, fields["conformed_period_of_report"], r"\d{8,8}")
        assert validate(file, fields["change_date"], r"\d{8,8}")
        assert validate(file, fields["period_of_report"], r"\d\d\d\d-\d\d-\d\d")
        assert validate(
            file, fields["not_subject_to_section_16"], r"[10]", none_allowed=True
        )
        assert validate(file, fields["issuer_cik"], r"\d+")
        assert validate(file, fields["issuer_name"], r".+")
        assert validate(file, fields["issuer_trading_symbol"], r"[A-Z\.]+")
        assert validate(file, fields["regcik"], r"\d+")
        assert validate(file, fields["regsic"], r"\d\d\d\d", none_allowed=True)
        assert validate(file, fields["no_securities_owned"], r"[01]")
Example #5
0
def test_extract_doclevel_form3(test_form3):
    """
    Validate Form3 extraction code against a single detailed example
    :param test_form3:
    :return:
    """
    doc = Form3(test_form3)
    assert doc.accession_num == "0001209191-20-054135"
    assert doc.filename == test_form3.name
    fields = doc.doc_info
    assert len(fields) == 19
    assert fields["filename"] == test_form3.name
    assert fields["accession_num"] == doc.accession_num
    assert fields["sec_accept_datetime"] == "20201007163300"
    assert fields["sec_file_num"] == "001-03950"
    assert fields["doc_count"] == "2"
    assert fields["filed_date"] == "20201007"
    assert fields["conformed_period_of_report"] == "20201001"
    assert fields["change_date"] == "20201007"
    assert fields["schema_version"] == "X0206"
    assert fields["document_type"] == "3"
    assert fields["period_of_report"] == "2020-10-01"
    assert fields["not_subject_to_section_16"] is None
    assert fields["issuer_cik"] == "0000037996"
    assert fields["issuer_name"] == "FORD MOTOR CO"
    assert fields["issuer_trading_symbol"] == "F"
    assert fields["remarks"] is None
    assert fields["regcik"] == "0000037996"
    assert fields["regsic"] == "3711"
    assert fields["no_securities_owned"] == "0"
def test_extract_footnotes_form3(test_form3):
    """
    Validate Form3 extraction code against a single detailed example
    :param test_form3:
    :return:
    """
    doc = Form3(test_form3)

    assert doc.accession_num == "0001209191-20-054135"
    assert doc.filename == test_form3.name

    fields_list = doc.footnotes
    assert len(fields_list) == 19
    assert len(fields_list[0]) == 6

    assert fields_list[0]["filename"] == test_form3.name
    assert fields_list[0]["accession_num"] == doc.accession_num
    assert fields_list[0]["footnote"] == "F1"
    assert fields_list[0]["index"] == "derivHolding1"
    assert fields_list[0]["field"] == "conversionOrExercisePrice"
    assert fields_list[0]["text"][:27] == "These Ford Stock Fund Units"

    assert fields_list[18]["filename"] == test_form3.name
    assert fields_list[18]["accession_num"] == doc.accession_num
    assert fields_list[18]["footnote"] == "F9"
    assert fields_list[18]["index"] == "derivHolding9"
    assert fields_list[18]["field"] == "expirationDate"
    assert fields_list[18]["text"][:27] == "These Ford Restricted Stock"
Example #7
0
def create_doc(file: Path) -> Document:
    xmlpath = Document.xml_document_fields["document_type"]
    regex = re.compile(f"<{xmlpath}>(.+)</{xmlpath}>")
    form_type = regex.findall(file.read_text())[0]
    if form_type == "3":
        return Form3(file)
    elif form_type == "4":
        return Form4(file)
    elif form_type == "5":
        return Form5(file)
    else:
        typer.secho(f"WARNING: {form_type} not a supported form type",
                    fg=typer.colors.RED)
        return None
Example #8
0
def test_extract_derivative_trans_form3(test_form3):
    """
    Validate Form3 extraction code against a single detailed example
    :param test_form3:
    :return:
    """
    doc = Form3(test_form3)
    assert doc.accession_num == "0001209191-20-054135"
    assert doc.filename == test_form3.name

    fields_list = doc.derivatives
    assert len(fields_list) == 9

    assert len(fields_list[0]) == 12
    assert fields_list[0]["filename"] == test_form3.name
    assert fields_list[0]["accession_num"] == doc.accession_num
    assert fields_list[0]["order"] == "1"
    assert fields_list[0]["type"] == "derivHolding"
    assert fields_list[0]["index"] == "derivHolding1"
    assert fields_list[0]["security_title"] == "BEP Ford Stock Fund Units"
    assert fields_list[0]["conversion_or_exercise_price"] == ""
    assert fields_list[0]["exercise_date"] == ""
    assert fields_list[0]["expiration_date"] == ""
    assert (
        fields_list[0]["underlying_security_title"] == "Common Stock, $0.01 par value"
    )
    assert fields_list[0]["underlying_security_shares"] == "65"
    assert fields_list[0]["direct_or_indirect_ownership"] == "D"

    assert len(fields_list[8]) == 12
    assert fields_list[8]["filename"] == test_form3.name
    assert fields_list[8]["accession_num"] == doc.accession_num
    assert fields_list[8]["order"] == "9"
    assert fields_list[8]["type"] == "derivHolding"
    assert fields_list[8]["index"] == "derivHolding9"
    assert fields_list[8]["security_title"] == "Ford Stock Units"
    assert fields_list[8]["conversion_or_exercise_price"] == ""
    assert fields_list[8]["exercise_date"] == ""
    assert fields_list[8]["expiration_date"] == ""
    assert (
        fields_list[8]["underlying_security_title"] == "Common Stock, $0.01 par value"
    )
    assert fields_list[8]["underlying_security_shares"] == "247533"
    assert fields_list[8]["direct_or_indirect_ownership"] == "D"
Example #9
0
def create_doc(file: Path) -> Union[None, Document]:
    """
    A factory function returns a Document object with the right subtype.
    :param file: The file object that is the source of the Document
    :return: A Document object
    """
    xmlpath = Document.xml_document_fields["document_type"]
    regex = re.compile(f"<{xmlpath}>(.+)</{xmlpath}>")
    form_type = regex.findall(file.read_text())[0]
    if form_type == "3":
        return Form3(file)
    elif form_type == "4":
        return Form4(file)
    elif form_type == "5":
        return Form5(file)
    else:
        typer.secho(
            f"WARNING: {form_type} not a supported form type", fg=typer.colors.RED
        )
        return None
def test_extract_signature_form3(test_form3):
    """
    Validate Form3 extraction code against a single detailed example
    :param test_form3:
    :return:
    """
    doc = Form3(test_form3)

    assert doc.accession_num == "0001209191-20-054135"
    assert doc.filename == test_form3.name

    fields_list = doc.nonderivatives
    assert len(fields_list) == 1
    assert len(fields_list[0]) == 8
    assert fields_list[0]["filename"] == test_form3.name
    assert fields_list[0]["accession_num"] == doc.accession_num
    assert fields_list[0]["order"] == "1"
    assert fields_list[0]["type"] == "nonDerivHolding"
    assert fields_list[0]["index"] == "nonDerivHolding1"
    assert fields_list[0]["security_title"] == "Common Stock, $0.01 par value"
    assert fields_list[0]["shares_owned_following_transaction"] == "157800"
    assert fields_list[0]["direct_or_indirect_ownership"] == "D"
def test_extract_signature_form3_collection(test_form3_collection,
                                            doc_num: int):
    """
    Validate Form3 extraction code against a random sample of documents
    :param test_form3_collection:
    :return:
    """
    file = list(test_form3_collection.glob("*.txt"))[doc_num]
    doc = Form3(file)
    assert doc.filename == file.name
    fields_list = doc.signatures
    assert len(fields_list) > 0
    for idx, fields in enumerate(fields_list):
        assert (len(fields)) == 7
        assert fields["filename"] == file.name
        assert fields["accession_num"] == doc.accession_num
        assert fields["order"] == f"{idx+1}"
        assert fields["type"] == "signature"
        assert fields["index"] == f"signature{idx+1}"

        assert validate(file, fields["signature_name"], r".+")
        assert validate(file, fields["signature_date"], r"\d\d\d\d-\d\d-\d\d")
def test_extract_footnotes_form4_collection(test_form4_collection,
                                            doc_num: int):
    """
    Validate Form4 extraction code against a random sample of documents
    :param test_form4_collection:
    :return:
    """
    file = list(test_form4_collection.glob("*.txt"))[doc_num]
    doc = Form3(file)
    assert doc.filename == file.name
    fields_list = doc.footnotes
    assert len(fields_list) >= 0
    for idx, fields in enumerate(fields_list):
        assert (len(fields)) == 6
        assert fields["filename"] == file.name
        assert fields["accession_num"] == doc.accession_num

        assert validate(file, fields["accession_num"], r"[\d-]+")
        assert validate(file, fields["footnote"], r".+")
        assert validate(file, fields["index"], r"\w+\d+")
        assert validate(file, fields["field"], r"\w+")
        assert validate(file, fields["field"], r".+")
def test_extract_signature_form3(test_form3):
    """
    Validate Form3 extraction code against a single detailed example
    :param test_form3:
    :return:
    """
    doc = Form3(test_form3)

    assert doc.accession_num == "0001209191-20-054135"
    assert doc.filename == test_form3.name

    fields_list = doc.signatures
    assert len(fields_list) == 1
    assert len(fields_list[0]) == 7

    assert fields_list[0]["filename"] == test_form3.name
    assert fields_list[0]["accession_num"] == doc.accession_num
    assert fields_list[0]["order"] == "1"
    assert fields_list[0]["type"] == "signature"
    assert fields_list[0]["index"] == "signature1"
    assert fields_list[0][
        "signature_name"] == "Jerome F. Zaremba,\nAttorney-in-Fact"
    assert fields_list[0]["signature_date"] == "2020-10-07"
def test_extract_nonderivatives_form3_collection(test_form3_collection,
                                                 doc_num: int):
    """
    Validate Form3 extraction code against a random sample of documents
    :param test_form3_collection:
    :return:
    """
    file = list(test_form3_collection.glob("*.txt"))[doc_num]
    doc = Form3(file)
    assert doc.filename == file.name
    fields_list = doc.nonderivatives
    assert len(fields_list) >= 0
    for idx, fields in enumerate(fields_list):
        assert (len(fields)) == 8
        assert fields["filename"] == file.name
        assert fields["accession_num"] == doc.accession_num
        assert fields["order"] == f"{idx+1}"
        assert fields["type"] == "nonDerivHolding"
        assert fields["index"] == f"nonDerivHolding{idx+1}"

        assert validate(file, fields["security_title"], r".+")
        assert validate(file, fields["shares_owned_following_transaction"],
                        r"[\d\.]+")
        assert validate(file, fields["direct_or_indirect_ownership"], r"[DI]")