Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
22 changes: 22 additions & 0 deletions submissions/mcp-hackathon/marketmind-ai/RIGHTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Submission rights declaration

Project: `MarketMind AI`
Submission slug: `marketmind-ai`
Submitter: `gurusankar55`
Date: `2026-09-10`

The submitter confirms that they own, or have sufficient authorization for, the source code, dependencies, service, data, branding, and other materials submitted in this pull request.

Subject to the official program terms, the submitter authorizes X-Agent to retain, reproduce, audit, test, archive, and publish the submitted program artifact for judging, fraud prevention, dispute handling, ecosystem submission, and post-award accountability.

Third-party components and their licenses:
- FastAPI — MIT License
- Pandas — BSD-3-Clause License
- Requests — Apache License 2.0
- Uvicorn — BSD-3-Clause License
- Kraken public market-data API

Exceptions or restrictions:
- No known restrictions.
- Market data is obtained from a public third-party API.
- The service is provided for informational market intelligence and does not execute trades or manage wallets.
58 changes: 58 additions & 0 deletions submissions/mcp-hackathon/marketmind-ai/SUBMISSION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# MarketMind AI

## Capability

- One-line description: Agent-callable crypto market intelligence API that returns market indicators and a structured market assessment for supported trading pairs.
- Who it helps: AI agents, developers, and users who need structured crypto market research data through a simple HTTP API.
- Capability boundary: Market research and analysis only. It does not execute trades, place orders, manage wallets, or provide security/audit services.

## Live API

- API base URL: https://marketmind-ai-js97.onrender.com
- Health-check URL: https://marketmind-ai-js97.onrender.com/health
- Authentication: none
- Rate limits / known limits: Public Render free service may spin down after inactivity. Market data availability depends on the public Kraken API and supported trading pairs.
- API contract: GET /v1/market-intelligence/{symbol}

Example:
GET /v1/market-intelligence/BTCUSDT

## Source and reproducibility

- Source repository: https://github.com/gurusankar55/MarketMind-AI
- Review commit: `2578c4097be83add08543464b05c628b07425b79`
- Source submitted in this PR: `source/`
- Run tests: `python -c "from candles import get_candles; print(get_candles('BTCUSDT').tail())"`
- Run locally: `cd app && uvicorn main:app --reload`
- Deploy: Render Web Service using `pip install -r requirements.txt` and `cd app && uvicorn main:app --host 0.0.0.0 --port $PORT`
- Version binding:

GET /health

{"status":"ok","commit":"2578c4097be83add08543464b05c628b07425b79"}

GET /.well-known/xagent-verification.json

{"schemaVersion":1,"slug":"marketmind-ai","commit":"2578c4097be83add08543464b05c628b07425b79"}

## Verification

The reproducible call instructions and example responses are in `verification/README.md`.

- Health-check result: HTTP 200 with status `ok` and the exact deployed review commit.
- Capability call: GET /v1/market-intelligence/BTCUSDT returns current market price, EMA20, EMA50, EMA200, RSI14, MACD, MACD signal, and a market assessment score/regime.
- Expected error behavior: Unsupported or invalid symbols may return an HTTP error. The API does not require authentication.

## Security and data handling

- Data collected: Public cryptocurrency market candle data.
- Purpose and retention: Data is used only to calculate market indicators and assessment for the API response. No user account data is stored.
- Third parties / outbound network calls: Public Kraken market-data API.
- Secrets: No secrets are committed. No authentication credentials are required.
- Known risks / restrictions: Market data can change rapidly and should be treated as informational market intelligence, not guaranteed financial advice or trade execution.

## Support

- Team / builder: gurusankar55
- Contact: GitHub repository issues
- License / rights: Project source is submitted by the builder for hackathon review and archival.
1 change: 1 addition & 0 deletions submissions/mcp-hackathon/marketmind-ai/source/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
__pycache__/
41 changes: 41 additions & 0 deletions submissions/mcp-hackathon/marketmind-ai/source/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# MarketMind AI

Agent-callable crypto market intelligence API.

## Features

- Public crypto market candle data
- EMA 20, 50, 200
- RSI 14
- MACD
- Market assessment score
- Simple JSON API for AI agents
- X-Agent verification endpoints

## API

GET `/v1/market-intelligence/{symbol}`

Examples:

`/v1/market-intelligence/BTCUSDT`

`/v1/market-intelligence/ETHUSDT`

`/v1/market-intelligence/SOLUSDT`

## Health

GET `/health`

## X-Agent Verification

GET `/.well-known/xagent-verification.json`

## Tech Stack

- Python
- FastAPI
- Pandas
- Requests
- Kraken public market data
86 changes: 86 additions & 0 deletions submissions/mcp-hackathon/marketmind-ai/source/app/candles.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import requests
import pandas as pd

KRAKEN_URL = "https://api.kraken.com/0/public/OHLC"


def get_candles(symbol: str, interval: str = "1h", limit: int = 250):
symbol = symbol.upper()

if not symbol.endswith("USDT"):
raise ValueError("Only USDT pairs are supported")

base = symbol[:-4]

# Kraken uses XBT instead of BTC
if base == "BTC":
pair = "XBTUSD"
else:
pair = f"{base}USD"

