Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
859c076
feat: add prediction market sentiment engine
Barac9492 Mar 16, 2026
958867a
fix: Vercel build + redesign PredictionView UI/UX
Barac9492 Mar 16, 2026
2f26804
fix: add SPA rewrite rule for Vercel client-side routing
Barac9492 Mar 16, 2026
15b2177
feat: add Anthropic Claude support alongside Ollama/OpenAI
Barac9492 Mar 16, 2026
9e6e6c1
fix: Polymarket JSON string parsing + Anthropic support
Barac9492 Mar 16, 2026
40e5db8
Add PRD for Polymarket monetization engine
claude Mar 16, 2026
94d0ea5
Merge pull request #1 from Barac9492/claude/implement-todo-item-GZHYu
Barac9492 Mar 16, 2026
4747fd6
fix: refactor OasisProfileGenerator + SimulationConfigGenerator to us…
Barac9492 Mar 16, 2026
528389d
feat: add backtest script + reduce default rounds to 2
Barac9492 Mar 17, 2026
5513542
fix: HOLD signal when 0 posts analyzed, prevent false BUY signals
Barac9492 Mar 17, 2026
5debd9f
feat: split LLM strategy — Claude for analysis, Ollama for simulation
Barac9492 Mar 17, 2026
c4525c9
feat: replace OASIS simulation with direct LLM debate
Barac9492 Mar 17, 2026
b00c3bb
feat: tune prompts — evidence-weighted debate + blended probability
Barac9492 Mar 17, 2026
b47e484
feat: add signal calibration — market regression, edge penalty, date …
Barac9492 Mar 17, 2026
b9bc1f7
refactor: dead code cleanup, comment translation, calibration config …
Barac9492 Mar 18, 2026
59dc5ad
feat: add SQLite storage layer and backtest/position data models
Barac9492 Mar 18, 2026
c13d848
feat: add backtesting engine, calibration service, and paper trader
Barac9492 Mar 18, 2026
5e461fe
feat: add backtest API endpoints
Barac9492 Mar 18, 2026
1727353
test: add 62-test suite for backtesting system
Barac9492 Mar 18, 2026
7c2eab3
feat: add BacktestView frontend + PAPER badge
Barac9492 Mar 18, 2026
aa0dbc5
docs: add DESIGN.md, TODOS.md, update task tracker
Barac9492 Mar 18, 2026
10fa428
Merge remote-tracking branch 'origin/main' into feat/phase1-backtesting
Barac9492 Mar 18, 2026
1a7a003
docs: update project documentation for Phase 1
Barac9492 Mar 18, 2026
006b872
chore: add project config, design doc, and market data
Barac9492 Mar 18, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 9 additions & 6 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
.DS_Store
Thumbs.db

# 环境变量(保护敏感信息)
# Environment variables
.env
.env.local
.env.*.local
Expand Down Expand Up @@ -36,7 +36,7 @@ yarn-error.log*
*.swp
*.swo

# 测试
# Test
.pytest_cache/
.coverage
htmlcov/
Expand All @@ -45,17 +45,20 @@ htmlcov/
.cursor/
.claude/

# 文档与测试程序
# Documentation and test programs
mydoc/
mytest/

# 日志文件
# Log files
backend/logs/
*.log

# 上传文件
# Uploads
backend/uploads/

# Docker 数据
# SQLite data
backend/data/

# Docker
data/backend/venv311/
backend/venv311/
116 changes: 116 additions & 0 deletions DESIGN.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
# MiroFish Design Tokens

Extracted from `PredictionView.vue`. All new views and components must follow these tokens.

---

## Typography

| Role | Family | Variable |
|-------------|---------------------------------------------------|------------|
| Monospace | `'JetBrains Mono', 'SF Mono', monospace` | `--mono` |
| Sans-serif | `'Space Grotesk', 'Noto Sans SC', system-ui, sans-serif` | `--sans` |

### Sizes & Weights

| Element | Size | Weight | Letter-spacing |
|-------------------|---------|--------|----------------|
| Page title | 28px | 700 | -0.02em |
| Section heading | 16px | 600 | -0.01em |
| Body text | 14px | 400 | normal |
| Small / caption | 12px | 500 | 0.02em |
| Badge label | 11px | 600 | 0.05em |
| Mono data | 13-14px | 500 | normal |

---

## Colors

| Token | Hex | Usage |
|--------------------|-----------|--------------------------------|
| `--text-primary` | `#000` | Nav, headings, primary text |
| `--orange` | `#FF4500` | Accent, links, active states |
| `--green` | `#10B981` | Success, BUY signal, positive |
| `--red` | `#dc2626` | Error, SELL signal, negative |
| `--border` | `#EAEAEA` | Panel borders, dividers |
| `--bg-subtle` | `#FAFAFA` | Subtle background fills |
| `--text-secondary` | `#666` | Secondary labels |
| `--text-muted` | `#999` | Muted / tertiary text |

---

## Spacing

| Token | Value | Usage |
|-------------|---------|----------------------------|
| Max-width | 1400px | Page container |
| Padding | 40px | Container horizontal pad |
| Grid gap | 30px | Between panel columns |

