# coding: utf-8 """JoinQuant hosted wrapper. Upload the generated bundle, not this source file, to JoinQuant. The bundle tool replaces the marked import block with the exact portable core source. """ # __PORTABLE_CORE_BUNDLE_START__ from quant60.portable_core import ( build_rebalance_plan, build_target_weight_plan, convert_symbol, lookup_target_package_exact, target_package_tape_sha256, verify_target_package, ) # __PORTABLE_CORE_BUNDLE_END__ import base64 as _q60_base64 import json as _q60_json import math class PriceHistoryUnavailable(RuntimeError): pass class UnmanagedPositionError(RuntimeError): pass class ClockStateError(RuntimeError): pass # __BASELINE_CONFIG_START__ CONFIG = { "decision_mode": "portable_momentum_smoke", "target_package_count": 0, "target_package_tape_sha256": None, "universe_mode": "pit_index", "index_symbol": "000905.XSHG", "qmt_sector_name": "中证500", "dedicated_account_required": True, "exclude_st": True, "universe": [ "600000.XSHG", "000001.XSHE", "300750.XSHE", "000333.XSHE", ], "lookback": 20, # The first session close supplies the signal; the second session open # supplies the hosted execution boundary, matching the QMT daily wrapper. "skip": 0, "top_n": 20, "max_weight": 0.05, "gross_target": 0.95, "cash_buffer": 0.02, "lot_size": 100, "participation_rate": 0.1, "slippage_bps": 2.0, "commission_rate": 0.0002, "minimum_commission": 5.0, "stamp_duty_rate": 0.0005, "transfer_fee_rate": 0.00001, "rebalance_schedule": "weekly_first_close", } # __BASELINE_CONFIG_END__ # __TARGET_PACKAGE_TAPE_START__ TARGET_PACKAGES = [] # __TARGET_PACKAGE_TAPE_END__ MOMENTUM_SMOKE_MODE = "portable_momentum_smoke" TARGET_PACKAGE_MODE = "target_package" EVIDENCE_PREFIX = "QUANT60_JOINQUANT_EVIDENCE_V1 " EVIDENCE_CHUNK_CHARACTERS = 1800 TARGET_PRICE_SOURCE = "CURRENT_DATA_DAY_OPEN" def _evidence_value(value, depth=0): """Return stable JSON data without allowing observation to stop trading.""" if depth > 8: return "" if value is None or isinstance(value, (bool, int, str)): return value if isinstance(value, float): return value if math.isfinite(value) else None if isinstance(value, dict): return { str(key): _evidence_value(item, depth + 1) for key, item in sorted( value.items(), key=lambda pair: str(pair[0]), ) } if isinstance(value, (list, tuple)): return [_evidence_value(item, depth + 1) for item in value] isoformat = getattr(value, "isoformat", None) if callable(isoformat): try: return str(isoformat()) except Exception: return "" try: return str(value) except Exception: return "" def _evidence_context_time(context): try: return _evidence_value(getattr(context, "current_dt", None)) except Exception: return None def _emit_evidence( event, payload=None, context=None, chunk_index=None, chunk_count=None, ): """Print one prefixed canonical JSON record and always fail soft.""" try: sequence = int( getattr(g, "quant60_evidence_sequence", 0) or 0 ) + 1 g.quant60_evidence_sequence = sequence record = { "context_time": _evidence_context_time(context), "decision_mode": getattr( g, "quant60_decision_mode", CONFIG.get("decision_mode"), ), "event": str(event), "payload": _evidence_value(payload or {}), "schema_version": "1.0", "sequence": sequence, "source": "joinquant_hosted", } if chunk_index is not None or chunk_count is not None: if ( type(chunk_index) is not int or type(chunk_count) is not int or chunk_index <= 0 or chunk_count <= 0 or chunk_index > chunk_count ): return None record["chunk_index"] = chunk_index record["chunk_count"] = chunk_count encoded = _q60_json.dumps( record, ensure_ascii=True, sort_keys=True, separators=(",", ":"), allow_nan=False, ) print(EVIDENCE_PREFIX + encoded) except Exception: # Evidence is observational. A logging/serialization failure must # never alter an already verified decision or hosted order path. return None return record def _emit_chunked_evidence(event, payload, context=None): """Emit reconstructable base64 chunks of one canonical JSON payload.""" try: canonical = _q60_json.dumps( _evidence_value(payload), ensure_ascii=True, sort_keys=True, separators=(",", ":"), allow_nan=False, ).encode("ascii") encoded = _q60_base64.b64encode(canonical).decode("ascii") chunks = [ encoded[index : index + EVIDENCE_CHUNK_CHARACTERS] for index in range(0, len(encoded), EVIDENCE_CHUNK_CHARACTERS) ] or [""] count = len(chunks) for index, content in enumerate(chunks, 1): _emit_evidence( event, { "chunk_encoding": "base64-canonical-json", "content": content, "encoded_length": len(encoded), }, context, chunk_index=index, chunk_count=count, ) except Exception: return None return count def _observe_object(value, fields): if value is None: return None output = {"object_type": type(value).__name__} for name in fields: try: item = getattr(value, name) except Exception: continue if callable(item): continue output[name] = _evidence_value(item) return output def _observe_order(value): return _observe_object( value, ( "order_id", "add_time", "security", "amount", "filled", "price", "avg_cost", "side", "action", "status", "target_quantity", ), ) def _observe_trade(value): return _observe_object( value, ( "trade_id", "order_id", "time", "security", "amount", "price", ), ) def _observe_platform_collection(api_name, observer): """Read an optional hosted collection without assuming API availability.""" function = globals().get(api_name) if not callable(function): return { "available": False, "reason": "API_UNAVAILABLE", } try: raw = function() except Exception as exc: return { "available": False, "error_type": type(exc).__name__, "reason": "API_CALL_FAILED", } if hasattr(raw, "items"): items = [ { "key": str(key), "value": observer(value), } for key, value in sorted( raw.items(), key=lambda pair: str(pair[0]), ) ] elif isinstance(raw, (list, tuple)): items = [observer(value) for value in raw] elif raw is None: items = [] else: items = [observer(raw)] return { "available": True, "count": len(items), "items": items, } def _observe_portfolio(context): try: portfolio = context.portfolio except Exception as exc: return { "available": False, "error_type": type(exc).__name__, } output = { "available": True, "fields": {}, "positions": [], } for name in ( "total_value", "cash", "available_cash", "positions_value", "returns", ): try: value = getattr(portfolio, name) except Exception: continue output["fields"][name] = _evidence_value(value) try: positions = getattr(portfolio, "positions", {}) if hasattr(positions, "items"): for symbol, position in sorted( positions.items(), key=lambda pair: str(pair[0]), ): item = _observe_object( position, ( "total_amount", "closeable_amount", "price", "avg_cost", "value", ), ) item["symbol"] = str(symbol) output["positions"].append(item) except Exception as exc: output["positions_error_type"] = type(exc).__name__ return output def _plan_evidence(plan): if not isinstance(plan, dict): return None return { "decision_mode": plan.get("decision_mode"), "execution_contract": plan.get("execution_contract"), "lineage": plan.get("lineage"), "orders": plan.get("orders"), "targets": plan.get("targets"), "universe": plan.get("universe"), "weights": plan.get("weights"), } def _validated_target_packages(config): mode = config.get("decision_mode") if mode not in (MOMENTUM_SMOKE_MODE, TARGET_PACKAGE_MODE): raise ValueError("unsupported decision_mode") if not isinstance(TARGET_PACKAGES, list): raise ValueError("TARGET_PACKAGES must be a list") expected_count = config.get("target_package_count") expected_sha256 = config.get("target_package_tape_sha256") if mode == MOMENTUM_SMOKE_MODE: if ( type(expected_count) is not int or expected_count != 0 or expected_sha256 is not None or TARGET_PACKAGES ): raise ValueError( "portable_momentum_smoke cannot carry target packages" ) return [] if type(expected_count) is not int or expected_count <= 0: raise ValueError( "target_package mode requires a positive target_package_count" ) if expected_count != len(TARGET_PACKAGES): raise ValueError("target package count mismatch") actual_sha256 = target_package_tape_sha256(TARGET_PACKAGES) if expected_sha256 != actual_sha256: raise ValueError("target package tape sha256 mismatch") verified = [] package_ids = set() decision_ids = set() clocks = set() for raw_package in TARGET_PACKAGES: package = verify_target_package(raw_package) package_id = package["package_id"] decision_id = package["decision_id"] clock = (package["signal_as_of"], package["next_session"]) if ( package_id in package_ids or decision_id in decision_ids or clock in clocks ): raise ValueError("duplicate target package decision identity") package_ids.add(package_id) decision_ids.add(decision_id) clocks.add(clock) verified.append(package) return verified def initialize(context): """Configure the selected daily-open decision mode.""" set_option("avoid_future_data", True) set_option("use_real_price", True) g.quant60_evidence_sequence = 0 g.quant60_order_observations = [] g.quant60_config = dict(CONFIG) g.quant60_target_packages = _validated_target_packages( g.quant60_config ) g.quant60_decision_mode = g.quant60_config["decision_mode"] if g.quant60_config["decision_mode"] == MOMENTUM_SMOKE_MODE: if g.quant60_config.get("rebalance_schedule") != "weekly_first_close": raise ValueError("unsupported rebalance_schedule") if g.quant60_config.get("universe_mode") not in ("pit_index", "fixed"): raise ValueError("unsupported universe_mode") if ( g.quant60_config.get("universe_mode") == "pit_index" and not g.quant60_config.get("dedicated_account_required") ): raise ValueError("pit_index mode requires a dedicated account") set_benchmark(g.quant60_config["index_symbol"]) commission = ( float(g.quant60_config["commission_rate"]) + float(g.quant60_config["transfer_fee_rate"]) ) set_order_cost( OrderCost( open_tax=0.0, close_tax=float(g.quant60_config["stamp_duty_rate"]), open_commission=commission, close_commission=commission, close_today_commission=0.0, min_commission=float( g.quant60_config["minimum_commission"] ), ), type="stock", ) # JoinQuant applies half of PriceRelatedSlippage on each side. The local # slippage_bps setting is one-sided, hence the explicit factor of two. set_slippage( PriceRelatedSlippage( 2.0 * float(g.quant60_config["slippage_bps"]) / 10000.0 ), type="stock", ) set_option( "order_volume_ratio", float(g.quant60_config["participation_rate"]), ) g.quant60_last_plan = None g.quant60_last_universe = None g.quant60_last_universe_as_of = None g.quant60_skipped_orders = [] g.quant60_pending_first_session = None g.quant60_last_callback_date = None run_daily(rebalance, time="open") _emit_evidence( "INIT", { "benchmark": g.quant60_config["index_symbol"], "package_count": len(g.quant60_target_packages), "package_ids": [ package["package_id"] for package in g.quant60_target_packages ], "rebalance_callback": "run_daily_open", "target_package_tape_sha256": g.quant60_config.get( "target_package_tape_sha256" ), }, context, ) def _decision_mode(): configured = g.quant60_config.get("decision_mode") frozen = getattr(g, "quant60_decision_mode", configured) if configured != frozen: raise ValueError("decision_mode cannot change after initialize") return frozen def _close_history(symbol, count): raw = attribute_history( symbol, count, unit="1d", fields=["close"], skip_paused=False, df=False, fq="pre", ) values = list(raw.get("close", [])) if hasattr(raw, "get") else [] if len(values) != int(count): raise PriceHistoryUnavailable( "%s needs %d completed daily closes, got %d" % (symbol, int(count), len(values)) ) output = [] for value in values: try: number = float(value) except (TypeError, ValueError): raise PriceHistoryUnavailable( "%s contains a missing/non-numeric close" % symbol ) if not math.isfinite(number) or number <= 0.0: raise PriceHistoryUnavailable( "%s contains a missing/non-positive close" % symbol ) output.append(number) return output def _close_histories(symbols, count): raw = history( int(count), unit="1d", field="close", security_list=list(symbols), df=False, skip_paused=False, fq="pre", ) if not hasattr(raw, "get"): raise PriceHistoryUnavailable("history returned an invalid payload") output = {} for symbol in symbols: values = list(raw.get(symbol, [])) if len(values) != int(count): raise PriceHistoryUnavailable( "%s needs %d completed daily closes, got %d" % (symbol, int(count), len(values)) ) clean = [] for value in values: try: number = float(value) except (TypeError, ValueError): raise PriceHistoryUnavailable( "%s contains a missing/non-numeric close" % symbol ) if not math.isfinite(number) or number <= 0.0: raise PriceHistoryUnavailable( "%s contains a missing/non-positive close" % symbol ) clean.append(number) output[convert_symbol(symbol, "canonical")] = clean return output def _decision_universe(context): config = g.quant60_config if config.get("universe_mode") == "fixed": values = list(config["universe"]) else: as_of = _as_date( getattr(context, "previous_date", None), "previous_date", ) values = get_index_stocks( config["index_symbol"], date=as_of, ) if not values: raise PriceHistoryUnavailable( "no PIT index members for %s on %s" % (config["index_symbol"], as_of.isoformat()) ) g.quant60_last_universe_as_of = as_of.isoformat() normalized = sorted( set(convert_symbol(symbol, "joinquant") for symbol in values) ) if not normalized: raise PriceHistoryUnavailable("decision universe is empty") g.quant60_last_universe = list(normalized) return normalized def _filter_st_universe(context, symbols): if not g.quant60_config.get("exclude_st", True): return list(symbols) as_of = _as_date( getattr(context, "previous_date", None), "previous_date", ) raw = get_extras( "is_st", list(symbols), end_date=as_of, count=1, df=False, ) if not hasattr(raw, "get"): raise PriceHistoryUnavailable( "get_extras is_st returned an invalid payload" ) output = [] for symbol in symbols: values = list(raw.get(symbol, [])) if len(values) != 1: raise PriceHistoryUnavailable( "%s needs one PIT is_st value on %s" % (symbol, as_of.isoformat()) ) try: numeric = float(values[0]) except (TypeError, ValueError): raise PriceHistoryUnavailable( "%s contains a non-boolean PIT is_st value" % symbol ) if not math.isfinite(numeric) or numeric not in (0.0, 1.0): raise PriceHistoryUnavailable( "%s contains an invalid PIT is_st value" % symbol ) if not bool(numeric): output.append(symbol) if not output: raise PriceHistoryUnavailable( "PIT ST exclusion removed the entire decision universe" ) g.quant60_last_universe = list(output) return output def _position_amount(position, name, default=0): value = getattr(position, name, default) return int(value or 0) def _snapshot_portfolio(context, managed): current = {} sellable = {} managed = set(convert_symbol(symbol, "canonical") for symbol in managed) dynamic = ( _decision_mode() == MOMENTUM_SMOKE_MODE and g.quant60_config.get("universe_mode") == "pit_index" ) positions = getattr(context.portfolio, "positions", {}) for symbol, position in positions.items(): canonical = convert_symbol(str(symbol), "canonical") quantity = _position_amount(position, "total_amount") if quantity and canonical not in managed and not dynamic: raise UnmanagedPositionError( "account contains unmanaged position %s; use a dedicated " "strategy account or reconcile ownership before trading" % canonical ) if canonical not in managed and not dynamic: continue current[canonical] = quantity sellable[canonical] = _position_amount( position, "closeable_amount", current[canonical] ) equity = float(getattr(context.portfolio, "total_value", 0.0) or 0.0) return current, sellable, equity def _is_star_board(symbol): code = str(symbol).split(".", 1)[0] return code.startswith("688") or code.startswith("689") def _order_request(symbol, delta): """Build a fail-closed hosted order request from current market data. JoinQuant rejects an unprotected market order for STAR Market securities. A limit at the exchange daily bound supplies equivalent worst-price protection while keeping the rebalance target expressed in exact shares. """ try: item = get_current_data()[symbol] except Exception as exc: g.quant60_skipped_orders.append( {"symbol": symbol, "reason": "current_data_unavailable", "detail": str(exc)} ) return None if bool(getattr(item, "paused", False)): g.quant60_skipped_orders.append( {"symbol": symbol, "reason": "paused"} ) return None if not _is_star_board(symbol): return {"style": None} field = "high_limit" if int(delta) > 0 else "low_limit" raw_price = getattr(item, field, None) try: protection_price = float(raw_price) except (TypeError, ValueError): protection_price = float("nan") if ( not math.isfinite(protection_price) or protection_price <= 0.0 or protection_price >= 10000.0 ): g.quant60_skipped_orders.append( { "symbol": symbol, "reason": "star_protection_price_invalid", "detail": field, } ) return None try: style = LimitOrderStyle(protection_price) except Exception as exc: g.quant60_skipped_orders.append( { "symbol": symbol, "reason": "star_protection_style_unavailable", "detail": str(exc), } ) return None return {"style": style} def _target_package_for_open(context): current_date = _as_date(getattr(context, "current_dt", None), "current_dt") previous_date = _as_date( getattr(context, "previous_date", None), "previous_date", ) signal_as_of = ( previous_date.isoformat() + "T15:00:00+08:00" ) next_session = current_date.isoformat() config = g.quant60_config packages = _validated_target_packages(config) matches = [ package for package in packages if package["signal_as_of"] == signal_as_of and package["next_session"] == next_session ] if not matches: _emit_evidence( "TARGET_PACKAGE_NOOP", { "fallback_invoked": False, "next_session": next_session, "orders_submitted": 0, "package_count": len(packages), "reason": "NO_EXACT_CLOCK_MATCH", "signal_as_of": signal_as_of, "target_package_tape_sha256": config[ "target_package_tape_sha256" ], }, context, ) return None if len(matches) != 1: raise ValueError("ambiguous target package clock") package = lookup_target_package_exact( packages, signal_as_of, next_session, decision_id=matches[0]["decision_id"], expected_tape_sha256=config["target_package_tape_sha256"], expected_count=config["target_package_count"], ) _emit_evidence( "TARGET_PACKAGE_HIT", { "lineage": _target_lineage(package), "target_package_tape_sha256": config[ "target_package_tape_sha256" ], }, context, ) return package def _target_prices(symbols): try: current_data = get_current_data() except Exception as exc: raise PriceHistoryUnavailable( "current_data is unavailable: %s" % exc ) prices = {} for canonical in sorted(symbols): symbol = convert_symbol(canonical, "joinquant") try: raw_price = getattr(current_data[symbol], "day_open") price = float(raw_price) except (KeyError, AttributeError, TypeError, ValueError): raise PriceHistoryUnavailable( "%s has no usable current day_open" % symbol ) if not math.isfinite(price) or price <= 0.0: raise PriceHistoryUnavailable( "%s has no usable current day_open" % symbol ) prices[canonical] = price return prices def _target_lineage(package): return { "package_id": package["package_id"], "package_sha256": package["package_sha256"], "decision_id": package["decision_id"], "signal_as_of": package["signal_as_of"], "next_session": package["next_session"], "release": package["release"], "model_id": package["model_id"], } def _compute_target_package_plan(context): package = _target_package_for_open(context) if package is None: return None managed = sorted(package["universe"]) current, sellable, equity = _snapshot_portfolio(context, managed) if equity <= 0: raise ValueError("portfolio.total_value must be positive") prices = _target_prices( set(package["target_weights"]) | set(current) ) _emit_evidence( "PLATFORM_BINDING_INPUT", { "current": current, "equity": equity, "lineage": _target_lineage(package), "price_source": TARGET_PRICE_SOURCE, "prices": prices, "sellable": sellable, }, context, ) plan = build_target_weight_plan( target_weights=package["target_weights"], prices=prices, current=current, sellable=sellable, equity=equity, cash_buffer=g.quant60_config["cash_buffer"], lot_size=g.quant60_config["lot_size"], decision_id=package["decision_id"], package_sha256=package["package_sha256"], ) plan["decision_mode"] = TARGET_PACKAGE_MODE plan["lineage"] = _target_lineage(package) plan["universe"] = package["universe"] plan["execution_contract"] = { "signal_price_source": TARGET_PRICE_SOURCE, "submit_trigger": "DECLARED_NEXT_SESSION_OPEN_CALLBACK", "declared_next_session": package["next_session"], "real_platform_observed": False, } _emit_evidence( "TARGET_PACKAGE_PLAN", _plan_evidence(plan), context, ) return plan def compute_plan(context): """Return the selected portable plan without submitting orders.""" if _decision_mode() == TARGET_PACKAGE_MODE: return _compute_target_package_plan(context) config = g.quant60_config required = int(config["lookback"]) + int(config["skip"]) + 1 platform_universe = _decision_universe(context) platform_universe = _filter_st_universe( context, platform_universe, ) price_history = _close_histories(platform_universe, required) current, sellable, equity = _snapshot_portfolio( context, platform_universe, ) if equity <= 0: raise ValueError("portfolio.total_value must be positive") plan = build_rebalance_plan( price_history=price_history, current=current, sellable=sellable, equity=equity, lookback=config["lookback"], skip=config["skip"], top_n=config["top_n"], max_weight=config["max_weight"], gross_target=config["gross_target"], cash_buffer=config["cash_buffer"], lot_size=config["lot_size"], ) return plan def _submit_plan(context, plan, managed): """Submit a portable plan's exact executable share deltas.""" if plan is None: return None observe_target_package = ( plan.get("decision_mode") == TARGET_PACKAGE_MODE ) order_deltas = plan["orders"] current, _, unused_equity = _snapshot_portfolio( context, managed, ) del unused_equity all_symbols = set(current) all_symbols.update(order_deltas) # Exits first. The requested target is current + executable delta, not the # unconstrained portfolio target; this preserves T+1 sellable caps and odd # lots from the portable plan. for canonical in sorted( all_symbols, key=lambda item: ( int(order_deltas.get(item, 0)) > 0, item, ), ): delta = int(order_deltas.get(canonical, 0)) if delta == 0: continue platform_symbol = convert_symbol(canonical, "joinquant") skipped_before = len(g.quant60_skipped_orders) request = _order_request(platform_symbol, delta) if request is None: skipped = g.quant60_skipped_orders[skipped_before:] if not skipped: skipped = [ { "symbol": platform_symbol, "reason": "ORDER_REQUEST_NOT_BUILT", } ] if observe_target_package: for item in skipped: _emit_evidence( "SKIPPED_ORDER", { "canonical_symbol": canonical, "delta": delta, "lineage": plan.get("lineage"), "skip": item, }, context, ) continue target = int(current.get(canonical, 0)) + delta request_evidence = { "canonical_symbol": canonical, "current_quantity": int(current.get(canonical, 0)), "delta": delta, "lineage": plan.get("lineage"), "platform_symbol": platform_symbol, "style": _observe_object( request["style"], ("kind", "limit_price"), ), "target_quantity": target, } if observe_target_package: _emit_evidence( "ORDER_REQUEST", request_evidence, context, ) try: if request["style"] is None: order_result = order_target(platform_symbol, target) else: order_result = order_target( platform_symbol, target, style=request["style"], ) except Exception as exc: if observe_target_package: _emit_evidence( "ORDER_RETURN", { "error_type": type(exc).__name__, "lineage": plan.get("lineage"), "outcome": "EXCEPTION", "platform_symbol": platform_symbol, "target_quantity": target, }, context, ) raise observation = { "lineage": plan.get("lineage"), "order": _observe_order(order_result), "outcome": "RETURNED", "platform_symbol": platform_symbol, "target_quantity": target, } if observe_target_package: g.quant60_order_observations.append(observation) _emit_evidence( "ORDER_RETURN", observation, context, ) g.quant60_last_plan = plan return plan def _execute_rebalance(context): """Submit the selected portable plan's exact executable share deltas.""" plan = compute_plan(context) if plan is None: return None managed = ( sorted(plan["universe"]) if "universe" in plan else ( g.quant60_last_universe or g.quant60_config["universe"] ) ) return _submit_plan(context, plan, managed) def _as_date(value, name): if hasattr(value, "date"): value = value.date() if not hasattr(value, "isocalendar"): raise ClockStateError("%s must be a date/datetime" % name) return value def rebalance(context): """Execute on the session immediately after a week's first close. A daily state machine is used instead of ``run_weekly(..., 2)`` so a one-session holiday week still executes on the next available session. """ current_date = _as_date(getattr(context, "current_dt", None), "current_dt") previous_date = _as_date( getattr(context, "previous_date", None), "previous_date", ) if g.quant60_last_callback_date == current_date: return None if _decision_mode() == TARGET_PACKAGE_MODE: # EOD evidence is session-scoped. Clear the prior session only after # the duplicate-date guard so a same-day retry cannot erase evidence. g.quant60_last_plan = None g.quant60_order_observations = [] g.quant60_skipped_orders = [] # Consume the daily clock token before crossing the hosted order # boundary so callback retries cannot duplicate an accepted prefix. g.quant60_last_callback_date = current_date return _execute_rebalance(context) pending = g.quant60_pending_first_session is_first_session = ( previous_date.isocalendar()[:2] != current_date.isocalendar()[:2] ) if pending is not None: if previous_date != pending: raise ClockStateError( "pending first-session close is not the immediately " "previous trading session" ) # Consume the clock token before crossing any hosted order boundary. # A partial API failure must not make a callback retry duplicate the # already accepted prefix of the order list. g.quant60_pending_first_session = ( current_date if is_first_session else None ) g.quant60_last_callback_date = current_date plan = _execute_rebalance(context) return plan if is_first_session: g.quant60_pending_first_session = current_date g.quant60_last_callback_date = current_date return None def after_trading_end(context): """Emit a best-effort end-of-day observation without changing state.""" if _decision_mode() != TARGET_PACKAGE_MODE: return None return _emit_chunked_evidence( "EOD_STATUS", { "last_plan": _plan_evidence( getattr(g, "quant60_last_plan", None) ), "order_returns": getattr( g, "quant60_order_observations", [], ), "orders_api": _observe_platform_collection( "get_orders", _observe_order, ), "portfolio": _observe_portfolio(context), "skipped_orders": getattr( g, "quant60_skipped_orders", [], ), "trades_api": _observe_platform_collection( "get_trades", _observe_trade, ), }, context, )