JC321 commited on
Commit
852ab2d
·
verified ·
1 Parent(s): c0bdef3

Upload financial_analyzer.py

Browse files
Files changed (1) hide show
  1. financial_analyzer.py +85 -79
financial_analyzer.py CHANGED
@@ -78,102 +78,108 @@ class FinancialAnalyzer:
78
  """
79
  financial_data = []
80
 
81
- # Step 1: Get company filings to see what forms were filed
82
  filings_10k = self.edgar_client.get_company_filings(cik, ['10-K'])
83
  filings_20f = self.edgar_client.get_company_filings(cik, ['20-F'])
84
- filings_10q = self.edgar_client.get_company_filings(cik, ['10-Q'])
85
 
86
- all_filings = filings_10k + filings_20f + filings_10q
87
-
88
- if not all_filings:
89
  return []
90
 
91
- # Step 2: Get company facts to extract fiscal years from filings
92
- facts = self.edgar_client.get_company_facts(cik)
93
- if not facts:
 
 
 
 
 
 
 
 
 
 
 
 
 
94
  return []
95
 
96
- # Step 3: Extract fiscal years from the facts data based on actual filings
97
- # Build a map of accession_number -> fiscal_year
98
- accession_to_fy = {}
99
- fiscal_years = set()
100
 
101
- # Check US-GAAP and IFRS data sources
102
- for data_source in ["us-gaap", "ifrs-full"]:
103
- if data_source in facts.get("facts", {}):
104
- source_data = facts["facts"][data_source]
105
-
106
- # Look for Revenue tags to map accession numbers to fiscal years
107
- revenue_tags = ["Revenues", "RevenueFromContractWithCustomerExcludingAssessedTax",
108
- "Revenue", "RevenueFromContractWithCustomer"]
109
-
110
- for tag in revenue_tags:
111
- if tag in source_data:
112
- units = source_data[tag].get("units", {})
113
- if "USD" in units:
114
- for entry in units["USD"]:
115
- form = entry.get("form", "")
116
- fy = entry.get("fy", 0)
117
- accn = entry.get("accn", "")
118
- fp = entry.get("fp", "")
119
-
120
- # Only consider annual reports for fiscal year determination
121
- if form in ["10-K", "20-F"] and fy > 0 and (fp == "FY" or not fp):
122
- # Store the mapping
123
- if accn:
124
- accession_to_fy[accn] = fy
125
- fiscal_years.add(fy)
126
- break
127
- if fiscal_years:
128
- break
129
 
130
- # Step 4: If we have fiscal years from facts, use them
131
- # Otherwise, fall back to filing dates
132
- if fiscal_years:
133
- # Sort fiscal years in descending order and take the most recent N years
134
- sorted_fiscal_years = sorted(fiscal_years, reverse=True)
135
- target_years = sorted_fiscal_years[:years]
136
- else:
137
- # Fallback: use filing dates
138
- filing_years = set()
139
- for filing in all_filings:
140
- if 'filing_date' in filing and filing['filing_date']:
141
- try:
142
- filing_year = int(filing['filing_date'][:4])
143
- filing_years.add(filing_year)
144
- except ValueError:
145
- continue
146
-
147
- if not filing_years:
148
- return []
149
-
150
- sorted_years = sorted(filing_years, reverse=True)
151
- target_years = sorted_years[:years]
 
 
 
 
 
 
 
 
 
152
 
153
- # Step 5: Generate period list (annual and quarterly) for target years
154
  periods = []
155
- for year in target_years:
156
- # Add annual data (use FY prefix to indicate fiscal year)
157
- periods.append(f"FY{year}")
158
- # Add quarterly data in order Q4, Q3, Q2, Q1
 
 
 
 
 
 
 
 
 
159
  for quarter in range(4, 0, -1):
160
- periods.append(f"{year}Q{quarter}")
 
 
 
 
 
161
 
162
  # Step 6: Get financial data for each period
163
- for period in periods:
164
- # Extract year from period (handle both "FY2024" and "2024Q1" formats)
165
- if period.startswith("FY"):
166
- year_str = period[2:] # Remove "FY" prefix
167
- else:
168
- year_str = period.split('Q')[0] if 'Q' in period else period
169
 
170
- data = self.edgar_client.get_financial_data_for_period(cik, year_str if not period.startswith("FY") else year_str)
171
 
172
- # Add period info to result
173
  if data and "period" in data:
174
- # For annual data, use "FY" prefix if it's fiscal year based
175
- if 'Q' not in period and period.startswith("FY"):
176
- data["period"] = f"FY{data['period']}"
 
177
  financial_data.append(data)
178
 
179
  return financial_data
 
78
  """
