taylortrader 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- taylortrader-0.1.0/.env.example +23 -0
- taylortrader-0.1.0/.github/dependabot.yml +14 -0
- taylortrader-0.1.0/.github/workflows/ci.yml +37 -0
- taylortrader-0.1.0/.github/workflows/package.yml +53 -0
- taylortrader-0.1.0/.github/workflows/release.yml +57 -0
- taylortrader-0.1.0/.gitignore +45 -0
- taylortrader-0.1.0/CONTRIBUTING.md +39 -0
- taylortrader-0.1.0/LICENSE.md +105 -0
- taylortrader-0.1.0/PKG-INFO +265 -0
- taylortrader-0.1.0/README.md +230 -0
- taylortrader-0.1.0/SECURITY.md +20 -0
- taylortrader-0.1.0/assets/logo.svg +7 -0
- taylortrader-0.1.0/config.example.toml +129 -0
- taylortrader-0.1.0/dashboard/index.html +14 -0
- taylortrader-0.1.0/dashboard/package-lock.json +924 -0
- taylortrader-0.1.0/dashboard/package.json +24 -0
- taylortrader-0.1.0/dashboard/public/favicon.svg +7 -0
- taylortrader-0.1.0/dashboard/src/App.tsx +103 -0
- taylortrader-0.1.0/dashboard/src/advice.tsx +45 -0
- taylortrader-0.1.0/dashboard/src/api.ts +464 -0
- taylortrader-0.1.0/dashboard/src/components/AIFields.tsx +63 -0
- taylortrader-0.1.0/dashboard/src/components/AIGrades.tsx +139 -0
- taylortrader-0.1.0/dashboard/src/components/EquityChart.tsx +207 -0
- taylortrader-0.1.0/dashboard/src/components/ErrorBoundary.tsx +26 -0
- taylortrader-0.1.0/dashboard/src/components/Header.tsx +246 -0
- taylortrader-0.1.0/dashboard/src/components/InvestCard.tsx +62 -0
- taylortrader-0.1.0/dashboard/src/components/Keys.tsx +76 -0
- taylortrader-0.1.0/dashboard/src/components/ModeDialog.tsx +57 -0
- taylortrader-0.1.0/dashboard/src/components/Panels.tsx +451 -0
- taylortrader-0.1.0/dashboard/src/components/Sell.tsx +84 -0
- taylortrader-0.1.0/dashboard/src/components/StrategyEditor.tsx +299 -0
- taylortrader-0.1.0/dashboard/src/components/TradeChart.tsx +392 -0
- taylortrader-0.1.0/dashboard/src/components/WhatIf.tsx +165 -0
- taylortrader-0.1.0/dashboard/src/components/forms.tsx +163 -0
- taylortrader-0.1.0/dashboard/src/format.ts +58 -0
- taylortrader-0.1.0/dashboard/src/main.tsx +15 -0
- taylortrader-0.1.0/dashboard/src/pages/GuidePage.tsx +189 -0
- taylortrader-0.1.0/dashboard/src/pages/InvestPage.tsx +395 -0
- taylortrader-0.1.0/dashboard/src/pages/Overview.tsx +70 -0
- taylortrader-0.1.0/dashboard/src/pages/SettingsPage.tsx +407 -0
- taylortrader-0.1.0/dashboard/src/pages/SetupPage.tsx +102 -0
- taylortrader-0.1.0/dashboard/src/pages/SignInPage.tsx +46 -0
- taylortrader-0.1.0/dashboard/src/pages/StrategiesPage.tsx +83 -0
- taylortrader-0.1.0/dashboard/src/settings.ts +38 -0
- taylortrader-0.1.0/dashboard/src/styles.css +812 -0
- taylortrader-0.1.0/dashboard/src/useChartWidth.ts +14 -0
- taylortrader-0.1.0/dashboard/src/usePoll.ts +70 -0
- taylortrader-0.1.0/dashboard/tsconfig.json +17 -0
- taylortrader-0.1.0/dashboard/vite.config.ts +12 -0
- taylortrader-0.1.0/docs/images/ai-decisions.png +0 -0
- taylortrader-0.1.0/docs/images/overview.png +0 -0
- taylortrader-0.1.0/docs/images/phone.png +0 -0
- taylortrader-0.1.0/docs/images/strategies.png +0 -0
- taylortrader-0.1.0/docs/images/trade-chart.gif +0 -0
- taylortrader-0.1.0/docs/images/what-if.png +0 -0
- taylortrader-0.1.0/docs/proposals/investing.md +154 -0
- taylortrader-0.1.0/pyproject.toml +72 -0
- taylortrader-0.1.0/scripts/build-release.sh +26 -0
- taylortrader-0.1.0/scripts/githooks/pre-commit +4 -0
- taylortrader-0.1.0/src/taylortrader/__init__.py +6 -0
- taylortrader-0.1.0/src/taylortrader/alerts.py +121 -0
- taylortrader-0.1.0/src/taylortrader/app.py +124 -0
- taylortrader-0.1.0/src/taylortrader/backtest.py +179 -0
- taylortrader-0.1.0/src/taylortrader/broker.py +343 -0
- taylortrader-0.1.0/src/taylortrader/chart.py +133 -0
- taylortrader-0.1.0/src/taylortrader/cli.py +660 -0
- taylortrader-0.1.0/src/taylortrader/config.py +444 -0
- taylortrader-0.1.0/src/taylortrader/criteria.py +135 -0
- taylortrader-0.1.0/src/taylortrader/data.py +244 -0
- taylortrader-0.1.0/src/taylortrader/executor.py +136 -0
- taylortrader-0.1.0/src/taylortrader/grading.py +195 -0
- taylortrader-0.1.0/src/taylortrader/guardrails/__init__.py +22 -0
- taylortrader-0.1.0/src/taylortrader/guardrails/engine.py +106 -0
- taylortrader-0.1.0/src/taylortrader/guardrails/invest.py +34 -0
- taylortrader-0.1.0/src/taylortrader/guardrails/limits.py +54 -0
- taylortrader-0.1.0/src/taylortrader/guardrails/models.py +53 -0
- taylortrader-0.1.0/src/taylortrader/home.py +80 -0
- taylortrader-0.1.0/src/taylortrader/indicators.py +90 -0
- taylortrader-0.1.0/src/taylortrader/invest.py +352 -0
- taylortrader-0.1.0/src/taylortrader/journal.py +305 -0
- taylortrader-0.1.0/src/taylortrader/launchd.py +146 -0
- taylortrader-0.1.0/src/taylortrader/llm.py +286 -0
- taylortrader-0.1.0/src/taylortrader/logging_setup.py +59 -0
- taylortrader-0.1.0/src/taylortrader/mcp_server.py +391 -0
- taylortrader-0.1.0/src/taylortrader/replay.py +191 -0
- taylortrader-0.1.0/src/taylortrader/report.py +259 -0
- taylortrader-0.1.0/src/taylortrader/search.py +312 -0
- taylortrader-0.1.0/src/taylortrader/secrets.py +206 -0
- taylortrader-0.1.0/src/taylortrader/secretscan.py +126 -0
- taylortrader-0.1.0/src/taylortrader/service.py +597 -0
- taylortrader-0.1.0/src/taylortrader/stats.py +139 -0
- taylortrader-0.1.0/src/taylortrader/strategies/__init__.py +7 -0
- taylortrader-0.1.0/src/taylortrader/strategies/ai.py +253 -0
- taylortrader-0.1.0/src/taylortrader/strategies/base.py +83 -0
- taylortrader-0.1.0/src/taylortrader/strategies/builtin.py +267 -0
- taylortrader-0.1.0/src/taylortrader/strategies/registry.py +33 -0
- taylortrader-0.1.0/src/taylortrader/strategies/rule.py +49 -0
- taylortrader-0.1.0/src/taylortrader/web/__init__.py +0 -0
- taylortrader-0.1.0/src/taylortrader/web/api.py +978 -0
- taylortrader-0.1.0/src/taylortrader/web/remote.py +142 -0
- taylortrader-0.1.0/src/taylortrader/web/runtime.py +80 -0
- taylortrader-0.1.0/src/taylortrader/web/static/assets/index-CT_-f4CD.js +9 -0
- taylortrader-0.1.0/src/taylortrader/web/static/assets/index-DSHKlv3w.css +1 -0
- taylortrader-0.1.0/src/taylortrader/web/static/assets/martian-mono-cyrillic-400-normal-BCR-5knY.woff2 +0 -0
- taylortrader-0.1.0/src/taylortrader/web/static/assets/martian-mono-cyrillic-400-normal-Br6HGNtH.woff +0 -0
- taylortrader-0.1.0/src/taylortrader/web/static/assets/martian-mono-cyrillic-600-normal-BK9F1QH4.woff2 +0 -0
- taylortrader-0.1.0/src/taylortrader/web/static/assets/martian-mono-cyrillic-600-normal-DfZOe4kq.woff +0 -0
- taylortrader-0.1.0/src/taylortrader/web/static/assets/martian-mono-latin-400-normal-DM4nBGIh.woff +0 -0
- taylortrader-0.1.0/src/taylortrader/web/static/assets/martian-mono-latin-400-normal-DZsjfPjH.woff2 +0 -0
- taylortrader-0.1.0/src/taylortrader/web/static/assets/martian-mono-latin-600-normal-BlUmYrg6.woff2 +0 -0
- taylortrader-0.1.0/src/taylortrader/web/static/assets/martian-mono-latin-600-normal-CDEEqth2.woff +0 -0
- taylortrader-0.1.0/src/taylortrader/web/static/assets/martian-mono-latin-ext-400-normal-CBFElp5P.woff +0 -0
- taylortrader-0.1.0/src/taylortrader/web/static/assets/martian-mono-latin-ext-400-normal-CqsZQCXg.woff2 +0 -0
- taylortrader-0.1.0/src/taylortrader/web/static/assets/martian-mono-latin-ext-600-normal-B7SJLXMk.woff2 +0 -0
- taylortrader-0.1.0/src/taylortrader/web/static/assets/martian-mono-latin-ext-600-normal-DcTSv0-g.woff +0 -0
- taylortrader-0.1.0/src/taylortrader/web/static/assets/schibsted-grotesk-latin-400-normal-BkiRe4WW.woff +0 -0
- taylortrader-0.1.0/src/taylortrader/web/static/assets/schibsted-grotesk-latin-400-normal-DPhJBilQ.woff2 +0 -0
- taylortrader-0.1.0/src/taylortrader/web/static/assets/schibsted-grotesk-latin-600-normal-BieE9YjJ.woff +0 -0
- taylortrader-0.1.0/src/taylortrader/web/static/assets/schibsted-grotesk-latin-600-normal-Czv9Obfv.woff2 +0 -0
- taylortrader-0.1.0/src/taylortrader/web/static/assets/schibsted-grotesk-latin-800-normal-CIaq-TR1.woff2 +0 -0
- taylortrader-0.1.0/src/taylortrader/web/static/assets/schibsted-grotesk-latin-800-normal-Dl5-MP1T.woff +0 -0
- taylortrader-0.1.0/src/taylortrader/web/static/assets/schibsted-grotesk-latin-ext-400-normal-DHVTfbSM.woff2 +0 -0
- taylortrader-0.1.0/src/taylortrader/web/static/assets/schibsted-grotesk-latin-ext-400-normal-DUPvg9bQ.woff +0 -0
- taylortrader-0.1.0/src/taylortrader/web/static/assets/schibsted-grotesk-latin-ext-600-normal-C5pQPdUJ.woff2 +0 -0
- taylortrader-0.1.0/src/taylortrader/web/static/assets/schibsted-grotesk-latin-ext-600-normal-DQsnXf5q.woff +0 -0
- taylortrader-0.1.0/src/taylortrader/web/static/assets/schibsted-grotesk-latin-ext-800-normal-CZWJQj-F.woff2 +0 -0
- taylortrader-0.1.0/src/taylortrader/web/static/assets/schibsted-grotesk-latin-ext-800-normal-DS3YHxa9.woff +0 -0
- taylortrader-0.1.0/src/taylortrader/web/static/favicon.svg +7 -0
- taylortrader-0.1.0/src/taylortrader/web/static/index.html +15 -0
- taylortrader-0.1.0/src/taylortrader/whatif.py +92 -0
- taylortrader-0.1.0/tests/__init__.py +0 -0
- taylortrader-0.1.0/tests/test_ai.py +267 -0
- taylortrader-0.1.0/tests/test_cli.py +125 -0
- taylortrader-0.1.0/tests/test_data_feeds.py +124 -0
- taylortrader-0.1.0/tests/test_grading.py +180 -0
- taylortrader-0.1.0/tests/test_guardrails.py +85 -0
- taylortrader-0.1.0/tests/test_invest.py +405 -0
- taylortrader-0.1.0/tests/test_launchd.py +61 -0
- taylortrader-0.1.0/tests/test_mcp.py +194 -0
- taylortrader-0.1.0/tests/test_replay.py +117 -0
- taylortrader-0.1.0/tests/test_search.py +196 -0
- taylortrader-0.1.0/tests/test_secrets.py +207 -0
- taylortrader-0.1.0/tests/test_service.py +887 -0
- taylortrader-0.1.0/tests/test_stats.py +38 -0
- taylortrader-0.1.0/tests/test_strategies_and_backtest.py +237 -0
- taylortrader-0.1.0/tests/test_web.py +657 -0
- taylortrader-0.1.0/tests/test_whatif.py +65 -0
- taylortrader-0.1.0/uv.lock +1888 -0
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Copy to .env (git-ignored) or, better, store these in the macOS Keychain:
|
|
2
|
+
# security add-generic-password -s taylortrader -a ALPACA_PAPER_KEY_ID -w
|
|
3
|
+
# (-w with no value prompts for it, so the secret never lands in shell history)
|
|
4
|
+
#
|
|
5
|
+
# Lookup order for each name: environment variable, then .env, then Keychain (service "taylortrader").
|
|
6
|
+
|
|
7
|
+
ALPACA_PAPER_KEY_ID=
|
|
8
|
+
ALPACA_PAPER_SECRET_KEY=
|
|
9
|
+
|
|
10
|
+
# Live keys are only read when config mode = "live" AND TAYLORTRADER_ALLOW_LIVE=1 (the dashboard sets it when you type GO LIVE).
|
|
11
|
+
ALPACA_LIVE_KEY_ID=
|
|
12
|
+
ALPACA_LIVE_SECRET_KEY=
|
|
13
|
+
# TAYLORTRADER_ALLOW_LIVE=1
|
|
14
|
+
|
|
15
|
+
# Alerts (optional)
|
|
16
|
+
NTFY_TOPIC=
|
|
17
|
+
EMAIL_PASSWORD=
|
|
18
|
+
HEALTHCHECK_URL=
|
|
19
|
+
|
|
20
|
+
# AI strategy (optional): the key for the provider set in [ai] in config.toml.
|
|
21
|
+
# A local model (Ollama, LM Studio) needs no key: set [ai] endpoint instead.
|
|
22
|
+
ANTHROPIC_API_KEY=
|
|
23
|
+
OPENAI_API_KEY=
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
version: 2
|
|
2
|
+
updates:
|
|
3
|
+
- package-ecosystem: github-actions
|
|
4
|
+
directory: /
|
|
5
|
+
schedule:
|
|
6
|
+
interval: weekly
|
|
7
|
+
- package-ecosystem: uv
|
|
8
|
+
directory: /
|
|
9
|
+
schedule:
|
|
10
|
+
interval: weekly
|
|
11
|
+
- package-ecosystem: npm
|
|
12
|
+
directory: /dashboard
|
|
13
|
+
schedule:
|
|
14
|
+
interval: weekly
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
on:
|
|
3
|
+
push:
|
|
4
|
+
branches: [main]
|
|
5
|
+
pull_request:
|
|
6
|
+
|
|
7
|
+
permissions:
|
|
8
|
+
contents: read
|
|
9
|
+
|
|
10
|
+
jobs:
|
|
11
|
+
test:
|
|
12
|
+
strategy:
|
|
13
|
+
matrix:
|
|
14
|
+
os: [macos-latest, ubuntu-latest]
|
|
15
|
+
runs-on: ${{ matrix.os }}
|
|
16
|
+
steps:
|
|
17
|
+
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
|
|
18
|
+
- uses: astral-sh/setup-uv@d0cc045d04ccac9d8b7881df0226f9e82c39688e # v6.8.0
|
|
19
|
+
- run: uv sync --locked
|
|
20
|
+
- run: uv run ruff check src tests
|
|
21
|
+
- run: uv run pytest -q
|
|
22
|
+
# The same secret scan the pre-commit hook runs, over every tracked file.
|
|
23
|
+
- run: uv run python -m taylortrader.secretscan
|
|
24
|
+
|
|
25
|
+
dashboard:
|
|
26
|
+
runs-on: ubuntu-latest
|
|
27
|
+
steps:
|
|
28
|
+
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
|
|
29
|
+
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
|
|
30
|
+
with:
|
|
31
|
+
node-version: 22
|
|
32
|
+
cache: npm
|
|
33
|
+
cache-dependency-path: dashboard/package-lock.json
|
|
34
|
+
- run: npm ci
|
|
35
|
+
working-directory: dashboard
|
|
36
|
+
- run: npx tsc --noEmit -p . && npm run build
|
|
37
|
+
working-directory: dashboard
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# Builds the package people install and tests it with the newest dependencies allowed, not uv.lock:
|
|
2
|
+
# that's what a new user gets. Runs weekly so a breaking dependency update shows up here first.
|
|
3
|
+
name: Package
|
|
4
|
+
on:
|
|
5
|
+
schedule:
|
|
6
|
+
- cron: "17 13 * * 1"
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
workflow_call:
|
|
9
|
+
|
|
10
|
+
permissions:
|
|
11
|
+
contents: read
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
build:
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
steps:
|
|
17
|
+
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
|
|
18
|
+
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
|
|
19
|
+
with:
|
|
20
|
+
node-version: 22
|
|
21
|
+
# No caches in the build that releases ship from: a poisoned cache can't reach a release.
|
|
22
|
+
- uses: astral-sh/setup-uv@d0cc045d04ccac9d8b7881df0226f9e82c39688e # v6.8.0
|
|
23
|
+
with:
|
|
24
|
+
enable-cache: false
|
|
25
|
+
# Also fails if the dashboard is missing or a file that must never ship got in.
|
|
26
|
+
- run: bash scripts/build-release.sh
|
|
27
|
+
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
|
28
|
+
with:
|
|
29
|
+
name: dist
|
|
30
|
+
path: dist/
|
|
31
|
+
if-no-files-found: error
|
|
32
|
+
|
|
33
|
+
test:
|
|
34
|
+
needs: build
|
|
35
|
+
strategy:
|
|
36
|
+
fail-fast: false
|
|
37
|
+
matrix:
|
|
38
|
+
os: [macos-latest, ubuntu-latest]
|
|
39
|
+
python: ["3.12", "3.14"]
|
|
40
|
+
runs-on: ${{ matrix.os }}
|
|
41
|
+
steps:
|
|
42
|
+
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
|
|
43
|
+
- uses: astral-sh/setup-uv@d0cc045d04ccac9d8b7881df0226f9e82c39688e # v6.8.0
|
|
44
|
+
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
|
|
45
|
+
with:
|
|
46
|
+
name: dist
|
|
47
|
+
path: dist/
|
|
48
|
+
- run: uv venv --python ${{ matrix.python }} fresh
|
|
49
|
+
- run: uv pip install --python fresh --only-binary ":all:" dist/*.whl pytest httpx
|
|
50
|
+
- name: Tests run against the installed package
|
|
51
|
+
run: |
|
|
52
|
+
fresh/bin/python -c "import taylortrader, sys; assert 'site-packages' in taylortrader.__file__, taylortrader.__file__"
|
|
53
|
+
fresh/bin/python -m pytest -q
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Push a tag like v0.1.0 to publish. See CONTRIBUTING.md.
|
|
2
|
+
name: Release
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags: ["v*"]
|
|
6
|
+
|
|
7
|
+
permissions:
|
|
8
|
+
contents: read
|
|
9
|
+
|
|
10
|
+
jobs:
|
|
11
|
+
version:
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
steps:
|
|
14
|
+
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
|
|
15
|
+
with:
|
|
16
|
+
fetch-depth: 0
|
|
17
|
+
- name: The tagged commit is on main
|
|
18
|
+
run: git merge-base --is-ancestor "$GITHUB_SHA" origin/main
|
|
19
|
+
- name: The tag matches the version in the code
|
|
20
|
+
run: |
|
|
21
|
+
want="${GITHUB_REF_NAME#v}"
|
|
22
|
+
grep -qx "version = \"$want\"" pyproject.toml
|
|
23
|
+
grep -qx "__version__ = \"$want\"" src/taylortrader/__init__.py
|
|
24
|
+
|
|
25
|
+
package:
|
|
26
|
+
needs: version
|
|
27
|
+
uses: ./.github/workflows/package.yml
|
|
28
|
+
|
|
29
|
+
pypi:
|
|
30
|
+
needs: package
|
|
31
|
+
runs-on: ubuntu-latest
|
|
32
|
+
environment: pypi
|
|
33
|
+
permissions:
|
|
34
|
+
id-token: write # Trusted Publishing: a short-lived login from GitHub, no stored token
|
|
35
|
+
steps:
|
|
36
|
+
- uses: astral-sh/setup-uv@d0cc045d04ccac9d8b7881df0226f9e82c39688e # v6.8.0
|
|
37
|
+
with:
|
|
38
|
+
enable-cache: false
|
|
39
|
+
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
|
|
40
|
+
with:
|
|
41
|
+
name: dist
|
|
42
|
+
path: dist/
|
|
43
|
+
- run: uv publish --trusted-publishing always
|
|
44
|
+
|
|
45
|
+
github-release:
|
|
46
|
+
needs: pypi
|
|
47
|
+
runs-on: ubuntu-latest
|
|
48
|
+
permissions:
|
|
49
|
+
contents: write
|
|
50
|
+
steps:
|
|
51
|
+
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
|
|
52
|
+
with:
|
|
53
|
+
name: dist
|
|
54
|
+
path: dist/
|
|
55
|
+
- run: gh release create "$GITHUB_REF_NAME" dist/* --repo "$GITHUB_REPOSITORY" --generate-notes
|
|
56
|
+
env:
|
|
57
|
+
GH_TOKEN: ${{ github.token }}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# --- Secrets: never commit ---
|
|
2
|
+
.env
|
|
3
|
+
.env.*
|
|
4
|
+
!.env.example
|
|
5
|
+
*.pem
|
|
6
|
+
*.key
|
|
7
|
+
secrets/
|
|
8
|
+
# Local config may hold account-specific settings; commit config.example.toml instead
|
|
9
|
+
config.toml
|
|
10
|
+
|
|
11
|
+
# --- Runtime data: market data cache, trade journal, logs ---
|
|
12
|
+
var/
|
|
13
|
+
*.db
|
|
14
|
+
*.sqlite
|
|
15
|
+
*.sqlite3
|
|
16
|
+
*.parquet
|
|
17
|
+
*.log
|
|
18
|
+
cache/
|
|
19
|
+
logs/
|
|
20
|
+
|
|
21
|
+
# --- Python ---
|
|
22
|
+
__pycache__/
|
|
23
|
+
*.py[cod]
|
|
24
|
+
.venv/
|
|
25
|
+
.pytest_cache/
|
|
26
|
+
.ruff_cache/
|
|
27
|
+
dist/
|
|
28
|
+
build/
|
|
29
|
+
*.egg-info/
|
|
30
|
+
|
|
31
|
+
# --- Dashboard ---
|
|
32
|
+
node_modules/
|
|
33
|
+
src/taylortrader/web/static/
|
|
34
|
+
|
|
35
|
+
# --- OS / editors ---
|
|
36
|
+
.DS_Store
|
|
37
|
+
.idea/
|
|
38
|
+
.vscode/
|
|
39
|
+
|
|
40
|
+
# Local notes
|
|
41
|
+
docs/journal/
|
|
42
|
+
config.toml.bak
|
|
43
|
+
config.tmp
|
|
44
|
+
*.toml.tmp
|
|
45
|
+
*.bak
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
Bug reports, ideas and fixes are welcome. For anything large, open an issue first so we can agree on
|
|
4
|
+
the approach before you spend time on it.
|
|
5
|
+
|
|
6
|
+
## Setup
|
|
7
|
+
|
|
8
|
+
```sh
|
|
9
|
+
uv sync
|
|
10
|
+
git config core.hooksPath scripts/githooks # scans each commit for secrets
|
|
11
|
+
uv run pytest -q
|
|
12
|
+
uv run ruff check src tests
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
The hooks setting turns on the pre-commit secret scan, which catches keys before they get into a commit. Run the
|
|
16
|
+
tests and the linter before you open a pull request; CI runs both.
|
|
17
|
+
|
|
18
|
+
The dashboard is in `dashboard/` (`npm install`, then `npm run build`).
|
|
19
|
+
|
|
20
|
+
## Ground rules
|
|
21
|
+
|
|
22
|
+
- Safety first: every strategy buy has a stop-loss held at the broker, and nothing goes around the guardrails.
|
|
23
|
+
- Never commit keys, account numbers or real trading records.
|
|
24
|
+
- New behavior comes with tests. Anything that claims a strategy works needs the holdout and luck test.
|
|
25
|
+
- Use your own paper account, never live, while developing.
|
|
26
|
+
|
|
27
|
+
## Your contribution
|
|
28
|
+
|
|
29
|
+
By submitting a contribution, you confirm it's your own work, and you agree that it's licensed under
|
|
30
|
+
this project's [license](LICENSE.md) and that the project's owner may also use, relicense and sell it
|
|
31
|
+
as part of TaylorTrader, including in paid versions. You keep the copyright to your work.
|
|
32
|
+
|
|
33
|
+
## Releasing (maintainer)
|
|
34
|
+
1. Set the same new version in `pyproject.toml` and `src/taylortrader/__init__.py`, and commit.
|
|
35
|
+
2. `git tag v0.1.0 && git push origin v0.1.0`
|
|
36
|
+
|
|
37
|
+
The Release workflow builds the package with the dashboard inside, installs it fresh, runs the tests,
|
|
38
|
+
publishes to PyPI and creates a GitHub Release. PyPI versions can't be reused, so a bad release gets
|
|
39
|
+
a new version number. Publishing uses PyPI Trusted Publishing, so there's no token to store.
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# Functional Source License, Version 1.1, ALv2 Future License
|
|
2
|
+
|
|
3
|
+
## Abbreviation
|
|
4
|
+
|
|
5
|
+
FSL-1.1-ALv2
|
|
6
|
+
|
|
7
|
+
## Notice
|
|
8
|
+
|
|
9
|
+
Copyright 2026 Brandon Taylor
|
|
10
|
+
|
|
11
|
+
## Terms and Conditions
|
|
12
|
+
|
|
13
|
+
### Licensor ("We")
|
|
14
|
+
|
|
15
|
+
The party offering the Software under these Terms and Conditions.
|
|
16
|
+
|
|
17
|
+
### The Software
|
|
18
|
+
|
|
19
|
+
The "Software" is each version of the software that we make available under
|
|
20
|
+
these Terms and Conditions, as indicated by our inclusion of these Terms and
|
|
21
|
+
Conditions with the Software.
|
|
22
|
+
|
|
23
|
+
### License Grant
|
|
24
|
+
|
|
25
|
+
Subject to your compliance with this License Grant and the Patents,
|
|
26
|
+
Redistribution and Trademark clauses below, we hereby grant you the right to
|
|
27
|
+
use, copy, modify, create derivative works, publicly perform, publicly display
|
|
28
|
+
and redistribute the Software for any Permitted Purpose identified below.
|
|
29
|
+
|
|
30
|
+
### Permitted Purpose
|
|
31
|
+
|
|
32
|
+
A Permitted Purpose is any purpose other than a Competing Use. A Competing Use
|
|
33
|
+
means making the Software available to others in a commercial product or
|
|
34
|
+
service that:
|
|
35
|
+
|
|
36
|
+
1. substitutes for the Software;
|
|
37
|
+
|
|
38
|
+
2. substitutes for any other product or service we offer using the Software
|
|
39
|
+
that exists as of the date we make the Software available; or
|
|
40
|
+
|
|
41
|
+
3. offers the same or substantially similar functionality as the Software.
|
|
42
|
+
|
|
43
|
+
Permitted Purposes specifically include using the Software:
|
|
44
|
+
|
|
45
|
+
1. for your internal use and access;
|
|
46
|
+
|
|
47
|
+
2. for non-commercial education;
|
|
48
|
+
|
|
49
|
+
3. for non-commercial research; and
|
|
50
|
+
|
|
51
|
+
4. in connection with professional services that you provide to a licensee
|
|
52
|
+
using the Software in accordance with these Terms and Conditions.
|
|
53
|
+
|
|
54
|
+
### Patents
|
|
55
|
+
|
|
56
|
+
To the extent your use for a Permitted Purpose would necessarily infringe our
|
|
57
|
+
patents, the license grant above includes a license under our patents. If you
|
|
58
|
+
make a claim against any party that the Software infringes or contributes to
|
|
59
|
+
the infringement of any patent, then your patent license to the Software ends
|
|
60
|
+
immediately.
|
|
61
|
+
|
|
62
|
+
### Redistribution
|
|
63
|
+
|
|
64
|
+
The Terms and Conditions apply to all copies, modifications and derivatives of
|
|
65
|
+
the Software.
|
|
66
|
+
|
|
67
|
+
If you redistribute any copies, modifications or derivatives of the Software,
|
|
68
|
+
you must include a copy of or a link to these Terms and Conditions and not
|
|
69
|
+
remove any copyright notices provided in or with the Software.
|
|
70
|
+
|
|
71
|
+
### Disclaimer
|
|
72
|
+
|
|
73
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND WITHOUT WARRANTIES OF ANY KIND, EXPRESS OR
|
|
74
|
+
IMPLIED, INCLUDING WITHOUT LIMITATION WARRANTIES OF FITNESS FOR A PARTICULAR
|
|
75
|
+
PURPOSE, MERCHANTABILITY, TITLE OR NON-INFRINGEMENT.
|
|
76
|
+
|
|
77
|
+
IN NO EVENT WILL WE HAVE ANY LIABILITY TO YOU ARISING OUT OF OR RELATED TO THE
|
|
78
|
+
SOFTWARE, INCLUDING INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES,
|
|
79
|
+
EVEN IF WE HAVE BEEN INFORMED OF THEIR POSSIBILITY IN ADVANCE.
|
|
80
|
+
|
|
81
|
+
### Trademarks
|
|
82
|
+
|
|
83
|
+
Except for displaying the License Details and identifying us as the origin of
|
|
84
|
+
the Software, you have no right under these Terms and Conditions to use our
|
|
85
|
+
trademarks, trade names, service marks or product names.
|
|
86
|
+
|
|
87
|
+
## Grant of Future License
|
|
88
|
+
|
|
89
|
+
We hereby irrevocably grant you an additional license to use the Software under
|
|
90
|
+
the Apache License, Version 2.0 that is effective on the second anniversary of
|
|
91
|
+
the date we make the Software available. On or after that date, you may use the
|
|
92
|
+
Software under the Apache License, Version 2.0, in which case the following
|
|
93
|
+
will apply:
|
|
94
|
+
|
|
95
|
+
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
|
|
96
|
+
this file except in compliance with the License.
|
|
97
|
+
|
|
98
|
+
You may obtain a copy of the License at
|
|
99
|
+
|
|
100
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
101
|
+
|
|
102
|
+
Unless required by applicable law or agreed to in writing, software distributed
|
|
103
|
+
under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
|
104
|
+
CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
105
|
+
specific language governing permissions and limitations under the License.
|
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: taylortrader
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A safety-first trading bot and scheduled long-term investing for Alpaca, with a local dashboard.
|
|
5
|
+
Project-URL: Homepage, https://github.com/brandonmtaylor/taylor-trader
|
|
6
|
+
Project-URL: Source, https://github.com/brandonmtaylor/taylor-trader
|
|
7
|
+
Project-URL: Issues, https://github.com/brandonmtaylor/taylor-trader/issues
|
|
8
|
+
Project-URL: Releases, https://github.com/brandonmtaylor/taylor-trader/releases
|
|
9
|
+
Project-URL: Security, https://github.com/brandonmtaylor/taylor-trader/security/policy
|
|
10
|
+
Author: Brandon Taylor
|
|
11
|
+
License-Expression: FSL-1.1-ALv2
|
|
12
|
+
License-File: LICENSE.md
|
|
13
|
+
Keywords: alpaca,backtesting,investing,trading,trading-bot
|
|
14
|
+
Classifier: Development Status :: 3 - Alpha
|
|
15
|
+
Classifier: Intended Audience :: End Users/Desktop
|
|
16
|
+
Classifier: Operating System :: MacOS
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
21
|
+
Classifier: Topic :: Office/Business :: Financial :: Investment
|
|
22
|
+
Requires-Python: >=3.12
|
|
23
|
+
Requires-Dist: alpaca-py==0.44.0
|
|
24
|
+
Requires-Dist: anthropic<3,>=2.4
|
|
25
|
+
Requires-Dist: fastapi<1,>=0.115
|
|
26
|
+
Requires-Dist: mcp<3,>=2.3
|
|
27
|
+
Requires-Dist: numpy<3,>=2.0
|
|
28
|
+
Requires-Dist: openai<4,>=1.50
|
|
29
|
+
Requires-Dist: pandas<4,>=2.2
|
|
30
|
+
Requires-Dist: pyarrow>=17
|
|
31
|
+
Requires-Dist: pydantic<3,>=2.7
|
|
32
|
+
Requires-Dist: uvicorn<1,>=0.32
|
|
33
|
+
Requires-Dist: yfinance==1.7.0
|
|
34
|
+
Description-Content-Type: text/markdown
|
|
35
|
+
|
|
36
|
+
# TaylorTrader
|
|
37
|
+
|
|
38
|
+
**Set your strategies once, and let the bot watch the market for you.** TaylorTrader runs on your own
|
|
39
|
+
computer and trades your [Alpaca](https://alpaca.markets) account automatically: it checks prices all
|
|
40
|
+
day, buys and sells when your strategies say so, protects those trades with stop-losses, and tells you
|
|
41
|
+
what it did. Mix short-term trading strategies, an AI that makes the calls, and long-term investing on
|
|
42
|
+
a schedule. No staring at charts.
|
|
43
|
+
|
|
44
|
+

|
|
45
|
+
|
|
46
|
+
- **Runs on its own.** Once it's set up, it trades and invests by itself during market hours, checks
|
|
47
|
+
that every position is protected, and sends you a summary after each close. You step in only when
|
|
48
|
+
you want to.
|
|
49
|
+
- **Talk to it from Claude.** Describe an idea in plain English and Claude turns it into rules,
|
|
50
|
+
backtests them against buying and holding, and adds the strategy when you say so. Ask how it's
|
|
51
|
+
doing, pause it, or move a stock to another strategy, all in conversation.
|
|
52
|
+
- **An AI strategy that shows its work.** A language model decides buy, sell or hold, and explains
|
|
53
|
+
every call with its confidence, pros and cons. A report card grades each call against what happened next.
|
|
54
|
+
- **Strategies without code.** Pick a built-in, or write rules like `close > ma_50 and rsi < 40`, and
|
|
55
|
+
backtest them in a click.
|
|
56
|
+
- **Scheduled investing.** Put a set amount into a mix of funds every week or month, kept in balance,
|
|
57
|
+
and see first how that plan would have done over the last 10 years.
|
|
58
|
+
- **On your phone.** Open the dashboard from your phone on your Wi-Fi, and get alerts for every buy,
|
|
59
|
+
sell and problem.
|
|
60
|
+
- **Safety first.** Stop-losses held at Alpaca, limits on every order, and paper trading until you
|
|
61
|
+
choose otherwise.
|
|
62
|
+
|
|
63
|
+
> **Not financial advice.** It trades on **paper** (simulated money) until you switch to live yourself.
|
|
64
|
+
> Trading can lose money, and you're responsible for every order it places. Provided as is, with no
|
|
65
|
+
> warranty (see the [license](https://github.com/brandonmtaylor/taylor-trader/blob/main/LICENSE.md)).
|
|
66
|
+
|
|
67
|
+
**Status:** early, and in a paper-trading trial.
|
|
68
|
+
|
|
69
|
+
## A quick tour
|
|
70
|
+
|
|
71
|
+
**Ask Claude.** With the MCP server connected, for example:
|
|
72
|
+
```text
|
|
73
|
+
You: Add a strategy for NVDA and AMD: buy when they pull back to the 50-day average with RSI
|
|
74
|
+
under 40, sell when RSI goes over 70.
|
|
75
|
+
Claude: Writes the rules, backtests them on both stocks against buying and holding, shows you
|
|
76
|
+
the results, and adds the strategy once you say so.
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
**Every trade on the chart.** Each buy and sell, the stop-loss, and how much of the move each sell kept.
|
|
80
|
+
Hover for any bar's price, and add moving averages, RSI and MACD.
|
|
81
|
+
|
|
82
|
+

|
|
83
|
+
|
|
84
|
+
**The AI's reasoning, call by call.**
|
|
85
|
+
|
|
86
|
+

|
|
87
|
+
|
|
88
|
+
**What if you'd started 10 years ago?** Your investing plan, run on real past prices for each mix.
|
|
89
|
+
|
|
90
|
+

|
|
91
|
+
|
|
92
|
+
<table>
|
|
93
|
+
<tr>
|
|
94
|
+
<td width="62%"><img alt="The Strategies page: strategy, symbols, bar size, position size, stop-loss and a one-click backtest" src="https://raw.githubusercontent.com/brandonmtaylor/taylor-trader/main/docs/images/strategies.png"></td>
|
|
95
|
+
<td width="38%"><img alt="The dashboard on a phone, over the home Wi-Fi" src="https://raw.githubusercontent.com/brandonmtaylor/taylor-trader/main/docs/images/phone.png"></td>
|
|
96
|
+
</tr>
|
|
97
|
+
<tr>
|
|
98
|
+
<td>Set up strategies and backtest them against buying and holding, without code.</td>
|
|
99
|
+
<td>Open it from your phone on the same Wi-Fi, with a passcode.</td>
|
|
100
|
+
</tr>
|
|
101
|
+
</table>
|
|
102
|
+
|
|
103
|
+
## Install
|
|
104
|
+
**Platforms:** macOS is fully supported. Linux runs the dashboard, backtests and a foreground
|
|
105
|
+
`taylortrader run`, with keys in a `.env` file; running in the background is set up for macOS only so
|
|
106
|
+
far. Windows isn't supported.
|
|
107
|
+
|
|
108
|
+
You need a free [Alpaca](https://app.alpaca.markets/signup) paper account (email only, no money).
|
|
109
|
+
```bash
|
|
110
|
+
curl -LsSf https://astral.sh/uv/install.sh | sh # once, if you don't have uv
|
|
111
|
+
uv tool install taylortrader
|
|
112
|
+
taylortrader # opens the dashboard and walks you through setup
|
|
113
|
+
```
|
|
114
|
+
Setup takes about ten minutes: connect your Alpaca paper keys, pick a strategy and backtest it, check
|
|
115
|
+
the safety limits, optionally add phone or email alerts, and start the bot in **dry run** (it decides
|
|
116
|
+
and alerts, but places no orders). Then switch between Dry run, Paper and Live at the top of the page.
|
|
117
|
+
|
|
118
|
+
Settings, the trade journal and logs live in `~/Library/Application Support/TaylorTrader` on macOS
|
|
119
|
+
(`~/.local/share/taylortrader` on Linux). Update with `uv tool upgrade taylortrader`. The dashboard's
|
|
120
|
+
**Guide** page explains everything in plain language.
|
|
121
|
+
|
|
122
|
+
### Does my computer need to stay on?
|
|
123
|
+
The bot only checks prices while your computer is awake, so a Mac that stays on (a Mac mini, or a
|
|
124
|
+
laptop left plugged in and open) works best. On a laptop that sleeps:
|
|
125
|
+
- Your stop-losses keep protecting open positions, because they're held at Alpaca, not on your computer.
|
|
126
|
+
- Strategies on daily bars miss little; ones on 1- to 15-minute bars miss whatever happens while it sleeps.
|
|
127
|
+
- The invest plan catches up: a buy that comes due while the laptop is asleep goes in when it wakes.
|
|
128
|
+
- The watchdog may send a "not running" alert after the laptop wakes up.
|
|
129
|
+
|
|
130
|
+
### From your phone
|
|
131
|
+
`taylortrader wifi on` prints a passcode and the address to open (`http://<your-mac>.local:8787`).
|
|
132
|
+
Each device signs in once and stays signed in for 30 days. Going live, changing API keys, and turning
|
|
133
|
+
real-money buying back on after a pause only work on the Mac itself. It's plain http, so use it on a
|
|
134
|
+
home network you trust; for anywhere else, put the Mac and phone on [Tailscale](https://tailscale.com).
|
|
135
|
+
`wifi off` closes it again.
|
|
136
|
+
|
|
137
|
+
## Talk to it from Claude (MCP)
|
|
138
|
+
TaylorTrader includes an MCP server, so Claude Code or the Claude desktop app can check on the bot and
|
|
139
|
+
adjust it: "how did the AI strategy do this week?", "move PLTR to macd_rsi", "backtest rsi_14 on NVDA
|
|
140
|
+
hourly", or describe an idea and let Claude write the rules and test it. It's optional; the bot runs
|
|
141
|
+
the same without it.
|
|
142
|
+
|
|
143
|
+
- **Claude Code:** [install it](https://claude.com/claude-code), then run once:
|
|
144
|
+
```bash
|
|
145
|
+
claude mcp add taylortrader --scope user -- taylortrader mcp
|
|
146
|
+
```
|
|
147
|
+
- **Claude desktop app:** Settings, then Developer, then Edit Config. Add this to the file (merge it if
|
|
148
|
+
it already has `mcpServers`) and reopen the app:
|
|
149
|
+
```json
|
|
150
|
+
{ "mcpServers": { "taylortrader": { "command": "/full/path/to/taylortrader", "args": ["mcp"] } } }
|
|
151
|
+
```
|
|
152
|
+
The desktop app needs the full path (`which taylortrader` prints it).
|
|
153
|
+
|
|
154
|
+
The dashboard's **Settings** page, under Claude, shows both filled in for your computer, with copy
|
|
155
|
+
buttons. Then ask Claude "how's my trading bot doing?" to check it's connected. The dashboard doesn't
|
|
156
|
+
need to be open.
|
|
157
|
+
|
|
158
|
+
It uses the same rules as the dashboard: every change is checked, hard limits still apply, and changes
|
|
159
|
+
are logged as coming from Claude. It can't go live, read or change keys, loosen limits on a live
|
|
160
|
+
account, or turn buying back on after you pause it. Selling on a live account is off unless you turn
|
|
161
|
+
on **Let Claude sell on a live account** in Settings, on your Mac.
|
|
162
|
+
|
|
163
|
+
## AI strategy (experimental)
|
|
164
|
+
`ai` asks a language model whether to buy, sell or hold, using your plain-English instructions, recent
|
|
165
|
+
bars, indicators, and optionally the last 3 days of news. It works with:
|
|
166
|
+
- **Your Claude subscription** through [Claude Code](https://claude.com/claude-code) (`claude -p`, with
|
|
167
|
+
no tools and none of your own settings). No API key; calls count toward your plan.
|
|
168
|
+
- **The Claude API**, billed per call. The sturdier choice for running unattended.
|
|
169
|
+
- **Any OpenAI-compatible API**: OpenAI, OpenRouter, Groq, or a free local model through Ollama or
|
|
170
|
+
LM Studio.
|
|
171
|
+
|
|
172
|
+
The model only proposes. Position size, the stop-loss and every limit still apply, and an error, an
|
|
173
|
+
off-menu answer or low confidence means hold. A daily call limit caps cost.
|
|
174
|
+
|
|
175
|
+
It can't be backtested honestly, so the backtester refuses it: try it in dry run, then on paper.
|
|
176
|
+
`taylortrader replay` tests it on past bars with each stock disguised, so the model can't recall what
|
|
177
|
+
happened next.
|
|
178
|
+
|
|
179
|
+
## Strategies
|
|
180
|
+
Built-ins: `macd_rsi`, `macd`, `ma_20`, `rsi_14`, `ma_20_rsi`, `ma_200_rsi`, `ma_20_over_200_rsi`,
|
|
181
|
+
`chaikin`, `pullback`. Each symbol belongs to one strategy, so
|
|
182
|
+
it's always clear who manages a position.
|
|
183
|
+
|
|
184
|
+
Or write your own with `rule`: a buy rule and a sell rule, like `close > ma_50 and rsi < 40` or
|
|
185
|
+
`close > prev_high_20`. Rules can use price, volume, MACD and Chaikin, plus these at any length up to
|
|
186
|
+
250 bars: `ma_N`, `ema_N`, `high_N`, `low_N`, `change_N` (percent), `avg_volume_N`, `rsi_N`, `atr_N`.
|
|
187
|
+
Rules are parsed, never run as code.
|
|
188
|
+
|
|
189
|
+
**Test an idea before trusting it.** The backtester always compares against buying and holding.
|
|
190
|
+
`taylortrader search` goes further: it tunes on older data, then tests once on held-back data, and
|
|
191
|
+
checks the result against random entries, so luck doesn't pass for skill.
|
|
192
|
+
|
|
193
|
+
## Long-term investing
|
|
194
|
+
An **invest plan** puts a set amount into a fixed mix of funds on a schedule (say $200 a month into US
|
|
195
|
+
stocks, international stocks and bonds) and holds it.
|
|
196
|
+
- Each contribution goes to whatever is furthest under its target first, so new money keeps the mix
|
|
197
|
+
balanced without selling. Fractional shares, so any amount splits exactly.
|
|
198
|
+
- A period is never bought twice, even across restarts: each buy is recorded first and carries an
|
|
199
|
+
order id Alpaca won't accept twice.
|
|
200
|
+
- It invests cash already in your Alpaca account; it can't move money from your bank.
|
|
201
|
+
- Start in preview: it alerts what it would buy and places nothing. Buying for real asks you to type
|
|
202
|
+
the amount and schedule.
|
|
203
|
+
|
|
204
|
+
The ready-made mixes are examples, not recommendations. What's built and what's planned is in the
|
|
205
|
+
[investing proposal](https://github.com/brandonmtaylor/taylor-trader/blob/main/docs/proposals/investing.md).
|
|
206
|
+
|
|
207
|
+
## Safety limits
|
|
208
|
+
- **Stop-losses live at the broker.** Every strategy buy is a bracket order with a stop-loss held by
|
|
209
|
+
Alpaca, so the stop still works if TaylorTrader or your computer stops. A stop limits losses but can
|
|
210
|
+
fill below its price when a stock gaps down or moves fast. (The invest plan doesn't use stops: holding
|
|
211
|
+
through dips is its point.)
|
|
212
|
+
- **Every order is checked** against position size, total exposure, daily loss, buys per day, stop
|
|
213
|
+
width, and a pause switch. Settings can tighten the built-in hard limits but never loosen them.
|
|
214
|
+
Sells are never blocked.
|
|
215
|
+
- **It only manages what it bought.** Shares you already owned aren't touched, even if you add the
|
|
216
|
+
symbol to a strategy.
|
|
217
|
+
- **Keys stay secret.** They live in the macOS Keychain (or a private `.env` file elsewhere), are
|
|
218
|
+
masked in logs, and the dashboard never shows them again. Config files with secret-looking values
|
|
219
|
+
are rejected.
|
|
220
|
+
- **Real money needs two steps:** live keys that open an active account, and typing `GO LIVE` in the
|
|
221
|
+
dashboard on your Mac.
|
|
222
|
+
- **It tells you when something's wrong:** a missing stop, a refused order, prices that stopped
|
|
223
|
+
arriving, a strategy that hasn't traded in two weeks, or the bot itself going quiet.
|
|
224
|
+
|
|
225
|
+
## Command line
|
|
226
|
+
Everything the dashboard does also works from a terminal:
|
|
227
|
+
```bash
|
|
228
|
+
taylortrader doctor # settings, credentials (found or missing), secret scan
|
|
229
|
+
taylortrader strategies # what you can pick
|
|
230
|
+
taylortrader backtest VRT --strategy macd_rsi --timeframe 5Min --days 365
|
|
231
|
+
taylortrader account # read-only: positions, stops, positions it doesn't manage
|
|
232
|
+
taylortrader alerts-test # push and email test
|
|
233
|
+
taylortrader run --dry-run --once # one check: decides and alerts, places no orders
|
|
234
|
+
taylortrader kill on # pause new buys; sells and stops keep working
|
|
235
|
+
taylortrader journal # recent orders and the heartbeat
|
|
236
|
+
taylortrader dashboard --background # keep the dashboard running (also --restart, --stop)
|
|
237
|
+
taylortrader wifi on # open it to your phone on the same Wi-Fi
|
|
238
|
+
```
|
|
239
|
+
Settings live in `config.toml` with no secrets in it;
|
|
240
|
+
[config.example.toml](https://github.com/brandonmtaylor/taylor-trader/blob/main/config.example.toml)
|
|
241
|
+
explains each one. The bot notices a saved change and restarts itself with it, and a file with a
|
|
242
|
+
mistake in it is reported and ignored.
|
|
243
|
+
|
|
244
|
+
**Price data:** `feed = "yahoo"` (the default) covers every exchange and is current, but unofficial;
|
|
245
|
+
the bot switches to Alpaca IEX on its own if Yahoo fails or falls behind. `"iex"` is Alpaca, real
|
|
246
|
+
time, one exchange. Backtests use Alpaca's full-market (SIP) history.
|
|
247
|
+
|
|
248
|
+
## From source
|
|
249
|
+
```bash
|
|
250
|
+
git clone https://github.com/brandonmtaylor/taylor-trader && cd taylor-trader
|
|
251
|
+
uv sync
|
|
252
|
+
cd dashboard && npm install && npm run build && cd .. # once, and after UI changes
|
|
253
|
+
uv run taylortrader # uses this folder for settings and data
|
|
254
|
+
```
|
|
255
|
+
In a checkout, put `uv run` in front of every command above. See
|
|
256
|
+
[CONTRIBUTING.md](https://github.com/brandonmtaylor/taylor-trader/blob/main/CONTRIBUTING.md) to help
|
|
257
|
+
out, and [SECURITY.md](https://github.com/brandonmtaylor/taylor-trader/blob/main/SECURITY.md) to report
|
|
258
|
+
a problem privately.
|
|
259
|
+
|
|
260
|
+
## License
|
|
261
|
+
Source-available under the [Functional Source License 1.1, Apache 2.0 future
|
|
262
|
+
license](https://github.com/brandonmtaylor/taylor-trader/blob/main/LICENSE.md) (FSL-1.1-ALv2). Use it,
|
|
263
|
+
change it, run it for yourself, learn from it, contribute: all free. What it doesn't allow is selling
|
|
264
|
+
it, or a product built from it that does the same job, in competition with TaylorTrader. Each version
|
|
265
|
+
becomes plain Apache 2.0 two years after it's released.
|