sec-api.ioSEC API by D2V
FilingsPricingSandboxDocs
Log inGet Free API Key
API Documentation
Introduction

Filing Query API
Full-Text Search API
Stream API
Download & PDF Generator API
XBRL-to-JSON Converter 
Extractor API 

Form ADV API - Investment Advisers

Form 3/4/5 API - Insider Trading
Form 144 API - Restricted Sales
Form 13F API - Institut. Holdings
Form 13D/13G API - Activist Invst.
Form N-PORT API - Mutual Funds

Form N-CEN API - Annual Reports
Form N-PX API - Proxy Voting

Form S-1/424B4 API - IPOs, Notes
Form C API - Crowdfunding
Form D API - Private Sec. Offerings
Form 1-A/1-K/1-Z - Reg A Offerings

Form 8-K API - Item 4.01
Form 8-K API - Item 4.02
Form 8-K API - Item 5.02

Executive Compensation API
Directors & Board Members
Company Subsidiaries
Outstanding Shares & Public Float

SEC Enforcement Actions
SEC Litigation Releases
SEC Administrative Proceedings
Overview
Example: Python
AAER Database API
SRO Filings Database

CIK, CUSIP, Ticker Mapping API
EDGAR Entities Database

Financial Statements

Analysis of SEC Administrative Proceedings with Python

Open In Colab   Download Notebook