---

## Components

### Panels
- Border: `1px solid var(--border)`
- Border-radius: **0** (no rounded corners)
- Background: `#fff`
- No box-shadow

### Badges
- Uppercase text, `11px` font, `600` weight, `0.05em` letter-spacing
- Padding: `4px 10px`
- Border: `1px solid` (color matches text)
- No border-radius

### Skeleton Loaders
- Background: `var(--bg-subtle)`
- Shimmer animation (left-to-right sweep)
- Match the dimensions of the content they replace

### Empty States
- Centered text, muted color (`var(--text-muted)`)
- Optional icon above text

### Progress Bars
- Track: `var(--bg-subtle)`
- Fill: `var(--orange)` or signal color
- Height: 4-6px
- No border-radius

---

## Anti-patterns

Do **not** use:
- Rounded corners (`border-radius`)
- Box shadows (`box-shadow`)
- Gradient fills (`linear-gradient`, `radial-gradient`)

---

## CSS Variables Reference

```css
:root {
--mono: 'JetBrains Mono', 'SF Mono', monospace;
--sans: 'Space Grotesk', 'Noto Sans SC', system-ui, sans-serif;
--orange: #FF4500;
--green: #10B981;
--red: #dc2626;
--border: #EAEAEA;
--bg-subtle: #FAFAFA;
--text-primary: #000;
--text-secondary: #666;
--text-muted: #999;
}
```

---

## Responsive Breakpoints

