If I am still active on manifold at the end of 2025 I will run three regressions on my profit graph post-the large jump on Feb 22. I will run a exponential, linear, and logarithmic regression with intercept (linear regressions on the data transformed by ln x, x, and e^x respectively) and resolve to the one with lowest mean squared loss. I will not resolve to Other.
Update 2026-01-28 (PST) (AI summary of creator comment): The creator has approved a specific implementation for calculating the regressions. The script uses:
Profit calculation:
investmentValue + balance - totalDepositsLinear regression: Direct fit of y = ax + b
Logarithmic regression: Fit of y = a*log(x+1) + b
Exponential regression: Fit in log space (ln(y) = ln(a) + bx), then transformed back to y = a*e^(bx)
All MSE calculations are performed in the original data space (not transformed space)
🏅 Top traders
| # | Trader | Total profit |
|---|---|---|
| 1 | Ṁ329 | |
| 2 | Ṁ193 | |
| 3 | Ṁ142 | |
| 4 | Ṁ16 | |
| 5 | Ṁ1 |
Maybe a better set of possibilities for future markets would instead be linear, sublinear, and supralinear, where you calculate the curvature of the trend and see if its positive, near 0, or negative. This would be more complete than considering just exponential and logarithmic functions, which are pretty specific functions that 1. are unlikely to accurately describe the actual trend in this case 2. only gain distinction to other functions over a larger range of time. Obviously positive curvature will correlate with exponential fitting and negative with logarithmic, but directly calculating the curvature should be less ambiguous.
If this vibe coded script is correct (pulls data + makes fits + plots), fitting data from 2025-02-23 to present day, best fit is exponential
#!/usr/bin/env python3
"""
Script to fetch and plot Manifold portfolio history for a user.
This script calls the Manifold API to get portfolio history and plots the investment value.
"""
import matplotlib.pyplot as plt
from datetime import datetime
import random
import requests
import numpy as np
# Hard-coded constants
USERNAME = "spiderduckpig"
# PERIOD = "allTime" # Options: 'daily', 'weekly', 'monthly', 'allTime'
PERIOD = "allTime" # Options: 'daily', 'weekly', 'monthly', 'allTime'
API_BASE_URL = "https://api.manifold.markets/v0"
# Date range for fitting (inclusive)
FIT_START_DATE = "2025-02-23"
# FIT_END_DATE = "2025-12-31"
FIT_END_DATE = "2026-12-31"
def get_user_id(username):
"""Get user ID from username."""
url = f"{API_BASE_URL}/user/{username}"
response = requests.get(url)
response.raise_for_status()
return response.json()["id"]
def get_portfolio_history(user_id, period):
"""Get portfolio history for a user over a specified period."""
url = f"{API_BASE_URL}/get-user-portfolio-history"
params = {
"userId": user_id,
"period": period
}
response = requests.get(url, params=params)
response.raise_for_status()
return response.json()
def plot_investment_value(history, username):
"""Plot the investment value over time."""
if not history:
print("No portfolio history data available.")
return
# Extract timestamps and investment values as numpy arrays
timestamps = np.array([entry["timestamp"] for entry in history])
investment_values = np.array([entry["investmentValue"] + entry["balance"] - entry['totalDeposits'] for entry in history])
# investment_values = np.array([entry["profit"] for entry in history])
# Convert timestamps to datetime objects
dates = np.array([datetime.fromtimestamp(ts / 1000) for ts in timestamps])
# Filter data for the fitting range
fit_start = datetime.strptime(FIT_START_DATE, "%Y-%m-%d")
fit_end = datetime.strptime(FIT_END_DATE, "%Y-%m-%d")
mask = (dates >= fit_start) & (dates <= fit_end)
fit_dates = dates[mask]
fit_values = investment_values[mask]
fit_timestamps = timestamps[mask]
if len(fit_dates) == 0:
print(f"Warning: No data points found in the range {FIT_START_DATE} to {FIT_END_DATE}")
print("Skipping fitting...")
fit_x = None
else:
print(f"\nFitting data from {FIT_START_DATE} to {FIT_END_DATE}")
print(f" Fitting data points: {len(fit_dates)}")
# Convert dates to days since start for fitting (makes coefficients more interpretable)
fit_x = (fit_timestamps - fit_timestamps[0]) / (1000 60 60 * 24) # Days since start
# Linear fit: y = a*x + b
A_linear = np.vstack([fit_x, np.ones(len(fit_x))]).T
coeffs_linear = np.linalg.lstsq(A_linear, fit_values, rcond=None)[0]
a_linear, b_linear = coeffs_linear
y_linear = a_linear * fit_x + b_linear
# Logarithmic fit: y = a*log(x+1) + b
# We fit this directly using least squares
A_log = np.vstack([np.log(fit_x + 1), np.ones(len(fit_x))]).T
coeffs_log = np.linalg.lstsq(A_log, fit_values, rcond=None)[0]
a_log, b_log = coeffs_log
y_log = a_log * np.log(fit_x + 1) + b_log
# Exponential fit: y = a*e^(b*x)
# Transform: ln(y) = ln(a) + b*x
# Fit in log space, then transform back
log_y = np.log(fit_values)
A_exp = np.vstack([fit_x, np.ones(len(fit_x))]).T
coeffs_exp_log = np.linalg.lstsq(A_exp, log_y, rcond=None)[0]
b_exp, ln_a_exp = coeffs_exp_log
a_exp = np.exp(ln_a_exp)
y_exp = a_exp np.exp(b_exp fit_x)
# Calculate mean squared errors (in original data space)
mse_linear = np.mean((fit_values - y_linear) ** 2)
mse_log = np.mean((fit_values - y_log) ** 2)
mse_exp = np.mean((fit_values - y_exp) ** 2)
print(f"\nLinear fit: y = {a_linear:.4f}*x + {b_linear:.2f}")
print(f" Mean Squared Error: {mse_linear:.2e}")
print(f"\nLogarithmic fit: y = {a_log:.4f}*log(x+1) + {b_log:.2f}")
print(f" Mean Squared Error: {mse_log:.2e}")
print(f"\nExponential fit: y = {a_exp:.2f}*e^({b_exp:.6f}*x)")
print(f" Mean Squared Error: {mse_exp:.2e}")
# Create the plot
plt.figure(figsize=(14, 7))
plt.plot(dates, investment_values, linewidth=2, label='Actual Data', alpha=0.7)
# Plot fits if available
if fit_x is not None:
plt.plot(fit_dates, y_linear, '--', linewidth=2, label=f'Linear Fit (MSE: {mse_linear:.2e})', alpha=0.8)
plt.plot(fit_dates, y_log, '--', linewidth=2, label=f'Logarithmic Fit (MSE: {mse_log:.2e})', alpha=0.8)
plt.plot(fit_dates, y_exp, '--', linewidth=2, label=f'Exponential Fit (MSE: {mse_exp:.2e})', alpha=0.8)
# Highlight the fitting range
plt.axvline(fit_start, color='gray', linestyle=':', alpha=0.5, label='Fit Range')
plt.axvline(fit_end, color='gray', linestyle=':', alpha=0.5)
plt.xlabel("Date")
plt.ylabel("Investment Value (M$)")
plt.title(f"Portfolio Investment Value for {username}")
plt.legend()
plt.grid(True, alpha=0.3)
plt.xticks(rotation=45)
plt.tight_layout()
# Show some statistics
print(f"\nPortfolio Statistics:")
print(f" Period: {PERIOD}")
print(f" Data points: {len(history)}")
print(f" Start date: {dates[0].strftime('%Y-%m-%d')}")
print(f" End date: {dates[-1].strftime('%Y-%m-%d')}")
print(f" Initial investment value: M${investment_values[0]:.2f}")
print(f" Final investment value: M${investment_values[-1]:.2f}")
print(f" Change: M${investment_values[-1] - investment_values[0]:.2f}")
# print(f" Percent change: {((investment_values[-1] - investment_values[0]) / investment_values[0] * 100):.2f}%")
# Show the plot
plt.show()
def main():
print(f"Fetching portfolio history for user: {USERNAME}")
print(f"Period: {PERIOD}")
print()
# Get user ID
user_id = get_user_id(USERNAME)
print(f"User ID: {user_id}")
# Get portfolio history
history = get_portfolio_history(user_id, PERIOD)
# Plot the investment value
plot_investment_value(history, USERNAME)
if name == "__main__":
main()