Skip to main content
Glama
seonglae

openportfolio

by seonglae

openportfolio

모든 계좌를 하나의 장부로. 모든 예측을 기록으로.

오픈소스, 자체 호스팅 포트폴리오 트래커. 모든 증권사, 연금, 지갑, 은행 계좌를 하나의 순자산으로 모으고, 가격 뒤에 있는 투자자 자금 흐름을 저장하며, 사전에 등록한 예측을 Brier 점수로 평가합니다. 어디에도 제공업체 API 키가 없습니다.

License npm TypeScript Stars

웹사이트 · 문서 · 라이브 데모

Deploy with Vercel

대시보드와 백엔드를 한 번에 배포합니다. 동기화 워커는 설계상 사용자 머신에서 실행됩니다: 배포 참조.

스크린샷은 데모 장부를 보여줍니다. 모든 수치는 가상입니다.

상태: 사전 릴리스. 실행되며 아래 설정이 작동합니다. 인터페이스는 여전히 변경될 수 있습니다.

거래 봇이 아닙니다. 백엔드에는 주문을 체결하는 기능이 없고, 포함된 어댑터는 canPlaceOrders: false를 선언하며, PlaceOrderRequest는 기본값이 없는 OrderConfirmation을 요구합니다. 이 도구가 하는 일은 집계, 관찰, 그리고 점수 기록입니다.

서로 무관해 보이지만 실제로는 같은 문제인 두 가지 문제.

포트폴리오는 구조적으로 분산되어 있습니다. 여기 증권사, 저기 연금, ISA, 거래소 계좌, 은행 잔고, 어떤 API도 반환하지 못하는 보유 자산. 그 앱들은 각자 숫자를 보여주지만, 어느 것도 당신의 숫자를 보여주지 않습니다. 그래서 실제로 결정을 좌우하는 수치들, 총액, 특정 종목에의 집중도, 지출하지 않는 통화로 보유된 비중 같은 것들은 아무도 가지고 있지 않은 수치입니다. 추정에 의존하게 되고, 그 추정은 결정을 회피하는 방향으로 관대해집니다.

시장 논평은 책임을 묻지 않습니다. 그리고 모델이 무엇을 묻든 자신만만한 방향성 전망을 내놓게 된 순간부터 더욱 그렇게 되었습니다. 문제는 전망이 틀렸다는 것이 아닙니다. 틀려도 아무런 대가가 없고 흔적도 남지 않는다는 것이 문제입니다. 그래서 읽을 가치가 있는 예측가와 그저 말만 유창한 예측가는 외부에서도, 내부에서도 구분할 수 없습니다.

둘 다 회계 실패이므로, openportfolio는 이를 회계로 취급합니다.

하나의 순자산

거래처 어댑터를 통해 단일 기준 통화로 계좌를 모으고, 환율은 변환된 행에 저장되어 스냅샷이 오늘의 환율이 아니라 그 시점의 장부 가치를 기록합니다. 세 곳에 나뉘어 보유된 포지션은 하나의 익스포저입니다.

가격이 아닌 자금 흐름

가격은 누가 사고 누가 팔 수밖에 없었는지의 결과물입니다. 투자자 유형별 순매수, 회전율, 날짜가 있는 선물 이벤트 달력은 누군가 물어볼 때 파생되는 것이 아니라 일급 시리즈로 저장됩니다. 강제 매도자는 일정이 있으며 그 일정은 공개됩니다. 참가자 유형별 포지셔닝은 CFTC의 주간 Commitments of Traders에서 키 없이 제공됩니다.

점수가 매겨진 실적 기록

예측은 확률, 기간, 그리고 이를 확정하는 조건과 함께 사전에 등록됩니다. 기간이 지나면 기계적으로 확정 가능한 예측은 스스로 확정되고 Brier 점수가 매겨집니다. 신뢰도 다이어그램이 핵심 산출물입니다: 당신이 말한 것, 실제 일어난 일, 그리고 그 사이의 간극을 보여줍니다.

