@hummingbot/skills 1.0.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 (35) hide show
  1. package/README.md +63 -0
  2. package/package.json +28 -0
  3. package/skills/candles-feed/SKILL.md +259 -0
  4. package/skills/candles-feed/scripts/calculate_indicator.sh +359 -0
  5. package/skills/candles-feed/scripts/get_candles.sh +158 -0
  6. package/skills/candles-feed/scripts/get_funding_rate.sh +112 -0
  7. package/skills/candles-feed/scripts/get_price.sh +86 -0
  8. package/skills/candles-feed/scripts/list_candle_connectors.sh +47 -0
  9. package/skills/executor-creator/SKILL.md +212 -0
  10. package/skills/executor-creator/scripts/clear_position.sh +54 -0
  11. package/skills/executor-creator/scripts/create_executor.sh +92 -0
  12. package/skills/executor-creator/scripts/get_executor.sh +37 -0
  13. package/skills/executor-creator/scripts/get_executor_schema.sh +37 -0
  14. package/skills/executor-creator/scripts/get_executors_summary.sh +30 -0
  15. package/skills/executor-creator/scripts/get_position.sh +44 -0
  16. package/skills/executor-creator/scripts/get_positions.sh +30 -0
  17. package/skills/executor-creator/scripts/list_executor_types.sh +30 -0
  18. package/skills/executor-creator/scripts/list_executors.sh +52 -0
  19. package/skills/executor-creator/scripts/setup_executor.sh +197 -0
  20. package/skills/executor-creator/scripts/stop_executor.sh +54 -0
  21. package/skills/hummingbot-api-setup/SKILL.md +308 -0
  22. package/skills/hummingbot-api-setup/references/original_setup.sh +628 -0
  23. package/skills/hummingbot-api-setup/scripts/check_prerequisites.sh +92 -0
  24. package/skills/hummingbot-api-setup/scripts/deploy_full_stack.sh +151 -0
  25. package/skills/hummingbot-api-setup/scripts/health_check.sh +100 -0
  26. package/skills/hummingbot-api-setup/scripts/step1_detect_system.sh +88 -0
  27. package/skills/hummingbot-api-setup/scripts/step2_check_dependencies.sh +81 -0
  28. package/skills/keys-manager/SKILL.md +132 -0
  29. package/skills/keys-manager/scripts/add_credentials.sh +106 -0
  30. package/skills/keys-manager/scripts/get_connector_config.sh +67 -0
  31. package/skills/keys-manager/scripts/list_account_credentials.sh +82 -0
  32. package/skills/keys-manager/scripts/list_connectors.sh +64 -0
  33. package/skills/keys-manager/scripts/remove_credentials.sh +79 -0
  34. package/skills/keys-manager/scripts/setup_connector.sh +214 -0
  35. package/skills.json +137 -0
