한개의 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()