오직 한 가지 이유로 존재하는 네 번째 테이블이 있습니다. "발표를 기다렸다가 결정하라"는 형태의 권고는 말하는 순간 증발합니다. decisions는 그러한 결정들의 대기열이며, 각각 트리거 조건과 결과를 가지며, 그중 하나가 바뀔 때까지 보드에 남아 있습니다.

Related MCP server: FinChat

제공업체 API 키 없음

장부를 관찰하는 것은 실제로 무언가가 관찰하고 있을 때만 유용합니다: 장 마감 후 정산, 기간이 지난 날 예측 확정, 3주 전에 만기가 된 연기된 결정을 발견하는 것.

종량제 추론은 그런 용도에 맞지 않습니다. 실행마다 토큰당 비용이 청구되면 모든 자동 점검이 구매가 되고, 운영자의 돈을 요청 없이 쓰는 제품은 먼저 물어보거나, 일괄 처리하거나, 배급해야 합니다. 세 가지 모두 스스로를 관찰하는 포트폴리오를 보려면 허락을 구해야 하는 포트폴리오로 만듭니다.

그래서 모든 모델 호출은 대신 이미 로그인되어 있는 에이전트 CLI로 전달됩니다: codex, antigravity, 또는 claude, 작업별 폴백 순서가 있습니다. 이 저장소에는 제공업체 키가 없고 넣을 필드도 없습니다. 그렇다고 실행이 무료라는 뜻은 아닙니다: 구독 요금제에는 속도 제한이 있고, 폴백 체인이 존재하는 이유 중 하나는 한 제공업체가 다른 제공업체보다 먼저 한도에 도달하기 때문입니다. 달라지는 것은 제한의 종류입니다. 에이전트 작업은 지출이 아니라 할당량과 실제 시간에 의해 제한되므로, 호출 하나하나를 정당화할 필요가 없습니다.

결과적으로 openportfolio는 설계상 자체 호스팅입니다. 사용자의 배포는 사용자의 머신에서 사용자의 로그인으로, 사용자의 계정에 대해 동기화를 실행합니다.

기능

표면

순자산

계좌, 잔고, 거래처별·자산군별 세분화, 단일 기준 통화 스냅샷, 키 없는 환율

거래처

선언된 기능이 있는 어댑터 계약; 상장 종목과 코인용 키 없는 시세 어댑터, 수동 어댑터 포함

자금 흐름

세션별, 시장별 또는 심볼별 투자자 유형별 순매수 및 회전율

예측

확률, 기간, 확정 기준; 기간 만료 시 자동 확정; Brier 점수 및 신뢰도 구간

결정

연기된 결정 대기열, 트리거 조건 및 결과 포함

촉매

날짜가 있는 선물 이벤트와 그 영향 자산

감사

모든 상태 변경 변이의 추가 전용 기록, 크론이 무인으로 수행한 작업 포함

MCP

codex / antigravity / claude가 장부를 직접 읽고 쓸 수 있는 25개 도구

멀티 테넌시

모든 테이블이 테넌트로 범위 지정, 모든 인덱스가 테넌트로 시작, 테넌트당 서비스 키 하나

빠른 시작

Node 22+, pnpm, Convex 계정 필요. 무료 티어로 충분합니다.

git clone https://github.com/seonglae/openportfolio.git
cd openportfolio
pnpm install

cp .env.example .env.local
npx convex dev --once          # creates the deployment

# create the first book
npx convex env set OPENPORTFOLIO_DEV_TENANT home
npx convex run tenants:create '{"slug":"home","name":"Home","baseCurrency":"GBP"}'

# the UI, then the sync loop
pnpm --filter openportfolio-browser dev   # http://localhost:6101
npx tsx sync-worker.mts --once

아무것도 연결하지 않으면 제공 가능한 거래처를 등록하고 순자산 0을 기록하는데, 이는 정확합니다. 실제 값을 얻으려면 수동 보유 파일을 추가하세요:

