技能创建器
skill-creator
创建、改进和评估自定义技能,把专业流程转化为可重复使用的 AI 能力。
plaid-investments【数据与研究】Implements investment tracking features via the Plaid API (InvestmentsGet, HoldingsList, Transactions) to access and manage investment portfolio data for users in financial applications.
独立 GitHub 快照 · 自动分类 · 以原作者文档为准
name: plaid-investments description: Implements investment tracking features via the Plaid API (InvestmentsGet, HoldingsList, Transactions) to access and manage investment portfolio data for users in financial applications. license: MIT compatibility: opencode metadata: version: "1.0.0" domain: payments triggers: plaid investments, investment tracking, plaid investments get, portfolio holdings, investment positions, securities data, brokerage account sync, asset allocation archetypes: tactical anti_triggers: - brainstorming - vague ideation response_profile: verbosity: low directive_strength: high abstraction_level: operational role: implementation scope: implementation output-format: code related-skills: plaid-authentication, plaid-transactions
Implements investment portfolio management workflows using the Plaid Investments API to retrieve holdings, positions, securities data, and investment-related transactions from linked brokerage accounts. Covers portfolio aggregation, asset allocation analysis, and performance tracking.
InvestmentsGet with a valid access token from the auth flowinvestments) in your Link Token requestUse this skill when:
Avoid this skill for:
investments product.import plaid
from dataclasses import dataclass, field
from typing import Optional, List
from datetime import datetime
@dataclass
class InvestmentPosition:
"""A single investment holding/position from Plaid."""
position_id: str
institution_name: str
quantity: float
unit_price: Optional[float] # May be null for some institutions
market_value: Optional[float]
security_id: str
type: str # "equity", "etf", "mutual_fund", "fixed_income"
name: str
ticker_symbol: Optional[str]
@dataclass
class PortfolioSnapshot:
"""Aggregated portfolio snapshot."""
positions: List[InvestmentPosition] = field(default_factory=list)
total_market_value: float = 0.0
total_cost_basis: Optional[float] = None
gain_loss: Optional[float] = None
gain_loss_percentage: Optional[float] = None
class PlaidInvestmentsService:
"""Service for retrieving and analyzing investment portfolio data from Plaid."""
def __init__(self, client_id: str, secret: str, environment: str = "sandbox"):
self.client = plaid.Client(
client_id=client_id,
secret=secret,
environment=getattr(plaid.Environment, environment),
)
def get_investments(self, access_token: str) -> dict:
"""Fetch investment holdings and positions from Plaid."""
response = self.client.InvestmentsGetV2(access_token=access_token)
return response
@staticmethod
def _parse_position(data: dict) -> InvestmentPosition:
"""Parse a single position dictionary into a typed object."""
security = data.get("security", {})
return InvestmentPosition(
position_id=data["position_id"],
institution_name=data.get("institution_name", "Unknown"),
quantity=float(data.get("quantity", 0)),
unit_price=float(data["unit_price"]) if data.get("unit_price") else None,
market_value=float(data["market_value"]) if data.get("market_value") else None,
security_id=security.get("investment_type", "unknown"),
type=security.get("type", "equity"),
name=security.get("name", "Unknown"),
ticker_symbol=security.get("ticker_symbol"),
)
def analyze_portfolio(self, access_token: str) -> PortfolioSnapshot:
"""Retrieve and aggregate investment data into a portfolio snapshot."""
result = PortfolioSnapshot()
try:
response = self.get_investments(access_token)
except plaid.errors.PlaidApiError as e:
raise RuntimeError(f"Failed to retrieve investments: {e}") from e
raw_positions = response.get("positions", [])
for pos_data in raw_positions:
result.positions.append(self._parse_position(pos_data))
# Calculate totals
values = [p.market_value for p in result.positions if p.market_value is not None]
result.total_market_value = sum(values)
cost_basis = [p.unit_price * p.quantity for p in result.positions if p.unit_price]
if cost_basis:
result.total_cost_basis = sum(cost_basis)
result.gain_loss = result.total_market_value - result.total_cost_basis
if result.total_cost_basis > 0:
result.gain_loss_percentage = (result.gain_loss / result.total_cost_basis) * 100
return result
from collections import defaultdict
class AssetAllocationAnalyzer:
"""Analyze portfolio allocation across asset types and sectors."""
@staticmethod
def compute_allocation(positions: List[InvestmentPosition], total_value: float) -> dict:
"""Compute asset allocation percentages by position type."""
if total_value == 0:
return {}
allocation = defaultdict(float)
for pos in positions:
pct = (pos.market_value or 0) / total_value * 100
allocation[pos.type] += pct
return {
asset: round(pct, 2)
for asset, pct in sorted(allocation.items(), key=lambda x: -x[1])
}
@staticmethod
def generate_allocation_summary(
positions: List[InvestmentPosition], total_value: float
) -> str:
"""Generate a human-readable allocation summary."""
allocation = AssetAllocationAnalyzer.compute_allocation(positions, total_value)
lines = [f"Portfolio Total: ${total_value:,.2f}"]
for asset_type, pct in allocation.items():
bar = "#" * int(pct / 2)
lines.append(f" {asset_type:>15}: {pct:5.1f}% {bar}")
return "\n".join(lines)
def get_investment_transactions(client, access_token: str, count: int = 20) -> List[dict]:
"""Retrieve recent investment-related transactions."""
response = client.TransactionsGet(
access_token=access_token,
count=count,
product_types=["transactions"],
)
# Filter for investment-type transactions (buys, sells, dividends)
investment_txns = [
txn for txn in response.get("transactions", [])
if txn.get("payment_category", {}).get("subcategory") in [
"Investment Transfer", "Dividend", "Capital Gain Distribution"
]
]
return investment_txns
investments product when creating Link Tokens for brokerage accounts.When implementing Plaid Investments, output must contain:
InvestmentsGetV2 invocation with proper error handling| Skill | Purpose |
|---|---|
plaid-authentication | Initial brokerage account linking before investment data retrieval |
plaid-transactions | Combine banking and investment transactions for full financial picture |
Authoritative documentation links for this skill's domain. The model follows markdown links to resolve external references and inline content.