Manual de operación del repositorio kline_timestamp para agentes LLM y humanos.
Este archivo describe cómo operar, mantener y contribuir al repositorio kline_timestamp. Está pensado para que tanto agentes automatizados como desarrolladores humanos puedan trabajar de forma autónoma con información verificable.
- Distribution name (PyPI):
kline_timestamp - Import name:
kline_timestamp(flat layout, paquete enkline_timestamp/) - Versión actual:
0.3.0(hardcoded ensetup.py:20) - Gestión de versión: manual, string literal en
setup.py. No usa SCM niversion.py. - Packaging:
setup.pyclásico (setuptools). No haypyproject.tomlnisetup.cfg. - Licencia: MIT
- Python requerido:
>=3.9
pandas>=2.3.0,<3.0pytz>=2024.1
Declaradas en requirements.txt y leídas por setup.py.
kline_timestamp/ ← raíz del repo
├── kline_timestamp/ ← paquete importable
│ ├── __init__.py ← re-exporta KlineTimestamp
│ └── kline_timestamp.py ← clase principal (única)
├── examples/
│ └── kline_timestamp_basic.ipynb
├── dist/ ← artefactos de build (whl + tar.gz 0.2.0)
├── kline_timestamp.egg-info/
├── setup.py
├── requirements.txt
├── MANIFEST.in
├── deploy.sh ← script de build + upload a PyPI
├── README.md
├── CHANGELOG.md
├── LICENSE
└── .gitignore
- Layout: flat (no
src/). - Módulo único: toda la lógica está en
kline_timestamp/kline_timestamp.py. - Clase principal:
KlineTimestamp- dataclass frozen, inmutable. - Intervalos soportados: 1m, 3m, 5m, 15m, 30m, 1h, 2h, 4h, 6h, 8h, 12h, 1d, 3d, 1w (fijos) + 1M (mensual, variable).
- No hay: tests, linters, type-checkers, CI, docs (Sphinx/MkDocs), ni entrypoints CLI.
- Test runner: no detectado. No hay directorio
tests/ni configuración de pytest/unittest. - Linters/formatters: no detectados. No hay
ruff.toml,.flake8,pyproject.tomlcon config, etc. - Type checker: no detectado. No hay config de mypy/pyright.
- CI: no detectado. No hay
.github/workflows/ni.gitlab-ci.yml. - Gestión de deps: pip directo (
requirements.txt). No usa poetry/pdm/uv.
- No hay Sphinx ni MkDocs.
- La documentación es el
README.mdy el notebook de ejemplo.
- Remotes:
github->git@github.com:nand0san/KlineTimestamp.gitnas->ssh://ffad@192.168.89.201/.../kline_timestamp(NAS local)
- Rama actual:
master(trackingnas/master) - Otras ramas locales:
github(apunta a commit631675a, release 0.2.0) - Ramas remotas:
github/github,nas/github,nas/master - Remote HEAD: no determinable (el remote
originno existe; haygithubynas) - Tags: ninguno
- Convención de ramas: no formalizada.
masteres la rama de desarrollo principal. - Convención de commits: mensajes cortos en español/inglés, sin formato estricto.
- Publicado: sí,
kline_timestampversión0.2.0(2025-11-23) - Summary: "KlineTimestamp is a Python library designed to efficiently handle timestamps within discrete time intervals (klines/candlesticks), commonly used in financial data analysis."
- Home page: https://github.com/nand0san/kline_timestamp
- Author: nand0san
Referencia rapida para que un agente pueda usar kline_timestamp sin leer el codigo fuente.
from kline_timestamp import KlineTimestampKlineTimestamp(timestamp_ms: int, interval: str, tzinfo: str | pytz.BaseTzInfo = "UTC")timestamp_ms: epoch en milisegundos (UTC). Debe serint(nofloat).interval: intervalo de la vela. Case-insensitive excepto1M(mensual).tzinfo: zona horaria para presentacion. No afecta identidad ni comparaciones.
Fijos: 1m, 3m, 5m, 15m, 30m, 1h, 2h, 4h, 6h, 8h, 12h, 1d, 3d, 1w
Variable: 1M (mensual, 28-31 dias segun mes). Case-sensitive: 1M != 1m.
kt.open- primer ms de la vela (epoch ms UTC)kt.close- ultimo ms de la vela (epoch ms UTC)kt.tick_ms- duracion de la vela en ms (variable para 1M)kt.interval- intervalo normalizado (str)kt.tzinfo- zona horaria (pytz.BaseTzInfo)kt.timestamp_ms- timestamp original pasado al constructor
# Conversiones
kt.to_datetime() # -> datetime.datetime (tz-aware)
kt.to_pandas_timestamp() # -> pd.Timestamp (tz-aware)
# Transformaciones inmutables (devuelven nueva instancia)
kt.with_timezone("UTC") # cambiar zona horaria
kt.with_interval("15m") # cambiar intervalo (re-snap)
# Navegacion
kt.next() # siguiente vela contigua
kt.prev() # vela anterior contigua# Aritmetica
kt + timedelta(hours=1) # -> KlineTimestamp desplazado
kt - timedelta(hours=1) # -> KlineTimestamp desplazado
kt - kt_other # -> timedelta (diferencia entre opens)
timedelta(...) + kt # -> KlineTimestamp (__radd__)
# Comparaciones (por (open, tick_ms), timezone ignorado)
kt == kt_other
kt < kt_other
kt > kt_other
kt <= kt_other
kt >= kt_other
# Hash (consistente con __eq__)
hash(kt) # hash((open, tick_ms))tick_msvaria: febrero bisiesto = 2986400000, marzo = 3186400000, etc.next()/prev()navegan por meses calendario (no suman tick_ms fijo).kt + timedelta(days=15)re-snap al mes del timestamp resultante.- Dos klines mensuales del mismo mes son iguales independientemente del timestamp original.
from kline_timestamp import KlineTimestamp
from datetime import timedelta
# Crear vela de 1 hora
kt = KlineTimestamp(1633036800000, "1h", "Europe/Madrid")
print(kt.open, kt.close, kt.to_datetime())
# Iterar 5 velas hacia adelante
current = kt
for _ in range(5):
current = current.next()
print(current.to_datetime())
# Vela mensual
kt_month = KlineTimestamp(1709251200000, "1M", "UTC")
print(kt_month.to_datetime()) # 2024-03-01
print(kt_month.next().to_datetime()) # 2024-04-01
print(kt_month.prev().to_datetime()) # 2024-02-01
# Diferencia temporal
delta = kt_month - kt_month.prev()
print(delta.days) # 29 (febrero 2024, bisiesto)- Pasar
floatcomotimestamp_ms->TypeError - Pasar
"1M"esperando minuto -> es mensual. Usar"1m"para minuto. - Comparar klines de distinto intervalo con mismo open: no son iguales (distinto
tick_ms).
| Elemento | Idioma | Ejemplo |
|---|---|---|
| Módulos, clases, funciones, métodos | English | KlineTimestamp, with_timezone() |
| Variables | English, autoexplicativas | open_ts, tick_ms |
| Comentarios | Español, mínimos | # Normaliza el intervalo |
| Docstrings | Español, concisos | """Retorna la siguiente vela...""" |
- Formato: NumPy style (napoleon-compatible), para futura integración con Sphinx.
- Resumen en 1 línea.
Parameters/Returns/Raisescuando aplique.- Type hints en firmas (
from __future__ import annotationsya presente). - Describir contratos (pre/post), no repetir el código.
- Clase principal inmutable (
@dataclass(frozen=True)). Toda mutación retorna instancia nueva. __post_init__para validación y cálculo de campos derivados.- Separación clara: identidad lógica
(open, interval)vs. presentación (timezone). - Excepciones explícitas con mensajes útiles (
ValueError,TypeError). - No hay logging actualmente.
- Orden: stdlib -> third-party (
pandas,pytz) -> local. - Un solo módulo de lógica:
kline_timestamp.py. No hay riesgo de imports circulares. - Nuevos módulos: colocar en
kline_timestamp/y exportar desde__init__.py.
from __future__ import annotationshabilitado.- Usar
Union,ClassVar,Dictdetyping(compatibilidad 3.9). - Si se sube el mínimo a 3.10+, preferir
X | Ynativo.
kline_timestamp/ ← paquete importable
__init__.py ← exporta KlineTimestamp
kline_timestamp.py ← clase KlineTimestamp (única)
examples/
kline_timestamp_basic.ipynb ← notebook de ejemplo
setup.py ← metadata + build
requirements.txt ← deps de instalación
MANIFEST.in ← archivos extra en sdist
deploy.sh ← build + twine upload
CHANGELOG.md ← changelog (Keep a Changelog)
README.md ← docs principal
LICENSE ← MIT
python3 -m venv .venv
source .venv/bin/activatepip install -e .Esto instala kline_timestamp + dependencias (pandas, pytz).
pip install -r requirements.txtpython -m kline_timestamp.kline_timestampEjecuta el bloque if __name__ == "__main__" con un ejemplo manual.
No se detectan variables de entorno requeridas.
No existe infraestructura de testing, linting ni type-checking en el repo.
# Tests (futuro)
pytest tests/ -v
# Lint (futuro)
ruff check .
# Format (futuro)
ruff format .
# Type-check (futuro)
mypy kline_timestamp/Un cambio está listo cuando:
- Pasa todos los tests (cuando existan).
- No introduce errores de lint/type.
- Docstrings actualizados si la API pública cambió.
- Herramienta de docs: ninguna (no hay Sphinx ni MkDocs).
- Documentación existente:
README.md+CHANGELOG.md+ notebook de ejemplo. - Docstrings: presentes en la clase principal, estilo corto en español.
- Docstrings NumPy style para compatibilidad futura con Sphinx + napoleon.
CHANGELOG.mdsigue Keep a Changelog + SemVer.- Ejemplos en
examples/como notebooks Jupyter.
| Campo | Valor |
|---|---|
| Distribution name | kline_timestamp |
| Import name | kline_timestamp |
| Publicado en PyPI | Sí |
| Última versión | 0.2.0 (2025-11-23) |
| URL PyPI | https://pypi.org/project/kline_timestamp/ |
| Home page | https://github.com/nand0san/kline_timestamp |
# 1. Actualizar version en setup.py
# 2. Actualizar CHANGELOG.md
# 3. Commit
git add setup.py CHANGELOG.md
git commit -m "release: vX.Y.Z"
# 4. Tag (OBLIGATORIO, sincronizado con la version de setup.py y PyPI)
git tag vX.Y.Z
# 5. Build y upload
./deploy.sh # ejecuta: rm -rf dist/ build/ && python -m build && twine upload dist/*
# 6. Push con tags
git push nas master --tagsRequiere:
buildytwineinstalados.- Token de PyPI configurado (
.pypirco variable de entorno).
- Todo commit de release debe llevar un tag con formato
vX.Y.Z(SemVer). - El tag debe coincidir exactamente con la version declarada en
setup.py:20. - Si se publica en PyPI, la version del tag,
setup.pyy PyPI deben ser identicas. - Crear el tag antes de hacer push:
git tag vX.Y.Z. - Push de tags:
git push nas master --tagsygit push github github --tags. - No crear tags sin commit de release asociado.
- No publicar en PyPI sin tag.
| Remote | URL | Uso |
|---|---|---|
github |
git@github.com:nand0san/KlineTimestamp.git |
Repositorio público |
nas |
ssh://ffad@192.168.89.201/.../kline_timestamp |
Backup/NAS privado |
master- rama principal de desarrollo (trackingnas/master).github- rama de release publico (apunta a release 0.2.0).- No hay rama
mainnidevlocales.
# Crear feature branch desde master
git checkout master
git pull nas master
git checkout -b feature/mi-cambio
# Trabajar, commit
git add <archivos>
git commit -m "descripcion corta del cambio"
# Mergear a master
git checkout master
git merge feature/mi-cambio
# Push a NAS
git push nas master
# Push a GitHub (cuando sea release)
git push github master:github- Mensajes cortos, imperativos.
- Idioma: español o inglés (historial mixto).
- Scope opcional:
feat:,fix:,docs:(no formalizado, pero recomendado). - Commits de release: deben ir acompañados de un tag
vX.Y.Z(ver seccion 9).
La rama local github (tracking github/github) es la unica rama que se publica en el remote github (git@github.com:nand0san/KlineTimestamp.git). No se hace push de master ni de feature branches al remote de GitHub.
Todos los commits que lleguen a la rama github deben ser squash merges desde master:
git checkout github
git merge --squash master
git commit -m "descripcion publica del cambio"
git tag vX.Y.Z # sincronizado con setup.py y PyPI
git push github github --tagsEsto garantiza que el historial interno de desarrollo (commits intermedios, ramas de trabajo, mensajes de debug) no quede expuesto en el repositorio publico.
Antes de cada commit en la rama github, verificar y corregir todo el contenido staged:
- Co-Authored-By / co-authored-by: eliminar cualquier linea de co-autoria de agentes (Claude, Copilot, GPT, Codex, etc.) de los mensajes de commit y del contenido de archivos.
- Agentes como colaboradores: ningun agente debe aparecer como autor, co-autor o colaborador en commits, PRs ni en ningun metadata de GitHub.
- Caracteres watermark: sustituir caracteres atipicos usados como watermark por sus equivalentes normales:
- Guion largo
-(em-dash U+2014) -> guion normal- - Guion medio
-(en-dash U+2013) -> guion normal- - Comillas tipograficas
""''-> comillas rectas"' - Espacios especiales (non-breaking space U+00A0, thin space U+2009, etc.) -> espacio normal
- Cualquier otro caracter Unicode inusual que no pertenezca al contenido tecnico del codigo.
- Guion largo
- Revision manual: antes del push, ejecutar:
# Buscar em-dash, en-dash y comillas tipograficas en archivos staged git diff --cached | grep -P '[\x{2014}\x{2013}\x{201C}\x{201D}\x{2018}\x{2019}\x{00A0}]' # Buscar menciones a agentes en el diff git diff --cached | grep -i -E '(co-authored|claude|copilot|codex|openai|anthropic|gpt-)' # Buscar en el mensaje de commit antes de hacer push git log -1 --format=%B | grep -i -E '(co-authored|claude|copilot|codex|openai|anthropic|gpt-)'
- Si se detecta algo: corregir, re-stage y hacer commit nuevo. No hacer push hasta que las verificaciones pasen limpias.
master (desarrollo) ──squash merge──► github (publicacion) ──push──► github remote
│
├─ sin rastros de agentes
├─ sin co-authored-by
├─ sin caracteres watermark
└─ historial limpio y compacto
- Leer este
AGENTS.md. - Leer
kline_timestamp/kline_timestamp.py(módulo único, ~244 líneas). - Leer
setup.pysi el cambio afecta metadata/versión. - Verificar que no hay tests que ejecutar (actualmente no existen).
- Verificar estado del repo:
git status -sb.
<tipo>: <descripcion corta imperativa>
[cuerpo opcional]
Tipos sugeridos: feat, fix, refactor, docs, chore.
- Si cambia la API pública -> actualizar
README.mdy docstrings. - Si cambia la versión -> actualizar
setup.py:20, añadir entrada enCHANGELOG.mdy crear tagvX.Y.Z. - Si se añade funcionalidad -> considerar ejemplo en
examples/.
El agente debe incluir en su respuesta:
- Archivos tocados (con rutas).
- Comandos ejecutados.
- Si se creó commit: hash y mensaje.
- Si hay efectos secundarios conocidos.
- No modificar
deploy.shsin confirmación. - No hacer
git pushsin autorización explícita. - Versión solo se bumpa con indicación del usuario.
Aspectos ausentes que se podrían mejorar (sin implementar aquí):
| Gap | Propuesta mínima |
|---|---|
| Tests | Crear tests/test_kline_timestamp.py con pytest. Cubrir: creación, validación, open/close, conversiones, navegación, aritmética, comparaciones, edge cases. |
| Linter/formatter | Añadir ruff con config en pyproject.toml. |
| Type checker | Añadir mypy con --strict o pyright. |
| CI | GitHub Actions: lint + tests en push/PR. |
| pyproject.toml | Migrar de setup.py a PEP 621 (pyproject.toml). |
| Sphinx docs | Configurar docs/ con autodoc + napoleon para generar API docs desde docstrings. |
| py.typed marker | Añadir kline_timestamp/py.typed (el classifier Typing :: Typed ya está). |