[
  { "accountKey": "isa", "symbol": "VWRL", "assetClass": "etf", "qty": 40, "price": 118.2, "currency": "GBP" },
  { "accountKey": "wallet", "symbol": "BTC", "assetClass": "crypto", "qty": 0.15, "price": 0, "currency": "USD" }
]
export OPENPORTFOLIO_MANUAL_HOLDINGS=$PWD/holdings.json
npx convex run accounts:link '{"accountKey":"isa","venue":"manual","kind":"brokerage","label":"ISA","currency":"GBP"}'
npx convex run accounts:link '{"accountKey":"wallet","venue":"manual","kind":"wallet","label":"Wallet","currency":"USD"}'
npx tsx sync-worker.mts --once

파일의 가격은 시작점일 뿐 기록이 아닙니다: 워커는 자산군별로 라우팅된 키 없는 소스로 가능한 모든 행을 다시 시세 조회하고, GBP로 변환하여 총액 하나를 기록합니다. 주식, ETF, 펀드는 Yahoo로, 코인은 CoinGecko로 갑니다. 기록된 가격 자체가 기록인 행, 예를 들어 연금이나 부동산은 other 클래스로 지정되며, 어떤 시세 소스도 조회하지 않습니다.

전체 가이드: openportfolio.app/docs/quickstart

또는 배포하기

Deploy with Vercel

이 흐름은 이 저장소를 사용자의 Git 계정으로 복제하고, Vercel Marketplace에서 Convex 통합을 설치하고, 사용자의 Convex 팀 아래에 Convex 프로젝트를 프로비저닝하고, 하나의 값을 요청한 다음, 두 부분을 단일 명령으로 빌드합니다:

npx convex deploy --cmd-url-env-var-name VITE_CONVEX_URL --cmd 'pnpm --filter openportfolio-browser build'

Marketplace 단계가 이 흐름이 한 번의 클릭인 유일한 이유입니다: Vercel은 사용자를 따로 보내 백엔드를 먼저 만들게 하는 대신 가져오기 중에 백엔드를 생성할 수 있고, 빌드에 배포 키를 전달합니다. vercel.jsonCONVEX_DEPLOY_KEY에 따라 명령을 보호하고 일반 브라우저 빌드로 폴백하므로, 같은 파일이 직접 프로비저닝한 배포에 호스팅 페이지를 원하는 경우도 처리합니다. 가드가 없으면 그 경우 빌드가 실패합니다.

아무것도 요구하지 않습니다. 로그인은 방금 생성된 배포 내부에서 실행되므로 키가 필요 없습니다: 인증은 비밀번호 제공자를 사용하는 Convex Auth이며, 사용자의 배포가 자체 토큰을 발행하고 검증하므로 로그인은 배포를 벗어나지 않습니다. 경로에 인증 회사가 없고, 다른 곳에 만들 계정도 없습니다. Convex Auth는 상류에서 베타 상태이며, 이것이 이 선택의 정직한 비용입니다.

그러면 Convex 쪽에서 명령 하나로 배포의 서명 키를 생성하고 첫 번째 책을 만듭니다. 첫 번째 가입자가 그 책을 소유합니다:

npx @convex-dev/auth
npx convex run tenants:create '{"slug":"home","name":"Home","baseCurrency":"GBP"}'

그러면 가입은 자동으로 닫힙니다. 어떤 테넌트에도 속하지 않은 호출자는 오직 최초의 책만 만들 수 있으므로, 공개 URL이 다른 사람의 백엔드가 되지 않습니다. OPENPORTFOLIO_OPEN_SIGNUP=1로 다시 열 수 있습니다.

동기화 워커는 여기에 포함되지 않으며 포함될 수도 없습니다. 워커는 어댑터를 통해 계정을 읽고, 모델 작업을 사용자가 로그인한 에이전트 CLI에 전달하는데, 서버리스 함수 안에는 로그인된 CLI가 없습니다. 배포된 절반은 여전히 예측을 해결하고 Convex 자체 크론에서 점수를 매깁니다. 잔액을 새로 고치고 싶을 때 워커를 실행하세요. 자세한 내용: Deploying.