On this page:
  • Quick Start
    • Data Loading
      • Proceedings by Year and Month
        • Proceedings by Year and Settlement Type
          • Proceedings by Year And Count of Agreements to Pay Penalties
          • Penalty Amount Analysis
            • Penalty Amount by Year
              • Top 10 Penalty Amounts
                • Penalties by Type of Defendant
                • Proceedings by Category
                  • Requested Reliefs by Category
                    • Violated Securities Laws

                      This tutorial provides a step-by-step guide to accessing and analyzing SEC administrative proceedings using Python and the Administrative Proccedings API. The dataset for this tutorial contains all SEC administrative proceedings from 1995 to 2024, including parties involved, order types, penalties, and more.

                      The analysis will cover the following topics:

                      • Data loading, cleaning, and preprocessing
                      • Proceedings published per year and month
                      • Top 10 most common order types
                      • Penalty amounts per year and respondent type
                      • And more

                      Quick Start

                      !pip install sec-api
                      # NOTE: Replace with your own API key
                      API_KEY_SEC_API = "YOUR_API_KEY"
                      from sec_api import SecAdministrativeProceedingsApi

                      adminProceedingsApi = SecAdministrativeProceedingsApi(API_KEY_SEC_API)

                      searchRequest = {
                          "query": "releasedAt:[2024-01-01 TO 2024-12-31]",
                          "from": "0",
                          "size": "50",
                          "sort": [{"releasedAt": {"order": "desc"}}],
                      }

                      response = adminProceedingsApi.get_data(searchRequest)
                      proceedings = response["data"]

                      print(f"Loaded first {len(proceedings)} proceedings")
                      Loaded first 50 proceedings
                      import pandas as pd

                      df = pd.DataFrame(proceedings)
                      df.head()
                      Out[3]:
                      idreleasedAtreleaseNofileNumbersrespondentsrespondentsTextresourcestitlesummarytags...parallelActionsTakenByhasAgreedToSettlementhasAgreedToPayPenaltypenaltyAmountsrequestedReliefviolatedSectionsordersinvestigationConductedBylitigationLedByotherAgenciesInvolved
                      00ab80b58b2fcf40e7497aa0000759a372024-12-31T12:19:45-05:00[34-102060, AAER-4554][3-22386][{'name': 'Accell Audit & Compliance, PA', 'ty...Accell Audit & Compliance, PA[{'label': 'primary', 'url': 'https://www.sec....ORDER INSTITUTING PUBLIC ADMINISTRATIVE PROCEE...The SEC has instituted public administrative p...[fraudulent financial reporting, accounting mi......[]TrueTrue[{'penaltyAmount': '75000', 'penaltyAmountText...[][Section 10(b) of the Exchange Act, Rule 10b-5][Accell is suspended from appearing or practic...[][][]
                      10dbf2331563447a91e64b780772391152024-12-30T13:02:35-05:00[IA-6806][3-22385][{'name': 'Steven J. Susoeff', 'type': 'indivi...Steven J. Susoeff[{'label': 'primary', 'url': 'https://www.sec....ORDER INSTITUTING ADMINISTRATIVE PROCEEDINGS P...The SEC has instituted administrative proceedi...[fraudulent cherry-picking, investment adviser......[]TrueFalse[][][Sections 17(a) of the Securities Act of 1933,...[Respondent Susoeff is barred from association...[][][]
                      28ad2aaf148601d33de3460509dd08cec2024-12-27T17:12:33-05:00[34-102047, AAER-4553][3-22384][{'name': 'Christopher Hiestand', 'type': 'ind...Christopher Hiestand, CPA[{'label': 'primary', 'url': 'https://www.sec....ORDER INSTITUTING PUBLIC ADMINISTRATIVE PROCEE...The SEC has instituted public administrative p...[fraudulent financial reporting, accounting mi......[]TrueTrue[{'penaltyAmount': '50000', 'penaltyAmountText...[][Section 10(b) of the Exchange Act, Rule 10b-5][Hiestand is suspended from appearing or pract...[][][]
                      3804947f56e7146f94b3ce9bf64d8012a2024-12-23T14:42:30-05:00[34-102031][3-22383][{'name': 'Richard Brown', 'type': 'individual...Richard Brown[{'label': 'primary', 'url': 'https://www.sec....ORDER INSTITUTING ADMINISTRATIVE PROCEEDINGS P...The SEC has instituted administrative proceedi...[securities fraud, disclosure fraud]...[United States District Court for the Eastern ...TrueFalse[][disgorgement of profits, civil penalties][Section 17(a) of the Securities Act of 1933, ...[Respondent Brown is barred from association w...[][][]
                      491a2c34129c53e911759a959be1aa8292024-12-20T17:51:48-05:00[33-11349][3-22382][{'name': 'Tai Mo Shan Limited', 'type': 'comp...Tai Mo Shan Limited[{'label': 'primary', 'url': 'https://www.sec....ORDER INSTITUTING CEASE-AND-DESIST PROCEEDINGS...The SEC has instituted cease-and-desist procee...[unregistered securities, crypto, misleading c......[]TrueTrue[{'penaltyAmount': '73452756', 'penaltyAmountT...[disgorgement of profits, civil penalties][Sections 5(a) and 5(c) of the Securities Act,...[Respondent Tai Mo Shan cease and desist from ...[][][]

                      5 rows × 22 columns

                      print(df.info())
                      <class 'pandas.core.frame.DataFrame'>
                      RangeIndex: 50 entries, 0 to 49
                      Data columns (total 22 columns):
                       # Column Non-Null Count Dtype
                      --- ------ -------------- -----
                       0 id 50 non-null object
                       1 releasedAt 50 non-null object
                       2 releaseNo 50 non-null object
                       3 fileNumbers 50 non-null object
                       4 respondents 50 non-null object
                       5 respondentsText 50 non-null object
                       6 resources 50 non-null object
                       7 title 50 non-null object
                       8 summary 50 non-null object
                       9 tags 50 non-null object
                       10 entities 50 non-null object
                       11 complaints 50 non-null object
                       12 parallelActionsTakenBy 50 non-null object
                       13 hasAgreedToSettlement 50 non-null bool
                       14 hasAgreedToPayPenalty 50 non-null bool
                       15 penaltyAmounts 50 non-null object
                       16 requestedRelief 50 non-null object
                       17 violatedSections 50 non-null object
                       18 orders 50 non-null object
                       19 investigationConductedBy 50 non-null object
                       20 litigationLedBy 50 non-null object
                       21 otherAgenciesInvolved 50 non-null object
                      dtypes: bool(2), object(20)
                      memory usage: 8.0+ KB
                      None

                      Data Loading

                      import os
                      import json
                      import time
                      import random
                      import sys
                      from concurrent.futures import ThreadPoolExecutor
                      import pandas as pd
                      from sec_api import SecAdministrativeProceedingsApi

                      adminProceedingsApi = SecAdministrativeProceedingsApi(API_KEY_SEC_API)

                      YEARS = range(2024, 1994, -1) # from 2024 to 2004
                      TEMP_FILE_TEMPLATE = "./temp_file_{}.jsonl"
                      TARGET_FILE = "./sec-administrative-proceedings.jsonl"


                      def process_year(year):
                          backoff_time = random.randint(10, 800) / 1000
                          print(f"Starting year {year} with backoff time {backoff_time:,}s"); sys.stdout.flush()
                          time.sleep(backoff_time)

                          tmp_filename = TEMP_FILE_TEMPLATE.format(year)
                          tmp_file = open(tmp_filename, "a")

                          for month in range(12, 0, -1):
                              search_from = 0
                              month_counter = 0

                              while True:
                                  query = f"releasedAt:[{year}-{month:02d}-01 TO {year}-{month:02d}-31]"
                                  searchRequest = {
                                      "query": query,
                                      "from": search_from,
                                      "size": "50",
                                      "sort": [{"releasedAt": {"order": "desc"}}],
                                  }

                                  response = None
                                  try:
                                      response = adminProceedingsApi.get_data(searchRequest)
                                  except Exception as e:
                                      print(f"{year}-{month:02d} error: {e}"); sys.stdout.flush()
                                      continue

                                  if response == None or len(response["data"]) == 0:
                                      break

                                  search_from += 50
                                  month_counter += len(response["data"])
                                  jsonl_data = "\n".join([json.dumps(entry) for entry in response["data"]])
                                  tmp_file.write(jsonl_data + "\n")

                              print(f"Finished loading {month_counter} proceedings for {year}-{month:02d}")
                              sys.stdout.flush()

                          tmp_file.close()

                          return year



                      if not os.path.exists(TARGET_FILE):
                          with ThreadPoolExecutor(max_workers=4) as pool:
                              processed_years = list(pool.map(process_year, YEARS))
                          print("Finished processing all years.", processed_years)

                          # merge the temporary files into one final file
                          with open(TARGET_FILE, "a") as outfile:
                              for year in YEARS:
                                  temp_file = TEMP_FILE_TEMPLATE.format(year)
                                  if os.path.exists(temp_file):
                                      with open(temp_file, "r") as infile:
                                          outfile.write(infile.read())
                      else:
                          print("File already exists. Skipping download.")
                      File already exists. Skipping download.
                      # load JSONL into dataframe
                      df = pd.read_json(TARGET_FILE, lines=True)

                      # convert "releasedAt" to datetime and to EST timezone
                      df["releasedAt"] = pd.to_datetime(df["releasedAt"], utc=True)
                      df["releasedAt"] = df["releasedAt"].dt.tz_convert("US/Eastern")
                      df["releasedAtYear"] = df["releasedAt"].dt.year
                      df["releasedAtMonth"] = df["releasedAt"].dt.month
                      df["releasedAtYearMonth"] = df["releasedAt"].map(lambda x: x.strftime("%Y-%m"))
                      # Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday
                      df["releasedAtDay"] = df["releasedAt"].dt.day_name()
                      df["hasAgreedToSettlement"] = df["hasAgreedToSettlement"].astype(bool)
                      df["hasAgreedToPayPenalty"] = df["hasAgreedToPayPenalty"].astype(bool)
                      first_year = df["releasedAtYear"].min(); last_year = df["releasedAtYear"].max()

                      print(f"Loaded {len(df):,.0f} SEC administrative proceedings from {first_year} to {last_year}\n")
                      df.head()
                      Loaded 17,987 SEC administrative proceedings from 1995 to 2024

                      Out:
                      idreleasedAtreleaseNofileNumbersrespondentsrespondentsTextresourcestitlesummarytags...requestedReliefviolatedSectionsordersinvestigationConductedBylitigationLedByotherAgenciesInvolvedreleasedAtYearreleasedAtMonthreleasedAtYearMonthreleasedAtDay
                      00ab80b58b2fcf40e7497aa0000759a372024-12-31 12:19:45-05:00[34-102060, AAER-4554][3-22386][{'name': 'Accell Audit & Compliance, PA', 'ty...Accell Audit & Compliance, PA[{'label': 'primary', 'url': 'https://www.sec....ORDER INSTITUTING PUBLIC ADMINISTRATIVE PROCEE...The SEC has instituted public administrative p...[fraudulent financial reporting, accounting mi......[][Section 10(b) of the Exchange Act, Rule 10b-5][Accell is suspended from appearing or practic...[][][]2024122024-12Tuesday
                      10dbf2331563447a91e64b780772391152024-12-30 13:02:35-05:00[IA-6806][3-22385][{'name': 'Steven J. Susoeff', 'type': 'indivi...Steven J. Susoeff[{'label': 'primary', 'url': 'https://www.sec....ORDER INSTITUTING ADMINISTRATIVE PROCEEDINGS P...The SEC has instituted administrative proceedi...[fraudulent cherry-picking, investment adviser......[][Sections 17(a) of the Securities Act of 1933,...[Respondent Susoeff is barred from association...[][][]2024122024-12Monday
                      28ad2aaf148601d33de3460509dd08cec2024-12-27 17:12:33-05:00[34-102047, AAER-4553][3-22384][{'name': 'Christopher Hiestand', 'type': 'ind...Christopher Hiestand, CPA[{'label': 'primary', 'url': 'https://www.sec....ORDER INSTITUTING PUBLIC ADMINISTRATIVE PROCEE...The SEC has instituted public administrative p...[fraudulent financial reporting, accounting mi......[][Section 10(b) of the Exchange Act, Rule 10b-5][Hiestand is suspended from appearing or pract...[][][]2024122024-12Friday
                      3804947f56e7146f94b3ce9bf64d8012a2024-12-23 14:42:30-05:00[34-102031][3-22383][{'name': 'Richard Brown', 'type': 'individual...Richard Brown[{'label': 'primary', 'url': 'https://www.sec....ORDER INSTITUTING ADMINISTRATIVE PROCEEDINGS P...The SEC has instituted administrative proceedi...[securities fraud, disclosure fraud]...[disgorgement of profits, civil penalties][Section 17(a) of the Securities Act of 1933, ...[Respondent Brown is barred from association w...[][][]2024122024-12Monday
                      491a2c34129c53e911759a959be1aa8292024-12-20 17:51:48-05:00[33-11349][3-22382][{'name': 'Tai Mo Shan Limited', 'type': 'comp...Tai Mo Shan Limited[{'label': 'primary', 'url': 'https://www.sec....ORDER INSTITUTING CEASE-AND-DESIST PROCEEDINGS...The SEC has instituted cease-and-desist procee...[unregistered securities, crypto, misleading c......[disgorgement of profits, civil penalties][Sections 5(a) and 5(c) of the Securities Act,...[Respondent Tai Mo Shan cease and desist from ...[][][]2024122024-12Friday

                      5 rows × 26 columns

                      Proceedings by Year and Month

                      import matplotlib.pyplot as plt
                      import matplotlib.style as style

                      style.use("default")

                      params = {
                          "axes.labelsize": 8, "font.size": 8, "legend.fontsize": 8,
                          "xtick.labelsize": 8, "ytick.labelsize": 8, "font.family": "sans-serif",
                          "axes.spines.top": False, "axes.spines.right": False, "grid.color": "grey",
                          "axes.grid": True, "axes.grid.axis": "y", "grid.alpha": 0.5, "grid.linestyle": ":",
                      }

                      plt.rcParams.update(params)
                      # piv table with years = index, months = columns, values = count of proceedings
                      unique_proceedings = df.explode('fileNumbers').drop_duplicates(subset=['fileNumbers'], keep='last')

                      df_year_month = unique_proceedings.pivot_table(
                      # df_year_month = df.pivot_table(
                          index="releasedAtYear",
                          columns="releasedAtMonth",
                          values="id",
                          aggfunc="count",
                          fill_value=0,
                      )

                      total_col = df_year_month.sum(axis=1)
                      mean_col = round(df_year_month.mean(axis=1), 0)
                      median_col = round(df_year_month.median(axis=1), 0)

                      df_year_month["total"] = total_col
                      df_year_month["mean"] = mean_col
                      df_year_month["median"] = median_col

                      total_row = df_year_month.sum(axis=0)
                      mean_row = round(df_year_month.mean(axis=0), 0)
                      median_row = round(df_year_month.median(axis=0), 0)

                      df_year_month.loc["total"] = total_row
                      df_year_month.loc["mean"] = mean_row
                      df_year_month.loc["median"] = median_row

                      df_year_month = df_year_month.astype(int)

                      print("SEC Administrative Proceedings by Year and Month")
                      df_year_month
                      SEC Administrative Proceedings by Year and Month
                      Out[8]:
                      releasedAtMonth123456789101112totalmeanmedian
                      releasedAtYear
                      199500000000111972820
                      19962527159141411866198122281914
                      199717191517191310167565252372016
                      199815314191320211756168142161816
                      19991915202427111049611415152802317
                      200041515191332913641210282342014
                      2001818161031281416391516182291916
                      20022019332513273623241830393072624
                      20032320212039263035493319233382824
                      20041227311929243553563224353773130
                      200518301531212152289982
                      2006310324354130525444
                      200741123347120124032
                      200817853464133125754
                      20097431419443638273328312842428
                      20104226454142343739572036284473738
                      20113462323647394329483536314723936
                      20124056383439333533472828444553836
                      20133224385038183644975328334914137
                      201451514138365442481313858336215245
                      2015354747553710145551045338576745650
                      201643574846235735149854341536805747
                      20175842294645472852952818335214344
                      201823263341494946851521524525955044
                      20191321105243133671041581714206075128
                      202051352035313051441572214345244434
                      20211418161776275963981320284493724
                      202232561925334118681421714164814028
                      202313121743712726571771114154834022
                      20241738172525283531785748505394533
                      total6747867557448518697991208229766461278811047920757
                      mean2226252528292740772220263683125
                      median1822202430282938621817284123426
                      fig, ax = plt.subplots(figsize=(5, 3))

                      df_year_month.loc[1996:2024]["total"].plot(
                          kind="line",
                          ax=ax,
                          marker="o",
                          markersize=3,
                          linewidth=1,
                      )
                      ax.set_title("Administrative Proceedings with \nUnique File Numbers per Year")
                      ax.set_xlabel("Year")
                      ax.set_ylabel("Number of Proceedings")
                      plt.tight_layout()
                      plt.grid(axis="x")
                      ax.set_axisbelow(True)
                      plt.show()

                      Proceedings by Year and Settlement Type

                      # piv table for hasAgreedToSettlement
                      # col = hasAgreedToSettlement (true, false), index = year, values = count of cases
                      df_year_settlement = unique_proceedings.pivot_table(
                          index="releasedAtYear",
                          columns="hasAgreedToSettlement",
                          values="id",
                          aggfunc="count",
                          fill_value=0,
                      )

                      total_col = df_year_settlement.sum(axis=1)
                      mean_col = round(df_year_settlement.mean(axis=1), 0)
                      median_col = round(df_year_settlement.median(axis=1), 0)

                      total_row = df_year_settlement.sum(axis=0)
                      mean_row = round(df_year_settlement.mean(axis=0), 0)
                      median_row = round(df_year_settlement.median(axis=0), 0)

                      df_year_settlement.loc["total"] = total_row
                      df_year_settlement.loc["mean"] = mean_row
                      df_year_settlement.loc["median"] = median_row

                      df_year_settlement = df_year_settlement.astype(int)

                      df_year_settlement
                      Out[10]:
                      hasAgreedToSettlementFalseTrue
                      releasedAtYear
                      1995325
                      199656172
                      199746191
                      199845171
                      199971209
                      200041193
                      200134195
                      200256251
                      200369269
                      200495282
                      20052574
                      20061341
                      2007634
                      20081344
                      2009120164
                      2010192255
                      2011207265
                      2012219236
                      2013212279
                      2014245376
                      2015287387
                      2016201479
                      2017170351
                      2018174421
                      2019176431
                      2020178346
                      2021168281
                      2022209272
                      2023151332
                      2024131408
                      total36137434
                      mean120248
                      median126260
                      # stacked bar chart for hasAgreedToSettlement
                      fig, ax = plt.subplots(figsize=(6, 4))

                      df_year_settlement.drop(["total", "mean", "median"]).plot(
                          kind="bar", stacked=False, ax=ax, color=["#1f77b4", "#ff7f0e"]
                      )

                      plt.title("SEC Administrative Proceedings by Year and Settlement")
                      plt.xlabel("Year")
                      plt.ylabel("Count")
                      plt.legend(["No Settlement", "Settlement"], loc="upper right")
                      plt.grid(axis="x")
                      ax.set_axisbelow(True)
                      plt.tight_layout()
                      plt.show()

                      Proceedings by Year And Count of Agreements to Pay Penalties

                      # piv table for hasAgreedToPayPenalty
                      # col = hasAgreedToPayPenalty (true, false), index = year, values = count of cases
                      df_year_penalty = unique_proceedings.pivot_table(
                          index="releasedAtYear",
                          columns="hasAgreedToPayPenalty",
                          values="id",
                          aggfunc="count",
                          fill_value=0,
                      )

                      total_col = df_year_penalty.sum(axis=1)
                      mean_col = round(df_year_penalty.mean(axis=1), 0)
                      median_col = round(df_year_penalty.median(axis=1), 0)

                      total_row = df_year_penalty.sum(axis=0)
                      mean_row = round(df_year_penalty.mean(axis=0), 0)
                      median_row = round(df_year_penalty.median(axis=0), 0)

                      df_year_penalty.loc["total"] = total_row
                      df_year_penalty.loc["mean"] = mean_row
                      df_year_penalty.loc["median"] = median_row

                      df_year_penalty = df_year_penalty.astype(int)

                      df_year_penalty
                      Out[12]:
                      hasAgreedToPayPenaltyFalseTrue
                      releasedAtYear
                      1995226
                      199617949
                      199718453
                      199815858
                      199921268
                      200016767
                      200117059
                      200223869
                      200327068
                      2004263114
                      20056336
                      20063519
                      20072416
                      20083720
                      200921074
                      201035592
                      201137498
                      201237580
                      2013369122
                      2014396225
                      2015427247
                      2016420260
                      2017313208
                      2018326269
                      2019421186
                      2020309215
                      2021264185
                      2022313168
                      2023249234
                      2024223316
                      total73663681
                      mean246123
                      median25686
                      # stacked bar chart for hasAgreedToSettlement
                      fig, ax = plt.subplots(figsize=(6, 3.5))

                      df_year_penalty.drop(["total", "mean", "median"]).plot(
                          kind="bar", stacked=False, ax=ax, color=["#1f77b4", "#ff7f0e"]
                      )

                      plt.title("SEC Administrative Proceedings by Year and Penalty")
                      plt.xlabel("Year")
                      plt.ylabel("Count")
                      plt.legend(["Did not agree to penalty", "Agreed to penalty"], loc="upper left")
                      plt.grid(axis="x")
                      ax.set_axisbelow(True)
                      plt.tight_layout()
                      plt.show()

                      Penalty Amount Analysis

                      all_penalties = []
                      file_numbers = {}

                      # iterate over all rows, extract penalties and append to all_penalties
                      for i, row in unique_proceedings.iterrows():
                          penaltyAmounts = row["penaltyAmounts"]

                          if isinstance(penaltyAmounts, list):
                              for penalty in penaltyAmounts:
                                  if "penaltyAmount" in penalty:
                                      # find entity with "name" == "imposedOn"
                                      entity = list(filter(lambda x: x["name"] == penalty["imposedOn"], row["entities"]))
                                      entity_type = entity[0]["type"] if entity else None

                                      all_penalties.append(
                                          {
                                              # "caseCitation": row['caseCitation'],
                                              "fileNumber": row["fileNumbers"],
                                              "releaseNo": row["releaseNo"],
                                              "releasedAt": row["releasedAt"],
                                              "releasedAtYear": row["releasedAtYear"],
                                              "releasedAtMonth": row["releasedAtMonth"],
                                              "amount": penalty["penaltyAmount"],
                                              "imposedOn": penalty["imposedOn"],
                                              "imposedOnType": entity_type,
                                              # "url": row["url"],
                                          }
                                      )

                      all_penalties_df = pd.DataFrame(all_penalties)
                      all_penalties_df["amount"] = all_penalties_df["amount"].astype(float)

                      # remove all doubles by caseCitation and imposedOn
                      all_penalties_df = all_penalties_df.drop_duplicates(
                          subset=["fileNumber", "imposedOn", "amount"], keep="last"
                      )

                      all_penalties_df
                      Out[14]:
                      fileNumberreleaseNoreleasedAtreleasedAtYearreleasedAtMonthamountimposedOnimposedOnType
                      03-22386[34-102060, AAER-4554]2024-12-31 12:19:45-05:0020241275000.00Accell Audit & Compliance, PAcompany
                      13-22384[34-102047, AAER-4553]2024-12-27 17:12:33-05:0020241250000.00Christopher Hiestandindividual
                      23-22382[33-11349]2024-12-20 17:51:48-05:0020241273452756.00Tai Mo Shan Limitedcompany
                      33-22382[33-11349]2024-12-20 17:51:48-05:0020241212916153.00Tai Mo Shan Limitedcompany
                      43-22382[33-11349]2024-12-20 17:51:48-05:0020241236726378.00Tai Mo Shan Limitedcompany
                      ...........................
                      59333-8865[34-36338]1995-10-05 09:11:20-04:0019951010000.00John Laurientiindividual
                      59343-8865[34-36338]1995-10-05 09:11:20-04:0019951050000.00Dickinson & Co.company
                      59353-8864[34-36334]1995-10-04 09:11:20-04:0019951011402.50Lewco Securities Corporationcompany
                      59363-8863[34-36333]1995-10-04 09:11:20-04:00199510107000.00French American Banking Corporationcompany
                      59373-8863[34-36333]1995-10-04 09:11:20-04:0019951015918.84French American Banking Corporationcompany

                      5909 rows × 8 columns

                      Penalty Amount by Year

                      # aggregate amount by year
                      penalties_year = all_penalties_df.groupby("releasedAtYear")["amount"].sum()
                      penalties_year = penalties_year.astype(int)
                      penalties_year = pd.DataFrame(penalties_year)
                      penalties_year["amount"] = round(penalties_year["amount"] / 1_000_000, 2)
                      print("Total Penalties in Million USD by Year")
                      penalties_year
                      Total Penalties in Million USD by Year
                      Out[15]:
                      amount
                      releasedAtYear
                      19955.22
                      199630.19
                      199720.13
                      199820.49
                      199954.28
                      2000131.97
                      2001635.92
                      200260.40
                      2003431.53
                      20041602.46
                      2005752.19
                      2006317.54
                      200731.34
                      2008681.46
                      2009243.64
                      20101566.58
                      20111011.27
                      2012319.56
                      2013889.66
                      20144464.57
                      20151254.10
                      20161787.28
                      2017887.40
                      20181845.09
                      2019944.43
                      20203181.67
                      2021792.16
                      20221557.67
                      20231478.46
                      20242158.77
                      fig, ax = plt.subplots(figsize=(5, 3))

                      penalties_year["amount"].plot(
                          kind="line",
                          ax=ax,
                          marker="o",
                          markersize=3,
                          linewidth=1,
                      )

                      ax.get_yaxis().set_major_formatter(plt.FuncFormatter(lambda x, loc: "{:,}".format(int(x))))
                      ax.set_title("Penalties per Year")
                      ax.set_xlabel("Year")
                      ax.set_ylabel("Penalty Amount\nin Million USD")
                      plt.tight_layout()
                      plt.grid(axis="x")
                      ax.set_axisbelow(True)
                      plt.show()

                      Top 10 Penalty Amounts

                      # sort all penalties by amount, show top 10
                      top_10_penalties = all_penalties_df.sort_values("amount", ascending=False).head(10)
                      top_10_penalties["amount"] = round(top_10_penalties["amount"] / 1_000_000, 2)
                      top_10_penalties["amount"] = top_10_penalties["amount"].map("{:,.1f}".format)
                      print("Top 10 SEC Penalties in Million USD between 1995 and 2024")
                      top_10_penalties[['amount', 'imposedOn', 'releasedAt', 'releaseNo']]
                      Top 10 SEC Penalties in Million USD between 1995 and 2024
                      Out[17]:
                      amountimposedOnreleasedAtreleaseNo
                      3808900.0S.A.C. Capital Advisors, LLC2014-06-27 09:21:21-04:00[IA-3864]
                      3809900.0CR Intrinsic Investors, LLC2014-06-27 09:21:21-04:00[IA-3864]
                      3810900.0Sigma Capital Management, LLC2014-06-27 09:21:21-04:00[IA-3864]
                      3807900.0S.A.C. Capital Advisors, L.P.2014-06-27 09:21:21-04:00[IA-3864]
                      2027853.2Petróleo Brasileiro S.A. – Petrobras2018-09-27 09:24:56-04:00[33-10561, 34-84205, AAER-3989]
                      944675.0Allianz Global Investors U.S. LLC2022-05-17 09:28:19-04:00[34-94927, IA-6027]
                      1345606.3The Goldman Sachs Group, Inc.2020-10-22 09:26:36-04:00[34-90243, AAER-4191]
                      5341606.0Republic New York Securities Corp.2001-12-17 08:12:59-05:00[34-45157]
                      4329583.5Barry J. Minkow2011-11-22 08:18:30-05:00[IA-3320]
                      1449556.7Herbalife Nutrition Ltd.2020-08-28 09:26:48-04:00[34-89704, AAER-4165]

                      Penalties by Type of Defendant

                      # create piv table across years and imposedOnType, with values = sum of penalties
                      penalties_entity_type = all_penalties_df.pivot_table(
                          index="releasedAtYear",
                          columns="imposedOnType",
                          values="amount",
                          aggfunc="sum",
                          fill_value=0,
                      )

                      total_col = penalties_entity_type.sum(axis=1)
                      mean_col = round(penalties_entity_type.mean(axis=1), 0)
                      median_col = round(penalties_entity_type.median(axis=1), 0)

                      total_row = penalties_entity_type.sum(axis=0)
                      mean_row = round(penalties_entity_type.mean(axis=0), 0)
                      median_row = round(penalties_entity_type.median(axis=0), 0)

                      penalties_entity_type.loc["total"] = total_row
                      penalties_entity_type.loc["mean"] = mean_row
                      penalties_entity_type.loc["median"] = median_row

                      # format to million and , notation
                      penalties_entity_type = round(penalties_entity_type / 1_000_000, 2)
                      penalties_entity_type = penalties_entity_type.map("{:,.1f}".format)

                      print("SEC Penalties in Million USD by Year and Entity Type")

                      penalties_entity_type = penalties_entity_type[['company', 'individual']]
                      penalties_entity_type
                      SEC Penalties in Million USD by Year and Entity Type
                      Out[18]:
                      imposedOnTypecompanyindividual
                      releasedAtYear
                      19955.20.0
                      199621.28.9
                      199711.65.8
                      199813.43.3
                      199951.31.9
                      2000119.712.2
                      2001607.928.0
                      200213.446.9
                      2003375.456.0
                      20041,002.4206.5
                      2005231.45.6
                      2006297.72.6
                      200728.33.1
                      2008520.7101.1
                      2009106.012.2
                      20101,120.739.2
                      2011374.0606.1
                      2012161.9141.3
                      2013741.8145.2
                      20144,128.851.9
                      2015913.483.5
                      20161,713.439.7
                      2017790.638.1
                      20181,705.046.1
                      2019802.878.2
                      20203,121.823.0
                      2021764.823.8
                      20221,333.219.0
                      20231,041.818.5
                      20241,904.929.7
                      total24,024.41,877.4
                      mean800.862.6
                      median564.328.8
                      fig, ax = plt.subplots(figsize=(5, 3))

                      data_to_plot = penalties_entity_type.loc[1995:2024].map(
                          lambda x: float(x.replace(",", ""))
                      )

                      data_to_plot.plot(kind="bar", stacked=False, ax=ax, color=["#1f77b4", "#ff7f0e"])

                      plt.title("Proceedings Penalties by Year and Entity Type")
                      plt.xlabel("Year")
                      plt.ylabel("Penalty Amount\nin Million USD")
                      plt.legend(["Company", "Individual"], loc="upper right")
                      plt.grid(axis="x")
                      ax.set_axisbelow(True)
                      plt.tight_layout()
                      plt.show()

                      Proceedings by Category

                      all_tags = []

                      for i, row in unique_proceedings.iterrows():
                          tags = row["tags"]
                          if isinstance(tags, list):
                            all_tags.extend(tags)

                      all_tags = pd.Series(all_tags)
                      all_tags = all_tags.value_counts().reset_index()
                      all_tags.columns = ["tag", "count"]

                      print("Top 10 Tags in SEC Administrative Proceedings")
                      all_tags.head(10)
                      Top 10 Tags in SEC Administrative Proceedings
                      Out[20]:
                      tagcount
                      0securities fraud2115
                      1delinquent filings1676
                      2disclosure fraud1336
                      3fraud894
                      4accounting fraud743
                      5unregistered securities634
                      6securities violation532
                      7investment adviser499
                      8insider trading464
                      9misrepresentation395

                      Requested Reliefs by Category

                      # count all unique requestedRelief
                      all_requested_relief = []

                      for i, row in unique_proceedings.iterrows():
                          requestedRelief = row["requestedRelief"]
                          if isinstance(requestedRelief, list):
                              all_requested_relief.extend(requestedRelief)

                      all_requested_relief = pd.DataFrame(all_requested_relief, columns=["requestedRelief"])

                      all_requested_relief["requestedRelief"] = (
                          all_requested_relief["requestedRelief"]
                          .str.replace("cease-and-desist order", "cease and desist order")
                          .replace("permanent injunctions", "permanent injunction")
                      )

                      all_requested_relief = all_requested_relief.value_counts().reset_index()

                      print("Top 10 Requested Reliefs in SEC Administrative Proceedings")
                      all_requested_relief.head(10)
                      Top 10 Requested Reliefs in SEC Administrative Proceedings
                      Out[21]:
                      requestedReliefcount
                      0civil penalties2591
                      1disgorgement of profits2045
                      2cease and desist order1709
                      3permanent injunction913
                      4suspend or revoke the registration of each cla...635
                      5censure466
                      6civil money penalty378
                      7suspend for a period not exceeding twelve months287
                      8revoke the registration of each class of secur...285
                      9disgorgement234

                      Violated Securities Laws

                      # count all unique violatedSections
                      all_violated_sections = []

                      for i, row in unique_proceedings.iterrows():
                          violatedSections = row["violatedSections"]
                          if isinstance(violatedSections, list):
                              all_violated_sections.extend(violatedSections)

                      all_violated_sections = pd.Series(all_violated_sections)
                      all_violated_sections = all_violated_sections.value_counts().reset_index()

                      all_violated_sections.columns = ["violatedSections", "count"]

                      print("Top 10 Violated Securities Laws in SEC Administrative Proceedings")
                      all_violated_sections.head(10)
                      Top 10 Violated Securities Laws in SEC Administrative Proceedings
                      Out[22]:
                      violatedSectionscount
                      0Rule 10b-52547
                      1Exchange Act Section 13(a)1701
                      2Section 10(b) of the Exchange Act1445
                      3Rules 13a-1 and 13a-131251
                      4Section 17(a) of the Securities Act of 19331137
                      5Section 10(b) of the Securities Exchange Act o...699
                      6Section 17(a) of the Securities Act570
                      7Rules 13a-1528
                      8Section 13(a) of the Exchange Act492
                      9Rules 13a-13472

                      Footer

                      Products

                      • EDGAR Filing Search API
                      • Full-Text Search API
                      • Real-Time Filing Stream API
                      • Filing Download & PDF Generator API
                      • XBRL-to-JSON Converter
                      • 10-K/10-Q/8-K Item Extractor
                      • Investment Adviser & Form ADV API
                      • Insider Trading Data - Form 3, 4, 5
                      • Restricted Sales Notifications - Form 144
                      • Institutional Holdings - Form 13F
                      • Form N-PORT API - Investment Company Holdings
                      • Form N-CEN API - Annual Reports by Investment Companies
                      • Form N-PX API - Proxy Voting Records
                      • Form 13D/13G API
                      • Form S-1/424B4 - IPOs, Debt & Rights Offerings
                      • Form C - Crowdfunding Offerings
                      • Form D - Private Placements & Exempt Offerings
                      • Regulation A Offering Statements API
                      • Changes in Auditors & Accountants
                      • Non-Reliance on Prior Financial Statements
                      • Executive Compensation Data API
                      • Directors & Board Members Data
                      • Company Subsidiaries Database
                      • Outstanding Shares & Public Float
                      • SEC Enforcement Actions
                      • Accounting & Auditing Enforcement Releases (AAERs)
                      • SRO Filings
                      • CIK, CUSIP, Ticker Mapping

                      General

                      • Pricing
                      • Features
                      • Supported Filings
                      • EDGAR Filing Statistics

                      Account

                      • Sign Up - Start Free Trial
                      • Log In
                      • Forgot Password

                      Developers

                      • API Sandbox
                      • Documentation
                      • Resources & Tutorials
                      • Python API SDK
                      • Node.js API SDK

                      Legal

                      • Terms of Service
                      • Privacy Policy

                      Legal

                      • Terms of Service
                      • Privacy Policy

                      SEC API

                      © 2025 sec-api.io by Data2Value GmbH. All rights reserved.

                      SEC® and EDGAR® are registered trademarks of the U.S. Securities and Exchange Commission (SEC).

                      EDGAR is the Electronic Data Gathering, Analysis, and Retrieval system operated by the SEC.

                      sec-api.io and Data2Value GmbH are independent of, and not affiliated with, sponsored by, or endorsed by the U.S. Securities and Exchange Commission.

                      sec-api.io is classified under SIC code 7375 (Information Retrieval Services), providing on-demand access to structured data and online information services.