| Breakpoint | Target | Notes |
|------------|---------|-----------------------------------|
| 1024px | Tablet | Stack grid to single column |
| 768px | Mobile | Reduce padding, smaller type |
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ The [original MiroFish](https://github.com/666ghj/MiroFish) was built for the Ch
3. **Simulation** — Agents interact on simulated social platforms: posting, replying, arguing, shifting opinions. The system tracks sentiment evolution, topic propagation, and influence dynamics in real time.
4. **Report** — A ReportAgent analyzes the post-simulation environment, interviews a focus group of agents, searches the knowledge graph for evidence, and generates a structured analysis.
5. **Interaction** — Chat with any agent from the simulated world. Ask them why they posted what they posted. Full memory and personality persists.
6. **Prediction Markets** — Browse live Polymarket markets, run a multi-agent debate simulation, and generate calibrated trading signals (BUY_YES / BUY_NO / HOLD) with edge and confidence scores.
7. **Backtesting** — Validate signal quality against resolved markets. Computes accuracy, Brier score, ROI, Sharpe ratio, max drawdown, and calibration RMSE. Paper trading mode simulates execution with slippage.

## Screenshot

Expand Down Expand Up @@ -137,12 +139,15 @@ This fork introduces a clean abstraction layer between the application and the g
┌─────────────────────────────────────────┐
│ Flask API │
│ graph.py simulation.py report.py │
│ prediction.py backtest.py │
└──────────────┬──────────────────────────┘
│ app.extensions['neo4j_storage']
┌──────────────▼──────────────────────────┐
│ Service Layer │
│ EntityReader GraphToolsService │
│ GraphMemoryUpdater ReportAgent │
│ PredictionManager Backtester │
│ Calibrator PaperTrader │
└──────────────┬──────────────────────────┘
│ storage: GraphStorage
┌──────────────▼──────────────────────────┐
Expand Down Expand Up @@ -171,6 +176,8 @@ This fork introduces a clean abstraction layer between the application and the g
- Hybrid search: 0.7 × vector similarity + 0.3 × BM25 keyword search
- Synchronous NER/RE extraction via local LLM (replaces Zep's async episodes)
- All original dataclasses and LLM tools (InsightForge, Panorama, Agent Interviews) preserved
- Prediction pipeline: market → scenario → LLM debate → calibrated signal (60-90s per market)
- SQLite (WAL mode) for backtest results, paper trading positions, calibration models

## Hardware Requirements

Expand Down Expand Up @@ -203,3 +210,5 @@ This is a modified fork of [MiroFish](https://github.com/666ghj/MiroFish) by [66
- Entire frontend translated from Chinese to English (20 files, 1,000+ strings)
- All Zep references replaced with Neo4j across the UI
- Rebranded to MiroFish Offline
- Prediction market signal engine (Polymarket integration, LLM debate simulation)
- Backtesting + paper trading system with SQLite storage and 62-test suite
6 changes: 3 additions & 3 deletions ROADMAP.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# MiroFish-Offline Roadmap

## Current State (v0.2.0)
## Current State (v0.2.0+)

Fully local fork running on Neo4j CE + Ollama. All Zep Cloud dependencies removed. Core pipeline works: upload text → build knowledge graph → entity extraction → simulation → report generation.
Fully local fork running on Neo4j CE + Ollama. All Zep Cloud dependencies removed. Core pipeline works: upload text → build knowledge graph → entity extraction → simulation → report generation. Prediction market signal engine with backtesting, paper trading, and SQLite storage. 62-test suite.

---

Expand Down Expand Up @@ -52,7 +52,7 @@ Fully local fork running on Neo4j CE + Ollama. All Zep Cloud dependencies remove
- [ ] Authentication & multi-user support
- [ ] Graph versioning: snapshot and restore graph states
- [ ] Plugin system for custom NER extractors, search strategies, and report templates
- [ ] Comprehensive test suite (unit + integration + E2E)
- [x] Comprehensive test suite — 62 tests (unit + integration) for prediction/backtest system
- [ ] Performance benchmarks: document throughput (texts/min) and latency per hardware tier
- [ ] Helm chart for Kubernetes deployment

Expand Down
8 changes: 8 additions & 0 deletions TODOS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# MiroFish TODOs

## Backlog

- [ ] **P2** JSON to SQLite migration for historical prediction runs
- [ ] **P2** CI/CD pipeline via GitHub Actions
- [ ] **P2** SQLite disk-full error handling
- [ ] **P2** Extract shared CSS components before Phase 2
37 changes: 23 additions & 14 deletions backend/app/__init__.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
"""
MiroFish Backend - Flask Application Factory
MiroFish Backend Flask application factory
"""

import os
import warnings

# Suppress multiprocessing resource_tracker warnings (from third-party libraries like transformers)
# Must be set before all other imports
# Suppress multiprocessing resource_tracker warnings from third-party libs
warnings.filterwarnings("ignore", message=".*resource_tracker.*")

from flask import Flask, request
Expand All @@ -17,19 +16,17 @@


def create_app(config_class=Config):
"""Flask application factory function"""
"""Flask application factory"""
app = Flask(__name__)
app.config.from_object(config_class)

# Configure JSON encoding: ensure Chinese displays directly (not as \uXXXX)
# Flask >= 2.3 uses app.json.ensure_ascii, older versions use JSON_AS_ASCII config
# JSON encoding: display CJK characters directly (not \uXXXX)
if hasattr(app, 'json') and hasattr(app.json, 'ensure_ascii'):
app.json.ensure_ascii = False

# Setup logging
logger = setup_logger('mirofish')

# Only print startup info in reloader subprocess (avoid printing twice in debug mode)
# Only log startup info in the reloader child process (avoid duplicate logs in debug mode)
is_reloader_process = os.environ.get('WERKZEUG_RUN_MAIN') == 'true'
debug_mode = app.config.get('DEBUG', False)
should_log_startup = not debug_mode or is_reloader_process
Expand All @@ -54,19 +51,30 @@ def create_app(config_class=Config):
# Store None so endpoints can return 503 gracefully
app.extensions['neo4j_storage'] = None

# Register simulation process cleanup function (ensure all simulation processes terminate on server shutdown)
# --- Initialize SQLite storage ---
from .storage.sqlite_store import SQLiteStore
try:
sqlite_store = SQLiteStore(Config.SQLITE_DB_PATH)
app.extensions['sqlite'] = sqlite_store
if should_log_startup:
logger.info("SQLiteStore initialized (%s)", Config.SQLITE_DB_PATH)
except Exception as e:
logger.error("SQLiteStore initialization failed: %s", e)
app.extensions['sqlite'] = None

# Register simulation process cleanup
from .services.simulation_runner import SimulationRunner
SimulationRunner.register_cleanup()
if should_log_startup:
logger.info("Simulation process cleanup function registered")
logger.info("Simulation process cleanup registered")

# Request logging middleware
@app.before_request
def log_request():
logger = get_logger('mirofish.request')
logger.debug(f"Request: {request.method} {request.path}")
if request.content_type and 'json' in request.content_type:
logger.debug(f"Request body: {request.get_json(silent=True)}")
logger.debug(f"Body: {request.get_json(silent=True)}")

@app.after_request
def log_response(response):
Expand All @@ -75,18 +83,19 @@ def log_response(response):
return response

# Register blueprints
from .api import graph_bp, simulation_bp, report_bp
from .api import graph_bp, simulation_bp, report_bp, prediction_bp, backtest_bp
app.register_blueprint(graph_bp, url_prefix='/api/graph')
app.register_blueprint(simulation_bp, url_prefix='/api/simulation')
app.register_blueprint(report_bp, url_prefix='/api/report')
app.register_blueprint(prediction_bp, url_prefix='/api/prediction')
app.register_blueprint(backtest_bp, url_prefix='/api/backtest')

# Health check
@app.route('/health')
def health():
return {'status': 'ok', 'service': 'MiroFish-Offline Backend'}

if should_log_startup:
logger.info("MiroFish-Offline Backend startup complete")
logger.info("MiroFish-Offline Backend started")

return app

7 changes: 5 additions & 2 deletions backend/app/api/__init__.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
"""
API Routes Module
API route modules
"""

from flask import Blueprint

graph_bp = Blueprint('graph', __name__)
simulation_bp = Blueprint('simulation', __name__)
report_bp = Blueprint('report', __name__)
prediction_bp = Blueprint('prediction', __name__)
backtest_bp = Blueprint('backtest', __name__)

from . import graph # noqa: E402, F401
from . import simulation # noqa: E402, F401
from . import report # noqa: E402, F401

from . import prediction # noqa: E402, F401
from . import backtest # noqa: E402, F401
Loading