Cloudflare 버튼은 없습니다. 그 버튼은 Workers만 지원하며, 모노레포 모드는 앱이 하위 디렉터리에 완전히 격리되어 있어야 하는데 browser/는 그렇지 않습니다.

공개하기 전에

로컬호스트에서 열려 있는 두 가지가 있으며, 배포가 인터넷에서 접근 가능해지기 전에 닫아야 합니다.

  1. 개발 테넌트. OPENPORTFOLIO_DEV_TENANT가 설정되어 있는 동안에는 인증되지 않은 모든 호출자가 그 테넌트로 범위가 지정됩니다. 이 값을 해제하세요. 로그인은 이미 있으며 구성이 필요 없습니다.

  2. 서비스 키. 워커와 MCP 서버는 브라우저 세션이 없으므로 키를 제시합니다. 로컬에서 생성하고 해시만 보내세요.

npx @convex-dev/auth          # once, generates this deployment's signing keys
npx convex env unset OPENPORTFOLIO_DEV_TENANT

KEY="$(openssl rand -hex 32)"
npx convex run tenants:issueServiceKey "{\"key\":\"$KEY\",\"label\":\"sync-worker\",\"role\":\"member\"}"
echo "OPENPORTFOLIO_SERVICE_KEY=$KEY" >> .env.local

멀티 테넌시

하나의 배포가 여러 책을 보유합니다. 핵심 불변식은 호출자가 자신이 어떤 테넌트인지 말하지 않는다는 것입니다.

tenantId는 호출자의 멤버십 행 또는 서비스 키 자체의 행에서 파생되므로, 클라이언트가 다른 책에 도달하기 위해 설정할 수 있는 인자가 없습니다. 공개 API는 tenantSlug를 받지만, 여러 테넌트에 속한 호출자를 위한 구분자로만 사용됩니다. 멤버십이 여전히 결정합니다. 다른 테넌트에 속한 문서 ID는 금지됨이 아니라 누락으로 읽힙니다. "금지됨"은 행이 존재한다는 것을 확인시켜 주기 때문이며, 그것 자체가 교차 테넌트 읽기가 됩니다.

모든 인덱스는 tenantId로 시작하므로, 범위를 잊은 쿼리는 인덱스를 전혀 사용할 수 없습니다. 한 가지 예외는 의도적이며 표시되어 있습니다. 리졸버 크론은 테넌트 없는 인덱스를 통해 모든 책의 기한 호출을 훑으며, 바로 그 이유로 internalMutation입니다. 어떤 클라이언트에서도 도달할 수 없습니다.

자세한 내용: openportfolio.app/docs/multi-tenancy

거래소 어댑터

어댑터는 자신이 할 수 있는 것을 선언하고 그 부분만 구현합니다:

type VenueAdapter = {
  venue: string;
  kind: AccountKind;
  capabilities: { canReadBalances: boolean; canReadQuotes: boolean; canPlaceOrders: boolean };
  readBalances(request: ReadBalancesRequest): Promise<AdapterBalance[]>;
  readQuote(request: ReadQuoteRequest): Promise<AdapterQuote>;
  placeOrder?(request: PlaceOrderRequest): Promise<OrderReceipt>;
};

네 가지가 제공되며, 그중 어느 것도 키가 필요 없습니다. yahoo는 상장된 모든 곳의 모든 것을, 상장이 거래되는 통화로 가격을 매기므로, 미국 주식, LSE ETF, KRX 종목이 있는 책은 그 어느 곳에도 계정이 없어도 최신 상태를 유지합니다. coingecko는 코인 가격을 매깁니다. 둘 다 잔액을 거부합니다. 가격 소스는 보유 내역을 알지 못하며, 빈 목록을 반환하면 "아무것도 보유하지 않음"으로 읽히기 때문입니다. manual은 사용자가 유지하는 JSON 파일을 읽습니다. 이는 연금이나 비상장 보유분이 총액에서 빠지지 않고 포함되는 방식입니다. csv는 브로커 자체 내보내기를 읽습니다. OPENPORTFOLIO_CSV_DIR을 폴더로 지정하고 <accountKey>.csv를 그 안에 넣으세요. 열은 이름으로 일치하므로 대부분의 내보내기는 수정 없이 작동하며, API가 전혀 없는 계정도 포함합니다.

