import os
import pandas as pd
from collections import Counter

# 여러 폴더에서 상장일을 추출하여 합칠 수 있도록 폴더 경로들을 리스트로 저장
base_dirs = [
    "C:\\\\Users\\\\wnstj\\\\OneDrive\\\\바탕 화면\\\\ETF\\\\ACE",
    "C:\\\\Users\\\\wnstj\\\\OneDrive\\\\바탕 화면\\\\ETF\\\\BNK",
    "C:\\\\Users\\\\wnstj\\\\OneDrive\\\\바탕 화면\\\\ETF\\\\DAISHIN343",
    "C:\\\\Users\\\\wnstj\\\\OneDrive\\\\바탕 화면\\\\ETF\\\\HANARO",
    "C:\\\\Users\\\\wnstj\\\\OneDrive\\\\바탕 화면\\\\ETF\\\\KODEX",
    "C:\\\\Users\\\\wnstj\\\\OneDrive\\\\바탕 화면\\\\ETF\\\\KOSEF",
    "C:\\\\Users\\\\wnstj\\\\OneDrive\\\\바탕 화면\\\\ETF\\\\NEW",
    "C:\\\\Users\\\\wnstj\\\\OneDrive\\\\바탕 화면\\\\ETF\\\\PLUS",
    "C:\\\\Users\\\\wnstj\\\\OneDrive\\\\바탕 화면\\\\ETF\\\\RISE",
    "C:\\\\Users\\\\wnstj\\\\OneDrive\\\\바탕 화면\\\\ETF\\\\SOL",
    "C:\\\\Users\\\\wnstj\\\\OneDrive\\\\바탕 화면\\\\ETF\\\\TIGER",
    "C:\\\\Users\\\\wnstj\\\\OneDrive\\\\바탕 화면\\\\ETF\\\\TIMEFOLIO",
    "C:\\\\Users\\\\wnstj\\\\OneDrive\\\\바탕 화면\\\\ETF\\\\TREX",
    "C:\\\\Users\\\\wnstj\\\\OneDrive\\\\바탕 화면\\\\ETF\\\\VITA",
    "C:\\\\Users\\\\wnstj\\\\OneDrive\\\\바탕 화면\\\\ETF\\\\WON",
    "C:\\\\Users\\\\wnstj\\\\OneDrive\\\\바탕 화면\\\\ETF\\\\에셋플러스",
    # 추가 폴더 경로를 여기에 추가 가능
]

# 상장일을 담고 있는 열의 이름
listing_date_column = "날짜"

# 모든 ETF 상장 년-월을 저장할 리스트
all_listing_dates = []

# 각 폴더에서 ETF 상장일 추출하여 리스트에 저장하는 함수
def extract_etf_listing_info(base_dir):
    listing_dates = []  # 각 폴더마다 별도의 상장일 리스트 생성
    for file in os.listdir(base_dir):
        if file.endswith('.csv'):
            file_path = os.path.join(base_dir, file)
            # CSV 파일 로드
            try:
                df = pd.read_csv(file_path)
                
                # 상장일 열에서 년과 월 추출
                if listing_date_column in df.columns:
                    df[listing_date_column] = pd.to_datetime(df[listing_date_column], errors='coerce')

                    # 상장일을 가장 과거의 날짜로 추정 (즉, 가장 마지막 날짜가 상장일)
                    listing_date = df[listing_date_column].min()
                    listing_year_month = listing_date.strftime("%Y.%m")
                    
                    # 상장 년-월을 리스트에 추가
                    listing_dates.append(listing_year_month)
                else:
                    print(f"상장일 열을 찾을 수 없습니다: {file}")
                    
            except Exception as e:
                print(f"파일을 읽는 중 오류가 발생했습니다: {file_path}, 오류: {e}")

    
    return listing_dates

# 모든 폴더에서 상장일 추출
for base_dir in base_dirs:
    all_listing_dates.extend(extract_etf_listing_info(base_dir))

# 상장 년-월별 빈도 계산
date_counts = Counter(all_listing_dates)

# 상장된 ETF의 총 개수 출력
total_etf_count = sum(date_counts.values())
print(f"총 상장된 ETF 개수: {total_etf_count}개")

# 가장 많이 상장된 년-월과 그 빈도 출력
most_common_date = date_counts.most_common(1)[0]
print(f"가장 많이 상장된 년-월: {most_common_date[0]}, 상장된 ETF 수: {most_common_date[1]}개")

# 모든 년-월별 상장 빈도 출력
print("\\n상장 빈도별 년-월 목록:")
for date, count in date_counts.most_common():
    print(f"{date}: {count}개")

크롤링한 네이버 증권 ETF 일별 종가 데이터를 통해 각 종목의 상장일을 추출함

이를 활용해서 윈도우 사이즈를 결정하는데 필요한 정보를 출력함

import seaborn as sns
import matplotlib.pyplot as plt

plt.rcParams['font.family'] ='Malgun Gothic'
plt.rcParams['axes.unicode_minus'] =False

date_count_df = pd.DataFrame(date_counts.items(), columns=['Year-Month', 'Count'])
date_count_df = date_count_df.sort_values('Year-Month')

plt.figure(figsize=(20,10))
sns.barplot(x='Year-Month', y='Count', data=date_count_df)

plt.title("ETF 상장 빈도 (년-월별)", fontsize=10)
plt.xticks(rotation=90)

plt.tight_layout()
plt.show()

image.png

월별 ETF 상장 수를 시각화하여 어느 정도의 범위로 지정할지 판단함

현재 : 21년 9월 상장 ETF까지 사용(윈도우 크기 3년, 약 1000개의 일별 종가 데이터)