package/README.md ADDED
@@ -0,0 +1,63 @@
1
+ # Hummingbot Skills
2
+
3
+ AI agent skills for [Hummingbot](https://hummingbot.org) algorithmic trading infrastructure.
4
+
5
+ Built on the [Agent Skills](https://agentskills.io) open standard.
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ npx skills add hummingbot/skills
11
+ ```
12
+
13
+ Or install a specific skill:
14
+ ```bash
15
+ npx skills add hummingbot/skills --skill executor-creator
16
+ ```
17
+
18
+ ## Usage
19
+
20
+ After installing, ask your AI agent:
21
+
22
+ - "Create a BTC position with 2% stop loss and 4% take profit"
23
+ - "Show me the RSI for ETH on Binance"
24
+ - "Add my Binance API keys"
25
+ - "Set up Hummingbot with Docker"
26
+
27
+ ## Available Skills
28
+
29
+ | Skill | Description |
30
+ |-------|-------------|
31
+ | [hummingbot-api-setup](./skills/hummingbot-api-setup/) | Deploy Hummingbot infrastructure (Docker, API, Gateway) |
32
+ | [keys-manager](./skills/keys-manager/) | Manage exchange API credentials |
33
+ | [executor-creator](./skills/executor-creator/) | Create trading executors (position, grid, DCA, TWAP) |
34
+ | [candles-feed](./skills/candles-feed/) | Fetch market data and technical indicators |
35
+
36
+ ## Prerequisites
37
+
38
+ Skills interact with the Hummingbot API server:
39
+ - **URL**: `http://localhost:8000`
40
+ - **Credentials**: `admin:admin`
41
+ - **Docs**: `http://localhost:8000/docs`
42
+
43
+ Use the `hummingbot-api-setup` skill to deploy the API server.
44
+
45
+ ## Repository Structure
46
+
47
+ ```
48
+ hummingbot/skills/
49
+ ├── skills/ # Skill definitions
50
+ │ ├── hummingbot-api-setup/ # Infrastructure setup
51
+ │ │ ├── SKILL.md
52
+ │ │ └── scripts/
53
+ │ ├── keys-manager/ # API credentials
54
+ │ ├── executor-creator/ # Trading executors
55
+ │ └── candles-feed/ # Market data
56
+ └── skills.json # Skill metadata (for webapp)
57
+ ```
58
+
59
+ ## Links
60
+
61
+ - [Hummingbot](https://hummingbot.org)
62
+ - [skills.sh](https://skills.sh)
63
+ - [Agent Skills Spec](https://agentskills.io)
package/package.json ADDED
@@ -0,0 +1,28 @@
1
+ {
2
+ "name": "@hummingbot/skills",
3
+ "version": "1.0.0",
4
+ "description": "AI agent skills for Hummingbot algorithmic trading infrastructure",
5
+ "keywords": [
6
+ "hummingbot",
7
+ "trading",
8
+ "crypto",
9
+ "ai-agent",
10
+ "skills",
11
+ "algorithmic-trading"
12
+ ],
13
+ "homepage": "https://skills.hummingbot.org",
14
+ "repository": {
15
+ "type": "git",
16
+ "url": "git+https://github.com/hummingbot/skills.git"
17
+ },
18
+ "license": "Apache-2.0",
19
+ "author": "Hummingbot Foundation <dev@hummingbot.org>",
20
+ "files": [
21
+ "skills/",
22
+ "skills.json",
23
+ "README.md"
24
+ ],
25
+ "publishConfig": {
26
+ "access": "public"
27
+ }
28
+ }
@@ -0,0 +1,259 @@
1
+ ---
2
+ name: candles-feed
3
+ description: Fetch market data (OHLCV candles) and calculate technical indicators (RSI, EMA, MACD, Bollinger Bands) from exchanges via Hummingbot API. Use this skill when the user needs price data, candlestick charts, or technical analysis.
4
+ license: Apache-2.0
5
+ ---
6
+
7
+ # Hummingbot Candles Skill
8
+
9
+ This skill fetches candlestick (OHLCV) data from exchanges and calculates technical indicators. It provides the data foundation for strategy development and market analysis.
10
+
11
+ ## Prerequisites
12
+
13
+ - Hummingbot API server must be running (use the setup skill)
14
+ - Exchange connector must support candle data
15
+
16
+ ## Capabilities
17
+
18
+ ### 1. Get Available Connectors
19
+
20
+ List exchanges that support candle data:
21
+
22
+ ```bash
23
+ ./scripts/list_candle_connectors.sh
24
+ ```
25
+
26
+ ### 2. Fetch Candles
27
+
28
+ Get OHLCV data for a trading pair:
29
+
30
+ ```bash
31
+ ./scripts/get_candles.sh \
32
+ --connector binance \
33
+ --pair BTC-USDT \
34
+ --interval 1h \
35
+ --days 30
36
+ ```
37
+
38
+ Supported intervals: `1m`, `5m`, `15m`, `30m`, `1h`, `4h`, `1d`, `1w`
39
+
40
+ ### 3. Calculate Indicators
41
+
42
+ Calculate technical indicators on candle data:
43
+
44
+ ```bash
45
+ # RSI (Relative Strength Index)
46
+ ./scripts/calculate_indicator.sh \
47
+ --connector binance \
48
+ --pair BTC-USDT \
49
+ --indicator rsi \
50
+ --period 14
51
+
52
+ # EMA (Exponential Moving Average)
53
+ ./scripts/calculate_indicator.sh \
54
+ --connector binance \
55
+ --pair BTC-USDT \
56
+ --indicator ema \
57
+ --period 20
58
+
59
+ # MACD (Moving Average Convergence Divergence)
60
+ ./scripts/calculate_indicator.sh \
61
+ --connector binance \
62
+ --pair BTC-USDT \
63
+ --indicator macd \
64
+ --fast 12 \
65
+ --slow 26 \
66
+ --signal 9
67
+
68
+ # Bollinger Bands
69
+ ./scripts/calculate_indicator.sh \
70
+ --connector binance \
71
+ --pair BTC-USDT \
72
+ --indicator bb \
73
+ --period 20 \
74
+ --std 2
75
+ ```
76
+
77
+ ### 4. Get Current Price
78
+
79
+ Get the latest price for trading pairs:
80
+
81
+ ```bash
82
+ ./scripts/get_price.sh \
83
+ --connector binance \
84
+ --pairs "BTC-USDT,ETH-USDT"
85
+ ```
86
+
87
+ ### 5. Get Funding Rate (Perpetuals)
88
+
89
+ Get funding rate for perpetual contracts:
90
+
91
+ ```bash
92
+ ./scripts/get_funding_rate.sh \
93
+ --connector binance_perpetual \
94
+ --pair BTC-USDT
95
+ ```
96
+
97
+ ## Supported Indicators
98
+
99
+ | Indicator | Code | Parameters | Description |
100
+ |-----------|------|------------|-------------|
101
+ | RSI | `rsi` | period | Relative Strength Index |
102
+ | EMA | `ema` | period | Exponential Moving Average |
103
+ | SMA | `sma` | period | Simple Moving Average |
104
+ | MACD | `macd` | fast, slow, signal | Moving Average Convergence Divergence |
105
+ | Bollinger Bands | `bb` | period, std | Volatility bands |
106
+ | ATR | `atr` | period | Average True Range |
107
+ | VWAP | `vwap` | - | Volume Weighted Average Price |
108
+ | Stochastic | `stoch` | k_period, d_period | Stochastic Oscillator |
109
+
110
+ ## Candle Data Format
111
+
112
+ Returned candle data includes:
113
+
114
+ | Field | Type | Description |
115
+ |-------|------|-------------|
116
+ | `timestamp` | int | Unix timestamp (ms) |
117
+ | `open` | float | Opening price |
118
+ | `high` | float | Highest price |
119
+ | `low` | float | Lowest price |
120
+ | `close` | float | Closing price |
121
+ | `volume` | float | Trading volume |
122
+
123
+ Example output:
124
+ ```json
125
+ {
126
+ "candles": [
127
+ {
128
+ "timestamp": 1706400000000,
129
+ "open": 42150.5,
130
+ "high": 42300.0,
131
+ "low": 42100.0,
132
+ "close": 42250.0,
133
+ "volume": 1250.5
134
+ }
135
+ ],
136
+ "interval": "1h",
137
+ "total_candles": 720
138
+ }
139
+ ```
140
+
141
+ ## Indicator Output
142
+
143
+ ### RSI Output
144
+ ```json
145
+ {
146
+ "indicator": "rsi",
147
+ "period": 14,
148
+ "current_value": 65.5,
149
+ "signal": "neutral",
150
+ "interpretation": {
151
+ "overbought": 70,
152
+ "oversold": 30,
153
+ "description": "RSI at 65.5 indicates slightly bullish momentum"
154
+ }
155
+ }
156
+ ```
157
+
158
+ ### MACD Output
159
+ ```json
160
+ {
161
+ "indicator": "macd",
162
+ "current_values": {
163
+ "macd_line": 125.5,
164
+ "signal_line": 110.2,
165
+ "histogram": 15.3
166
+ },
167
+ "signal": "bullish",
168
+ "interpretation": "MACD above signal line, positive momentum"
169
+ }
170
+ ```
171
+
172
+ ### Bollinger Bands Output
173
+ ```json
174
+ {
175
+ "indicator": "bb",
176
+ "period": 20,
177
+ "std": 2,
178
+ "current_values": {
179
+ "upper": 43500.0,
180
+ "middle": 42000.0,
181
+ "lower": 40500.0,
182
+ "current_price": 42250.0
183
+ },
184
+ "position": "middle",
185
+ "bandwidth": 0.071
186
+ }
187
+ ```
188
+
189
+ ## Workflow: Market Analysis
190
+
191
+ 1. **Check available connectors**
192
+ ```bash
193
+ ./scripts/list_candle_connectors.sh
194
+ ```
195
+
196
+ 2. **Fetch candle data**
197
+ ```bash
198
+ ./scripts/get_candles.sh --connector binance --pair BTC-USDT --interval 4h --days 30
199
+ ```
200
+
201
+ 3. **Calculate indicators**
202
+ ```bash
203
+ # Get RSI
204
+ ./scripts/calculate_indicator.sh --connector binance --pair BTC-USDT --indicator rsi --period 14
205
+
206
+ # Get EMA crossover
207
+ ./scripts/calculate_indicator.sh --connector binance --pair BTC-USDT --indicator ema --period 20
208
+ ./scripts/calculate_indicator.sh --connector binance --pair BTC-USDT --indicator ema --period 50
209
+ ```
210
+
211
+ 4. **Interpret signals**
212
+ - RSI > 70: Overbought, potential sell signal
213
+ - RSI < 30: Oversold, potential buy signal
214
+ - EMA(20) > EMA(50): Bullish trend
215
+ - EMA(20) < EMA(50): Bearish trend
216
+
217
+ ## API Endpoints Used
218
+
219
+ All requests go to `http://localhost:8000` with Basic Auth (`admin:admin`):
220
+
221
+ | Endpoint | Method | Description |
222
+ |----------|--------|-------------|
223
+ | `/market-data/available-candle-connectors` | GET | List connectors with candle support |
224
+ | `/market-data/historical-candles` | POST | Fetch bulk historical OHLCV data |
225
+ | `/market-data/candles` | POST | Fetch real-time OHLCV data |
226
+ | `/market-data/prices` | POST | Get current prices |
227
+ | `/market-data/funding-info` | POST | Get funding rates |
228
+
229
+ ## Data Fetching Strategy
230
+
231
+ Scripts use a dual-fetch approach for comprehensive data:
232
+ 1. **Historical candles** - Bulk data from `/market-data/historical-candles`
233
+ 2. **Real-time candles** - Latest data from `/market-data/candles`
234
+ 3. **Merge** - Deduplicate by timestamp, real-time overrides historical
235
+
236
+ ## Environment Variables
237
+
238
+ | Variable | Default | Description |
239
+ |----------|---------|-------------|
240
+ | `API_URL` | `http://localhost:8000` | API base URL |
241
+ | `API_USER` | `admin` | API username |
242
+ | `API_PASS` | `admin` | API password |
243
+
244
+ ## Error Handling
245
+
246
+ | Error | Cause | Solution |
247
+ |-------|-------|----------|
248
+ | "Connector not supported" | Exchange doesn't support candles | Use list_candle_connectors |
249
+ | "Invalid interval" | Unsupported interval format | Use 1m, 5m, 15m, 30m, 1h, 4h, 1d, 1w |
250
+ | "Rate limited" | Too many requests | Wait and retry |
251
+ | "Invalid trading pair" | Pair not available | Check exchange for valid pairs |
252
+
253
+ ## Notes
254
+
255
+ - Candle data is fetched directly from exchanges via the Hummingbot API
256
+ - Indicators are calculated locally using the fetched candle data
257
+ - Historical data availability varies by exchange (typically 30-90 days)
258
+ - For real-time data, consider shorter intervals (1m, 5m)
259
+ - For trend analysis, use longer intervals (4h, 1d)
@@ -0,0 +1,359 @@
1
+ #!/bin/bash
2
+ # Calculate technical indicators on candle data
3
+ # Usage: ./calculate_indicator.sh --connector CONNECTOR --pair PAIR --indicator INDICATOR [--period PERIOD] [options]
4
+
5
+ set -e
6
+
7
+ API_URL="${API_URL:-http://localhost:8000}"
8
+ API_USER="${API_USER:-admin}"
9
+ API_PASS="${API_PASS:-admin}"
10
+ CONNECTOR=""
11
+ TRADING_PAIR=""
12
+ INDICATOR=""
13
+ PERIOD=14
14
+ INTERVAL="1h"
15
+ DAYS=30
16
+ # MACD specific
17
+ FAST=12
18
+ SLOW=26
19
+ SIGNAL=9
20
+ # BB specific
21
+ STD=2
22
+
23
+ # Parse arguments
24
+ while [[ $# -gt 0 ]]; do
25
+ case $1 in
26
+ --connector)
27
+ CONNECTOR="$2"
28
+ shift 2
29
+ ;;
30
+ --pair)
31
+ TRADING_PAIR="$2"
32
+ shift 2
33
+ ;;
34
+ --indicator)
35
+ INDICATOR="$2"
36
+ shift 2
37
+ ;;
38
+ --period)
39
+ PERIOD="$2"
40
+ shift 2
41
+ ;;
42
+ --interval)
43
+ INTERVAL="$2"
44
+ shift 2
45
+ ;;
46
+ --days)
47
+ DAYS="$2"
48
+ shift 2
49
+ ;;
50
+ --fast)
51
+ FAST="$2"
52
+ shift 2
53
+ ;;
54
+ --slow)
55
+ SLOW="$2"
56
+ shift 2
57
+ ;;
58
+ --signal)
59
+ SIGNAL="$2"
60
+ shift 2
61
+ ;;
62
+ --std)
63
+ STD="$2"
64
+ shift 2
65
+ ;;
66
+ --api-url)
67
+ API_URL="$2"
68
+ shift 2
69
+ ;;
70
+ --api-user)
71
+ API_USER="$2"
72
+ shift 2
73
+ ;;
74
+ --api-pass)
75
+ API_PASS="$2"
76
+ shift 2
77
+ ;;
78
+ *)
79
+ shift
80
+ ;;
81
+ esac
82
+ done
83
+
84
+ # Validate required arguments
85
+ if [ -z "$CONNECTOR" ]; then
86
+ echo '{"error": "connector is required. Use --connector CONNECTOR_NAME"}'
87
+ exit 1
88
+ fi
89
+
90
+ if [ -z "$TRADING_PAIR" ]; then
91
+ echo '{"error": "trading pair is required. Use --pair TRADING_PAIR"}'
92
+ exit 1
93
+ fi
94
+
95
+ if [ -z "$INDICATOR" ]; then
96
+ echo '{"error": "indicator is required. Use --indicator [rsi|ema|sma|macd|bb|atr]"}'
97
+ exit 1
98
+ fi
99
+
100
+ # Calculate max records needed
101
+ case "$INTERVAL" in
102
+ *m)
103
+ MINUTES=${INTERVAL%m}
104
+ MAX_RECORDS=$((1440 * DAYS / MINUTES))
105
+ ;;
106
+ *h)
107
+ HOURS=${INTERVAL%h}
108
+ MAX_RECORDS=$((24 * DAYS / HOURS))
109
+ ;;
110
+ *d)
111
+ MAX_RECORDS=$DAYS
112
+ ;;
113
+ *)
114
+ MAX_RECORDS=$((24 * DAYS))
115
+ ;;
116
+ esac
117
+
118
+ # Calculate timestamps for historical fetch
119
+ END_TIME=$(date +%s)
120
+ START_TIME=$((END_TIME - DAYS * 24 * 3600))
121
+
122
+ # Fetch historical candles
123
+ HISTORICAL=$(curl -s -u "$API_USER:$API_PASS" \
124
+ -X POST "$API_URL/market-data/historical-candles" \
125
+ -H "Content-Type: application/json" \
126
+ -d "{\"connector_name\": \"$CONNECTOR\", \"trading_pair\": \"$TRADING_PAIR\", \"interval\": \"$INTERVAL\", \"start_time\": $START_TIME, \"end_time\": $END_TIME}" 2>/dev/null || echo "[]")
127
+
128
+ # Fetch real-time candles
129
+ REALTIME=$(curl -s -u "$API_USER:$API_PASS" \
130
+ -X POST "$API_URL/market-data/candles" \
131
+ -H "Content-Type: application/json" \
132
+ -d "{\"connector_name\": \"$CONNECTOR\", \"trading_pair\": \"$TRADING_PAIR\", \"interval\": \"$INTERVAL\", \"max_records\": 100}" 2>/dev/null || echo "[]")
133
+
134
+ # Merge and deduplicate by timestamp
135
+ CANDLES=$(echo "$HISTORICAL $REALTIME" | jq -s '.[0] + .[1] | group_by(.timestamp) | map(.[0]) | sort_by(.timestamp)')
136
+
137
+ if echo "$CANDLES" | jq -e '.detail' > /dev/null 2>&1; then
138
+ echo "{\"error\": \"Failed to fetch candles\", \"detail\": $CANDLES}"
139
+ exit 1
140
+ fi
141
+
142
+ # Extract close prices (compact JSON to avoid newline issues in heredoc)
143
+ CLOSES=$(echo "$CANDLES" | jq -c '[.[].close]')
144
+ HIGHS=$(echo "$CANDLES" | jq -c '[.[].high]')
145
+ LOWS=$(echo "$CANDLES" | jq -c '[.[].low]')
146
+ VOLUMES=$(echo "$CANDLES" | jq -c '[.[].volume]')
147
+ TOTAL=$(echo "$CANDLES" | jq 'length')
148
+
149
+ # Calculate indicator using Python (for accurate calculations)
150
+ calculate_with_python() {
151
+ python3 << PYTHON_SCRIPT
152
+ import json
153
+ import sys
154
+
155
+ closes = json.loads('$CLOSES')
156
+ highs = json.loads('$HIGHS')
157
+ lows = json.loads('$LOWS')
158
+ volumes = json.loads('$VOLUMES')
159
+ indicator = '$INDICATOR'
160
+ period = int('$PERIOD')
161
+ fast = int('$FAST')
162
+ slow = int('$SLOW')
163
+ signal_period = int('$SIGNAL')
164
+ std_dev = float('$STD')
165
+
166
+ def sma(data, period):
167
+ if len(data) < period:
168
+ return None
169
+ return sum(data[-period:]) / period
170
+
171
+ def ema(data, period):
172
+ if len(data) < period:
173
+ return None
174
+ multiplier = 2 / (period + 1)
175
+ ema_val = sum(data[:period]) / period
176
+ for price in data[period:]:
177
+ ema_val = (price - ema_val) * multiplier + ema_val
178
+ return ema_val
179
+
180
+ def rsi(data, period):
181
+ if len(data) < period + 1:
182
+ return None
183
+ gains = []
184
+ losses = []
185
+ for i in range(1, len(data)):
186
+ change = data[i] - data[i-1]
187
+ if change > 0:
188
+ gains.append(change)
189
+ losses.append(0)
190
+ else:
191
+ gains.append(0)
192
+ losses.append(abs(change))
193
+
194
+ avg_gain = sum(gains[-period:]) / period
195
+ avg_loss = sum(losses[-period:]) / period
196
+
197
+ if avg_loss == 0:
198
+ return 100
199
+ rs = avg_gain / avg_loss
200
+ return 100 - (100 / (1 + rs))
201
+
202
+ def macd(data, fast_period, slow_period, signal_period):
203
+ if len(data) < slow_period:
204
+ return None, None, None
205
+ fast_ema = ema(data, fast_period)
206
+ slow_ema = ema(data, slow_period)
207
+ macd_line = fast_ema - slow_ema
208
+
209
+ # Calculate signal line (EMA of MACD)
210
+ macd_values = []
211
+ for i in range(slow_period, len(data)):
212
+ subset = data[:i+1]
213
+ f = ema(subset, fast_period)
214
+ s = ema(subset, slow_period)
215
+ macd_values.append(f - s)
216
+
217
+ signal_line = ema(macd_values, signal_period) if len(macd_values) >= signal_period else macd_line
218
+ histogram = macd_line - signal_line
219
+
220
+ return macd_line, signal_line, histogram
221
+
222
+ def bollinger_bands(data, period, std_multiplier):
223
+ if len(data) < period:
224
+ return None, None, None
225
+ middle = sma(data, period)
226
+ variance = sum((x - middle) ** 2 for x in data[-period:]) / period
227
+ std = variance ** 0.5
228
+ upper = middle + (std_multiplier * std)
229
+ lower = middle - (std_multiplier * std)
230
+ return upper, middle, lower
231
+
232
+ def atr(highs, lows, closes, period):
233
+ if len(closes) < period + 1:
234
+ return None
235
+ tr_values = []
236
+ for i in range(1, len(closes)):
237
+ hl = highs[i] - lows[i]
238
+ hc = abs(highs[i] - closes[i-1])
239
+ lc = abs(lows[i] - closes[i-1])
240
+ tr_values.append(max(hl, hc, lc))
241
+ return sum(tr_values[-period:]) / period
242
+
243
+ result = {}
244
+ current_price = closes[-1] if closes else 0
245
+
246
+ if indicator == 'rsi':
247
+ value = rsi(closes, period)
248
+ if value is not None:
249
+ if value > 70:
250
+ sig = 'overbought'
251
+ elif value < 30:
252
+ sig = 'oversold'
253
+ else:
254
+ sig = 'neutral'
255
+ result = {
256
+ 'indicator': 'rsi',
257
+ 'period': period,
258
+ 'current_value': round(value, 2),
259
+ 'signal': sig,
260
+ 'interpretation': {
261
+ 'overbought_threshold': 70,
262
+ 'oversold_threshold': 30,
263
+ 'description': f'RSI at {round(value, 2)} indicates {sig} conditions'
264
+ }
265
+ }
266
+
267
+ elif indicator == 'ema':
268
+ value = ema(closes, period)
269
+ if value is not None:
270
+ trend = 'bullish' if current_price > value else 'bearish'
271
+ result = {
272
+ 'indicator': 'ema',
273
+ 'period': period,
274
+ 'current_value': round(value, 2),
275
+ 'current_price': round(current_price, 2),
276
+ 'signal': trend,
277
+ 'distance_pct': round((current_price - value) / value * 100, 2)
278
+ }
279
+
280
+ elif indicator == 'sma':
281
+ value = sma(closes, period)
282
+ if value is not None:
283
+ trend = 'bullish' if current_price > value else 'bearish'
284
+ result = {
285
+ 'indicator': 'sma',
286
+ 'period': period,
287
+ 'current_value': round(value, 2),
288
+ 'current_price': round(current_price, 2),
289
+ 'signal': trend,
290
+ 'distance_pct': round((current_price - value) / value * 100, 2)
291
+ }
292
+
293
+ elif indicator == 'macd':
294
+ macd_line, signal_line, histogram = macd(closes, fast, slow, signal_period)
295
+ if macd_line is not None:
296
+ sig = 'bullish' if histogram > 0 else 'bearish'
297
+ result = {
298
+ 'indicator': 'macd',
299
+ 'parameters': {'fast': fast, 'slow': slow, 'signal': signal_period},
300
+ 'current_values': {
301
+ 'macd_line': round(macd_line, 4),
302
+ 'signal_line': round(signal_line, 4),
303
+ 'histogram': round(histogram, 4)
304
+ },
305
+ 'signal': sig,
306
+ 'interpretation': f'MACD {"above" if histogram > 0 else "below"} signal line, {sig} momentum'
307
+ }
308
+
309
+ elif indicator == 'bb':
310
+ upper, middle, lower = bollinger_bands(closes, period, std_dev)
311
+ if upper is not None:
312
+ bandwidth = (upper - lower) / middle
313
+ if current_price > upper:
314
+ position = 'above_upper'
315
+ elif current_price < lower:
316
+ position = 'below_lower'
317
+ else:
318
+ position = 'middle'
319
+ result = {
320
+ 'indicator': 'bb',
321
+ 'period': period,
322
+ 'std': std_dev,
323
+ 'current_values': {
324
+ 'upper': round(upper, 2),
325
+ 'middle': round(middle, 2),
326
+ 'lower': round(lower, 2),
327
+ 'current_price': round(current_price, 2)
328
+ },
329
+ 'position': position,
330
+ 'bandwidth': round(bandwidth, 4)
331
+ }
332
+
333
+ elif indicator == 'atr':
334
+ value = atr(highs, lows, closes, period)
335
+ if value is not None:
336
+ atr_pct = (value / current_price) * 100
337
+ result = {
338
+ 'indicator': 'atr',
339
+ 'period': period,
340
+ 'current_value': round(value, 4),
341
+ 'current_price': round(current_price, 2),
342
+ 'atr_percent': round(atr_pct, 2),
343
+ 'interpretation': f'ATR of {round(value, 4)} ({round(atr_pct, 2)}% of price) indicates {"high" if atr_pct > 3 else "normal"} volatility'
344
+ }
345
+
346
+ else:
347
+ result = {'error': f'Unknown indicator: {indicator}'}
348
+
349
+ result['connector'] = '$CONNECTOR'
350
+ result['trading_pair'] = '$TRADING_PAIR'
351
+ result['interval'] = '$INTERVAL'
352
+ result['candles_used'] = len(closes)
353
+
354
+ print(json.dumps(result, indent=2))
355
+ PYTHON_SCRIPT
356
+ }
357
+
358
+ # Run calculation
359
+ calculate_with_python