@hummingbot/skills 1.0.0 → 1.0.5
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.
- package/README.md +15 -14
- package/package.json +5 -1
- package/skills/candles-feed/SKILL.md +2 -1
- package/skills/candles-feed/scripts/calculate_indicator.sh +2 -0
- package/skills/candles-feed/scripts/get_candles.sh +2 -0
- package/skills/candles-feed/scripts/get_funding_rate.sh +2 -0
- package/skills/candles-feed/scripts/get_price.sh +2 -0
- package/skills/candles-feed/scripts/list_candle_connectors.sh +2 -0
- package/skills/executor-creator/SKILL.md +48 -6
- package/skills/executor-creator/scripts/clear_position.sh +2 -0
- package/skills/executor-creator/scripts/create_executor.sh +11 -2
- package/skills/executor-creator/scripts/get_executor.sh +2 -0
- package/skills/executor-creator/scripts/get_executor_schema.sh +2 -0
- package/skills/executor-creator/scripts/get_executors_summary.sh +2 -0
- package/skills/executor-creator/scripts/get_position.sh +2 -0
- package/skills/executor-creator/scripts/get_positions.sh +2 -0
- package/skills/executor-creator/scripts/list_executor_types.sh +2 -0
- package/skills/executor-creator/scripts/list_executors.sh +2 -0
- package/skills/executor-creator/scripts/setup_executor.sh +23 -7
- package/skills/executor-creator/scripts/stop_executor.sh +2 -0
- package/skills/hummingbot-api-setup/SKILL.md +50 -258
- package/skills/hummingbot-api-setup/scripts/health_check.sh +2 -0
- package/skills/hummingbot-api-setup/{references/original_setup.sh → scripts/setup.sh} +76 -54
- package/skills/keys-manager/SKILL.md +2 -1
- package/skills/keys-manager/scripts/add_credentials.sh +2 -0
- package/skills/keys-manager/scripts/get_connector_config.sh +2 -0
- package/skills/keys-manager/scripts/list_account_credentials.sh +2 -0
- package/skills/keys-manager/scripts/list_connectors.sh +2 -0
- package/skills/keys-manager/scripts/remove_credentials.sh +2 -0
- package/skills/keys-manager/scripts/setup_connector.sh +2 -0
- package/skills/portfolio/SKILL.md +181 -0
- package/skills/portfolio/scripts/get_distribution.sh +52 -0
- package/skills/portfolio/scripts/get_history.sh +75 -0
- package/skills/portfolio/scripts/get_overview.sh +96 -0
- package/skills/portfolio/scripts/get_state.sh +96 -0
- package/skills.json +26 -6
- package/skills/hummingbot-api-setup/scripts/check_prerequisites.sh +0 -92
- package/skills/hummingbot-api-setup/scripts/deploy_full_stack.sh +0 -151
- package/skills/hummingbot-api-setup/scripts/step1_detect_system.sh +0 -88
- package/skills/hummingbot-api-setup/scripts/step2_check_dependencies.sh +0 -81
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: portfolio
|
|
3
|
+
description: View portfolio balances, positions, and history across all connected exchanges. Use this skill when the user wants to check their balance, see positions, view portfolio distribution, or track portfolio history.
|
|
4
|
+
license: Apache-2.0
|
|
5
|
+
creator-github-handle: fengtality
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# portfolio
|
|
9
|
+
|
|
10
|
+
This skill provides portfolio visibility across all connected exchanges and accounts.
|
|
11
|
+
|
|
12
|
+
## Prerequisites
|
|
13
|
+
|
|
14
|
+
- Hummingbot API server must be running
|
|
15
|
+
- Exchange credentials configured via keys-manager skill
|
|
16
|
+
|
|
17
|
+
## Quick Start
|
|
18
|
+
|
|
19
|
+
### Get Current Portfolio State
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
./scripts/get_state.sh
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Filter by specific connectors:
|
|
26
|
+
```bash
|
|
27
|
+
./scripts/get_state.sh --connector hyperliquid_perpetual
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Force refresh balances from exchange:
|
|
31
|
+
```bash
|
|
32
|
+
./scripts/get_state.sh --refresh
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### Get Portfolio Distribution
|
|
36
|
+
|
|
37
|
+
See token allocation across accounts:
|
|
38
|
+
```bash
|
|
39
|
+
./scripts/get_distribution.sh
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Get Portfolio History
|
|
43
|
+
|
|
44
|
+
View historical portfolio values:
|
|
45
|
+
```bash
|
|
46
|
+
./scripts/get_history.sh --days 7
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
With interval sampling:
|
|
50
|
+
```bash
|
|
51
|
+
./scripts/get_history.sh --days 30 --interval 1d
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### Get Full Portfolio Overview
|
|
55
|
+
|
|
56
|
+
Combined view with balances, positions, and orders:
|
|
57
|
+
```bash
|
|
58
|
+
./scripts/get_overview.sh
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Scripts
|
|
62
|
+
|
|
63
|
+
### get_state.sh
|
|
64
|
+
|
|
65
|
+
Fetches current portfolio state with token balances.
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
./scripts/get_state.sh [OPTIONS]
|
|
69
|
+
|
|
70
|
+
Options:
|
|
71
|
+
--account ACCOUNT Filter by account name (default: all)
|
|
72
|
+
--connector CONNECTOR Filter by connector name
|
|
73
|
+
--refresh Force refresh from exchange (slower but accurate)
|
|
74
|
+
--skip-gateway Skip Gateway wallets (faster for CEX-only)
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### get_distribution.sh
|
|
78
|
+
|
|
79
|
+
Shows portfolio distribution by token with percentages.
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
./scripts/get_distribution.sh [OPTIONS]
|
|
83
|
+
|
|
84
|
+
Options:
|
|
85
|
+
--account ACCOUNT Filter by account name
|
|
86
|
+
--connector CONNECTOR Filter by connector name
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### get_history.sh
|
|
90
|
+
|
|
91
|
+
Retrieves historical portfolio data with pagination.
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
./scripts/get_history.sh [OPTIONS]
|
|
95
|
+
|
|
96
|
+
Options:
|
|
97
|
+
--days DAYS Number of days of history (default: 7)
|
|
98
|
+
--interval INTERVAL Data granularity: 5m, 15m, 30m, 1h, 4h, 12h, 1d (default: 1h)
|
|
99
|
+
--account ACCOUNT Filter by account name
|
|
100
|
+
--connector CONNECTOR Filter by connector name
|
|
101
|
+
--limit LIMIT Max records to return (default: 100)
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### get_overview.sh
|
|
105
|
+
|
|
106
|
+
Comprehensive portfolio view including:
|
|
107
|
+
- Token balances
|
|
108
|
+
- Perpetual positions
|
|
109
|
+
- Active orders
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
./scripts/get_overview.sh [OPTIONS]
|
|
113
|
+
|
|
114
|
+
Options:
|
|
115
|
+
--account ACCOUNT Filter by account name
|
|
116
|
+
--connector CONNECTOR Filter by connector name
|
|
117
|
+
--no-balances Skip token balances
|
|
118
|
+
--no-positions Skip perpetual positions
|
|
119
|
+
--no-orders Skip active orders
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## Output Examples
|
|
123
|
+
|
|
124
|
+
### Portfolio State
|
|
125
|
+
```json
|
|
126
|
+
{
|
|
127
|
+
"accounts": {
|
|
128
|
+
"master_account": {
|
|
129
|
+
"hyperliquid_perpetual": {
|
|
130
|
+
"balances": {
|
|
131
|
+
"USDC": {"total": 1000.0, "available": 850.0}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
},
|
|
136
|
+
"total_value_usd": 1000.0
|
|
137
|
+
}
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### Portfolio Distribution
|
|
141
|
+
```json
|
|
142
|
+
{
|
|
143
|
+
"tokens": {
|
|
144
|
+
"USDC": {
|
|
145
|
+
"total_value": 1000.0,
|
|
146
|
+
"percentage": 100.0,
|
|
147
|
+
"accounts": ["master_account"]
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### Portfolio History
|
|
154
|
+
```json
|
|
155
|
+
{
|
|
156
|
+
"data": [
|
|
157
|
+
{"timestamp": 1706400000, "total_value": 1000.0},
|
|
158
|
+
{"timestamp": 1706486400, "total_value": 1050.0}
|
|
159
|
+
],
|
|
160
|
+
"interval": "1d",
|
|
161
|
+
"period": "7d"
|
|
162
|
+
}
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
## API Endpoints Used
|
|
166
|
+
|
|
167
|
+
| Endpoint | Method | Description |
|
|
168
|
+
|----------|--------|-------------|
|
|
169
|
+
| `/portfolio/state` | POST | Get current portfolio state |
|
|
170
|
+
| `/portfolio/distribution` | POST | Get token distribution |
|
|
171
|
+
| `/portfolio/history` | POST | Get historical data |
|
|
172
|
+
| `/trading/{account}/{connector}/orders` | GET | Get active orders |
|
|
173
|
+
| `/trading/{account}/{connector}/positions` | GET | Get perpetual positions |
|
|
174
|
+
|
|
175
|
+
## Environment Variables
|
|
176
|
+
|
|
177
|
+
| Variable | Default | Description |
|
|
178
|
+
|----------|---------|-------------|
|
|
179
|
+
| `API_URL` | `http://localhost:8000` | API base URL |
|
|
180
|
+
| `API_USER` | `admin` | API username |
|
|
181
|
+
| `API_PASS` | `admin` | API password |
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Get portfolio distribution by token
|
|
3
|
+
# Usage: ./get_distribution.sh [--account NAME] [--connector NAME]
|
|
4
|
+
|
|
5
|
+
set -e
|
|
6
|
+
|
|
7
|
+
# Load .env if present (check current dir, ~/.hummingbot/, ~/)
|
|
8
|
+
for f in .env ~/.hummingbot/.env ~/.env; do [ -f "$f" ] && source "$f" && break; done
|
|
9
|
+
API_URL="${API_URL:-http://localhost:8000}"
|
|
10
|
+
API_USER="${API_USER:-admin}"
|
|
11
|
+
API_PASS="${API_PASS:-admin}"
|
|
12
|
+
|
|
13
|
+
ACCOUNT=""
|
|
14
|
+
CONNECTOR=""
|
|
15
|
+
|
|
16
|
+
# Parse arguments
|
|
17
|
+
while [[ $# -gt 0 ]]; do
|
|
18
|
+
case $1 in
|
|
19
|
+
--account) ACCOUNT="$2"; shift 2 ;;
|
|
20
|
+
--connector) CONNECTOR="$2"; shift 2 ;;
|
|
21
|
+
--api-url) API_URL="$2"; shift 2 ;;
|
|
22
|
+
--api-user) API_USER="$2"; shift 2 ;;
|
|
23
|
+
--api-pass) API_PASS="$2"; shift 2 ;;
|
|
24
|
+
*) shift ;;
|
|
25
|
+
esac
|
|
26
|
+
done
|
|
27
|
+
|
|
28
|
+
# Build request body
|
|
29
|
+
REQUEST='{}'
|
|
30
|
+
|
|
31
|
+
if [ -n "$ACCOUNT" ]; then
|
|
32
|
+
REQUEST=$(echo "$REQUEST" | jq --arg acc "$ACCOUNT" '. + {account_names: [$acc]}')
|
|
33
|
+
fi
|
|
34
|
+
|
|
35
|
+
if [ -n "$CONNECTOR" ]; then
|
|
36
|
+
REQUEST=$(echo "$REQUEST" | jq --arg conn "$CONNECTOR" '. + {connector_names: [$conn]}')
|
|
37
|
+
fi
|
|
38
|
+
|
|
39
|
+
# Fetch distribution
|
|
40
|
+
RESPONSE=$(curl -s -X POST \
|
|
41
|
+
-u "$API_USER:$API_PASS" \
|
|
42
|
+
-H "Content-Type: application/json" \
|
|
43
|
+
-d "$REQUEST" \
|
|
44
|
+
"$API_URL/portfolio/distribution")
|
|
45
|
+
|
|
46
|
+
# Check for error
|
|
47
|
+
if echo "$RESPONSE" | jq -e '.detail' > /dev/null 2>&1; then
|
|
48
|
+
echo "{\"error\": \"Failed to get portfolio distribution\", \"detail\": $RESPONSE}"
|
|
49
|
+
exit 1
|
|
50
|
+
fi
|
|
51
|
+
|
|
52
|
+
echo "$RESPONSE" | jq '.'
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Get portfolio history with interval sampling
|
|
3
|
+
# Usage: ./get_history.sh [--days N] [--interval 1h] [--account NAME] [--connector NAME]
|
|
4
|
+
|
|
5
|
+
set -e
|
|
6
|
+
|
|
7
|
+
# Load .env if present (check current dir, ~/.hummingbot/, ~/)
|
|
8
|
+
for f in .env ~/.hummingbot/.env ~/.env; do [ -f "$f" ] && source "$f" && break; done
|
|
9
|
+
API_URL="${API_URL:-http://localhost:8000}"
|
|
10
|
+
API_USER="${API_USER:-admin}"
|
|
11
|
+
API_PASS="${API_PASS:-admin}"
|
|
12
|
+
|
|
13
|
+
DAYS=7
|
|
14
|
+
INTERVAL="1h"
|
|
15
|
+
ACCOUNT=""
|
|
16
|
+
CONNECTOR=""
|
|
17
|
+
LIMIT=100
|
|
18
|
+
|
|
19
|
+
# Parse arguments
|
|
20
|
+
while [[ $# -gt 0 ]]; do
|
|
21
|
+
case $1 in
|
|
22
|
+
--days) DAYS="$2"; shift 2 ;;
|
|
23
|
+
--interval) INTERVAL="$2"; shift 2 ;;
|
|
24
|
+
--account) ACCOUNT="$2"; shift 2 ;;
|
|
25
|
+
--connector) CONNECTOR="$2"; shift 2 ;;
|
|
26
|
+
--limit) LIMIT="$2"; shift 2 ;;
|
|
27
|
+
--api-url) API_URL="$2"; shift 2 ;;
|
|
28
|
+
--api-user) API_USER="$2"; shift 2 ;;
|
|
29
|
+
--api-pass) API_PASS="$2"; shift 2 ;;
|
|
30
|
+
*) shift ;;
|
|
31
|
+
esac
|
|
32
|
+
done
|
|
33
|
+
|
|
34
|
+
# Calculate start_time (N days ago in seconds)
|
|
35
|
+
START_TIME=$(($(date +%s) - (DAYS * 86400)))
|
|
36
|
+
|
|
37
|
+
# Build request body
|
|
38
|
+
REQUEST=$(jq -n \
|
|
39
|
+
--argjson start_time "$START_TIME" \
|
|
40
|
+
--arg interval "$INTERVAL" \
|
|
41
|
+
--argjson limit "$LIMIT" \
|
|
42
|
+
'{start_time: $start_time, interval: $interval, limit: $limit}')
|
|
43
|
+
|
|
44
|
+
if [ -n "$ACCOUNT" ]; then
|
|
45
|
+
REQUEST=$(echo "$REQUEST" | jq --arg acc "$ACCOUNT" '. + {account_names: [$acc]}')
|
|
46
|
+
fi
|
|
47
|
+
|
|
48
|
+
if [ -n "$CONNECTOR" ]; then
|
|
49
|
+
REQUEST=$(echo "$REQUEST" | jq --arg conn "$CONNECTOR" '. + {connector_names: [$conn]}')
|
|
50
|
+
fi
|
|
51
|
+
|
|
52
|
+
# Fetch history
|
|
53
|
+
RESPONSE=$(curl -s -X POST \
|
|
54
|
+
-u "$API_USER:$API_PASS" \
|
|
55
|
+
-H "Content-Type: application/json" \
|
|
56
|
+
-d "$REQUEST" \
|
|
57
|
+
"$API_URL/portfolio/history")
|
|
58
|
+
|
|
59
|
+
# Check for error
|
|
60
|
+
if echo "$RESPONSE" | jq -e '.detail' > /dev/null 2>&1; then
|
|
61
|
+
echo "{\"error\": \"Failed to get portfolio history\", \"detail\": $RESPONSE}"
|
|
62
|
+
exit 1
|
|
63
|
+
fi
|
|
64
|
+
|
|
65
|
+
# Add query metadata
|
|
66
|
+
cat << EOF
|
|
67
|
+
{
|
|
68
|
+
"query": {
|
|
69
|
+
"days": $DAYS,
|
|
70
|
+
"interval": "$INTERVAL",
|
|
71
|
+
"start_time": $START_TIME
|
|
72
|
+
},
|
|
73
|
+
"response": $RESPONSE
|
|
74
|
+
}
|
|
75
|
+
EOF
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Get comprehensive portfolio overview with balances, positions, and orders
|
|
3
|
+
# Usage: ./get_overview.sh [--account NAME] [--connector NAME] [--no-balances] [--no-positions] [--no-orders]
|
|
4
|
+
|
|
5
|
+
set -e
|
|
6
|
+
|
|
7
|
+
# Load .env if present (check current dir, ~/.hummingbot/, ~/)
|
|
8
|
+
for f in .env ~/.hummingbot/.env ~/.env; do [ -f "$f" ] && source "$f" && break; done
|
|
9
|
+
API_URL="${API_URL:-http://localhost:8000}"
|
|
10
|
+
API_USER="${API_USER:-admin}"
|
|
11
|
+
API_PASS="${API_PASS:-admin}"
|
|
12
|
+
|
|
13
|
+
ACCOUNT=""
|
|
14
|
+
CONNECTOR=""
|
|
15
|
+
INCLUDE_BALANCES=true
|
|
16
|
+
INCLUDE_POSITIONS=true
|
|
17
|
+
INCLUDE_ORDERS=true
|
|
18
|
+
|
|
19
|
+
# Parse arguments
|
|
20
|
+
while [[ $# -gt 0 ]]; do
|
|
21
|
+
case $1 in
|
|
22
|
+
--account) ACCOUNT="$2"; shift 2 ;;
|
|
23
|
+
--connector) CONNECTOR="$2"; shift 2 ;;
|
|
24
|
+
--no-balances) INCLUDE_BALANCES=false; shift ;;
|
|
25
|
+
--no-positions) INCLUDE_POSITIONS=false; shift ;;
|
|
26
|
+
--no-orders) INCLUDE_ORDERS=false; shift ;;
|
|
27
|
+
--api-url) API_URL="$2"; shift 2 ;;
|
|
28
|
+
--api-user) API_USER="$2"; shift 2 ;;
|
|
29
|
+
--api-pass) API_PASS="$2"; shift 2 ;;
|
|
30
|
+
*) shift ;;
|
|
31
|
+
esac
|
|
32
|
+
done
|
|
33
|
+
|
|
34
|
+
# Build filter request
|
|
35
|
+
FILTER_REQUEST='{}'
|
|
36
|
+
if [ -n "$ACCOUNT" ]; then
|
|
37
|
+
FILTER_REQUEST=$(echo "$FILTER_REQUEST" | jq --arg acc "$ACCOUNT" '. + {account_names: [$acc]}')
|
|
38
|
+
fi
|
|
39
|
+
if [ -n "$CONNECTOR" ]; then
|
|
40
|
+
FILTER_REQUEST=$(echo "$FILTER_REQUEST" | jq --arg conn "$CONNECTOR" '. + {connector_names: [$conn]}')
|
|
41
|
+
fi
|
|
42
|
+
|
|
43
|
+
# Initialize results
|
|
44
|
+
BALANCES="{}"
|
|
45
|
+
POSITIONS="[]"
|
|
46
|
+
ORDERS="[]"
|
|
47
|
+
|
|
48
|
+
# Fetch balances
|
|
49
|
+
if [ "$INCLUDE_BALANCES" = true ]; then
|
|
50
|
+
BALANCES=$(curl -s -X POST \
|
|
51
|
+
-u "$API_USER:$API_PASS" \
|
|
52
|
+
-H "Content-Type: application/json" \
|
|
53
|
+
-d "$FILTER_REQUEST" \
|
|
54
|
+
"$API_URL/portfolio/state" 2>/dev/null || echo '{}')
|
|
55
|
+
fi
|
|
56
|
+
|
|
57
|
+
# Fetch positions (for perpetual connectors)
|
|
58
|
+
if [ "$INCLUDE_POSITIONS" = true ]; then
|
|
59
|
+
# Get positions from executors endpoint
|
|
60
|
+
POSITIONS=$(curl -s -X GET \
|
|
61
|
+
-u "$API_USER:$API_PASS" \
|
|
62
|
+
"$API_URL/executors/positions/summary" 2>/dev/null || echo '[]')
|
|
63
|
+
fi
|
|
64
|
+
|
|
65
|
+
# Fetch active orders
|
|
66
|
+
if [ "$INCLUDE_ORDERS" = true ]; then
|
|
67
|
+
# Search for active orders
|
|
68
|
+
ORDER_REQUEST='{"status": ["OPEN", "PENDING"], "limit": 50}'
|
|
69
|
+
ORDERS=$(curl -s -X POST \
|
|
70
|
+
-u "$API_USER:$API_PASS" \
|
|
71
|
+
-H "Content-Type: application/json" \
|
|
72
|
+
-d "$ORDER_REQUEST" \
|
|
73
|
+
"$API_URL/trading/search-orders/" 2>/dev/null || echo '{"data": []}')
|
|
74
|
+
ORDERS=$(echo "$ORDERS" | jq '.data // []')
|
|
75
|
+
fi
|
|
76
|
+
|
|
77
|
+
# Build overview response
|
|
78
|
+
cat << EOF
|
|
79
|
+
{
|
|
80
|
+
"overview": {
|
|
81
|
+
"timestamp": $(date +%s),
|
|
82
|
+
"filters": {
|
|
83
|
+
"account": $([ -n "$ACCOUNT" ] && echo "\"$ACCOUNT\"" || echo "null"),
|
|
84
|
+
"connector": $([ -n "$CONNECTOR" ] && echo "\"$CONNECTOR\"" || echo "null")
|
|
85
|
+
}
|
|
86
|
+
},
|
|
87
|
+
"balances": $BALANCES,
|
|
88
|
+
"positions": $POSITIONS,
|
|
89
|
+
"active_orders": $ORDERS,
|
|
90
|
+
"summary": {
|
|
91
|
+
"has_balances": $([ "$BALANCES" != "{}" ] && echo "true" || echo "false"),
|
|
92
|
+
"position_count": $(echo "$POSITIONS" | jq 'if type == "array" then length else 0 end'),
|
|
93
|
+
"order_count": $(echo "$ORDERS" | jq 'if type == "array" then length else 0 end')
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
EOF
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Get current portfolio state with balances
|
|
3
|
+
# Usage: ./get_state.sh [--account NAME] [--connector NAME] [--refresh] [--skip-gateway]
|
|
4
|
+
|
|
5
|
+
set -e
|
|
6
|
+
|
|
7
|
+
# Load .env if present (check current dir, ~/.hummingbot/, ~/)
|
|
8
|
+
for f in .env ~/.hummingbot/.env ~/.env; do [ -f "$f" ] && source "$f" && break; done
|
|
9
|
+
API_URL="${API_URL:-http://localhost:8000}"
|
|
10
|
+
API_USER="${API_USER:-admin}"
|
|
11
|
+
API_PASS="${API_PASS:-admin}"
|
|
12
|
+
|
|
13
|
+
ACCOUNT=""
|
|
14
|
+
CONNECTOR=""
|
|
15
|
+
REFRESH="false"
|
|
16
|
+
SKIP_GATEWAY="false"
|
|
17
|
+
|
|
18
|
+
# Parse arguments
|
|
19
|
+
while [[ $# -gt 0 ]]; do
|
|
20
|
+
case $1 in
|
|
21
|
+
--account) ACCOUNT="$2"; shift 2 ;;
|
|
22
|
+
--connector) CONNECTOR="$2"; shift 2 ;;
|
|
23
|
+
--refresh) REFRESH="true"; shift ;;
|
|
24
|
+
--skip-gateway) SKIP_GATEWAY="true"; shift ;;
|
|
25
|
+
--api-url) API_URL="$2"; shift 2 ;;
|
|
26
|
+
--api-user) API_USER="$2"; shift 2 ;;
|
|
27
|
+
--api-pass) API_PASS="$2"; shift 2 ;;
|
|
28
|
+
*) shift ;;
|
|
29
|
+
esac
|
|
30
|
+
done
|
|
31
|
+
|
|
32
|
+
# Build request body
|
|
33
|
+
REQUEST=$(jq -n \
|
|
34
|
+
--argjson refresh "$REFRESH" \
|
|
35
|
+
--argjson skip_gateway "$SKIP_GATEWAY" \
|
|
36
|
+
'{refresh: $refresh, skip_gateway: $skip_gateway}')
|
|
37
|
+
|
|
38
|
+
# Add optional filters
|
|
39
|
+
if [ -n "$ACCOUNT" ]; then
|
|
40
|
+
REQUEST=$(echo "$REQUEST" | jq --arg acc "$ACCOUNT" '. + {account_names: [$acc]}')
|
|
41
|
+
fi
|
|
42
|
+
|
|
43
|
+
if [ -n "$CONNECTOR" ]; then
|
|
44
|
+
REQUEST=$(echo "$REQUEST" | jq --arg conn "$CONNECTOR" '. + {connector_names: [$conn]}')
|
|
45
|
+
fi
|
|
46
|
+
|
|
47
|
+
# Fetch portfolio state
|
|
48
|
+
RESPONSE=$(curl -s -X POST \
|
|
49
|
+
-u "$API_USER:$API_PASS" \
|
|
50
|
+
-H "Content-Type: application/json" \
|
|
51
|
+
-d "$REQUEST" \
|
|
52
|
+
"$API_URL/portfolio/state")
|
|
53
|
+
|
|
54
|
+
# Check for error
|
|
55
|
+
if echo "$RESPONSE" | jq -e '.detail' > /dev/null 2>&1; then
|
|
56
|
+
echo "{\"error\": \"Failed to get portfolio state\", \"detail\": $RESPONSE}"
|
|
57
|
+
exit 1
|
|
58
|
+
fi
|
|
59
|
+
|
|
60
|
+
# Calculate total value from response
|
|
61
|
+
# Response format: {account: {connector: [{token, units, price, value, available_units}]}}
|
|
62
|
+
TOTAL_VALUE=$(echo "$RESPONSE" | jq '[.. | objects | .value? // 0 | select(. != null and . != 0)] | add // 0')
|
|
63
|
+
|
|
64
|
+
# Format balances for easy reading
|
|
65
|
+
BALANCES=$(echo "$RESPONSE" | jq '
|
|
66
|
+
[to_entries[] |
|
|
67
|
+
{
|
|
68
|
+
account: .key,
|
|
69
|
+
connectors: [.value | to_entries[] |
|
|
70
|
+
{
|
|
71
|
+
connector: .key,
|
|
72
|
+
tokens: [.value[] |
|
|
73
|
+
{
|
|
74
|
+
token: .token,
|
|
75
|
+
units: .units,
|
|
76
|
+
available: .available_units,
|
|
77
|
+
price: .price,
|
|
78
|
+
value: .value
|
|
79
|
+
}
|
|
80
|
+
] | sort_by(-.value)
|
|
81
|
+
}
|
|
82
|
+
]
|
|
83
|
+
}
|
|
84
|
+
]
|
|
85
|
+
')
|
|
86
|
+
|
|
87
|
+
cat << EOF
|
|
88
|
+
{
|
|
89
|
+
"portfolio_state": $RESPONSE,
|
|
90
|
+
"summary": {
|
|
91
|
+
"total_value_usd": $TOTAL_VALUE,
|
|
92
|
+
"accounts": $(echo "$RESPONSE" | jq 'keys')
|
|
93
|
+
},
|
|
94
|
+
"balances": $BALANCES
|
|
95
|
+
}
|
|
96
|
+
EOF
|
package/skills.json
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
{
|
|
9
9
|
"id": "hummingbot-api-setup",
|
|
10
10
|
"name": "hummingbot-api-setup",
|
|
11
|
-
"description": "Deploy Hummingbot
|
|
11
|
+
"description": "Deploy Hummingbot API infrastructure",
|
|
12
12
|
"category": "infrastructure",
|
|
13
13
|
"triggers": ["install hummingbot", "setup trading", "deploy api", "docker setup"],
|
|
14
14
|
"path": "skills/hummingbot-api-setup",
|
|
@@ -18,12 +18,13 @@
|
|
|
18
18
|
"by_agent": {}
|
|
19
19
|
},
|
|
20
20
|
"first_seen": "2026-01-26T00:00:00Z",
|
|
21
|
-
"status": "active"
|
|
21
|
+
"status": "active",
|
|
22
|
+
"creatorGithubHandle": "david-hummingbot"
|
|
22
23
|
},
|
|
23
24
|
{
|
|
24
25
|
"id": "keys-manager",
|
|
25
26
|
"name": "keys-manager",
|
|
26
|
-
"description": "Manage
|
|
27
|
+
"description": "Manage spot and perpetual exchange API keys",
|
|
27
28
|
"category": "configuration",
|
|
28
29
|
"triggers": ["add api key", "configure exchange", "setup binance", "add credentials"],
|
|
29
30
|
"path": "skills/keys-manager",
|
|
@@ -33,7 +34,8 @@
|
|
|
33
34
|
"by_agent": {}
|
|
34
35
|
},
|
|
35
36
|
"first_seen": "2026-01-26T00:00:00Z",
|
|
36
|
-
"status": "active"
|
|
37
|
+
"status": "active",
|
|
38
|
+
"creatorGithubHandle": "cardosofede"
|
|
37
39
|
},
|
|
38
40
|
{
|
|
39
41
|
"id": "executor-creator",
|
|
@@ -48,7 +50,8 @@
|
|
|
48
50
|
"by_agent": {}
|
|
49
51
|
},
|
|
50
52
|
"first_seen": "2026-01-26T00:00:00Z",
|
|
51
|
-
"status": "active"
|
|
53
|
+
"status": "active",
|
|
54
|
+
"creatorGithubHandle": "cardosofede"
|
|
52
55
|
},
|
|
53
56
|
{
|
|
54
57
|
"id": "candles-feed",
|
|
@@ -63,7 +66,24 @@
|
|
|
63
66
|
"by_agent": {}
|
|
64
67
|
},
|
|
65
68
|
"first_seen": "2026-01-26T00:00:00Z",
|
|
66
|
-
"status": "active"
|
|
69
|
+
"status": "active",
|
|
70
|
+
"creatorGithubHandle": "fengtality"
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
"id": "portfolio",
|
|
74
|
+
"name": "portfolio",
|
|
75
|
+
"description": "View portfolio balances, positions, and history across all connected exchanges",
|
|
76
|
+
"category": "data",
|
|
77
|
+
"triggers": ["check balance", "portfolio", "show positions", "account balance", "my balance"],
|
|
78
|
+
"path": "skills/portfolio",
|
|
79
|
+
"installs": {
|
|
80
|
+
"total": 0,
|
|
81
|
+
"weekly": 0,
|
|
82
|
+
"by_agent": {}
|
|
83
|
+
},
|
|
84
|
+
"first_seen": "2026-01-29T00:00:00Z",
|
|
85
|
+
"status": "active",
|
|
86
|
+
"creatorGithubHandle": "fengtality"
|
|
67
87
|
},
|
|
68
88
|
{
|
|
69
89
|
"id": "spot-connector-tester",
|
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
# Check prerequisites for Hummingbot deployment
|
|
3
|
-
# Returns JSON with status of each requirement
|
|
4
|
-
|
|
5
|
-
set -e
|
|
6
|
-
|
|
7
|
-
check_docker() {
|
|
8
|
-
if command -v docker &> /dev/null && docker info &> /dev/null; then
|
|
9
|
-
echo "true"
|
|
10
|
-
else
|
|
11
|
-
echo "false"
|
|
12
|
-
fi
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
check_docker_compose() {
|
|
16
|
-
if command -v docker &> /dev/null && docker compose version &> /dev/null; then
|
|
17
|
-
echo "true"
|
|
18
|
-
else
|
|
19
|
-
echo "false"
|
|
20
|
-
fi
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
check_git() {
|
|
24
|
-
if command -v git &> /dev/null; then
|
|
25
|
-
echo "true"
|
|
26
|
-
else
|
|
27
|
-
echo "false"
|
|
28
|
-
fi
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
check_port() {
|
|
32
|
-
local port=$1
|
|
33
|
-
if ! lsof -i :$port &> /dev/null; then
|
|
34
|
-
echo "true"
|
|
35
|
-
else
|
|
36
|
-
echo "false"
|
|
37
|
-
fi
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
check_disk_space() {
|
|
41
|
-
# Check for at least 5GB free space
|
|
42
|
-
local free_space=$(df -BG . | awk 'NR==2 {print $4}' | sed 's/G//')
|
|
43
|
-
if [ "$free_space" -ge 5 ]; then
|
|
44
|
-
echo "true"
|
|
45
|
-
else
|
|
46
|
-
echo "false"
|
|
47
|
-
fi
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
# Run checks
|
|
51
|
-
DOCKER_OK=$(check_docker)
|
|
52
|
-
COMPOSE_OK=$(check_docker_compose)
|
|
53
|
-
GIT_OK=$(check_git)
|
|
54
|
-
PORT_8000_OK=$(check_port 8000)
|
|
55
|
-
PORT_15672_OK=$(check_port 15672)
|
|
56
|
-
PORT_5432_OK=$(check_port 5432)
|
|
57
|
-
DISK_OK=$(check_disk_space)
|
|
58
|
-
|
|
59
|
-
# Determine overall status
|
|
60
|
-
if [ "$DOCKER_OK" = "true" ] && [ "$COMPOSE_OK" = "true" ] && [ "$GIT_OK" = "true" ] && \
|
|
61
|
-
[ "$PORT_8000_OK" = "true" ] && [ "$PORT_15672_OK" = "true" ] && [ "$PORT_5432_OK" = "true" ] && \
|
|
62
|
-
[ "$DISK_OK" = "true" ]; then
|
|
63
|
-
READY="true"
|
|
64
|
-
else
|
|
65
|
-
READY="false"
|
|
66
|
-
fi
|
|
67
|
-
|
|
68
|
-
# Output JSON
|
|
69
|
-
cat << EOF
|
|
70
|
-
{
|
|
71
|
-
"ready": $READY,
|
|
72
|
-
"checks": {
|
|
73
|
-
"docker": $DOCKER_OK,
|
|
74
|
-
"docker_compose": $COMPOSE_OK,
|
|
75
|
-
"git": $GIT_OK,
|
|
76
|
-
"port_8000_available": $PORT_8000_OK,
|
|
77
|
-
"port_15672_available": $PORT_15672_OK,
|
|
78
|
-
"port_5432_available": $PORT_5432_OK,
|
|
79
|
-
"disk_space_5gb": $DISK_OK
|
|
80
|
-
},
|
|
81
|
-
"messages": [
|
|
82
|
-
$([ "$DOCKER_OK" = "false" ] && echo '"Docker is not installed or not running",' || echo '')
|
|
83
|
-
$([ "$COMPOSE_OK" = "false" ] && echo '"Docker Compose is not available",' || echo '')
|
|
84
|
-
$([ "$GIT_OK" = "false" ] && echo '"Git is not installed",' || echo '')
|
|
85
|
-
$([ "$PORT_8000_OK" = "false" ] && echo '"Port 8000 is already in use",' || echo '')
|
|
86
|
-
$([ "$PORT_15672_OK" = "false" ] && echo '"Port 15672 is already in use",' || echo '')
|
|
87
|
-
$([ "$PORT_5432_OK" = "false" ] && echo '"Port 5432 is already in use",' || echo '')
|
|
88
|
-
$([ "$DISK_OK" = "false" ] && echo '"Less than 5GB disk space available",' || echo '')
|
|
89
|
-
$([ "$READY" = "true" ] && echo '"All prerequisites met, ready to deploy"' || echo '"Some prerequisites not met"')
|
|
90
|
-
]
|
|
91
|
-
}
|
|
92
|
-
EOF
|