{
  "schemaVersion": "1.0",
  "item": {
    "slug": "tbot-controller",
    "name": "TBOT Controller",
    "source": "tencent",
    "type": "skill",
    "category": "金融交易",
    "sourceUrl": "https://clawhub.ai/PlusGenie/tbot-controller",
    "canonicalUrl": "https://clawhub.ai/PlusGenie/tbot-controller",
    "targetPlatform": "OpenClaw"
  },
  "install": {
    "downloadMode": "redirect",
    "downloadUrl": "/downloads/tbot-controller",
    "sourceDownloadUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=tbot-controller",
    "sourcePlatform": "tencent",
    "targetPlatform": "OpenClaw",
    "installMethod": "Manual import",
    "extraction": "Extract archive",
    "prerequisites": [
      "OpenClaw"
    ],
    "packageFormat": "ZIP package",
    "includedAssets": [
      "_meta.json",
      "README.md",
      "SKILL.md",
      "scripts/tbotjson.py",
      "scripts/requirements.txt",
      "scripts/tbot.sh"
    ],
    "primaryDoc": "SKILL.md",
    "quickSetup": [
      "Download the package from Yavira.",
      "Extract the archive and review SKILL.md first.",
      "Import or place the package into your OpenClaw setup."
    ],
    "agentAssist": {
      "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
      "steps": [
        "Download the package from Yavira.",
        "Extract it into a folder your agent can access.",
        "Paste one of the prompts below and point your agent at the extracted folder."
      ],
      "prompts": [
        {
          "label": "New install",
          "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Then review README.md for any prerequisites, environment setup, or post-install checks. Tell me what you changed and call out any manual steps you could not complete."
        },
        {
          "label": "Upgrade existing",
          "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Then review README.md for any prerequisites, environment setup, or post-install checks. Summarize what changed and any follow-up checks I should run."
        }
      ]
    },
    "sourceHealth": {
      "source": "tencent",
      "status": "healthy",
      "reason": "direct_download_ok",
      "recommendedAction": "download",
      "checkedAt": "2026-04-23T16:43:11.935Z",
      "expiresAt": "2026-04-30T16:43:11.935Z",
      "httpStatus": 200,
      "finalUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=4claw-imageboard",
      "contentType": "application/zip",
      "probeMethod": "head",
      "details": {
        "probeUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=4claw-imageboard",
        "contentDisposition": "attachment; filename=\"4claw-imageboard-1.0.1.zip\"",
        "redirectLocation": null,
        "bodySnippet": null
      },
      "scope": "source",
      "summary": "Source download looks usable.",
      "detail": "Yavira can redirect you to the upstream package for this source.",
      "primaryActionLabel": "Download for OpenClaw",
      "primaryActionHref": "/downloads/tbot-controller"
    },
    "validation": {
      "installChecklist": [
        "Use the Yavira download entry.",
        "Review SKILL.md after the package is downloaded.",
        "Confirm the extracted package contains the expected setup assets."
      ],
      "postInstallChecks": [
        "Confirm the extracted package includes the expected docs or setup files.",
        "Validate the skill or prompts are available in your target agent workspace.",
        "Capture any manual follow-up steps the agent could not complete."
      ]
    },
    "downloadPageUrl": "https://openagent3.xyz/downloads/tbot-controller",
    "agentPageUrl": "https://openagent3.xyz/skills/tbot-controller/agent",
    "manifestUrl": "https://openagent3.xyz/skills/tbot-controller/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/tbot-controller/agent.md"
  },
  "agentAssist": {
    "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
    "steps": [
      "Download the package from Yavira.",
      "Extract it into a folder your agent can access.",
      "Paste one of the prompts below and point your agent at the extracted folder."
    ],
    "prompts": [
      {
        "label": "New install",
        "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Then review README.md for any prerequisites, environment setup, or post-install checks. Tell me what you changed and call out any manual steps you could not complete."
      },
      {
        "label": "Upgrade existing",
        "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Then review README.md for any prerequisites, environment setup, or post-install checks. Summarize what changed and any follow-up checks I should run."
      }
    ]
  },
  "documentation": {
    "source": "clawhub",
    "primaryDoc": "SKILL.md",
    "sections": [
      {
        "title": "What this skill does",
        "body": "Query TBOT sqlite DB for alerts/orders/errors/portfolio (DB-first)\nStart/stop TradingBoat/TBOT (docker compose or systemd)\nFetch health/status (containers, ports, basic checks) only when explicitly requested\nRead recent logs only when explicitly requested"
      },
      {
        "title": "Safety rules",
        "body": "Default to read-only operations (status/logs) unless user explicitly requests a control action.\nFor any state-changing action (start/stop/restart/send), require explicit confirmation via the flag --run-it or environment variable RUN_IT=1. The controller will refuse execution otherwise.\nNever print secrets (webhook keys, tokens). Redact them."
      },
      {
        "title": "Refusal criteria (must-stop conditions)",
        "body": "The agent MUST stop and ask for user action if any of the following is true:\n\nRuntime location is unknown and discovery cannot uniquely resolve it.\nThe TBOT database path cannot be found or opened read-only.\nA request would start/stop/restart services or send signals without --run-it / RUN_IT=1.\nA request implies destructive DB changes (DROP/TRUNCATE/ALTER) or “run arbitrary SQL”."
      },
      {
        "title": "Prerequisites (first-time users)",
        "body": "This skill controls a separate TBOT runtime stack. The reference/runtime implementation is:\n\nopenclaw-on-tradingboat (TBOT runtime stack): https://github.com/PlusGenie/openclaw-on-tradingboat\n\nThis tbot-controller skill does not download or install the runtime for you. If the runtime is missing, the skill will run read-only DB helpers where possible, but status/logs/control actions will fail until the runtime exists."
      },
      {
        "title": "Install the runtime (recommended)",
        "body": "Clone the runtime repo:\n\ngit clone https://github.com/PlusGenie/openclaw-on-tradingboat.git\ncd openclaw-on-tradingboat\n\nEnsure you can start it manually (outside this skill). For Docker Compose based installs, this typically means:\n\ndocker compose up -d\n\nTell this skill where the runtime lives (recommended):\n\nSet TBOT_COMPOSE_DIR to the folder that contains docker-compose.yml or compose.yaml.\n\nExamples:\n\nexport TBOT_COMPOSE_DIR=\"$HOME/develop/github/openclaw-on-tradingboat\"\n\nOr add it to ~/.openclaw/.env / your skill env block in openclaw.json."
      },
      {
        "title": "Configure runtime secrets (outside this skill)",
        "body": "TBOT typically uses a .env file for broker credentials and webhook keys.\nDo not commit secrets to git.\nIf you are unsure whether the runtime is set to paper or live, this skill must refuse to execute any trade/action until you confirm which it is."
      },
      {
        "title": "Install / script permissions",
        "body": "This skill is invoked via a bash entrypoint script. Ensure it is executable:\n\nchmod +x scripts/tbot.sh"
      },
      {
        "title": "Python deps (OpenClaw-native)",
        "body": "This skill uses uv to run Python scripts in an isolated environment and auto-install dependencies from:\n\n{baseDir}/scripts/requirements.txt\n\nInstall uv (macOS):\n\nbrew install uv\n\nClawHub packaging note: if you publish this skill, ensure scripts/ (including requirements.txt) is included at the root of the repo."
      },
      {
        "title": "IMPORTANT: DB-first, discovery only for status/control",
        "body": "DB queries do NOT require discovery.\nDiscovery is required only before status/logs/control actions.\n\nOpenClaw must NOT hardcode old paths like ~/ib-gateway-docker.\n\nAlways prefer discovery output (usually pointing to openclaw-on-tradingboat)."
      },
      {
        "title": "Entry point (required)",
        "body": "OpenClaw MUST invoke this skill via:\n\nbash scripts/tbot.sh <mode> <args...>\n\nValid modes:\n\nctl — operations control (docker/systemd)\njson — JSON signal generation (schema-validated) and send to TBOT webhook (non-interactive)\nstatus — read-only inspection (probe & discovery)\n\nOpenClaw must never call python tbot*.py directly."
      },
      {
        "title": "Probe & Discovery (read-only, only for status/control)",
        "body": "When the user says “open TBOT”, “start TBOT”, “TBOT status”, etc., OpenClaw should:\n\nTry discovery first (read-only):\n\nbash scripts/tbot.sh status discover\n\nThis step is mandatory because the compose folder may change over time\n(for example migrating from ib-gateway-docker to openclaw-on-tradingboat).\n\nIf discovery returns a resolved runtime, run ctl commands by injecting env vars:\n\nDocker example:\n\nMODE=docker COMPOSE_DIR=\"<compose_dir>\" bash scripts/tbot.sh ctl status\n\nExample expected compose folder:\n\n~/develop/github/openclaw-on-tradingboat>\n\nsystemd example:\n\nMODE=systemd SERVICE_NAME=\"<service_name>\" SYSTEMD_USER=\"<0|1>\" bash scripts/tbot.sh ctl status\n\nOnly if discovery cannot resolve a single runtime, ask one precise question:\n\nDocker Compose: “What is the folder containing docker-compose.yml/compose.yaml? (Usually this is the tbot-runtime (example) folder.)”\nsystemd: “What is the service name (and is it --user)?”\n\nNotes:\n\nDiscovery must remain read-only (no starting/stopping).\nUse discovery output as the authoritative suggestion for MODE/COMPOSE_DIR/SERVICE_NAME."
      },
      {
        "title": "Why this matters",
        "body": "If OpenClaw skips discovery, it may incorrectly report TBOT as DOWN\nbecause it is checking an obsolete compose folder."
      },
      {
        "title": "Status (read-only, only if requested)",
        "body": "bash scripts/tbot.sh ctl status\nbash scripts/tbot.sh ctl logs --tail 200\n\nNote: With tbot-runtime (example), docker compose typically brings up three containers: ib-gateway-on-tradingboat (gnzsnz/ib-gateway), redis-on-tradingboat, and tbot-on-tradingboat.\n\nInternally:\n\nDocker: docker compose ps, docker compose logs --tail=200\nsystemd: systemctl --user status <service>, journalctl --user -u <service> -n 200"
      },
      {
        "title": "Control (explicit confirmation required)",
        "body": "bash scripts/tbot.sh ctl start --run-it\nbash scripts/tbot.sh ctl stop --run-it\nbash scripts/tbot.sh ctl restart --run-it\n\nTip: Use MODE=docker + COMPOSE_DIR pointed at tbot-runtime (example) to control the stack via docker compose.\n\nInternally:\n\nDocker: docker compose up -d, docker compose down\nsystemd: systemctl --user start <service>, systemctl --user stop <service>"
      },
      {
        "title": "JSON signal generation (generate + send)",
        "body": "json mode is non-interactive by design.\nOpenClaw MUST NOT ask the user for webhook details or trading intent if they can be inferred.\n\nInference rules:\n\nWebhook URL default: http://127.0.0.1:5001/webhook (override with TBOT_WEBHOOK_URL)\nWebhook key is read from the TBOT runtime .env by default (override with WEBHOOK_KEY)\norderRef is auto-generated when omitted\nNatural language like close 50 NFLX implies strategy.close, contract=stock, qty=50\n\njson mode generates a schema-valid TradingView-style payload and sends it to TBOT via webhook.\n\nDefaults / inference rules (do not ask the user):\n\nWebhook URL: default http://127.0.0.1:5001/webhook (override with TBOT_WEBHOOK_URL).\nWebhook key: read from runtime .env (override with WEBHOOK_KEY).\norderRef: if not provided, auto-generate Close_<TICKER>_<QTY>_<epoch_ms>.\nClose intent: inferred automatically; do not prompt the user.\n\n# Example (user: “close 50 NFLX now”)\nTBOT_WEBHOOK_URL=\"http://127.0.0.1:5001/webhook\" \\\nWEBHOOK_KEY=\"WebhookReceived:123456\" \\\nbash scripts/tbot.sh json \\\n  --ticker NFLX \\\n  --direction strategy.close \\\n  --contract stock \\\n  --metric qty=50\n\nGuarantees:\n\nOutput is validated against alert_webhook_schema.json\nUnsupported directions or metrics fail fast\nNo network calls or broker actions are performed\nThis generator is independent of the gateway container image (e.g., gnzsnz/ib-gateway).\n\nCopy-paste JSON output (expected schema shape)\n\nWhen asked to “generate a TradingView webhook JSON”, OpenClaw should output JSON exactly like this shape:\n\n{\n  \"timestamp\": 1710000000000,\n  \"ticker\": \"ES1!\",\n  \"currency\": \"USD\",\n  \"timeframe\": \"5\",\n  \"clientId\": 1,\n  \"key\": \"WebhookReceived:123456\",\n  \"contract\": \"future\",\n  \"orderRef\": \"Long#1\",\n  \"direction\": \"strategy.entrylong\",\n  \"exchange\": \"CME\",\n  \"lastTradeDateOrContractMonth\": \"202603\",\n  \"multiplier\": \"50\",\n  \"metrics\": [\n    {\"name\": \"entry.limit\", \"value\": 0},\n    {\"name\": \"entry.stop\", \"value\": 0},\n    {\"name\": \"exit.limit\", \"value\": 0},\n    {\"name\": \"exit.stop\", \"value\": 0},\n    {\"name\": \"qty\", \"value\": 1},\n    {\"name\": \"price\", \"value\": 5032.25}\n  ]\n}\n\nTip (local-first / zero-config examples): it’s OK to use a placeholder key value in docs.\nFor real TradingView → TBOT delivery, set it to your actual shared secret (TVWB key)."
      },
      {
        "title": "DB inspection (read-only, primary)",
        "body": "Preferred (via this skill, DB-first):\n\nbash scripts/tbot.sh status db --table orders --format summary --limit 100\nbash scripts/tbot.sh status db --table alerts --format summary --limit 100\nbash scripts/tbot.sh status db --table errors --format summary --limit 100\nbash scripts/tbot.sh status db --table tbot --format summary --limit 100\nUse --format json to return raw JSON.\n\n\nPortfolio/positions are derived from TBOTORDERS (same as /orders/data in UI)."
      },
      {
        "title": "Read-only helpers (DB-first)",
        "body": "Portfolio snapshot:\n\nbash scripts/tbot.sh status portfolio --format summary\n\n\nErrors tail (with grouping):\n\nbash scripts/tbot.sh status errors --format summary --limit 200\nbash scripts/tbot.sh status errors --group --limit 200\n\n\nHealth checks (HTTP):\n\nbash scripts/tbot.sh status health --base-url http://127.0.0.1:5001\n\nExample output (--format summary, orders):\n\nTotals:\n- Market value: 284,103.16\n- Unrealized PnL: 134,585.15\n- Realized PnL: 0.00\n\nTBOT_TIME        | ORD_TIME                | TICKER | TV_Close | ACTION | TYPE | QTY | LIMIT | STOP | ORDERID | ORDERREF  | STATUS    | POS | MRKVAL     | AVGF     | UnrealPnL  | RealPnL\n----------------+-------------------------+--------+----------+--------+------+-----+-------+------+---------+-----------+-----------+-----+------------+----------+------------+--------\n2026-02-05 20:06 | 2026-02-05 20:06:12.345 | TSLA   | 399.4796 | BUY    | LMT  | 455 | 0     | 0    | 12345   | Ptf_TSLA  | Portfolio | 455 | 181,763.22 | 187.9038 | 96,266.98  | 0\n\nDB path resolution (first match wins):\n\n--db-path /path/to/tbot_sqlite3\nTBOT_DB_PATH=/path/to/tbot_sqlite3\nTBOT_DB_OFFICE=/path/to/tbot_sqlite3\n\n\nDB location notes:\n\nInside the container, TBOT may create the DB at /home/tbot/tbot_sqlite3 if no volume is set.\nRecommended: bind-mount ./runtime/database to /home/tbot/database and set TBOT_DB_OFFICE=/home/tbot/database/tbot_sqlite3.\nWith the bind-mount, the host path is:\n\ntbot-runtime (example)/runtime/database/tbot_sqlite3\n\n\n\n\nAfter updating tbot-runtime (example)/docker-compose.yml, restart TBOT:\n\nMODE=docker COMPOSE_DIR=\"/path/to/your/tbot-runtime\" bash scripts/tbot.sh ctl restart --run-it\n\n\nContainer note:\n\nThe tbot container may not include sqlite3 CLI; read the DB on the host (preferred) via bind-mount.\n\n\nFallback (manual):\n\nsqlite3 <path> \"SELECT ...\""
      },
      {
        "title": "Known gaps & intended fixes (tracked)",
        "body": "Discovery can miss running docker compose stacks; use DB-first commands for portfolio instead of discovery.\nAdd explicit subcommands (planned): errors --tail (limit), health (HTTP checks for /orders/data + /tbot/data).\nAdd a single-line summary mode (planned): totals + top 3 positions + biggest losing position."
      },
      {
        "title": "Required fields",
        "body": "This skill generates JSON with fields used by TBOT/TradingBoat style alerts:\n\ntimestamp (ms since epoch)\nticker (e.g., AAPL, ES1!)\ncurrency (e.g., USD)\ntimeframe (e.g., 1, 5, 1D)\nclientId (integer; IBKR client ID)\nkey (TVWB shared key)\ncontract (e.g., stock, forex, crypto, future)\norderRef (string identifier)\ndirection (e.g., strategy.entrylong, strategy.entryshort, strategy.exitlong, strategy.exitshort, strategy.close, strategy.close_all)\nexchange, lastTradeDateOrContractMonth, multiplier (mostly for futures)\nmetrics (array of {name, value})"
      },
      {
        "title": "Example payload",
        "body": "(Uses a placeholder key value for copy-paste. Replace with your real TVWB shared key in production.)\n\n{\n  \"timestamp\": 1710000000000,\n  \"ticker\": \"ES1!\",\n  \"currency\": \"USD\",\n  \"timeframe\": \"5\",\n  \"clientId\": 1,\n  \"key\": \"WebhookReceived:123456\",\n  \"contract\": \"future\",\n  \"orderRef\": \"Long#1\",\n  \"direction\": \"strategy.entrylong\",\n  \"exchange\": \"CME\",\n  \"lastTradeDateOrContractMonth\": \"202603\",\n  \"multiplier\": \"50\",\n  \"metrics\": [\n    {\"name\": \"entry.limit\", \"value\": 0},\n    {\"name\": \"entry.stop\", \"value\": 0},\n    {\"name\": \"exit.limit\", \"value\": 0},\n    {\"name\": \"exit.stop\", \"value\": 0},\n    {\"name\": \"qty\", \"value\": 1},\n    {\"name\": \"price\", \"value\": 5032.25}\n  ]\n}"
      }
    ],
    "body": "What this skill does\nQuery TBOT sqlite DB for alerts/orders/errors/portfolio (DB-first)\nStart/stop TradingBoat/TBOT (docker compose or systemd)\nFetch health/status (containers, ports, basic checks) only when explicitly requested\nRead recent logs only when explicitly requested\nSafety rules\nDefault to read-only operations (status/logs) unless user explicitly requests a control action.\nFor any state-changing action (start/stop/restart/send), require explicit confirmation via the flag --run-it or environment variable RUN_IT=1. The controller will refuse execution otherwise.\nNever print secrets (webhook keys, tokens). Redact them.\nRefusal criteria (must-stop conditions)\n\nThe agent MUST stop and ask for user action if any of the following is true:\n\nRuntime location is unknown and discovery cannot uniquely resolve it.\nThe TBOT database path cannot be found or opened read-only.\nA request would start/stop/restart services or send signals without --run-it / RUN_IT=1.\nA request implies destructive DB changes (DROP/TRUNCATE/ALTER) or “run arbitrary SQL”.\nPrerequisites (first-time users)\n\nThis skill controls a separate TBOT runtime stack. The reference/runtime implementation is:\n\nopenclaw-on-tradingboat (TBOT runtime stack): https://github.com/PlusGenie/openclaw-on-tradingboat\n\nThis tbot-controller skill does not download or install the runtime for you. If the runtime is missing, the skill will run read-only DB helpers where possible, but status/logs/control actions will fail until the runtime exists.\n\nInstall the runtime (recommended)\nClone the runtime repo:\ngit clone https://github.com/PlusGenie/openclaw-on-tradingboat.git\ncd openclaw-on-tradingboat\n\nEnsure you can start it manually (outside this skill). For Docker Compose based installs, this typically means:\ndocker compose up -d\n\nTell this skill where the runtime lives (recommended):\nSet TBOT_COMPOSE_DIR to the folder that contains docker-compose.yml or compose.yaml.\n\nExamples:\n\nexport TBOT_COMPOSE_DIR=\"$HOME/develop/github/openclaw-on-tradingboat\"\n\n\nOr add it to ~/.openclaw/.env / your skill env block in openclaw.json.\n\nConfigure runtime secrets (outside this skill)\nTBOT typically uses a .env file for broker credentials and webhook keys.\nDo not commit secrets to git.\nIf you are unsure whether the runtime is set to paper or live, this skill must refuse to execute any trade/action until you confirm which it is.\nInstall / script permissions\n\nThis skill is invoked via a bash entrypoint script. Ensure it is executable:\n\nchmod +x scripts/tbot.sh\n\nPython deps (OpenClaw-native)\n\nThis skill uses uv to run Python scripts in an isolated environment and auto-install dependencies from:\n\n{baseDir}/scripts/requirements.txt\n\nInstall uv (macOS):\n\nbrew install uv\n\n\nClawHub packaging note: if you publish this skill, ensure scripts/ (including requirements.txt) is included at the root of the repo.\n\nIMPORTANT: DB-first, discovery only for status/control\n\nDB queries do NOT require discovery. Discovery is required only before status/logs/control actions.\n\nOpenClaw must NOT hardcode old paths like ~/ib-gateway-docker.\n\nAlways prefer discovery output (usually pointing to openclaw-on-tradingboat).\n\nCommands\nEntry point (required)\n\nOpenClaw MUST invoke this skill via:\n\nbash scripts/tbot.sh <mode> <args...>\n\n\nValid modes:\n\nctl — operations control (docker/systemd)\njson — JSON signal generation (schema-validated) and send to TBOT webhook (non-interactive)\nstatus — read-only inspection (probe & discovery)\n\nOpenClaw must never call python tbot*.py directly.\n\nProbe & Discovery (read-only, only for status/control)\n\nWhen the user says “open TBOT”, “start TBOT”, “TBOT status”, etc., OpenClaw should:\n\nTry discovery first (read-only):\nbash scripts/tbot.sh status discover\n\n\nThis step is mandatory because the compose folder may change over time (for example migrating from ib-gateway-docker to openclaw-on-tradingboat).\n\nIf discovery returns a resolved runtime, run ctl commands by injecting env vars:\nDocker example:\nMODE=docker COMPOSE_DIR=\"<compose_dir>\" bash scripts/tbot.sh ctl status\n\n\nExample expected compose folder:\n\n~/develop/github/openclaw-on-tradingboat> \n\nsystemd example:\nMODE=systemd SERVICE_NAME=\"<service_name>\" SYSTEMD_USER=\"<0|1>\" bash scripts/tbot.sh ctl status\n\nOnly if discovery cannot resolve a single runtime, ask one precise question:\nDocker Compose: “What is the folder containing docker-compose.yml/compose.yaml? (Usually this is the tbot-runtime (example) folder.)”\nsystemd: “What is the service name (and is it --user)?”\n\nNotes:\n\nDiscovery must remain read-only (no starting/stopping).\nUse discovery output as the authoritative suggestion for MODE/COMPOSE_DIR/SERVICE_NAME.\nWhy this matters\n\nIf OpenClaw skips discovery, it may incorrectly report TBOT as DOWN because it is checking an obsolete compose folder.\n\nStatus (read-only, only if requested)\nbash scripts/tbot.sh ctl status\nbash scripts/tbot.sh ctl logs --tail 200\n\n\nNote: With tbot-runtime (example), docker compose typically brings up three containers: ib-gateway-on-tradingboat (gnzsnz/ib-gateway), redis-on-tradingboat, and tbot-on-tradingboat.\n\nInternally:\n\nDocker: docker compose ps, docker compose logs --tail=200\nsystemd: systemctl --user status <service>, journalctl --user -u <service> -n 200\nControl (explicit confirmation required)\nbash scripts/tbot.sh ctl start --run-it\nbash scripts/tbot.sh ctl stop --run-it\nbash scripts/tbot.sh ctl restart --run-it\n\n\nTip: Use MODE=docker + COMPOSE_DIR pointed at tbot-runtime (example) to control the stack via docker compose.\n\nInternally:\n\nDocker: docker compose up -d, docker compose down\nsystemd: systemctl --user start <service>, systemctl --user stop <service>\nJSON signal generation (generate + send)\n\njson mode is non-interactive by design. OpenClaw MUST NOT ask the user for webhook details or trading intent if they can be inferred.\n\nInference rules:\n\nWebhook URL default: http://127.0.0.1:5001/webhook (override with TBOT_WEBHOOK_URL)\nWebhook key is read from the TBOT runtime .env by default (override with WEBHOOK_KEY)\norderRef is auto-generated when omitted\nNatural language like close 50 NFLX implies strategy.close, contract=stock, qty=50\n\njson mode generates a schema-valid TradingView-style payload and sends it to TBOT via webhook.\n\nDefaults / inference rules (do not ask the user):\n\nWebhook URL: default http://127.0.0.1:5001/webhook (override with TBOT_WEBHOOK_URL).\nWebhook key: read from runtime .env (override with WEBHOOK_KEY).\norderRef: if not provided, auto-generate Close_<TICKER>_<QTY>_<epoch_ms>.\nClose intent: inferred automatically; do not prompt the user.\n# Example (user: “close 50 NFLX now”)\nTBOT_WEBHOOK_URL=\"http://127.0.0.1:5001/webhook\" \\\nWEBHOOK_KEY=\"WebhookReceived:123456\" \\\nbash scripts/tbot.sh json \\\n  --ticker NFLX \\\n  --direction strategy.close \\\n  --contract stock \\\n  --metric qty=50\n\n\nGuarantees:\n\nOutput is validated against alert_webhook_schema.json\nUnsupported directions or metrics fail fast\nNo network calls or broker actions are performed\nThis generator is independent of the gateway container image (e.g., gnzsnz/ib-gateway).\nCopy-paste JSON output (expected schema shape)\n\nWhen asked to “generate a TradingView webhook JSON”, OpenClaw should output JSON exactly like this shape:\n\n{\n  \"timestamp\": 1710000000000,\n  \"ticker\": \"ES1!\",\n  \"currency\": \"USD\",\n  \"timeframe\": \"5\",\n  \"clientId\": 1,\n  \"key\": \"WebhookReceived:123456\",\n  \"contract\": \"future\",\n  \"orderRef\": \"Long#1\",\n  \"direction\": \"strategy.entrylong\",\n  \"exchange\": \"CME\",\n  \"lastTradeDateOrContractMonth\": \"202603\",\n  \"multiplier\": \"50\",\n  \"metrics\": [\n    {\"name\": \"entry.limit\", \"value\": 0},\n    {\"name\": \"entry.stop\", \"value\": 0},\n    {\"name\": \"exit.limit\", \"value\": 0},\n    {\"name\": \"exit.stop\", \"value\": 0},\n    {\"name\": \"qty\", \"value\": 1},\n    {\"name\": \"price\", \"value\": 5032.25}\n  ]\n}\n\n\nTip (local-first / zero-config examples): it’s OK to use a placeholder key value in docs. For real TradingView → TBOT delivery, set it to your actual shared secret (TVWB key).\n\nDB inspection (read-only, primary)\nPreferred (via this skill, DB-first):\nbash scripts/tbot.sh status db --table orders --format summary --limit 100\nbash scripts/tbot.sh status db --table alerts --format summary --limit 100\nbash scripts/tbot.sh status db --table errors --format summary --limit 100\nbash scripts/tbot.sh status db --table tbot --format summary --limit 100\nUse --format json to return raw JSON.\nPortfolio/positions are derived from TBOTORDERS (same as /orders/data in UI).\nRead-only helpers (DB-first)\nPortfolio snapshot:\nbash scripts/tbot.sh status portfolio --format summary\nErrors tail (with grouping):\nbash scripts/tbot.sh status errors --format summary --limit 200\nbash scripts/tbot.sh status errors --group --limit 200\nHealth checks (HTTP):\nbash scripts/tbot.sh status health --base-url http://127.0.0.1:5001\n\nExample output (--format summary, orders):\n\nTotals:\n- Market value: 284,103.16\n- Unrealized PnL: 134,585.15\n- Realized PnL: 0.00\n\nTBOT_TIME        | ORD_TIME                | TICKER | TV_Close | ACTION | TYPE | QTY | LIMIT | STOP | ORDERID | ORDERREF  | STATUS    | POS | MRKVAL     | AVGF     | UnrealPnL  | RealPnL\n----------------+-------------------------+--------+----------+--------+------+-----+-------+------+---------+-----------+-----------+-----+------------+----------+------------+--------\n2026-02-05 20:06 | 2026-02-05 20:06:12.345 | TSLA   | 399.4796 | BUY    | LMT  | 455 | 0     | 0    | 12345   | Ptf_TSLA  | Portfolio | 455 | 181,763.22 | 187.9038 | 96,266.98  | 0\n\nDB path resolution (first match wins):\n--db-path /path/to/tbot_sqlite3\nTBOT_DB_PATH=/path/to/tbot_sqlite3\nTBOT_DB_OFFICE=/path/to/tbot_sqlite3\nDB location notes:\nInside the container, TBOT may create the DB at /home/tbot/tbot_sqlite3 if no volume is set.\nRecommended: bind-mount ./runtime/database to /home/tbot/database and set TBOT_DB_OFFICE=/home/tbot/database/tbot_sqlite3.\nWith the bind-mount, the host path is:\ntbot-runtime (example)/runtime/database/tbot_sqlite3\nAfter updating tbot-runtime (example)/docker-compose.yml, restart TBOT:\nMODE=docker COMPOSE_DIR=\"/path/to/your/tbot-runtime\" bash scripts/tbot.sh ctl restart --run-it\nContainer note:\nThe tbot container may not include sqlite3 CLI; read the DB on the host (preferred) via bind-mount.\nFallback (manual):\nsqlite3 <path> \"SELECT ...\"\nKnown gaps & intended fixes (tracked)\nDiscovery can miss running docker compose stacks; use DB-first commands for portfolio instead of discovery.\nAdd explicit subcommands (planned): errors --tail (limit), health (HTTP checks for /orders/data + /tbot/data).\nAdd a single-line summary mode (planned): totals + top 3 positions + biggest losing position.\nData signal: TradingView-style webhook JSON generator\nRequired fields\n\nThis skill generates JSON with fields used by TBOT/TradingBoat style alerts:\n\ntimestamp (ms since epoch)\nticker (e.g., AAPL, ES1!)\ncurrency (e.g., USD)\ntimeframe (e.g., 1, 5, 1D)\nclientId (integer; IBKR client ID)\nkey (TVWB shared key)\ncontract (e.g., stock, forex, crypto, future)\norderRef (string identifier)\ndirection (e.g., strategy.entrylong, strategy.entryshort, strategy.exitlong, strategy.exitshort, strategy.close, strategy.close_all)\nexchange, lastTradeDateOrContractMonth, multiplier (mostly for futures)\nmetrics (array of {name, value})\nExample payload\n\n(Uses a placeholder key value for copy-paste. Replace with your real TVWB shared key in production.)\n\n{\n  \"timestamp\": 1710000000000,\n  \"ticker\": \"ES1!\",\n  \"currency\": \"USD\",\n  \"timeframe\": \"5\",\n  \"clientId\": 1,\n  \"key\": \"WebhookReceived:123456\",\n  \"contract\": \"future\",\n  \"orderRef\": \"Long#1\",\n  \"direction\": \"strategy.entrylong\",\n  \"exchange\": \"CME\",\n  \"lastTradeDateOrContractMonth\": \"202603\",\n  \"multiplier\": \"50\",\n  \"metrics\": [\n    {\"name\": \"entry.limit\", \"value\": 0},\n    {\"name\": \"entry.stop\", \"value\": 0},\n    {\"name\": \"exit.limit\", \"value\": 0},\n    {\"name\": \"exit.stop\", \"value\": 0},\n    {\"name\": \"qty\", \"value\": 1},\n    {\"name\": \"price\", \"value\": 5032.25}\n  ]\n}"
  },
  "trust": {
    "sourceLabel": "tencent",
    "provenanceUrl": "https://clawhub.ai/PlusGenie/tbot-controller",
    "publisherUrl": "https://clawhub.ai/PlusGenie/tbot-controller",
    "owner": "PlusGenie",
    "version": "1.0.0",
    "license": null,
    "verificationStatus": "Indexed source record"
  },
  "links": {
    "detailUrl": "https://openagent3.xyz/skills/tbot-controller",
    "downloadUrl": "https://openagent3.xyz/downloads/tbot-controller",
    "agentUrl": "https://openagent3.xyz/skills/tbot-controller/agent",
    "manifestUrl": "https://openagent3.xyz/skills/tbot-controller/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/tbot-controller/agent.md"
  }
}