Complete guide for setting up the Glogger signal bot on a new Windows machine, configuring brokers, and connecting Telegram alerts.
glogger_system\ folder to the new machine. The required structure is:
glogger_system/
src/
templates/
static/
data/ ← created automatically on first run
config.yaml
requirements.txt
run.bat
run_dashboard.bat
python -m pip install -r requirements.txt
Key packages: yfinance, flask, pyyaml, robin_stocks,
pyotp, pyetrade, matplotlib, holidays, requests
config.yaml; credentials are saved separately to %LOCALAPPDATA%\Glogger\secrets.json, outside the repository and OneDrive. At minimum you need Robinhood credentials and a Telegram bot token.
See the Configuration section below.
python -m tests.test_synthetic # unit tests
python -m src.main --once # single scan — confirms data + alerts work
Public settings live in config.yaml. Enter credentials through the Settings panel; they are stored locally in %LOCALAPPDATA%\Glogger\secrets.json and are never written back to the synced project.
account:
value: 5000 # your account balance in USD
max_risk_pct: 10 # never risk more than 10% per trade
trading:
mode: notify # notify | sandbox | live
broker: robinhood # robinhood | etrade (Robinhood is the default)
alerts:
telegram:
enabled: true
chat_id: "987654321"
forward_to: [] # add other recipients' chat IDs here
live_class_chat_id: "" # immutable outbound-only channel ID
# Enter broker passwords, API keys, TOTP secrets, and bot_token in Settings.
# They are stored outside this project in the local secret store.
python -m src.main
Or double-click run.bat. Starts before 10:00 AM ET. Must stay running all day during market hours.
python -m src.dashboard_server
Or double-click run_dashboard.bat. Then open http://localhost:5000.
run.batRobinhood is the default broker. The bot uses robin_stocks to look up option chains and place orders.
config.yaml.
A one-contract position receives a sell-to-close GTC limit at 2×. With two or more filled contracts, the bot sells the larger half at 2× to recover risk and places the smaller runner at 3×. Robinhood builds the plan from the actual filled quantity, including partial fills.
E*TRADE is optional. Use it if you prefer it over Robinhood.
Managed-exit limitation: the current E*TRADE adapter cannot confirm option fills or maintain GTC scaled exits. Automatic entries are disabled for this adapter; Telegram-confirmed entries remain manual-control trades and require you to place exits after the buy fills.
consumer_key and consumer_secret in the Settings panel; they are stored in the local secret store.
trading.broker to etrade in config.yaml (or via the Settings panel).
/newbot → follow prompts → copy the bot token.
chat_id. Send your bot any message once to activate the chat. For live-class output, configure the channel's immutable numeric live_class_chat_id; channel posts are outbound-only and can never issue trading commands.
/signals — see today's signal IDs
/trade <id> — preview a trade
/qty 2 — set a fixed quantity (e.g. always buy 2 contracts)
exp 7/10 — change expiration on the previewed trade
strike 620 — change strike (also: dist 8, qty 2, limit 0.40)
yes / si / dale — confirm and place
no / cancel — abort
See the full Bot Commands reference below for every available command.
alerts.telegram.forward_to. They must send the bot /start first.
Send any of these to your Telegram bot. Commands are case-insensitive. The bot only responds to the chat_id configured in config.yaml.
| Command | What it does |
|---|---|
/signals also /today, /hoy |
List every signal detected today with its ID, direction, strike, expiry, ask price, and the correct /trade command to use. |
/trade <id> |
Fetch a live quote for signal <id> and show a trade preview: contract details, quantity, total cost, risk %, and the 2×/3× scaled GTC exit plan. The quantity shown follows the priority: per-trade override → global /qty override → auto-calculated. Replies with "yes" or "no" to proceed. |
/trade <id> <qty> |
Same as /trade <id> but forces <qty> contracts for this one trade only — does not change the global setting. Example: /trade 7 3 previews signal 7 with exactly 3 contracts. |
/tradelive <id> |
Same as /trade but for signals detected from the professor's live class audio (tagged [LIVE CLASS] in /signals). |
yes / si / dale / ok / go / confirm |
Confirm the pending trade preview. The bot places the buy-to-open limit order, then protects the fill with the previewed scaled GTC exits. Works even when the bot is in notify mode. |
no / cancel / cancelar / abort / nope |
Cancel the pending trade preview. Nothing is placed. |
After a /trade or /tradelive preview (and before replying "yes"), you can
change anything about the trade by sending one of the messages below. Each one
fetches a fresh live quote and shows an updated preview, with a Customized: line listing
what you've changed. Adjustments stack — change the expiry, then the strike, then the quantity.
Sending /trade <id> again starts over with the signal's original values.
The slash is optional: strike 620 and /strike 620 both work.
| Message | What it does |
|---|---|
exp 7/10 also exp 2026-07-10, exp 7-10, exp 7/10/26 |
Change the expiration date. Accepts most date formats; a month/day without a year assumes the next occurrence. Also answers to expiry and expiration. |
exp +1 / exp +2 / exp next |
Roll to a later weekly expiry without typing a date. +1 = the next listed expiry after the current one, +2 = two out. SPY rolls Mon/Wed/Fri; other tickers roll Friday to Friday. Market holidays are skipped automatically. |
strike 620 |
Set an exact strike price. If that strike isn't listed on the chain, the bot picks the nearest available one and tells you in the preview. |
dist 8 also distance 8 |
Set the strike by distance from spot (the VALORES table method). Recomputes strike = spot + $8 for CALLs, spot − $8 for PUTs, using the live underlying price (falls back to the price when the signal fired). The preview shows which spot was used. |
qty 2 |
Change the contract quantity for this trade only. Doesn't touch the global /qty setting. (Note: bare qty 2 adjusts the pending trade; slash /qty 2 sets the global override.) |
limit 0.40 also price 0.40 |
Use a custom limit price instead of the live ask. The buy order is placed at your price, and exits scale from it (limit 0.40 → 2× at 0.80 and runner 3× at 1.20). Also lets you preview when the market is closed and the ask reads $0. |
/trade 7 → preview shows SPY CALL $630 exp Jul 6 →
exp +1 (roll to Jul 8) → strike 625 → qty 2 →
limit 0.40 → preview now shows every change → yes places 2 contracts
@ $0.40 with one contract at $0.80 GTC and one runner at $1.20 GTC.
By default the bot calculates contracts as floor(account × risk% / (ask × 100)).
You can override this up or down — buy fewer contracts than the bot suggests to reduce risk,
or buy more to scale up a high-conviction trade. The global setting persists in
data/bot_state.json and survives bot restarts.
| Command | What it does |
|---|---|
/qty |
Show the current quantity setting — either a fixed number or "auto (bot calculates)". |
/qty 1 |
Reduce to minimum. Always buy 1 contract regardless of account size. Useful for testing or when you want minimum exposure. |
/qty 2 / /qty 3 / /qty 5 … |
Set any fixed number. Every future /trade preview will use exactly that many contracts — whether that's fewer or more than the bot would calculate. Saved to disk immediately. Any whole number ≥ 1 is valid. |
/qty 10 / /qty 20 … |
Scale up. Buy more contracts than the bot's risk-cap would normally allow. Use with care — this intentionally exceeds the max risk % cap. |
/qty autoalso: /qty 0 · /qty off · /qty reset
|
Revert to automatic sizing. Clears the saved override. The bot calculates the quantity from your account value and max risk % on each trade. If the safe result is zero, no trade is left pending; use an explicit /trade <id> 1 only if you intentionally override that cap. Any of the four aliases work identically. |
/trade command —
/trade 7 3 previews signal 7 with exactly 3 contracts without changing the saved global setting.
Useful when you want a different size for just this one trade.
Priority order (highest wins):
/trade <id> <qty> (one-time inline)
› /qty <n> (global saved override)
› auto-calculated from account size
| Command | What it does |
|---|---|
/outcomes also /results |
Show the last 15 checked signal outcomes: contract, ask price, 2× target, option peak, WIN/LOSS, and win rate summary. |
/outcomes <n> |
Show the last <n> outcomes. Example: /outcomes 30. Outcomes are filled in by the hourly outcome checker; pending signals show ⏳. |
Robinhood sessions expire occasionally. Use these commands to reconnect from Telegram without touching the computer.
| Command | What it does |
|---|---|
/rh_status also /rhstatus |
Check whether the Robinhood session is currently active. ✅ = ready to trade. ❌ = needs login. |
/rh_login also /rhlogin |
Trigger a Robinhood login attempt. Robinhood will send a verification code via SMS, email, or push notification. Follow with /rh_code or /rh_push depending on what you receive. |
/rh_code <code> |
Submit the SMS or email verification code Robinhood sent. Example: /rh_code 123456. The bot completes the login and confirms with ✅. |
/rh_push also /rhpush |
After approving a push notification in the Robinhood app, send this to complete the login (waits up to 30 seconds for Robinhood to confirm). |
The dashboard is permanently reachable at
https://glogger.tail51945a.ts.net via Tailscale Funnel —
a fixed public HTTPS address that never changes across restarts. Funnel is a persistent
config on the Tailscale Windows service, so it comes back up on its own whenever the
dashboard does. (This replaced the old Cloudflare quick tunnel, which minted a new random
URL on every restart — see the FAQ for the full story.)
cloudflared tunnel --url http://localhost:5000 still works,
but prints a different random *.trycloudflare.com URL each run.
| Mode | What happens | When to use |
|---|---|---|
notify |
Sends Telegram alerts only. No orders placed. Telegram /trade still works (uses force=True). |
Start here. Run at least 30 days before going live. |
sandbox |
Places simulated orders in E*TRADE's sandbox (no real money). Robinhood has no sandbox — with the Robinhood broker, sandbox mode places no orders at all (alerts only). | E*TRADE testing before going live. For Robinhood, test with notify + the Paper Money page instead. |
live |
Places REAL orders. Requires confirm_live: "I UNDERSTAND THE RISKS" in config. |
Only after 30+ days of paper trading with good results. |
The Telegram /trade command bypasses the mode setting — you can place real orders via Telegram even in notify mode. This is intentional: you control each trade manually.
The bot has a built-in 2026 economic calendar in config.yaml. Every time a signal fires, the bot checks if a high-impact event is nearby and either blocks the auto-trade or adds a warning. You can add custom one-off dates in extra_event_days.
| Event | Config key | Severity | What it is |
|---|---|---|---|
| FOMC Decision | fomc_decision_2026 |
HIGH | Federal Reserve interest-rate decision + press conference. 2:00 PM ET. Auto-trades are blocked on these days. |
| FOMC Start | fomc_start_2026 |
MEDIUM | Day 1 of the 2-day FOMC meeting (no decision yet, but the market is cautious). Warning shown. |
| CPI | cpi_2026 |
HIGH | Consumer Price Index — BLS, 8:30 AM ET. The most market-moving inflation print. Auto-trades blocked. |
| PPI | ppi_2026 |
MEDIUM | Producer Price Index — BLS, 8:30 AM ET. Released the day after CPI. Warning shown. |
| PCE | pce_2026 |
MEDIUM | Personal Consumption Expenditures — BEA, 8:30 AM ET. The Fed's preferred inflation gauge. Warning shown. PCE ≠ FOMC — it is a separate monthly data release. |
| NFP | nfp_2026 |
HIGH | Non-Farm Payrolls (Employment Situation) — BLS, 8:30 AM ET, first Friday of each month. Most volatile macro release. Auto-trades blocked. |
| JOLTS | jolts_2026 |
MEDIUM | Job Openings & Labor Turnover Survey — BLS, 10:00 AM ET. Released ~6 weeks after reference month. |
| ADP | adp_2026 |
WATCH | ADP National Employment Report — 8:15 AM ET, Wednesday before NFP. Private-sector payrolls preview. |
| GDP | gdp_2026 |
HIGH | GDP Advance Estimate — BEA, 8:30 AM ET. Quarterly. Auto-trades blocked. |
| Retail Sales | retail_sales_2026 |
MEDIUM | Census Bureau, 8:30 AM ET. Key consumer spending gauge, released monthly. |
| Consumer Confidence | consumer_confidence_2026 |
WATCH | Conference Board, 10:00 AM ET, last Tuesday of each month. Awareness only. |
| Michigan Sentiment | michigan_sentiment_2026 |
WATCH | UMich Consumer Sentiment Preliminary — 10:00 AM ET, 2nd Friday of each month. Awareness only. |
| Beige Book | beige_book_2026 |
MEDIUM | Fed regional economic report, 2:00 PM ET, released ~2 weeks before each FOMC meeting. |
| ISM Mfg PMI | ism_mfg_2026 |
MEDIUM | ISM Manufacturing PMI — 10:00 AM ET, first business day of each month. |
| ISM Services PMI | ism_svc_2026 |
MEDIUM | ISM Services PMI — 10:00 AM ET, 3rd business day of each month. |
| Monthly OPEX | opex_monthly_2026 |
MEDIUM | Options expiration — 3rd Friday of non-quarterly months. Pinning and last-hour reversals are common. |
| Triple Witching | opex_quarterly_2026 |
HIGH | Quarterly OPEX — 3rd Friday of Mar / Jun / Sep / Dec. Stock options + index options + index futures all expire simultaneously. Massive volume. Auto-trades blocked. |
🚫 BLOCKED tag in the dashboard.Add any one-off high-impact dates (earnings, Fed speeches, geopolitical events) to config.yaml:
events:
extra_event_days: ["2026-07-15", "2026-09-22"]
These behave as HIGH-severity blocks.
Can I place real Robinhood orders from the Charts page?
Yes — this is the newest and most serious feature. On Charts, pick a contract and use Buy / Sell (or right-click the chart) to place a real-money Robinhood order, with the positions/orders panel and on-chart entry/exit markers showing actual fills and P&L. It is deliberately fail-closed: the dashboard PIN is asked once per browser session and never stored server-side, you must type the confirmation phrase, every order carries a durable idempotency key so a reload or double-tap cannot duplicate it, the contract's symbol/expiry/strike/type are cross-checked before submission, and if Robinhood's response is ambiguous the order is marked unknown and returns an explicit do-not-retry error rather than guessing. Liquidation quotes use the bid only.
What is Robinhood auto-import and the Sync now button?
A background daemon polls your filled option orders every 15 minutes and writes them into the trade history, pairing buys with their sell-to-close legs into realized P&L (including scaled 2×/3× exits). It rides an existing session and never starts a login on its own; Telegram only pings you for closed round trips. Toggle it and force an immediate run from the Robinhood Sync modal on the dashboard.
Can I get a Telegram ping when a price is hit?
Yes — set price alerts on the Charts page. A background checker looks every 30 seconds and messages you when the level trades through. An alert that fails to send stays armed and retries instead of being silently consumed. There is also a once-a-day "A-setup" heads-up when a symbol lines up on three supports at once.
Why does the dashboard ask for a PIN before showing anything?
There are two separate PINs. The access PIN unlocks the read-only data (stats, trades, charts P&L, logs) — it exists because the dashboard is published to the internet. The dashboard PIN is separate and is required for Settings and for anything that places an order. Both are constant-time compared and lock out for five minutes after repeated wrong attempts.
What are the Class Audio and Historical Class Library sections?
Class Audio transcribes the live professor session on weekdays (9:00–15:10 ET) with Whisper, extracts tickers/strategies mentioned, and relays them as clearly-labeled class alerts — informational only, it never auto-trades. The Historical Class Library imports recordings you already have: it transcribes them, OCRs the on-screen charts, and makes the result searchable from the dashboard.
What is the Paper Money page?
A fake-money trading account at /paper (💵 buttons in the dashboard navbar and charts header), modeled on uCharts Paper Money. You start with a virtual $10,000. It shows Account Value, Cash, Open/Realized P&L, Win Rate and Profit Factor, plus open positions with live prices, a per-strategy performance table, and full trade history. Reset account wipes all paper trades and sets a new starting balance. Nothing here touches a real broker.
How does the auto paper-trading bot work?
When the toggle on the Paper Money page is ON, every CALL/PUT signal the scanner logs today is automatically bought as a 1-contract paper trade at the signal's ask price — every strategy, regardless of tag. It runs in the background every 15 minutes (page doesn't need to be open) and each signal is traded only once. Positions auto-sell when the contract's bid touches the 2× target (Rule 27 exit — bid, because that's what a real GTC sell would fill at); the close pass runs in the same 15-minute background loop and on every page view. Expired contracts settle at intrinsic value computed from the spot on expiration day. The Strategy Performance table then shows which strategies actually make money.
How do I make manual paper trades?
Two ways: (1) turn the auto-bot toggle OFF on the Paper Money page — a manual entry form appears (ticker, CALL/PUT, strike, expiry, entry price, qty); or (2) on the Charts page, pick any contract in the Price Calculator and press 📝 Paper trade next to the Copy button. Manual and bot trades are labeled separately in the tables.
How do the themes work?
Every page (dashboard, charts, paper money, this page, and the PIN/login screens) has a theme toggle — in the dashboard/docs navbar, ◐ on the charts header and the login screens, a dropdown on Paper Money. Two options: dark (black) and gray, both with the US-flag watermark in the background. Your choice is saved in the browser and applies to all pages at once — including before you've entered your PIN.
Does the dashboard link change every time I reboot?
No — fixed as of 2026-07-05. The dashboard used to run behind a Cloudflare "quick tunnel," which mints a brand-new random *.trycloudflare.com address on every restart. URL shorteners were tried and abandoned as a workaround — shortener services refuse tunnel/redirector domains outright (a common phishing pattern), so that whole idea was dropped and nothing in the system uses one.
The real fix was switching to Tailscale Funnel — a free, permanent public HTTPS address for the dashboard that never changes across restarts. No domain purchase or DNS migration needed (a Cloudflare named tunnel was considered, but required either a $250/mo Business plan or migrating the whole brightstarsupplies.com domain's DNS, which risked the Google Workspace email records — Tailscale avoids all of that). The dashboard is now permanently reachable at https://glogger.tail51945a.ts.net (the device was renamed from its default desktop-ij0srrl to glogger for a cleaner URL), already saved as the Chrome bookmark. The old Cloudflare tunnel scripts (run_tunnel.ps1, the URL-watching logic in power_reset_helper.py) are no longer used by startup.
The charts said "Yahoo may be rate-limiting" — what happens now?
Options data (expirations and chains) loads from Yahoo Finance first; if Yahoo is rate-limited or returns nothing, the server automatically falls back to your Robinhood session (the same login the bot uses). When that happens the contract panel shows a small RH data pill. Expiration lists are cached for 6 hours, and the web server now handles requests in parallel, so one slow Yahoo call no longer freezes the whole page.
Why does the Price Calculator start with a higher underlying price?
The Simple calculator's "Underlying price" now defaults to the recommended strike from the PDF-criteria table — so the estimate immediately answers "what would this option be worth if the stock reaches the recommended level by the target date?" Click the blue Current: $X chip to reset it to the live spot, or type any price.
Can I use the dashboard and charts on my phone?
Yes — all pages adapt to phone screens (tested at Galaxy S Ultra size). On the dashboard the navbar buttons become icon-only, signal tabs swipe sideways, and wide tables scroll horizontally inside their card. On the charts page the sidebar stacks under the chart and the drawing tools work with touch (draw with your finger; pan/zoom stays normal when the cursor tool is selected).
The bot started but I don't see Telegram messages — what's wrong?
Check config.yaml: alerts.telegram.enabled must be true, and bot_token + chat_id must be correct. Send /start to your bot in Telegram at least once to activate the chat.
I sent /trade 5 and got "Signal 5 not found" — why?
/trade only searches today's signals. If the signal is from yesterday, it won't appear. Use /signals to see what IDs are available today.
The bot is in notify mode — can I still place trades via Telegram?
Yes. The Telegram listener uses force=True, which bypasses the mode check. You can place orders through Telegram regardless of whether the bot is in notify, sandbox, or live mode.
How do I switch from E*TRADE to Robinhood?
In the Settings panel (gear icon in the dashboard navbar), change Broker to Robinhood and save. You can also edit config.yaml directly: trading.broker: robinhood. Restart the bot for the change to take effect.
The bot shows 0 contracts — why?
Your 10% risk cap is smaller than the cost of one contract. Example: $200 account × 10% = $20 cap, but the contract asks $0.21 × 100 = $21. The Telegram preview will show 1 contract anyway and tell you you're slightly over the cap — you decide whether to proceed.
What is the scaled exit rule?
One contract exits at 2×. With two or more filled contracts, the larger half is offered at 2× to recover the original premium and the smaller runner at 3×. If the buy only partially fills, Robinhood rebuilds the plan from the actual filled quantity.
Where is the database stored?
glogger_system/data/glogger.db — SQLite file. The dashboard reads from it. Do not delete it; all signal history and P&L estimates are stored there.
How do I check if the Telegram listener is running?
Send /signals to your bot. If it replies within 30 seconds, the listener is active. If there's no response, the bot may not be running or the token/chat_id is wrong.
How do I add a second Telegram recipient?
In config.yaml, add their chat ID to alerts.telegram.forward_to: forward_to: ["987654321"]. They must send /start to the bot first. You can also do this from the Settings panel.
What Robinhood account number should I use?
Use the agentic account number (the one dedicated to the bot). Keep your personal trading account separate. If you only have one account, that's fine — just use that number.
Where can I change the account number without editing config.yaml?
In the dashboard Settings panel (gear icon in the navbar). Public settings are saved to config.yaml; account numbers and credentials are saved to the local secret store outside the project. Restart the bot for broker/credential changes to take effect.
How do I control how many contracts the bot buys?
Send /qty 2 (or any number) to set a global override — every future /trade preview will use that quantity. Send /qty auto to revert to automatic sizing. For a one-off change on a single trade, add the quantity directly to the command: /trade 5 3 previews signal 5 with exactly 3 contracts, without changing the global setting. The current override is saved to data/bot_state.json and survives bot restarts. Send /qty alone to see what's currently set.
The trade preview shows "[global override (2)]" — what does that mean?
It means a global quantity override of 2 is active (set with /qty 2). The bracket label always tells you why that quantity was chosen: auto = bot calculated it, global override = you set it with /qty, custom = you set it for this trade only (via /trade <id> <qty> or by sending qty <n> after the preview).
Can I change the expiration date or strike price before placing a trade?
Yes — after any /trade preview and before replying "yes", send exp 7/10 (or exp +1 for the next weekly expiry) to change the expiration, strike 620 for an exact strike, or dist 8 to recompute the strike as spot ± $8. Each message re-quotes the contract live and shows an updated preview. Changes stack, and the preview lists everything you've customized. See Customize Before Placing for the full list.
What's the difference between strike 620 and dist 8?
strike 620 pins an exact strike price. dist 8 uses the VALORES-table method: the bot fetches the live underlying price and sets strike = spot + $8 for CALLs (spot − $8 for PUTs). Use dist when the underlying has moved since the signal fired and you want to keep the same out-of-the-money distance. Setting one clears the other — whichever you sent last wins.
Can I buy at my own price instead of the live ask?
Yes — send limit 0.40 (or price 0.40) after a preview. The buy-to-open order is placed at your limit price, and the scaled exits use it ($0.40 entry → 2× at $0.80 and runner 3× at $1.20). This also works when the market is closed and the ask shows $0 — set a manual limit and the preview completes.
How do I check signal outcomes from Telegram without opening the dashboard?
Send /outcomes to see the last 15 checked signals with their WIN/LOSS result, option peak price, and overall win rate. Send /outcomes 30 to see more. The outcome checker runs automatically every hour in the background.
The bot can't place trades — what Robinhood commands do I use?
First send /rh_status to check if the session is active. If it's not, send /rh_login — Robinhood will send a verification code to your SMS, email, or Robinhood app. Then: if you got a code via SMS or email, reply /rh_code 123456; if you got a push notification and approved it in the app, reply /rh_push. See the Bot Commands section for details.
Can I place trades from Telegram even when the bot is in notify mode?
Yes — the Telegram /trade command always bypasses the mode setting and places real orders. This is intentional: the mode controls auto trades; Telegram gives you manual control over each trade regardless of mode.