agents/openai.yaml
interface: display_name: "Kanchi Dividend Us Tax Accounting" short_description: "Help with Kanchi Dividend Us Tax Accounting tasks"
tradermonty/claude-trading-skills · GitHub
Provide US dividend tax and account-location workflow for Kanchi-style income portfolios. Use when users ask about qualified vs ordinary dividends, 1099-DIV interpretation, REIT/BDC distribution treatment, holding-period checks, or taxable-vs-IRA account placement decisions for dividend assets.
프로젝트 폴더에서 아래 명령어를 실행하고, 설치할 에이전트를 선택하세요.
npx skills add tradermonty/claude-trading-skills --skill kanchi-dividend-us-tax-accounting설치 명령을 직접 실행해야 적용됩니다. 지원 에이전트와 필요한 권한·라이선스는 제작자의 안내를 확인하세요.
agents/openai.yamlinterface: display_name: "Kanchi Dividend Us Tax Accounting" short_description: "Help with Kanchi Dividend Us Tax Accounting tasks"
references/account-location-matrix.md# Account Location Matrix Use this matrix to propose placement between taxable and tax-advantaged accounts. ## Baseline Placement Logic | Instrument profile | Taxable account | Tax-advantaged account | Rationale | |---|---|---|---| | Qualified-dividend-heavy US equity | Usually preferred | Optional | Potentially better ongoing tax efficiency in taxable account | | REIT-heavy income holdings | Less preferred | Often preferred | Distribution may include higher ordinary-income components | | BDC/high-distribution structures | Less preferred | Often preferred | Tax treatment can be less favorable in taxable account | | MLP (partnership units) | Case-by-case | Caution in tax-advantaged accounts | UBTI and K-1 complexity can make placement non-trivial | | Broad index ETF with low turnover | Often acceptable | Also acceptable | Depends on overall asset-location design | If MLP is outside mandate, mark it explicitly as `OUT-OF-SCOPE` and exclude from default allocation logic. ## Conflict Resolution Rules When account-location recommendation conflicts with other needs: 1. Respect concentration and risk controls first. 2. Respect liquidity/withdrawal constraints second. 3. Optimize taxes third. ## Output Format Return one line per holding: ```text [Ticker] -> [Recommended Account] | Why: [one sentence] ```
references/annual-tax-memo-template.md# Annual Dividend Tax Planning Memo Template ```markdown # Annual Dividend Tax Planning Memo ([Year]) ## Filing Timeline - Tax year: - Filing deadline: - Extension status (filed/planned/not needed): - Expected filing date: ## Scope - Accounts included: - Holdings covered: - Data sources used: ## Assumptions - Rule set version/date: - Missing data assumptions: ## Distribution Classification Summary | Ticker | Account | Ordinary (est.) | Qualified (est.) | REIT/other components | Confidence | |---|---|---:|---:|---|---| | ... | ... | ... | ... | ... | High/Med/Low | ## Account-Location Actions | Ticker | Current location | Proposed location | Reason | |---|---|---|---| | ... | ... | ... | ... | ## Open Risks / Follow-Ups 1. ... 2. ... 3. ... ## Advisor Questions 1. ... 2. ... ``` Keep the memo concise and assumption-driven.
references/input-schema.md# Tax Planning Input Schema
Provide one JSON object with a non-empty `holdings` array.
```json
{
"holdings": [
{
"ticker": "JNJ",
"instrument_type": "stock",
"account_type": "taxable",
"security_type": "common",
"hold_days_in_window": 75
}
]
}
```
## Holding fields
- `ticker`: ticker symbol. Required operationally; missing values render as
`UNKNOWN` and must be corrected before acting.
- `instrument_type`: `stock`, `reit`, `bdc`, or `mlp`; defaults to `stock`.
- `account_type`: account label such as `taxable` or `ira`; defaults to
`unknown`.
- `security_type`: `common` or `preferred`; defaults to `common`.
- `hold_days_in_window`: integer holding days in the applicable ex-dividend
window. When absent, emit `assumption_required`.
For a not-yet-owned candidate, create a hypothetical row using the intended
account type and leave `hold_days_in_window` absent. Treat the resulting advice
as planning support, not a confirmed tax classification.
references/qualified-dividend-checklist.md# Qualified Dividend Checklist (US) Use this checklist for planning assumptions. ## Classification Pass For each holding, verify: 1. Distribution is potentially eligible for qualified treatment by instrument/type. 2. Shares meet required holding-period test around the ex-dividend date window. 3. No known disqualifying condition in the current fact pattern. If any item is uncertain, mark as `ASSUMPTION-REQUIRED`. ## Holding-Period Rules (US Federal, Common Planning Baseline) - Common stock baseline: hold shares for **more than 60 days** during the **121-day period** that starts **60 days before** the ex-dividend date. - Preferred stock (certain long-period dividends): often uses **more than 90 days** during a **181-day period** starting **90 days before** ex-dividend date. Use current IRS guidance as source of truth: - IRS Publication 550. - IRS Form 1099-DIV instructions. ## Practical Data Fields Track these fields for each position: - Ticker - Account type - Ex-dividend date - Purchase date(s) - Disposal date(s), if any - Days held in required window - Preliminary classification (`qualified-likely`, `ordinary-likely`, `unknown`) ## Common Pitfalls - Assuming all common-stock dividends will be qualified without holding-period verification. - Ignoring short holding periods caused by frequent tactical trading. - Treating REIT/BDC distributions as identical to standard qualified-dividend flows. - **Modeling special / variable dividends as steady qualified income** (WS-8 hand-off from `kanchi-dividend-sop`). When the upstream `dividend_basis` carries `special_dividend_flag` or `variable_policy_flag` (e.g. ORI annual specials, CALM variable policy), treat that cash as **lumpy and non-recurring** for account-location and cash-flow planning: budget the *regular* run-rate as base income and the special/variable component separately (timing unpredictable; may still be qualified but must not be annualized as if recurring). ## Recommended Source Hierarchy 1. Broker tax documents and distribution breakdowns. 2. Official IRS publications/instructions for current-year rules (Publication 550, 1099-DIV instructions). 3. Issuer or fund notices when classification is revised.
requirements.txt# stdlib-only: packaged scripts use the Python standard library only.
scripts/build_tax_planning_sheet.py#!/usr/bin/env python3
"""Generate a deterministic US dividend tax planning sheet."""
from __future__ import annotations
import argparse
import csv
import json
from dataclasses import dataclass
from datetime import date
from pathlib import Path
from typing import Any
@dataclass
class PlanningRow:
ticker: str
instrument_type: str
account_type: str
hold_days_in_window: int | None
classification: str
location_hint: str
note: str
def required_days(security_type: str | None) -> int:
if str(security_type or "").strip().lower() == "preferred":
return 91
return 61
def classify_holding(holding: dict[str, Any]) -> PlanningRow:
ticker = str(holding.get("ticker", "")).strip().upper() or "UNKNOWN"
instrument_type = str(holding.get("instrument_type", "stock")).strip().lower()
account_type = str(holding.get("account_type", "unknown")).strip().lower()
security_type = str(holding.get("security_type", "common")).strip().lower()
hold_days_raw = holding.get("hold_days_in_window")
hold_days: int | None
if hold_days_raw is None:
hold_days = None
else:
hold_days = int(hold_days_raw)
if instrument_type in {"reit", "bdc"}:
return PlanningRow(
ticker=ticker,
instrument_type=instrument_type,
account_type=account_type,
hold_days_in_window=hold_days,
classification="ordinary_likely",
location_hint="tax_advantaged_preferred",
note="distribution may include ordinary-income style components",
)
if instrument_type == "mlp":
return PlanningRow(
ticker=ticker,
instrument_type=instrument_type,
account_type=account_type,
hold_days_in_window=hold_days,
classification="out_of_scope_mlp",
location_hint="case_by_case",
note="check K-1 and UBTI implications before placement",
)
if hold_days is None:
return PlanningRow(
ticker=ticker,
instrument_type=instrument_type,
account_type=account_type,
hold_days_in_window=hold_days,
classification="assumption_required",
location_hint="taxable_preferred",
note="hold_days_in_window missing; cannot verify qualified treatment",
)
threshold = required_days(security_type)
if hold_days >= threshold:
classification = "qualified_likely"
note = f"hold_days_in_window >= {threshold}"
else:
classification = "ordinary_likely"
note = f"hold_days_in_window < {threshold}"
return PlanningRow(
ticker=ticker,
instrument_type=instrument_type,
account_type=account_type,
hold_days_in_window=hold_days,
classification=classification,
location_hint="taxable_preferred",
note=note,
)
def render_markdown(rows: list[PlanningRow], as_of: str) -> str:
lines = [
"# US Dividend Tax Planning Sheet",
"",
f"- as_of: `{as_of}`",
f"- holding_count: `{len(rows)}`",
"",
"| Ticker | Instrument | Account | Hold Days | Classification | Location Hint | Note |",
"|---|---|---|---:|---|---|---|",
]
for row in rows:
hold_days = "" if row.hold_days_in_window is None else str(row.hold_days_in_window)
lines.append(
f"| {row.ticker} | {row.instrument_type} | {row.account_type} | {hold_days} | "
f"{row.classification} | {row.location_hint} | {row.note} |"
)
lines.extend(
[
"",
"## Open Items",
"",
"- Confirm final classification against broker 1099-DIV and IRS current-year guidance.",
"- Escalate unresolved assumptions to CPA/tax advisor.",
"",
]
)
return "\n".join(lines)
def write_csv(path: Path, rows: list[PlanningRow]) -> None:
with path.open("w", encoding="utf-8", newline="") as f:
writer = csv.writer(f)
writer.writerow(
[
"ticker",
"instrument_type",
"account_type",
"hold_days_in_window",
"classification",
"location_hint",
"note",
]
)
for row in rows:
writer.writerow(
[
row.ticker,
row.instrument_type,
row.account_type,
row.hold_days_in_window if row.hold_days_in_window is not None else "",
row.classification,
row.location_hint,
row.note,
]
)
def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser(description="Build US dividend tax planning artifacts.")
parser.add_argument("--input", required=True, help="Path to JSON input with holdings list.")
parser.add_argument("--output-dir", default="reports", help="Output directory.")
parser.add_argument("--as-of", default=date.today().isoformat(), help="As-of date.")
return parser.parse_args()
def main() -> int:
args = parse_args()
payload = json.loads(Path(args.input).read_text())
holdings = payload.get("holdings", [])
if not isinstance(holdings, list) or not holdings:
raise SystemExit("Input JSON must include a non-empty holdings list.")
rows = [classify_holding(item) for item in holdings]
output_dir = Path(args.output_dir)
output_dir.mkdir(parents=True, exist_ok=True)
markdown_path = output_dir / f"tax_planning_sheet_{args.as_of}.md"
csv_path = output_dir / f"tax_planning_sheet_{args.as_of}.csv"
markdown_path.write_text(render_markdown(rows, args.as_of) + "\n", encoding="utf-8")
write_csv(csv_path, rows)
print(f"Wrote markdown: {markdown_path}")
print(f"Wrote csv: {csv_path}")
return 0
if __name__ == "__main__":
raise SystemExit(main())
scripts/tests/conftest.py"""Shared fixtures for Kanchi US tax accounting script tests.""" import os import sys sys.path.insert(0, os.path.join(os.path.dirname(__file__), ".."))
scripts/tests/test_build_tax_planning_sheet.py"""Tests for build_tax_planning_sheet.py."""
import csv
from pathlib import Path
from build_tax_planning_sheet import classify_holding, render_markdown, write_csv
def test_classify_stock_with_sufficient_days_is_qualified_likely() -> None:
row = classify_holding(
{
"ticker": "jnj",
"instrument_type": "stock",
"account_type": "taxable",
"hold_days_in_window": 75,
"security_type": "common",
}
)
assert row.classification == "qualified_likely"
def test_classify_missing_days_is_assumption_required() -> None:
row = classify_holding(
{
"ticker": "pg",
"instrument_type": "stock",
"account_type": "taxable",
}
)
assert row.classification == "assumption_required"
def test_classify_mlp_is_out_of_scope() -> None:
row = classify_holding(
{
"ticker": "et",
"instrument_type": "mlp",
"account_type": "ira",
"hold_days_in_window": 200,
}
)
assert row.classification == "out_of_scope_mlp"
assert row.location_hint == "case_by_case"
def test_markdown_and_csv_generation(tmp_path: Path) -> None:
rows = [
classify_holding(
{
"ticker": "o",
"instrument_type": "reit",
"account_type": "ira",
"hold_days_in_window": 100,
}
),
classify_holding(
{
"ticker": "jnj",
"instrument_type": "stock",
"account_type": "taxable",
"hold_days_in_window": 80,
}
),
]
markdown = render_markdown(rows, "2026-02-22")
assert "# US Dividend Tax Planning Sheet" in markdown
assert "| O | reit | ira | 100 | ordinary_likely |" in markdown
csv_path = tmp_path / "sheet.csv"
write_csv(csv_path, rows)
with csv_path.open() as f:
reader = list(csv.reader(f))
assert reader[0][0] == "ticker"
assert reader[1][0] == "O"
assert reader[2][0] == "JNJ"
SKILL.md--- name: kanchi-dividend-us-tax-accounting description: Provide US dividend tax and account-location workflow for Kanchi-style income portfolios. Use when users ask about qualified vs ordinary dividends, 1099-DIV interpretation, REIT/BDC distribution treatment, holding-period checks, or taxable-vs-IRA account placement decisions for dividend assets. --- # Kanchi Dividend Us Tax Accounting ## Overview Apply a practical US-tax workflow for dividend investors while keeping decisions auditable. Focus on account placement and classification, not legal/tax advice replacement. ## When to Use Use this skill when the user needs: - US dividend tax classification planning (qualified vs ordinary assumptions). - Holding-period checks before year-end tax planning. - Account-location decisions for stock/REIT/BDC/MLP income holdings. - A standardized annual dividend tax memo format. ## Prerequisites Prepare holding-level inputs: - `ticker` - `instrument_type` - `account_type` - `hold_days_in_window` (if available) Use the exact JSON contract and examples in `references/input-schema.md`. For deterministic output artifacts, provide JSON input and run: ```bash python3 skills/kanchi-dividend-us-tax-accounting/scripts/build_tax_planning_sheet.py \ --input /path/to/tax_input.json \ --output-dir reports/ ``` ## Guardrails Always state this clearly: tax outcomes depend on individual facts and jurisdiction. Treat this skill as planning support, then escalate final filing decisions to a tax professional. ## Workflow ### 1) Classify each distribution stream For each holding, classify expected cash flow into: - Potential qualified dividend. - Ordinary dividend/non-qualified distribution. - REIT/BDC-specific distribution components where applicable. Use `references/qualified-dividend-checklist.md` for holding-period and classification checks. ### 2) Validate holding-period eligibility assumptions For potential qualified treatment: - Check ex-dividend date windows. - Check required minimum holding days in the measurement window. - Flag positions at risk of failing holding-period requirement. If data is incomplete, mark status as `ASSUMPTION-REQUIRED`. ### 3) Map to reporting fields Map planning assumptions to expected tax-form buckets: - Ordinary dividend total. - Qualified dividend subset. - REIT-related components when reported separately. Use form terminology consistently so year-end reconciliation is straightforward. ### 4) Build account-location recommendation Use `references/account-location-matrix.md` to place assets by tax profile: - Taxable account for holdings likely to remain qualified-focused. - Tax-advantaged account for higher ordinary-income style distributions. When constraints conflict (liquidity, strategy, concentration), explain the tradeoff explicitly. ### 5) Produce annual planning memo Use `references/annual-tax-memo-template.md` and include: - Assumptions used. - Distribution classification summary. - Placement actions taken. - Open items for CPA/tax-advisor review. ## Output Always output: 1. Holding-level distribution classification table. 2. Account-location recommendation table with rationale. 3. Open-risk checklist for unresolved tax assumptions. 4. Optional generated artifacts from `skills/kanchi-dividend-us-tax-accounting/scripts/build_tax_planning_sheet.py`. ## Cadence Use this minimum rhythm: - Annually (60 min): full tax planning memo with account-location review. - Quarterly (15 min): refresh holding-period status for recent acquisitions. - Ad-hoc: rerun after material position changes, REIT/BDC additions, or triggered reviews from `kanchi-dividend-review-monitor`. ## Multi-Skill Handoff - Receive candidate and holding list from `kanchi-dividend-sop`. - Receive risk-event context (`WARN/REVIEW`) from `kanchi-dividend-review-monitor`. - Return account-location constraints back to `kanchi-dividend-sop` before new entries. ## Resources - `skills/kanchi-dividend-us-tax-accounting/scripts/build_tax_planning_sheet.py`: tax planning sheet generator. - `skills/kanchi-dividend-us-tax-accounting/scripts/tests/test_build_tax_planning_sheet.py`: tests for tax planning outputs. - `references/qualified-dividend-checklist.md`: classification and holding-period checks. - `references/account-location-matrix.md`: placement matrix by account type and instrument. - `references/annual-tax-memo-template.md`: reusable memo structure.