← back to Zero Code Trading Bot
scripts/new_bot.py
72 lines
#!/usr/bin/env python3
"""
new_bot.py — scaffold a new paper-first bot project from the template.
scripts/new_bot.py <bot-name> [--dest DIR] [--strategy path/to/strategy.json]
Copies assets/bot-template/ into DIR/<bot-name>/ (default DIR=~/Projects), drops
in a compiled strategy.json if one is provided (else the longshot-fade example),
git-inits the new project, and prints next steps. Never runs the bot; never
touches live keys.
"""
import argparse
import json
import os
import shutil
import subprocess
import sys
SKILL_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
TEMPLATE = os.path.join(SKILL_ROOT, "assets", "bot-template")
def main():
ap = argparse.ArgumentParser()
ap.add_argument("name", help="bot project name (kebab-case)")
ap.add_argument("--dest", default=os.path.expanduser("~/Projects"))
ap.add_argument("--strategy", help="path to a strategy.json to inject")
ap.add_argument("--no-git", action="store_true")
args = ap.parse_args()
dest = os.path.join(args.dest, args.name)
if os.path.exists(dest):
sys.exit(f"refusing to overwrite existing path: {dest}")
shutil.copytree(TEMPLATE, dest)
if args.strategy:
with open(args.strategy) as f:
strat = json.load(f)
strat.setdefault("name", args.name)
strat["mode"] = "paper" # always scaffold in paper mode, no exceptions
with open(os.path.join(dest, "strategy.json"), "w") as f:
json.dump(strat, f, indent=2)
# data/ is created on first fill; add a keep + gitignore for the ledger.
os.makedirs(os.path.join(dest, "data"), exist_ok=True)
with open(os.path.join(dest, ".gitignore"), "w") as f:
f.write("data/ledger.jsonl\ndata/LIVE_CONFIRMED\ndata/KILL\n.env\n__pycache__/\n")
if not args.no_git:
try:
subprocess.run(["git", "init", "-q"], cwd=dest, check=True)
subprocess.run(["git", "add", "-A"], cwd=dest, check=True)
subprocess.run(
["git", "-c", "user.email=steve@designerwallcoverings.com",
"-c", "user.name=Steve", "commit", "-q", "-m",
f"scaffold {args.name} paper bot"], cwd=dest, check=True)
except (subprocess.CalledProcessError, FileNotFoundError) as e:
print(f" (git init skipped: {e})")
print(f"✅ scaffolded paper bot → {dest}")
print(" next:")
print(f" cd {dest}")
print(" python venue_adapter.py # confirm live market data ($0)")
print(" python bot.py --once --dry-run # decide, place no fills")
print(" python bot.py --once # first paper fills")
print(" python dashboard.py --serve # watch paper P&L")
if __name__ == "__main__":
main()