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
78 changes: 71 additions & 7 deletions application/cycle_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@

import json
import os
from datetime import datetime, timezone

from quant_platform_kit.common.runtime_reports import persist_runtime_report
from quant_platform_kit.strategy_lifecycle.performance_monitor import try_record_platform_execution
from runtime_logging import RuntimeLogContext, emit_runtime_log
from runtime_support import finalize_notification_delivery
from runtime_support import build_runtime_evidence_aggregate_v2, finalize_notification_delivery


def execute_strategy_cycle(
Expand All @@ -21,6 +22,7 @@ def execute_strategy_cycle(
append_trend_pool_source_logs,
capture_market_snapshot,
compute_portfolio_allocation,
refresh_action_authorization=None,
build_balance_snapshot,
maybe_reset_daily_state,
maybe_rebase_daily_state_for_balance_change,
Expand All @@ -37,7 +39,7 @@ def execute_strategy_cycle(
translate_fn,
traceback_module,
):
circuit_breaker_pct = -0.05
circuit_breaker_pct = 0.0
min_bnb_value, buy_bnb_amount = 10.0, 15.0
cycle_settings = load_cycle_execution_settings()
btc_status_report_interval_hours = cycle_settings.btc_status_report_interval_hours
Expand All @@ -57,6 +59,11 @@ def execute_strategy_cycle(
state, trend_pool_resolution, runtime_trend_universe, allow_new_trend_entries = cycle_state
append_trend_pool_source_logs(log_buffer, trend_pool_resolution, allow_new_trend_entries)

report["release_identity"] = dict(trend_pool_resolution.get("runtime_evidence_identity", {}))
report["release_identity_sha256"] = str(trend_pool_resolution.get("release_identity_sha256", ""))
runtime.release_identity = dict(report["release_identity"])
runtime.release_identity_sha256 = report["release_identity_sha256"]

report["upstream_pool_symbols"] = list(runtime_trend_universe.keys())
if trend_pool_resolution["degraded"]:
report["degraded_mode_level"] = trend_pool_resolution.get("source_kind", "unknown")
Expand Down Expand Up @@ -88,12 +95,37 @@ def execute_strategy_cycle(
trend_indicators,
btc_snapshot,
)
risk_evidence = allocation.pop("_risk_evidence", {})
for field_name in (
"member_risk_assessment",
"account_risk_assessment",
"cap_assessment",
"strategy_stop_evaluation",
"order_authorization",
):
report[field_name] = dict(risk_evidence.get(field_name, {}))
Comment thread
Pigbibi marked this conversation as resolved.
total_equity = allocation["total_equity"]
trend_val_equity = allocation["trend_val"]

report["total_equity_usdt"] = total_equity
report["trend_equity_usdt"] = trend_val_equity

if refresh_action_authorization is not None:
runtime.action_authorizer = lambda **action: refresh_action_authorization(
runtime,
report,
state,
runtime_trend_universe,
trend_indicators,
btc_snapshot,
prices,
balances,
fuel_val,
allow_new_trend_entries=allow_new_trend_entries,
allow_pool_refresh=not trend_pool_resolution["degraded"],
**action,
)

now_utc = runtime.now_utc
today_utc = now_utc.strftime("%Y-%m-%d")
today_id_str = now_utc.strftime("%Y%m%d")
Expand All @@ -112,10 +144,6 @@ def execute_strategy_cycle(
daily_pnl, trend_daily_pnl = compute_daily_pnls(state, total_equity, trend_val_equity)
append_portfolio_report(log_buffer, allocation, fuel_val, daily_pnl, trend_daily_pnl, btc_snapshot)

if state.get("is_circuit_broken"):
log_buffer.insert(0, translate_fn("circuit_breaker_latched_line", total_equity=total_equity))
return report

if run_daily_circuit_breaker(
runtime,
report,
Expand All @@ -124,10 +152,12 @@ def execute_strategy_cycle(
balances,
u_total,
prices,
trend_daily_pnl,
daily_pnl,
circuit_breaker_pct,
log_buffer,
):
if state.get("is_circuit_broken"):
log_buffer.insert(0, translate_fn("circuit_breaker_latched_line", total_equity=total_equity))
return report

u_total = execute_trend_rotation(
Expand Down Expand Up @@ -187,6 +217,7 @@ def execute_strategy_cycle(
log_buffer,
)

runtime.action_cash_usdt = float(u_total)
manage_usdt_earn_buffer_runtime(
runtime,
report,
Expand Down Expand Up @@ -224,6 +255,7 @@ def execute_strategy_cycle(
except Exception:
pass
finally:
runtime.action_authorizer = None
report["log_lines"] = list(log_buffer)
finalize_notification_delivery(report)
try_record_platform_execution(
Expand Down Expand Up @@ -296,6 +328,33 @@ def run_live_cycle(
)
report = execute_cycle(runtime)
output_printer("\n".join(report.get("log_lines", [])))
produced_at_value = getattr(runtime, "now_utc", None) or datetime.now(timezone.utc)
produced_at = produced_at_value.astimezone(timezone.utc).replace(microsecond=0).isoformat().replace("+00:00", "Z")
static_degraded_without_identity = (
report.get("degraded_mode_level") == "static"
and report.get("release_identity") == {}
)
if not static_degraded_without_identity:
try:
report["runtime_evidence_aggregate"] = build_runtime_evidence_aggregate_v2(
produced_at=produced_at,
run_id=str(report.get("run_id") or getattr(runtime, "run_id", "")),
producer_revision=str(getattr(runtime, "producer_revision", "")),
release_identity=report.get("release_identity", {}),
member_risk_assessment=report.get("member_risk_assessment", {}),
account_risk_assessment=report.get("account_risk_assessment", {}),
cap_assessment=report.get("cap_assessment", {}),
order_authorization=report.get("order_authorization", {}),
strategy_stop_evaluation=report.get("strategy_stop_evaluation", {}),
account_breaker_evaluation=report.get("account_breaker_evaluation", {}),
execution_gate_outcome=str(report.get("order_authorization", {}).get("outcome", "REJECT")),
reconciliation={"status": "MISSING"},
)
except Exception as aggregate_exc:
report["status"] = "error"
report.setdefault("error_summary", {}).setdefault("errors", []).append(
{"stage": "runtime_evidence_aggregate", "message": str(aggregate_exc)}
)
report_path = report_writer(report)
persisted_local_path = report_path
persisted_cloud_uri = None
Expand All @@ -309,6 +368,11 @@ def run_live_cycle(
persisted_local_path = persisted.local_path or report_path
persisted_cloud_uri = persisted.cloud_uri
except Exception as persist_exc:
report["status"] = "error"
report.setdefault("error_summary", {}).setdefault("errors", []).append(
{"stage": "runtime_report_persist", "message": str(persist_exc)}
)
report_path = report_writer(report)
output_printer(f"failed to persist archived execution report: {persist_exc}")
report_status = str(report.get("status", "unknown"))
status_event = {
Expand Down
Loading