어떤 소스가 어떤 행의 가격을 매길지는 이미 그 행에 있는 자산 클래스로 결정되며, 다른 소스로 폴백하지 않습니다. 둘 다 잘못된 도구에 HTTP 200으로 응답합니다. Yahoo에 BTC를 요청하면 비트코인 약 $68,000 대신 약 $30의 Grayscale 신탁을 반환하고, CoinGecko에는 약 18센트 가치의 aapl이라는 ID의 토큰이 있습니다. 총액의 잘못된 숫자는 누락된 숫자보다 더 나쁘므로, 어느 소스에도 물어보면 안 되는 클래스는 그냥 재가격하지 않습니다.

키가 있는 브로커 어댑터는 제공되지 않습니다. 추가하려면 packages/node/src/adapters/에 모듈을 작성하고, 워커 환경에서 자격 증명을 가져오고, defaultRegistry()에 등록해야 합니다. 자격 증명을 워커 프로세스에 유지하세요. 백엔드는 그것을 보지 못하며, 이 저장소도 보지 못합니다.

자세: openportfolio.app/docs/adapters

요구 사항

  • Node 22+, pnpm

  • Convex 계정 (무료 티어로 충분)

  • 에이전트 워커를 원한다면 로그인된 에이전트 CLI가 하나 이상: codex, antigravity (agy), 또는 claude

  • 그 외에는 없습니다. 인증은 자체 배포에서 실행되는 Convex Auth이므로, 가입할 ID 공급자가 없습니다

개발

pnpm typecheck     # every workspace, src and test alike
pnpm test          # vitest across packages, convex handlers, browser helpers

# the demo build used for the screenshots and the hosted demo
pnpm --filter openportfolio-browser exec vite build --config vite.demo.config.ts

# the marketing site and docs are static; regenerate the docs pages after editing
python3 site/build-docs.py

규칙, 테넌트 불변식 전체, 그리고 이 저장소에서 작업하는 에이전트 CLI를 위한 참고 사항은 AGENTS.md에 있습니다.

라이선스

Apache-2.0. LICENSE를 참조하세요.

A
license - permissive license
Not graded
quality - not tested
C
maintenance

Maintenance

1Maintainers
No responseResponse time
Release cycle
0Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables AI agents to manage and analyze personal investment portfolios, including fund and stock holdings, net value tracking, XIRR calculations, penetration analysis, and backtesting.
    Apache 2.0
  • F
    license
    Not graded
    quality
    C
    maintenance
    Enables AI agents to manage personal finances through MCP tools for transaction management, spending analytics, and goal tracking.
    1
  • F
    license
    Not graded
    quality
    B
    maintenance
    Self-hosted household finance app for shared expenses, budgets, investments, loans, and zakat, exposing MCP tools for AI agents to manage finances via natural language.
    3
  • F
    license
    Not graded
    quality
    C
    maintenance
    An MCP server that exposes personal financial data — transaction ledger, portfolio holdings, live/historical market prices, and quantitative risk metrics — as standardized tools, resources, and prompts, enabling natural language reasoning over real computed numbers.

View all related MCP servers

Related MCP Connectors

  • Real SEC, 13F, insider, congress & macro data your AI agent can cite. Hosted MCP, 24 tools.

  • The financial MCP for AI agents - 90+ financial tables, SEC filings, signals, alt-data.

  • Shared long-term memory vault for AI agents with 20 MCP tools.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/seonglae/openportfolio'

If you have feedback or need assistance with the MCP directory API, please join our Discord server