CAFE

여러종목, 다양한 기간의 거품분석 Plot을 한번에 저장하는 코드

작성자sl100104|작성시간25.07.08|조회수59 목록 댓글 0

한개의 window 가령 30일, 한개의 종목 가령 BTC-USD을 여러개의 기간 및 종목으로 분석하고 각각 저장하는 sample 코드입니다. 파일 이름 저장등에 매우 도움이 될 것이라 믿습니다.

 

# Import libraries
import numpy as np
import yfinance as yf
import pandas as pd
import matplotlib.pyplot as plt
from lppls import lppls
import os

# 1. Data Preparation
symbol = "BTC-USD"
data = yf.download(symbol, start="2018-01-01", end="2025-07-08").reset_index()

# Convert to LPPLS format
time = np.array([d.toordinal() for d in data['Date']])
price = np.log(data['Close'].values)
observations = np.array([time, price])

# 2. Multi-Window Analysis
windows = [30, 60, 90, 120]  # Larger windows for volatile assets
results = []

# Ensure output directory exists
os.makedirs('lppls_results', exist_ok=True)

for window in windows:
    try:
        print(f"\n🔍 Processing window {window} ({windows.index(window)+1}/{len(windows)})...")
        
        # Initialize LPPLS model
        lppls_model = lppls.LPPLS(observations=observations)
        
        # Perform multi-window analysis
        res = lppls_model.mp_compute_nested_fits(
            workers=12,
            window_size=window,
            smallest_window_size=10,  # Reduced for crypto volatility
            outer_increment=1,
            inner_increment=5,
            max_searches=50,  # Increased search space
            progress_bar=True  # Visual feedback
        )
        
        # Save fitted plot
        fit_path = f'lppls_results/{symbol}_{window}_fit.png'
        lppls_model.plot_fit()
        plt.savefig(fit_path, dpi=300, bbox_inches='tight')
        plt.close()
        
        # Save confidence interval plot
        ci_path = f'lppls_results/{symbol}_{window}_ci.png'
        lppls_model.plot_confidence_indicators(res)
        plt.savefig(ci_path, dpi=300, bbox_inches='tight')
        plt.close()
        
        # Compute indicators and calculate crash probabilities
        res_df = lppls_model.compute_indicators(res)
        pos_crash_rate = (res_df['pos_conf'] / (res_df['pos_conf'] + res_df['neg_conf'])).mean() if 'pos_conf' in res_df.columns else np.nan
        neg_crash_rate = (res_df['neg_conf'] / (res_df['pos_conf'] + res_df['neg_conf'])).mean() if 'neg_conf' in res_df.columns else np.nan
        tc = res_df['tc'].iloc[0] if 'tc' in res_df.columns and not res_df['tc'].isnull().all() else None
        
        # Append results
        results.append({
            "Window Size": window,
            "Critical Time": pd.Timestamp.fromordinal(int(tc)).strftime('%Y-%m-%d') if tc else "N/A",
            "Bubble Probability": round(pos_crash_rate, 2) if not np.isnan(pos_crash_rate) else "N/A",
            "Anti-Bubble Probability": round(neg_crash_rate, 2) if not np.isnan(neg_crash_rate) else "N/A",
            "Status": "🚨 Bubble" if pos_crash_rate > 0.7 else "⚠️ Warning" if pos_crash_rate > 0.5 else "✅ Stable"
        })
        
    except Exception as e:
        print(f"\n❌ Error in window {window}:")
        print(f"Type: {type(e).__name__}")
        print(f"Details: {str(e)}\n")
        results.append({
            "Window Size": window,
            "Critical Time": "Error",
            "Bubble Probability": "Error",
            "Anti-Bubble Probability": "Error",
            "Status": "❌ Failed"
        })

# 3. Save and Display Results
result_table = pd.DataFrame(results)
print("\n📈 LPPLS Bubble Analysis Results")
print(result_table.to_markdown(index=False, tablefmt="pretty"))

# Save results table
result_table.to_csv(f'lppls_results/{symbol}_results.csv', index=False)

# 4. Plot BTC Price Trend (Optional)
plt.figure(figsize=(12, 6))
plt.plot(data['Date'], data['Close'], color='#FF9500', linewidth=2, label='BTC Price')
plt.title('BTC Price Trend (2018-01-01 to 2025-07-08)', fontsize=14)
plt.xlabel('Date', fontsize=12)
plt.ylabel('Price (USD)', fontsize=12)
plt.grid(True, linestyle='--', alpha=0.7)
plt.legend()
plt.tight_layout()
plt.show()

다음검색
현재 게시글 추가 기능 열기

댓글

댓글 리스트
맨위로

카페 검색

카페 검색어 입력폼