#!/usr/bin/env bash set -euo pipefail # shellcheck disable=SC1091 source "$(dirname "$0")/_env.sh" # Export best (or N-th) hyperopt epoch into strategy params JSON so backtesting # picks them up: user_data/strategies/.json STRATEGY="${STRATEGY:-SampleStrategy}" EPOCH="${EPOCH:--1}" OUT="${OUT:-user_data/strategies/${STRATEGY}.json}" TMP="$(mktemp)" trap 'rm -f "$TMP"' EXIT freqtrade hyperopt-show \ --config user_data/config.json \ -n "${EPOCH}" \ --print-json \ --no-header >"$TMP" PYTHON_BIN="${ROOT}/.venv/bin/python" if [[ ! -x "${PYTHON_BIN}" ]]; then PYTHON_BIN="$(command -v python3)" fi "${PYTHON_BIN}" - "$TMP" "$STRATEGY" "$OUT" <<'PY' import json, sys from pathlib import Path src, strategy, out = sys.argv[1], sys.argv[2], sys.argv[3] raw = Path(src).read_text().strip() # hyperopt-show may print log noise; keep the last JSON object start = raw.rfind("{") if start < 0: raise SystemExit(f"No JSON found in hyperopt-show output:\n{raw[:500]}") payload = json.loads(raw[start:]) KNOWN = ("buy", "sell", "roi", "stoploss", "trailing", "protection") def expand_tp_combo(sell: dict) -> dict: """If sell has tp_rr_combo 'a,b,c', mirror into tp1_rr/tp2_rr/tp3_rr.""" combo = sell.get("tp_rr_combo") if combo is None: return sell if isinstance(combo, (list, tuple)) and len(combo) == 3: a, b, c = (float(x) for x in combo) sell["tp_rr_combo"] = f"{a},{b},{c}" elif isinstance(combo, str) and "," in combo: a, b, c = (float(x) for x in combo.split(",")) else: return sell sell["tp1_rr"] = a sell["tp2_rr"] = b sell["tp3_rr"] = c return sell def as_params(obj: dict) -> dict: if "params" in obj and isinstance(obj["params"], dict): raw_params = obj["params"] if any(k in raw_params for k in KNOWN): params = {k: v for k, v in raw_params.items() if k in KNOWN} else: params = {"buy": raw_params} if raw_params else {} elif any(k in obj for k in KNOWN): params = {k: v for k, v in obj.items() if k in KNOWN} else: params = {"buy": obj} if obj else {} if "sell" in params and isinstance(params["sell"], dict): params["sell"] = expand_tp_combo(dict(params["sell"])) return params params = as_params(payload) doc = { "strategy_name": strategy, "params": params, } Path(out).write_text(json.dumps(doc, indent=2) + "\n") print(f"Wrote {out}") print(json.dumps(params, indent=2)) PY