79
  financial_data = []
80
 
81
+ # Step 1: Get company filings to determine what was actually filed
82
  filings_10k = self.edgar_client.get_company_filings(cik, ['10-K'])
83
  filings_20f = self.edgar_client.get_company_filings(cik, ['20-F'])
84
+ all_annual_filings = filings_10k + filings_20f
85
 
86
+ if not all_annual_filings:
 
 
87
  return []
88
 
89
+ # Step 2: Extract filing years from annual reports
90
+ # Use filing_date to determine the years we should query
91
+ filing_year_map = {} # Map: filing_year -> list of filings
92
+
93
+ for filing in all_annual_filings:
94
+ filing_date = filing.get('filing_date', '')
95
+ if filing_date and len(filing_date) >= 4:
96
+ try:
97
+ file_year = int(filing_date[:4])
98
+ if file_year not in filing_year_map:
99
+ filing_year_map[file_year] = []
100
+ filing_year_map[file_year].append(filing)
101
+ except ValueError:
102
+ continue
103
+
104
+ if not filing_year_map:
105
  return []
106
 
107
+ # Step 3: Sort years in descending order and take the most recent N years
108
+ sorted_years = sorted(filing_year_map.keys(), reverse=True)
109
+ target_years = sorted_years[:years]
 
110
 
111
+ # Step 4: For each target year, we need to find the fiscal year from Company Facts
112
+ # Get company facts to map filing years to fiscal years
113
+ facts = self.edgar_client.get_company_facts(cik)
114
+ filing_to_fiscal_year = {} # Map: filing_year -> fiscal_year
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
115
 
116
+ if facts:
117
+ # Try to map filing years to fiscal years using Company Facts
118
+ for data_source in ["us-gaap", "ifrs-full"]:
119
+ if data_source in facts.get("facts", {}):
120
+ source_data = facts["facts"][data_source]
121
+
122
+ # Look for Revenue tag to get fiscal year mapping
123
+ revenue_tags = ["Revenues", "RevenueFromContractWithCustomerExcludingAssessedTax",
124
+ "Revenue", "RevenueFromContractWithCustomer"]
125
+
126
+ for tag in revenue_tags:
127
+ if tag in source_data:
128
+ units = source_data[tag].get("units", {})
129
+ if "USD" in units:
130
+ for entry in units["USD"]:
131
+ form = entry.get("form", "")
132
+ fy = entry.get("fy", 0)
133
+ filed = entry.get("filed", "") # Filing date
134
+ fp = entry.get("fp", "")
135
+
136
+ # Map filing year to fiscal year
137
+ if form in ["10-K", "20-F"] and fy > 0 and filed and (fp == "FY" or not fp):
138
+ if len(filed) >= 10: # Format: YYYY-MM-DD
139
+ try:
140
+ file_year = int(filed[:4])
141
+ # Store the mapping: filing_year -> fiscal_year
142
+ if file_year not in filing_to_fiscal_year:
143
+ filing_to_fiscal_year[file_year] = fy
144
+ except ValueError:
145
+ continue
146
+ break # Found revenue tag, no need to check more
147
 
148
+ # Step 5: Generate period list for target years
149
  periods = []
150
+ for file_year in target_years:
151
+ # Try to get fiscal year from mapping, otherwise use filing year
152
+ fiscal_year = filing_to_fiscal_year.get(file_year, file_year)
153
+
154
+ # Add annual data for this fiscal year
155
+ periods.append({
156
+ 'period': str(fiscal_year),
157
+ 'type': 'annual',
158
+ 'fiscal_year': fiscal_year,
159
+ 'filing_year': file_year
160
+ })
161
+
162
+ # Add quarterly data for this fiscal year
163
  for quarter in range(4, 0, -1):
164
+ periods.append({
165
+ 'period': f"{fiscal_year}Q{quarter}",
166
+ 'type': 'quarterly',
167
+ 'fiscal_year': fiscal_year,
168
+ 'filing_year': file_year
169
+ })
170
 
171
  # Step 6: Get financial data for each period
172
+ for period_info in periods:
173
+ period = period_info['period']
174
+ fiscal_year = period_info['fiscal_year']
 
 
 
175
 
176
+ data = self.edgar_client.get_financial_data_for_period(cik, period)
177
 
 
178
  if data and "period" in data:
179
+ # Add fiscal year prefix for annual data
180
+ if period_info['type'] == 'annual':
181
+ data["period"] = f"FY{fiscal_year}"
182
+
183
  financial_data.append(data)
184
 
185
  return financial_data