response = requests.get(
KRAKEN_URL,
params={
"pair": pair,
"interval": 60
},
timeout=15
)

response.raise_for_status()

result = response.json()

if result.get("error"):
raise RuntimeError(
"Kraken market data error: " + str(result["error"])
)

data = result["result"]

pair_key = [key for key in data.keys() if key != "last"][0]
candles = data[pair_key]

if not candles:
raise RuntimeError("No candle data returned")

df = pd.DataFrame(
candles,
columns=[
"open_time",
"open",
"high",
"low",
"close",
"vwap",
"volume",
"count"
]
)

df["open_time"] = pd.to_datetime(
df["open_time"],
unit="s"
)

for column in ["open", "high", "low", "close", "volume"]:
df[column] = pd.to_numeric(
df[column],
errors="coerce"
)

df = df[
[
"open_time",
"open",
"high",
"low",
"close",
"volume"
]
]

df = df.dropna()
df = df.tail(limit).reset_index(drop=True)

return df
28 changes: 28 additions & 0 deletions submissions/mcp-hackathon/marketmind-ai/source/app/indicators.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import pandas as pd


def calculate_indicators(df):
df = df.copy()

df["ema20"] = df["close"].ewm(span=20, adjust=False).mean()
df["ema50"] = df["close"].ewm(span=50, adjust=False).mean()
df["ema200"] = df["close"].ewm(span=200, adjust=False).mean()

delta = df["close"].diff()

gain = delta.clip(lower=0)
loss = -delta.clip(upper=0)

avg_gain = gain.rolling(14).mean()
avg_loss = loss.rolling(14).mean()

rs = avg_gain / avg_loss.replace(0, pd.NA)
df["rsi14"] = 100 - (100 / (1 + rs))

ema12 = df["close"].ewm(span=12, adjust=False).mean()
ema26 = df["close"].ewm(span=26, adjust=False).mean()

df["macd"] = ema12 - ema26
df["macd_signal"] = df["macd"].ewm(span=9, adjust=False).mean()

return df
72 changes: 72 additions & 0 deletions submissions/mcp-hackathon/marketmind-ai/source/app/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import os

from fastapi import FastAPI

from candles import get_candles
from indicators import calculate_indicators
from scoring import calculate_score


app = FastAPI(
title="MarketMind AI",
description="Agent-callable crypto market intelligence API",
version="0.3.0"
)


PROJECT_SLUG = "marketmind-ai"


@app.get("/")
def root():
return {
"name": "MarketMind AI",
"status": "online",
"version": "0.3.0"
}


@app.get("/health")
def health():
commit = os.getenv("RENDER_GIT_COMMIT", "development")

return {
"status": "ok",
"commit": commit
}


@app.get("/.well-known/xagent-verification.json")
def xagent_verification():
commit = os.getenv("RENDER_GIT_COMMIT", "development")

return {
"schemaVersion": 1,
"slug": PROJECT_SLUG,
"commit": commit
}


@app.get("/v1/market-intelligence/{symbol}")
def market_intelligence(symbol: str):
df = get_candles(symbol)

df = calculate_indicators(df)

latest = df.iloc[-1]

score = calculate_score(latest)

return {
"symbol": symbol.upper(),
"price": float(latest["close"]),
"indicators": {
"ema20": float(latest["ema20"]),
"ema50": float(latest["ema50"]),
"ema200": float(latest["ema200"]),
"rsi14": float(latest["rsi14"]),
"macd": float(latest["macd"]),
"macdSignal": float(latest["macd_signal"])
},
"marketAssessment": score
}
26 changes: 26 additions & 0 deletions submissions/mcp-hackathon/marketmind-ai/source/app/market_data.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import requests

BINANCE_URL = "https://fapi.binance.com/fapi/v1/ticker/24hr"


def get_market_data(symbol: str):
symbol = symbol.upper()

response = requests.get(
BINANCE_URL,
params={"symbol": symbol},
timeout=10
)

response.raise_for_status()
data = response.json()

return {
"symbol": data["symbol"],
"price": float(data["lastPrice"]),
"priceChange24h": float(data["priceChangePercent"]),
"volume24h": float(data["volume"]),
"quoteVolume24h": float(data["quoteVolume"]),
"high24h": float(data["highPrice"]),
"low24h": float(data["lowPrice"])
}
41 changes: 41 additions & 0 deletions submissions/mcp-hackathon/marketmind-ai/source/app/scoring.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
def calculate_score(row):
score = 50

if row["close"] > row["ema20"]:
score += 10
else:
score -= 10

if row["ema20"] > row["ema50"]:
score += 10
else:
score -= 10

if row["ema50"] > row["ema200"]:
score += 10
else:
score -= 10

if row["rsi14"] >= 55:
score += 10
elif row["rsi14"] < 45:
score -= 10

if row["macd"] > row["macd_signal"]:
score += 10
else:
score -= 10

score = max(0, min(100, score))

if score >= 65:
regime = "bullish"
elif score <= 35:
regime = "bearish"
else:
regime = "neutral"

return {
"score": score,
"regime": regime
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
fastapi
uvicorn
pandas
requests
1 change: 1 addition & 0 deletions submissions/mcp-hackathon/marketmind-ai/source/start.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
uvicorn main:app --host 0.0.0.0 --port 8000
Loading