@backtest-kit/sidekick 9.0.0 → 9.1.0

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.
Files changed (49) hide show
  1. package/README.md +173 -173
  2. package/content/config/source/timeframe_15m.pine +113 -113
  3. package/content/config/source/timeframe_4h.pine +56 -56
  4. package/content/config/symbol.config.cjs +460 -460
  5. package/content/docker/ollama/docker-compose.yaml +34 -34
  6. package/content/docker/ollama/watch.sh +2 -2
  7. package/content/scripts/cache/cache_candles.mjs +47 -47
  8. package/content/scripts/cache/cache_model.mjs +42 -42
  9. package/content/scripts/cache/validate_candles.mjs +46 -46
  10. package/content/scripts/run_timeframe_15m.mjs +77 -77
  11. package/content/scripts/run_timeframe_4h.mjs +68 -68
  12. package/package.json +68 -68
  13. package/scripts/init.mjs +304 -304
  14. package/src/classes/BacktestLowerStopOnBreakevenAction.mjs +17 -17
  15. package/src/classes/BacktestPartialProfitTakingAction.mjs +24 -24
  16. package/src/classes/BacktestPositionMonitorAction.mjs +57 -57
  17. package/src/config/ccxt.mjs +15 -15
  18. package/src/config/params.mjs +1 -1
  19. package/src/config/setup.mjs +45 -45
  20. package/src/config/validate.mjs +14 -14
  21. package/src/enum/ActionName.mjs +5 -5
  22. package/src/enum/ExchangeName.mjs +3 -3
  23. package/src/enum/FrameName.mjs +6 -6
  24. package/src/enum/RiskName.mjs +4 -4
  25. package/src/enum/StrategyName.mjs +3 -3
  26. package/src/index.mjs +6 -6
  27. package/src/logic/action/backtest_lower_stop_on_breakeven.action.mjs +9 -9
  28. package/src/logic/action/backtest_partial_profit_taking.action.mjs +9 -9
  29. package/src/logic/action/backtest_position_monitor.action.mjs +9 -9
  30. package/src/logic/exchange/binance.exchange.mjs +69 -69
  31. package/src/logic/frame/dec_2025.frame.mjs +10 -10
  32. package/src/logic/frame/feb_2024.frame.mjs +10 -10
  33. package/src/logic/frame/nov_2025.frame.mjs +10 -10
  34. package/src/logic/frame/oct_2025.frame.mjs +10 -10
  35. package/src/logic/index.mjs +15 -15
  36. package/src/logic/risk/sl_distance.risk.mjs +32 -32
  37. package/src/logic/risk/tp_distance.risk.mjs +32 -32
  38. package/src/logic/strategy/main.strategy.mjs +48 -48
  39. package/src/main/bootstrap.mjs +52 -52
  40. package/src/math/timeframe_15m.math.mjs +68 -68
  41. package/src/math/timeframe_4h.math.mjs +53 -53
  42. package/src/utils/getArgs.mjs +17 -17
  43. package/template/CLAUDE.mustache +421 -421
  44. package/template/README.mustache +257 -257
  45. package/template/env.mustache +2 -2
  46. package/template/gitignore.mustache +29 -29
  47. package/template/jsconfig.json.mustache +26 -26
  48. package/template/package.mustache +37 -37
  49. package/template/types.mustache +11 -11
