Merge branch 'next' into mkt-fndm
This commit is contained in:
@@ -904,10 +904,79 @@ def analyze_bitcoin_prices(csv_path):
|
||||
# Main plotting functions
|
||||
|
||||
|
||||
def add_cdpr_plot(df, output: Output):
|
||||
"""
|
||||
Add a plot showing the Compounding Daily Periodic Rate (CDPR) over different time periods.
|
||||
"""
|
||||
plt.style.use("seaborn-v0_8")
|
||||
fig, ax = plt.subplots(figsize=(15, 6))
|
||||
|
||||
# Calculate CDPR for different time periods
|
||||
periods = [180, 360, 720]
|
||||
cdpr = {}
|
||||
|
||||
# Find the longest CDPR series length
|
||||
max_period = max(periods)
|
||||
|
||||
for period in periods:
|
||||
daily_returns = df["Close"].pct_change().fillna(0)
|
||||
cdpr[f"{period}d CDPR"] = (
|
||||
daily_returns.rolling(period).apply(
|
||||
lambda x: (1 + x).prod() ** (1 / period) - 1, raw=True
|
||||
)
|
||||
) * 100
|
||||
|
||||
# Clip all CDPR series to the length of the longest one
|
||||
cdpr[f"{period}d CDPR"] = cdpr[f"{period}d CDPR"][max_period:]
|
||||
|
||||
# Find the non-NaN min and max CDPR values
|
||||
cdpr_values = [values for values in cdpr.values()]
|
||||
min_cdpr = np.nanmin([np.nanmin(values) for values in cdpr_values])
|
||||
max_cdpr = np.nanmax([np.nanmax(values) for values in cdpr_values])
|
||||
|
||||
# Ensure x-axis (dates) and y-axis (CDPR) have the same length
|
||||
start_date = df["Date"].iloc[max_period:].min()
|
||||
end_date = df["Date"].max()
|
||||
plot_dates = pd.date_range(start=start_date, end=end_date, freq="D")
|
||||
|
||||
# Plot CDPR lines
|
||||
for label, values in cdpr.items():
|
||||
ax.plot(plot_dates, values, label=label)
|
||||
|
||||
# Customize the plot
|
||||
ax.set_title("Compounding Daily Periodic Rate (CDPR)")
|
||||
ax.set_xlabel("Date")
|
||||
ax.set_ylabel("CDPR (%)")
|
||||
ax.grid(True, alpha=0.3)
|
||||
|
||||
# Adjust y-axis tick marks and add shaded lines between ticks
|
||||
yticks = list(np.arange(int(min_cdpr), int(max_cdpr) + 1, 0.5))
|
||||
ax.set_yticks(yticks)
|
||||
ax.tick_params(axis="y", which="major", labelsize=8)
|
||||
ax.set_yticklabels(["{:.1f}%".format(y) for y in yticks])
|
||||
|
||||
# Add shaded lines between tick marks
|
||||
for i in range(1, len(yticks)):
|
||||
ax.axhline(
|
||||
y=yticks[i], color="lightgray", linestyle="--", linewidth=1, alpha=0.5
|
||||
)
|
||||
|
||||
ax.legend()
|
||||
|
||||
# Save the plot
|
||||
filename = output.named("bitcoin_cdpr_plot.png")
|
||||
plt.tight_layout()
|
||||
plt.savefig(filename, dpi=300, bbox_inches="tight")
|
||||
plt.close()
|
||||
|
||||
|
||||
def create_plots(df, output: Output, start=None, end=None, project_days=365):
|
||||
"""
|
||||
Create enhanced plots including market maturity visualization.
|
||||
"""
|
||||
# Add the new CDPR plot
|
||||
add_cdpr_plot(df, output)
|
||||
|
||||
# Filter data based on date range
|
||||
mask = pd.Series(True, index=df.index)
|
||||
if start:
|
||||
|
||||
Reference in New Issue
Block a user