package/README.md CHANGED
@@ -1,173 +1,173 @@
1
- # 🧿 @backtest-kit/sidekick
2
-
3
- > The easiest way to create a new Backtest Kit trading bot project. Scaffolds a multi-timeframe crypto trading strategy with Pine Script indicators via [PineTS](https://github.com/QuantForgeOrg/PineTS) runtime, 4H trend filter + 15m signal generator, partial profit taking, breakeven trailing stops, and risk validation.
4
-
5
- ![screenshot](https://raw.githubusercontent.com/tripolskypetr/backtest-kit/HEAD/assets/screenshots/screenshot16.png)
6
-
7
- [![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/tripolskypetr/backtest-kit)
8
- [![npm](https://img.shields.io/npm/v/@backtest-kit/sidekick.svg?style=flat-square)](https://npmjs.org/package/@backtest-kit/sidekick)
9
- [![License](https://img.shields.io/npm/l/@backtest-kit/sidekick.svg)](https://github.com/tripolskypetr/backtest-kit/blob/master/LICENSE)
10
-
11
- 📚 **[Backtest Kit Docs](https://backtest-kit.github.io/documents/article_07_ai_news_trading_signals.html)** | 🌟 **[GitHub](https://github.com/tripolskypetr/backtest-kit)**
12
-
13
- ## ✨ Features
14
-
15
- - 🚀 **Zero Config**: Get started with one command - no setup required
16
- - 📊 **Multi-timeframe analysis** — 4H daily trend filter (RSI + MACD + ADX) combined with 15m entry signals (EMA crossover + volume spike + momentum)
17
- - 📜 **Pine Script indicators** — strategies written in TradingView Pine Script v5, executed locally via `@backtest-kit/pinets`
18
- - 🛡️ **Risk management** — SL/TP distance validation, Kelly-optimized partial profit taking (33/33/34%), breakeven trailing stop
19
- - 🔄 **Position lifecycle** — full monitoring with scheduled/opened/closed/cancelled event logging
20
- - 🔌 **Binance integration** — OHLCV candles, order book depth, tick-precise price/quantity formatting via CCXT
21
- - 🕐 **Historical frames** — predefined backtest periods covering bull runs, sharp drops, and sideways markets
22
- - 🎨 **Web UI dashboard** — interactive charting via `@backtest-kit/ui`
23
- - 💾 **Persistent storage** — crash-safe state with atomic persistence for both backtest and live modes
24
-
25
- ## 🚀 Quick Start
26
-
27
- > **New to backtest-kit?** The fastest way to get a real, production-ready setup is to clone the [reference implementation](https://github.com/tripolskypetr/backtest-kit/tree/master/example) — a fully working news-sentiment AI trading system with LLM forecasting, multi-timeframe data, and a documented February 2026 backtest. Start there instead of from scratch.
28
-
29
- ### Create a New Project
30
-
31
- ```bash
32
- npx -y @backtest-kit/sidekick my-trading-bot
33
- cd my-trading-bot
34
- npm start
35
- ```
36
-
37
- That's it! You now have a working trading bot with:
38
- - Multi-timeframe Pine Script strategy (4H trend + 15m signals)
39
- - Risk management validation (SL/TP distance checks)
40
- - Partial profit taking and breakeven trailing stops
41
- - Cache utilities and debug scripts
42
- - CLAUDE.md for AI-assisted strategy iteration
43
- - Environment configuration
44
-
45
- ## 🏗️ Generated Project Structure
46
-
47
- ```
48
- my-trading-bot/
49
- ├── src/
50
- │ ├── index.mjs # Entry point — loads config, logic, bootstrap
51
- │ ├── main/bootstrap.mjs # Mode dispatcher (backtest / paper / live)
52
- │ ├── config/
53
- │ │ ├── setup.mjs # Logger, storage, notifications, UI server
54
- │ │ ├── validate.mjs # Schema validation for all enums
55
- │ │ ├── params.mjs # Environment variables (Ollama API key)
56
- │ │ └── ccxt.mjs # Binance exchange singleton via CCXT
57
- │ ├── logic/
58
- │ │ ├── strategy/main.strategy.mjs # Main strategy — multi-TF signal logic
59
- │ │ ├── exchange/binance.exchange.mjs # Exchange schema — candles, order book, formatting
60
- │ │ ├── frame/*.frame.mjs # Backtest time frames (Feb 2024, Oct–Dec 2025)
61
- │ │ ├── risk/sl_distance.risk.mjs # Stop-loss distance validation (≥0.2%)
62
- │ │ ├── risk/tp_distance.risk.mjs # Take-profit distance validation (≥0.2%)
63
- │ │ └── action/
64
- │ │ ├── backtest_partial_profit_taking.action.mjs
65
- │ │ ├── backtest_lower_stop_on_breakeven.action.mjs
66
- │ │ └── backtest_position_monitor.action.mjs
67
- │ ├── classes/
68
- │ │ ├── BacktestPartialProfitTakingAction.mjs # Scale out at 3 TP levels
69
- │ │ ├── BacktestLowerStopOnBreakevenAction.mjs # Trailing stop on breakeven
70
- │ │ └── BacktestPositionMonitorAction.mjs # Position event logger
71
- │ ├── math/
72
- │ │ ├── timeframe_4h.math.mjs # 4H trend data — RSI, MACD, ADX, DI+/DI-
73
- │ │ └── timeframe_15m.math.mjs # 15m signal data — EMA, ATR, volume, momentum
74
- │ ├── enum/ # String constants for type-safe schema refs
75
- │ └── utils/getArgs.mjs # CLI argument parser with defaults
76
- ├── config/source/
77
- │ ├── timeframe_4h.pine # Pine Script v5 — Daily Trend Filter (RSI/MACD/ADX)
78
- │ └── timeframe_15m.pine # Pine Script v5 — Signal Strategy (EMA/ATR/Volume)
79
- ├── scripts/
80
- │ ├── run_timeframe_15m.mjs # Standalone 15m Pine Script runner
81
- │ ├── run_timeframe_4h.mjs # Standalone 4H Pine Script runner
82
- │ └── cache/
83
- │ ├── cache_candles.mjs # Pre-download OHLCV candles (1m/15m/4h)
84
- │ ├── validate_candles.mjs # Verify cached candle data integrity
85
- │ └── cache_model.mjs # Pull Ollama LLM model with progress bar
86
- ├── docker/ollama/
87
- │ ├── docker-compose.yaml # Ollama GPU container setup
88
- │ └── watch.sh # nvidia-smi monitor
89
- ├── CLAUDE.md # AI strategy development guide
90
- ├── .env # Environment variables
91
- └── package.json # Dependencies
92
- ```
93
-
94
- ## 💡 Strategy Overview
95
-
96
- ### 🎯 4H Trend Filter (`timeframe_4h.pine`)
97
-
98
- Determines the market regime using three indicators:
99
-
100
- | Regime | Condition |
101
- |--------|-----------|
102
- | **AllowLong** | ADX > 25, MACD histogram > 0, DI+ > DI-, RSI > 50 |
103
- | **AllowShort** | ADX > 25, MACD histogram < 0, DI- > DI+, RSI < 50 |
104
- | **AllowBoth** | Strong trend but no clear bull/bear regime |
105
- | **NoTrades** | ADX ≤ 25 (weak trend) |
106
-
107
- ### ⚡ 15m Signal Generator (`timeframe_15m.pine`)
108
-
109
- Generates entry signals with EMA crossover confirmed by volume and momentum:
110
-
111
- - **Long**: EMA(5) crosses above EMA(13), RSI 40–65, price above EMA(50), volume spike (>1.5x MA), positive momentum
112
- - **Short**: EMA(5) crosses below EMA(13), RSI 35–60, price below EMA(50), volume spike, negative momentum
113
- - **SL/TP**: Static 2%/3% from entry price
114
- - **Signal expiry**: 5 bars
115
-
116
- ### 🛡️ Risk Filters
117
-
118
- - Reject signals where SL distance < 0.2% (slippage protection)
119
- - Reject signals where TP distance < 0.2% (slippage protection)
120
- - Trend alignment: long signals rejected in bear regime, short signals rejected in bull regime
121
-
122
- ### 💹 Position Management
123
-
124
- - **Partial profit taking**: Scale out at 3 levels — 33% at TP3, 33% at TP2, 34% at TP1
125
- - **Breakeven trailing stop**: When breakeven is reached, lower trailing stop by 3 points
126
-
127
- ## 🕐 Backtest Frames
128
-
129
- | Frame | Period | Market Note |
130
- |-------|--------|-------------|
131
- | `February2024` | Feb 1–29, 2024 | Bull run |
132
- | `October2025` | Oct 1–31, 2025 | Sharp drop Oct 9–11 |
133
- | `November2025` | Nov 1–30, 2025 | Sideways with downtrend |
134
- | `December2025` | Dec 1–31, 2025 | Sideways, no clear direction |
135
-
136
- ## 💡 CLI Options
137
-
138
- ```bash
139
- # Create project with custom name
140
- npx -y @backtest-kit/sidekick my-bot
141
-
142
- # Create in current directory (must be empty)
143
- npx -y @backtest-kit/sidekick .
144
- ```
145
-
146
- ## 📋 Dependencies
147
-
148
- | Package | Purpose |
149
- |---------|---------|
150
- | [backtest-kit](https://libraries.io/npm/backtest-kit) | Core backtesting/trading framework |
151
- | [@backtest-kit/pinets](https://github.com/QuantForgeOrg/PineTS) | Pine Script v5 runtime for Node.js |
152
- | [@backtest-kit/ui](https://libraries.io/npm/backtest-kit) | Interactive charting dashboard |
153
- | [@backtest-kit/ollama](https://libraries.io/npm/backtest-kit) | LLM inference integration |
154
- | [ccxt](https://github.com/ccxt/ccxt) | Binance exchange connectivity |
155
- | [functools-kit](https://www.npmjs.com/package/functools-kit) | `singleshot`, `randomString` utilities |
156
- | [pinolog](https://www.npmjs.com/package/pinolog) | File-based structured logging |
157
- | [openai](https://www.npmjs.com/package/openai) | OpenAI API client |
158
- | [ollama](https://www.npmjs.com/package/ollama) | Ollama local LLM client |
159
-
160
- ## 🔗 Links
161
-
162
- - [Backtest Kit Documentation](https://backtest-kit.github.io/documents/article_07_ai_news_trading_signals.html)
163
- - [GitHub Repository](https://github.com/tripolskypetr/backtest-kit)
164
- - [Demo Projects](https://github.com/tripolskypetr/backtest-kit/tree/master/demo)
165
- - [API Reference](https://backtest-kit.github.io/documents/article_07_ai_news_trading_signals.html)
166
-
167
- ## 🤝 Contribute
168
-
169
- Found a bug or want to add a feature? [Open an issue](https://github.com/tripolskypetr/backtest-kit/issues) or submit a PR!
170
-
171
- ## 📜 License
172
-
173
- MIT © [tripolskypetr](https://github.com/tripolskypetr)
1
+ # 🧿 @backtest-kit/sidekick
2
+
3
+ > The easiest way to create a new Backtest Kit trading bot project. Scaffolds a multi-timeframe crypto trading strategy with Pine Script indicators via [PineTS](https://github.com/QuantForgeOrg/PineTS) runtime, 4H trend filter + 15m signal generator, partial profit taking, breakeven trailing stops, and risk validation.
4
+
5
+ ![screenshot](https://raw.githubusercontent.com/tripolskypetr/backtest-kit/HEAD/assets/screenshots/screenshot16.png)
6
+
7
+ [![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/tripolskypetr/backtest-kit)
8
+ [![npm](https://img.shields.io/npm/v/@backtest-kit/sidekick.svg?style=flat-square)](https://npmjs.org/package/@backtest-kit/sidekick)
9
+ [![License](https://img.shields.io/npm/l/@backtest-kit/sidekick.svg)](https://github.com/tripolskypetr/backtest-kit/blob/master/LICENSE)
10
+
11
+ 📚 **[Backtest Kit Docs](https://backtest-kit.github.io/documents/article_07_ai_news_trading_signals.html)** | 🌟 **[GitHub](https://github.com/tripolskypetr/backtest-kit)**
12
+
13
+ ## ✨ Features
14
+
15
+ - 🚀 **Zero Config**: Get started with one command - no setup required
16
+ - 📊 **Multi-timeframe analysis** — 4H daily trend filter (RSI + MACD + ADX) combined with 15m entry signals (EMA crossover + volume spike + momentum)
17
+ - 📜 **Pine Script indicators** — strategies written in TradingView Pine Script v5, executed locally via `@backtest-kit/pinets`
18
+ - 🛡️ **Risk management** — SL/TP distance validation, Kelly-optimized partial profit taking (33/33/34%), breakeven trailing stop
19
+ - 🔄 **Position lifecycle** — full monitoring with scheduled/opened/closed/cancelled event logging
20
+ - 🔌 **Binance integration** — OHLCV candles, order book depth, tick-precise price/quantity formatting via CCXT
21
+ - 🕐 **Historical frames** — predefined backtest periods covering bull runs, sharp drops, and sideways markets
22
+ - 🎨 **Web UI dashboard** — interactive charting via `@backtest-kit/ui`
23
+ - 💾 **Persistent storage** — crash-safe state with atomic persistence for both backtest and live modes
24
+
25
+ ## 🚀 Quick Start
26
+
27
+ > **New to backtest-kit?** The fastest way to get a real, production-ready setup is to clone the [reference implementation](https://github.com/tripolskypetr/backtest-kit/tree/master/example) — a fully working news-sentiment AI trading system with LLM forecasting, multi-timeframe data, and a documented February 2026 backtest. Start there instead of from scratch.
28
+
29
+ ### Create a New Project
30
+
31
+ ```bash
32
+ npx -y @backtest-kit/sidekick my-trading-bot
33
+ cd my-trading-bot
34
+ npm start
35
+ ```
36
+
37
+ That's it! You now have a working trading bot with:
38
+ - Multi-timeframe Pine Script strategy (4H trend + 15m signals)
39
+ - Risk management validation (SL/TP distance checks)
40
+ - Partial profit taking and breakeven trailing stops
41
+ - Cache utilities and debug scripts
42
+ - CLAUDE.md for AI-assisted strategy iteration
43
+ - Environment configuration
44
+
45
+ ## 🏗️ Generated Project Structure
46
+
47
+ ```
48
+ my-trading-bot/
49
+ ├── src/
50
+ │ ├── index.mjs # Entry point — loads config, logic, bootstrap
51
+ │ ├── main/bootstrap.mjs # Mode dispatcher (backtest / paper / live)
52
+ │ ├── config/
53
+ │ │ ├── setup.mjs # Logger, storage, notifications, UI server
54
+ │ │ ├── validate.mjs # Schema validation for all enums
55
+ │ │ ├── params.mjs # Environment variables (Ollama API key)
56
+ │ │ └── ccxt.mjs # Binance exchange singleton via CCXT
57
+ │ ├── logic/
58
+ │ │ ├── strategy/main.strategy.mjs # Main strategy — multi-TF signal logic
59
+ │ │ ├── exchange/binance.exchange.mjs # Exchange schema — candles, order book, formatting
60
+ │ │ ├── frame/*.frame.mjs # Backtest time frames (Feb 2024, Oct–Dec 2025)
61
+ │ │ ├── risk/sl_distance.risk.mjs # Stop-loss distance validation (≥0.2%)
62
+ │ │ ├── risk/tp_distance.risk.mjs # Take-profit distance validation (≥0.2%)
63
+ │ │ └── action/
64
+ │ │ ├── backtest_partial_profit_taking.action.mjs
65
+ │ │ ├── backtest_lower_stop_on_breakeven.action.mjs
66
+ │ │ └── backtest_position_monitor.action.mjs
67
+ │ ├── classes/
68
+ │ │ ├── BacktestPartialProfitTakingAction.mjs # Scale out at 3 TP levels
69
+ │ │ ├── BacktestLowerStopOnBreakevenAction.mjs # Trailing stop on breakeven
70
+ │ │ └── BacktestPositionMonitorAction.mjs # Position event logger
71
+ │ ├── math/
72
+ │ │ ├── timeframe_4h.math.mjs # 4H trend data — RSI, MACD, ADX, DI+/DI-
73
+ │ │ └── timeframe_15m.math.mjs # 15m signal data — EMA, ATR, volume, momentum
74
+ │ ├── enum/ # String constants for type-safe schema refs
75
+ │ └── utils/getArgs.mjs # CLI argument parser with defaults
76
+ ├── config/source/
77
+ │ ├── timeframe_4h.pine # Pine Script v5 — Daily Trend Filter (RSI/MACD/ADX)
78
+ │ └── timeframe_15m.pine # Pine Script v5 — Signal Strategy (EMA/ATR/Volume)
79
+ ├── scripts/
80
+ │ ├── run_timeframe_15m.mjs # Standalone 15m Pine Script runner
81
+ │ ├── run_timeframe_4h.mjs # Standalone 4H Pine Script runner
82
+ │ └── cache/
83
+ │ ├── cache_candles.mjs # Pre-download OHLCV candles (1m/15m/4h)
84
+ │ ├── validate_candles.mjs # Verify cached candle data integrity
85
+ │ └── cache_model.mjs # Pull Ollama LLM model with progress bar
86
+ ├── docker/ollama/
87
+ │ ├── docker-compose.yaml # Ollama GPU container setup
88
+ │ └── watch.sh # nvidia-smi monitor
89
+ ├── CLAUDE.md # AI strategy development guide
90
+ ├── .env # Environment variables
91
+ └── package.json # Dependencies
92
+ ```
93
+
94
+ ## 💡 Strategy Overview
95
+
96
+ ### 🎯 4H Trend Filter (`timeframe_4h.pine`)
97
+
98
+ Determines the market regime using three indicators:
99
+
100
+ | Regime | Condition |
101
+ |--------|-----------|
102
+ | **AllowLong** | ADX > 25, MACD histogram > 0, DI+ > DI-, RSI > 50 |
103
+ | **AllowShort** | ADX > 25, MACD histogram < 0, DI- > DI+, RSI < 50 |
104
+ | **AllowBoth** | Strong trend but no clear bull/bear regime |
105
+ | **NoTrades** | ADX ≤ 25 (weak trend) |
106
+
107
+ ### ⚡ 15m Signal Generator (`timeframe_15m.pine`)
108
+
109
+ Generates entry signals with EMA crossover confirmed by volume and momentum:
110
+
111
+ - **Long**: EMA(5) crosses above EMA(13), RSI 40–65, price above EMA(50), volume spike (>1.5x MA), positive momentum
112
+ - **Short**: EMA(5) crosses below EMA(13), RSI 35–60, price below EMA(50), volume spike, negative momentum
113
+ - **SL/TP**: Static 2%/3% from entry price
114
+ - **Signal expiry**: 5 bars
115
+
116
+ ### 🛡️ Risk Filters
117
+
118
+ - Reject signals where SL distance < 0.2% (slippage protection)
119
+ - Reject signals where TP distance < 0.2% (slippage protection)
120
+ - Trend alignment: long signals rejected in bear regime, short signals rejected in bull regime
121
+
122
+ ### 💹 Position Management
123
+
124
+ - **Partial profit taking**: Scale out at 3 levels — 33% at TP3, 33% at TP2, 34% at TP1
125
+ - **Breakeven trailing stop**: When breakeven is reached, lower trailing stop by 3 points
126
+
127
+ ## 🕐 Backtest Frames
128
+
129
+ | Frame | Period | Market Note |
130
+ |-------|--------|-------------|
131
+ | `February2024` | Feb 1–29, 2024 | Bull run |
132
+ | `October2025` | Oct 1–31, 2025 | Sharp drop Oct 9–11 |
133
+ | `November2025` | Nov 1–30, 2025 | Sideways with downtrend |
134
+ | `December2025` | Dec 1–31, 2025 | Sideways, no clear direction |
135
+
136
+ ## 💡 CLI Options
137
+
138
+ ```bash
139
+ # Create project with custom name
140
+ npx -y @backtest-kit/sidekick my-bot
141
+
142
+ # Create in current directory (must be empty)
143
+ npx -y @backtest-kit/sidekick .
144
+ ```
145
+
146
+ ## 📋 Dependencies
147
+
148
+ | Package | Purpose |
149
+ |---------|---------|
150
+ | [backtest-kit](https://libraries.io/npm/backtest-kit) | Core backtesting/trading framework |
151
+ | [@backtest-kit/pinets](https://github.com/QuantForgeOrg/PineTS) | Pine Script v5 runtime for Node.js |
152
+ | [@backtest-kit/ui](https://libraries.io/npm/backtest-kit) | Interactive charting dashboard |
153
+ | [@backtest-kit/ollama](https://libraries.io/npm/backtest-kit) | LLM inference integration |
154
+ | [ccxt](https://github.com/ccxt/ccxt) | Binance exchange connectivity |
155
+ | [functools-kit](https://www.npmjs.com/package/functools-kit) | `singleshot`, `randomString` utilities |
156
+ | [pinolog](https://www.npmjs.com/package/pinolog) | File-based structured logging |
157
+ | [openai](https://www.npmjs.com/package/openai) | OpenAI API client |
158
+ | [ollama](https://www.npmjs.com/package/ollama) | Ollama local LLM client |
159
+
160
+ ## 🔗 Links
161
+
162
+ - [Backtest Kit Documentation](https://backtest-kit.github.io/documents/article_07_ai_news_trading_signals.html)
163
+ - [GitHub Repository](https://github.com/tripolskypetr/backtest-kit)
164
+ - [Demo Projects](https://github.com/tripolskypetr/backtest-kit/tree/master/demo)
165
+ - [API Reference](https://backtest-kit.github.io/documents/article_07_ai_news_trading_signals.html)
166
+
167
+ ## 🤝 Contribute
168
+
169
+ Found a bug or want to add a feature? [Open an issue](https://github.com/tripolskypetr/backtest-kit/issues) or submit a PR!
170
+
171
+ ## 📜 License
172
+
173
+ MIT © [tripolskypetr](https://github.com/tripolskypetr)
@@ -1,114 +1,114 @@
1
- //@version=5
2
- indicator("Signal Strategy 15m v1", overlay=true)
3
-
4
- plotcandle(open, high, low, close,
5
- color=close > open ? color.new(color.green, 70) : color.new(color.red, 70),
6
- wickcolor=color.new(color.gray, 70),
7
- bordercolor=color.new(color.gray, 70))
8
-
9
-
10
- // === INPUTS ===
11
- rsi_len = input.int(7, "RSI Length", minval=2)
12
- ema_fast_len = input.int(5, "EMA Fast", minval=1)
13
- ema_slow_len = input.int(13, "EMA Slow", minval=1)
14
- ema_trend_len = input.int(50, "EMA Trend", minval=1)
15
- atr_len = input.int(14, "ATR Length", minval=1)
16
- vol_ma_len = input.int(20, "Volume MA Length", minval=1)
17
-
18
- sl_mult = input.float(1.5, "SL ATR Multiplier", minval=0.5, step=0.1)
19
- tp_mult = input.float(2.5, "TP ATR Multiplier", minval=0.5, step=0.1)
20
- signal_valid_bars = input.int(5, "Signal Valid Bars", minval=1)
21
-
22
- // === INDICATORS ===
23
- rsi = ta.rsi(close, rsi_len)
24
- ema_fast = ta.ema(close, ema_fast_len)
25
- ema_slow = ta.ema(close, ema_slow_len)
26
- ema_trend = ta.ema(close, ema_trend_len)
27
- atr = ta.atr(atr_len)
28
-
29
- // Volume filter - выше среднего
30
- vol_ma = ta.sma(volume, vol_ma_len)
31
- vol_spike = volume > vol_ma * 1.5
32
-
33
- // Momentum confirmation
34
- mom = ta.mom(close, 3)
35
- mom_up = mom > 0
36
- mom_down = mom < 0
37
-
38
- // === TREND FILTER ===
39
- trend_up = close > ema_trend and ema_fast > ema_trend
40
- trend_down = close < ema_trend and ema_fast < ema_trend
41
-
42
- // === ENTRY CONDITIONS ===
43
- // Long: пересечение + RSI не перекуплен + тренд вверх + объём + momentum
44
- long_cond = ta.crossover(ema_fast, ema_slow) and rsi > 40 and rsi < 65 and trend_up and vol_spike and mom_up
45
-
46
- // Short: пересечение + RSI не перепродан + тренд вниз + объём + momentum
47
- short_cond = ta.crossunder(ema_fast, ema_slow) and rsi < 60 and rsi > 35 and trend_down and vol_spike and mom_down
48
-
49
- // === SIGNAL MANAGEMENT ===
50
- var int bars_since_signal = 0
51
- var int last_signal = 0
52
- var float entry_price = na
53
- var float signal_atr = na
54
-
55
- if long_cond
56
- last_signal := 1
57
- bars_since_signal := 0
58
- entry_price := close
59
- signal_atr := atr
60
- else if short_cond
61
- last_signal := -1
62
- bars_since_signal := 0
63
- entry_price := close
64
- signal_atr := atr
65
- else
66
- bars_since_signal += 1
67
-
68
- // Signal expires faster on 15m
69
- active_signal = bars_since_signal <= signal_valid_bars ? last_signal : 0
70
-
71
- // === DYNAMIC SL/TP based on ATR ===
72
- // sl = last_signal == 1 ? entry_price - signal_atr * sl_mult : last_signal == -1 ? entry_price + signal_atr * sl_mult : na
73
- // tp = last_signal == 1 ? entry_price + signal_atr * tp_mult : last_signal == -1 ? entry_price - signal_atr * tp_mult : na
74
-
75
- // === STATIC SL/TP for watch strategy ==
76
- sl = last_signal == -1 ? close * 1.02 : close * 0.98
77
- tp = last_signal == -1 ? close * 0.97 : close * 1.03
78
-
79
- // === VISUALIZATION ===
80
- line_color = active_signal == 1 ? color.green : active_signal == -1 ? color.red : color.gray
81
-
82
- plot(ema_fast, "EMA Fast", color=color.new(color.blue, 50), linewidth=1)
83
- plot(ema_slow, "EMA Slow", color=color.new(color.orange, 50), linewidth=1)
84
- plot(ema_trend, "EMA Trend", color=color.new(color.white, 70), linewidth=2)
85
-
86
- plotshape(long_cond, "Long", shape.triangleup, location.belowbar, color.green, size=size.small)
87
- plotshape(short_cond, "Short", shape.triangledown, location.abovebar, color.red, size=size.small)
88
-
89
- plot(close, "Active Signal", color=line_color, linewidth=6)
90
-
91
- // === OUTPUTS FOR BOT ===
92
- plot(close, "Close", display=display.data_window)
93
- plot(active_signal, "Signal", display=display.data_window)
94
- plot(sl, "StopLoss", display=display.data_window)
95
- plot(tp, "TakeProfit", display=display.data_window)
96
- plot(1440, "EstimatedTime", display=display.data_window) // 24 hour for 15m TF
97
-
98
- // === DEBUG: INDICATOR DUMP ===
99
- plot(rsi, "d_RSI", display=display.data_window)
100
- plot(ema_fast, "d_EmaFast", display=display.data_window)
101
- plot(ema_slow, "d_EmaSlow", display=display.data_window)
102
- plot(ema_trend, "d_EmaTrend", display=display.data_window)
103
- plot(atr, "d_ATR", display=display.data_window)
104
- plot(volume, "d_Volume", display=display.data_window)
105
- plot(vol_ma, "d_VolMA", display=display.data_window)
106
- plot(vol_spike ? 1 : 0, "d_VolSpike", display=display.data_window)
107
- plot(mom, "d_Mom", display=display.data_window)
108
- plot(mom_up ? 1 : 0, "d_MomUp", display=display.data_window)
109
- plot(mom_down ? 1 : 0, "d_MomDown", display=display.data_window)
110
- plot(trend_up ? 1 : 0, "d_TrendUp", display=display.data_window)
111
- plot(trend_down ? 1 : 0, "d_TrendDown", display=display.data_window)
112
- plot(long_cond ? 1 : 0, "d_LongCond", display=display.data_window)
113
- plot(short_cond ? 1 : 0, "d_ShortCond", display=display.data_window)
1
+ //@version=5
2
+ indicator("Signal Strategy 15m v1", overlay=true)
3
+
4
+ plotcandle(open, high, low, close,
5
+ color=close > open ? color.new(color.green, 70) : color.new(color.red, 70),
6
+ wickcolor=color.new(color.gray, 70),
7
+ bordercolor=color.new(color.gray, 70))
8
+
9
+
10
+ // === INPUTS ===
11
+ rsi_len = input.int(7, "RSI Length", minval=2)
12
+ ema_fast_len = input.int(5, "EMA Fast", minval=1)
13
+ ema_slow_len = input.int(13, "EMA Slow", minval=1)
14
+ ema_trend_len = input.int(50, "EMA Trend", minval=1)
15
+ atr_len = input.int(14, "ATR Length", minval=1)
16
+ vol_ma_len = input.int(20, "Volume MA Length", minval=1)
17
+
18
+ sl_mult = input.float(1.5, "SL ATR Multiplier", minval=0.5, step=0.1)
19
+ tp_mult = input.float(2.5, "TP ATR Multiplier", minval=0.5, step=0.1)
20
+ signal_valid_bars = input.int(5, "Signal Valid Bars", minval=1)
21
+
22
+ // === INDICATORS ===
23
+ rsi = ta.rsi(close, rsi_len)
24
+ ema_fast = ta.ema(close, ema_fast_len)
25
+ ema_slow = ta.ema(close, ema_slow_len)
26
+ ema_trend = ta.ema(close, ema_trend_len)
27
+ atr = ta.atr(atr_len)
28
+
29
+ // Volume filter - выше среднего
30
+ vol_ma = ta.sma(volume, vol_ma_len)
31
+ vol_spike = volume > vol_ma * 1.5
32
+
33
+ // Momentum confirmation
34
+ mom = ta.mom(close, 3)
35
+ mom_up = mom > 0
36
+ mom_down = mom < 0
37
+
38
+ // === TREND FILTER ===
39
+ trend_up = close > ema_trend and ema_fast > ema_trend
40
+ trend_down = close < ema_trend and ema_fast < ema_trend
41
+
42
+ // === ENTRY CONDITIONS ===
43
+ // Long: пересечение + RSI не перекуплен + тренд вверх + объём + momentum
44
+ long_cond = ta.crossover(ema_fast, ema_slow) and rsi > 40 and rsi < 65 and trend_up and vol_spike and mom_up
45
+
46
+ // Short: пересечение + RSI не перепродан + тренд вниз + объём + momentum
47
+ short_cond = ta.crossunder(ema_fast, ema_slow) and rsi < 60 and rsi > 35 and trend_down and vol_spike and mom_down
48
+
49
+ // === SIGNAL MANAGEMENT ===
50
+ var int bars_since_signal = 0
51
+ var int last_signal = 0
52
+ var float entry_price = na
53
+ var float signal_atr = na
54
+
55
+ if long_cond
56
+ last_signal := 1
57
+ bars_since_signal := 0
58
+ entry_price := close
59
+ signal_atr := atr
60
+ else if short_cond
61
+ last_signal := -1
62
+ bars_since_signal := 0
63
+ entry_price := close
64
+ signal_atr := atr
65
+ else
66
+ bars_since_signal += 1
67
+
68
+ // Signal expires faster on 15m
69
+ active_signal = bars_since_signal <= signal_valid_bars ? last_signal : 0
70
+
71
+ // === DYNAMIC SL/TP based on ATR ===
72
+ // sl = last_signal == 1 ? entry_price - signal_atr * sl_mult : last_signal == -1 ? entry_price + signal_atr * sl_mult : na
73
+ // tp = last_signal == 1 ? entry_price + signal_atr * tp_mult : last_signal == -1 ? entry_price - signal_atr * tp_mult : na
74
+
75
+ // === STATIC SL/TP for watch strategy ==
76
+ sl = last_signal == -1 ? close * 1.02 : close * 0.98
77
+ tp = last_signal == -1 ? close * 0.97 : close * 1.03
78
+
79
+ // === VISUALIZATION ===
80
+ line_color = active_signal == 1 ? color.green : active_signal == -1 ? color.red : color.gray
81
+
82
+ plot(ema_fast, "EMA Fast", color=color.new(color.blue, 50), linewidth=1)
83
+ plot(ema_slow, "EMA Slow", color=color.new(color.orange, 50), linewidth=1)
84
+ plot(ema_trend, "EMA Trend", color=color.new(color.white, 70), linewidth=2)
85
+
86
+ plotshape(long_cond, "Long", shape.triangleup, location.belowbar, color.green, size=size.small)
87
+ plotshape(short_cond, "Short", shape.triangledown, location.abovebar, color.red, size=size.small)
88
+
89
+ plot(close, "Active Signal", color=line_color, linewidth=6)
90
+
91
+ // === OUTPUTS FOR BOT ===
92
+ plot(close, "Close", display=display.data_window)
93
+ plot(active_signal, "Signal", display=display.data_window)
94
+ plot(sl, "StopLoss", display=display.data_window)
95
+ plot(tp, "TakeProfit", display=display.data_window)
96
+ plot(1440, "EstimatedTime", display=display.data_window) // 24 hour for 15m TF
97
+
98
+ // === DEBUG: INDICATOR DUMP ===
99
+ plot(rsi, "d_RSI", display=display.data_window)
100
+ plot(ema_fast, "d_EmaFast", display=display.data_window)
101
+ plot(ema_slow, "d_EmaSlow", display=display.data_window)
102
+ plot(ema_trend, "d_EmaTrend", display=display.data_window)
103
+ plot(atr, "d_ATR", display=display.data_window)
104
+ plot(volume, "d_Volume", display=display.data_window)
105
+ plot(vol_ma, "d_VolMA", display=display.data_window)
106
+ plot(vol_spike ? 1 : 0, "d_VolSpike", display=display.data_window)
107
+ plot(mom, "d_Mom", display=display.data_window)
108
+ plot(mom_up ? 1 : 0, "d_MomUp", display=display.data_window)
109
+ plot(mom_down ? 1 : 0, "d_MomDown", display=display.data_window)
110
+ plot(trend_up ? 1 : 0, "d_TrendUp", display=display.data_window)
111
+ plot(trend_down ? 1 : 0, "d_TrendDown", display=display.data_window)
112
+ plot(long_cond ? 1 : 0, "d_LongCond", display=display.data_window)
113
+ plot(short_cond ? 1 : 0, "d_ShortCond", display=display.data_window)
114
114
  plot(bars_since_signal, "d_BarsSinceSignal", display=display.data_window)