# A축 13편 hummingbot — 실행 기록

- 일시: 2026-09-22 01:46 ~ 02:16 (KST)
- 환경: macOS 26.6.2 · arm64 · uv 0.10.12 · CPython 3.12.13
- 설치: PyPI 휠 `hummingbot 20260920` (cp312 macOS arm64) · 전용 venv `/private/tmp/tut-venvs/hummingbot`
- 거래소: **공개 시세만.** API 키 없음, 거래소 계정 없음, 실주문 0건
- weltiq: 슬롯 2개를 순서대로 1개씩만 썼고 둘 다 **정지·삭제 완료**

## 1. 저장소 사실 (2026-09-22 확인)

GitHub API `/repos/hummingbot/hummingbot`:

| 항목 | 값 |
|---|---|
| 별 | 20,124 · 포크 4,948 · 열린 이슈 166 |
| 라이선스 | Apache-2.0 |
| 마지막 푸시 | 2026-09-20T12:13:41Z |
| 개설 | 2019-04-02 · 아카이브 아님 |
| PyPI | `hummingbot` 20260920 · `requires_python >=3.10.12` |
| hbot 버전 | `hbot dev-2.17.0` |

커넥터 수(`AllConnectorSettings.get_connector_settings()`): **63** — Exchange 33 · Derivative 30.
V1 전략 9개(`STRATEGIES`), V2 스크립트 17개(`scripts/`), V2 컨트롤러 market_making 3 · directional_trading 7 · generic 11(+예제 8).

## 2. 설치 실측

콜드 캐시(`--no-cache`) 2회:

```
Resolved 139 packages in 9.65s / Prepared 138 packages in 19.44s / Installed 139 packages in 183ms
Resolved 139 packages in 4.35s / Prepared 138 packages in  5.03s / Installed 139 packages in 254ms
```

워밍 캐시 재설치 11.19초(wall). 설치 패키지 139개.

## 3. 실행 회차 (전부 `binance_paper_trade` · SOL-USDT · `pure_market_making`)

| 회차 | 설정 | 시작~끝 | 체결 | 비고 |
|---|---|---|---|---|
| A | spread 0.5% · refresh 30s | 01:48:06~01:52:42 | **0** | 주문 생성 18 · 취소 16 |
| B | spread 0.01% · refresh 15s | 01:52:47~01:57:43 | 7 | 첫 체결 01:52:54 (기동 7초 뒤) |
| B' | 〃 (kill -9 뒤 재기동) | 01:57:52~01:59:01 | 1 | **지갑이 초기값으로 리셋** |
| C | kill_switch_rate −0.05 | 01:59:05~02:02:38 | 4 | 미발동 |
| D | kill_switch_rate −0.001 | 02:02:39~02:05:07 | 4 | 미발동 |
| E | kill_switch_rate −0.0001 | 02:05:08~02:08:21 | 1 | **02:05:22 발동** |
| F | spread 0.05% · refresh 30s | 02:10:12~02:15:41 | 3 | 캡처용 |

누적(`hbot history`, `TradeFill` 22행과 일치):

```
| binance_PaperTrade | SOL-USDT | 22 | buys 11 | sells 11 | base_vol 0 |
| trade_pnl -1.26844 | fees 1.29339 | total_pnl -2.56183 |
```

## 4. S8 — kill -9 뒤 잔고 리셋 (검산)

```
죽이기 직전 01:57:42   SOL 98.499     USDT 100176.2895
kill -9 01:57:43 → 재기동 01:57:52
01:57:57 매수 체결      0.5 SOL @ 117.6632 (수수료 0.1%, base 차감)
재기동 뒤  01:58:12     SOL 100.4995   USDT 99941.1684
```

검산: `100 + 0.4995 = 100.4995`, `100000 − 0.5 × 117.6632 = 99941.1684`.
→ 페이퍼 지갑이 `paper_trade_account_balance` 기본값(SOL 100 / USDT 100000)에서 다시 시작했다.
반면 `TradeFill` 기록은 그대로 남아 `hbot history` 의 거래 수는 7 → 8 로 이어졌다.

## 5. S7 — kill switch 발동 로그

```
2026-09-22 02:05:22,051 - hummingbot.core.utils.kill_switch - INFO - Kill switch threshold reached. Stopping the bot...
[Kill switch triggered]
Current profitability is -0.000001088316352160199703679330308. Stopping the bot...
Strategy stopped successfully
```

임계값은 `kill_switch_rate / 100`. −0.0001 → −0.000001. 실측 수익률 −0.00000108831… 이 이를 뚫었다.
−0.05·−0.001 에서 안 걸린 이유: 분모가 **포트폴리오 전체 평가액**(SOL 100 + USDT 100000 ≈ 111,700 USDT)이라
손실 1~2 USDT 는 −1e-5 언저리밖에 안 된다.

발동 뒤 `hbot status` 는 `state: running` 을 유지했고(uptime 186s) Markets/Assets/Orders 표만 사라졌다.
로그는 02:05:22 에서 멈췄다(더 이상 호가 갱신 없음).

## 6. S1 — 캔들 피드 (키 없음)

`candles_probe.py` — `CandlesFactory` 로 binance BTC-USDT 1d 90개, **3.406초**.
결과 `hb-btc-1d.csv`.

마지막 행 `timestamp 1789948800` = 2026-09-21 00:00 UTC 로 **아직 안 끝난 봉**(close 85987.32).

## 7. 봉 대조 (hummingbot ↔ weltiq)

`hb-btc-1d.csv` × `wq-btc-1d.json`(`GET /v1/bars?venue=binance-spot&symbol=BTCUSDT&tf=1d&hours=720`, 30개).

```
겹치는 일봉 30개 중 OHLC 네 값 모두 일치 30 · 다름 0
2026-08-23T09:00+09:00  hb(2026-08-22) o=78338.03 c=77074.93 | wq o=78338.03 c=77074.93 → 일치
2026-09-20T09:00+09:00  hb(2026-09-19) o=80883.86 c=81249.99 | wq o=80883.86 c=81249.99 → 일치
2026-09-21T09:00+09:00  hb(2026-09-20) o=81249.99 c=81178.00 | wq o=81249.99 c=81178.00 → 일치
hb 마지막 봉(2026-09-21 UTC, 미완성) close 85987.32 — weltiq 에는 없음
```

라벨 규약: hummingbot = 봉 **시작** 시각(UTC), weltiq = 봉 **마감** 시각(요청 시간대).

## 8. weltiq 슬롯 2개

| 슬롯 | 심볼 | 결과 |
|---|---|---|
| `ct_0b378584c0606064` a13-hummingbot-sol | SOLUSDT 1m | **엔진 미부착**(`engine_unavailable`, 빨강). 02:09:05~02:14:13 내내 빨강 |
| `ct_a98aae90e98c1517` a13-hummingbot-btc | BTCUSDT 1m | 40초 안에 `attached`·초록(`no_signal` 정상 대기). 02:14:19~02:15:55 |

원인 확인:

```
BTCUSDT 1m bars(최근 1h) = 60
SOLUSDT 1m bars(최근 1h) = 0
ETHUSDT 1m bars(최근 1h) = 0
```

→ 현재 binance-spot **1m 수집이 BTCUSDT 에만 있다.** 1m 슬롯을 다른 심볼로 만들면 엔진이 붙지 않는다.
(일봉은 SOLUSDT 도 30개 정상.) — **제품 과제**

둘 다 `POST /stop` → `DELETE` 완료. 증적 `weltiq/`.

## 8b. 대시보드 (`hummingbot/dashboard`)

- 저장소: ★367 · Apache-2.0 · **마지막 푸시 2025-10-27** (본체는 2026-09-20 — 약 1년 차)
- 설치: 전용 venv `/private/tmp/tut-venvs/hbdash`, `environment_conda.yml` 의 pip 목록 그대로 → **176 패키지**, Streamlit **1.64.0**
- 기동: `python -m streamlit run main.py --server.headless true --server.port 9040 --server.address 127.0.0.1`
  (기본 포트는 8501. 이 글은 9040 사용 — 작업 뒤 프로세스 종료·포트 반납 확인)
- 로그인: `AUTH_SYSTEM_ENABLED` 기본 false → 로그인 없이 열림. 켜면 `credentials.yml` 의 `admin`/`abc` 가 기본
- 거래소 키: 불필요 (`paper_trade` 경계 동일)

관측:

| 화면 | 결과 |
|---|---|
| 첫 화면 (Hummingbot Dashboard) | **뜹니다.** 단 화면 안에 `Demo Data Notice: ... simulated/mocked data` 경고가 있고 `Active Bots 3` · `$12,847` · `74.2%` · `1,247` 은 전부 예시 값 |
| Config Generator → PMM Simple | `Failed to initialize API client: 404, message='Not Found', url='http://127.0.0.1:8000/docker/running'` |
| Data → Download Candles | 동일 오류 |

원인: 대시보드는 백엔드 `hummingbot/hummingbot-api`(8000번)의 프런트이고, 그 백엔드는 도커로 봇 컨테이너를 관리한다.
우회: 도커가 되면 `hummingbot/deploy` 로 한 번에, 백엔드 포트가 다르면 `BACKEND_API_PORT`, 아니면 `hbot` CLI.

주의: 위 404 는 이 컴퓨터에서 8000번을 **무관한 다른 프로세스**가 점유 중이라 나온 응답이다.
아무것도 없으면 연결 거부로 나온다 — 뜻은 같다(백엔드 없음).

기동 로그: `dashboard-server.log`.

## 9. 그 밖에 관측된 것

- **`appnope` 미선언** — 휠로 설치하면 graceful stop 때 `ModuleNotFoundError: No module named 'appnope'` 가
  ERROR 로 찍힌다. 주문 취소·종료 자체는 그 뒤에 정상 수행됐다.
- **휠의 루트 경로** — `hummingbot.root_path()` 가 패키지 설치 위치를 가리켜 `conf/ logs/ data/ scripts/ controllers/` 를
  site-packages 밑에서 찾는다. 이 글에서는 작업 폴더를 그 자리에 심볼릭 링크로 걸어 우회했다.
- **`bin/hbot` 이 휠에 없다** — `hbot_run.py`(3줄) 로 `hummingbot.cli.main:main` 을 직접 불렀다.
- 페이퍼 체결 이벤트의 `event_source` 가 `None_PaperTrade`, 주문 id 가 `buy://SOL-USDT/<hex>` 형식.
- 페이퍼 수수료는 `trade_fee.percent = 0.001` (0.1%), base 자산에서 차감.

## 파일

```
shots/            01-install · 02-strategy-config · 03-paper-quoting · 04-fills-history
                  05-killswitch · 06-dashboard-landing · 07-dashboard-needs-backend
                  08-side-hummingbot · 09-weltiq-btc-green · 10-weltiq-sol-red
shots-src/        캡처에 렌더한 터미널 출력 원문(.txt)
logs/             runA~runF 실행 로그
weltiq/           슬롯 생성·정지·내보내기 응답
conf_pmm_tut13.yml / conf_client.yml / hbot_run.py / candles_probe.py
hb-btc-1d.csv / wq-btc-1d.json / hummingbot-trades.sqlite
```

## 2026-09-24 v2 재편 때 본문에서 내린 것

독자판(≤3,000어절)으로 재편하면서 본문에서 뺀 것. **숫자·명령·실패 기록은 버리지 않았다.**

### 4절 시나리오별 3줄 요약 (S1·S5·S6·S7·S8·D)

표 한 줄로 합쳤다. 빠진 「몇 단계였나」만 여기 남긴다 —
S1 한 단계(`CandlesFactory` 만들고 `ready` 대기) · S5 두 단계(스프레드 좁히기·재기동) ·
S6 다섯 단계(테두리 → 주문 → 기록 → `--set` 수정 → 재확인) · S7 세 단계(설정 한 줄·재기동·10초 주기 감시,
코드상 `_update_interval = 10.0`) · S8 두 단계(죽이기·다시 띄우기) · D 명령 하나(`hbot history`).

### 본문에서 뺀 원문 출력

- **S1 캔들 앞뒤 줄** — `rows: 90`, 첫 두 줄 `1782259200.0 62734.57 63239.06 59102.70 61077.99 30678.28543` ·
  `1782345600.0 61078.00 61962.40 58115.01 59794.00 30386.00694`, 끝 세 줄 중 마지막
  `1789948800.0 81178.01 86344.70 80850.22 85987.32 26265.99601`(= **2026-09-21 00:00 UTC, 미완성 봉**). `real 3.406`
- **S5 체결 원문** — `{"order_id":"sell://SOL-USDT/2222ae69cf751126bb7fa37158","trade_type":"TradeType.SELL",`
  `"order_type":"OrderType.LIMIT","price":"117.6368000000","amount":"0.5000000",`
  `"trade_fee":{"percent":"0.001","percent_token":null,"flat_fees":[]},`
  `"exchange_trade_id":"1790009574511919","exchange_order_id":"","event_source":"None_PaperTrade"}`
- **3절 호가 갱신 사이클 로그** — `01:48:09 Creating 1 bid orders at ['0.5 SOL, 117.1065 USDT']` /
  `01:48:09 Creating 1 ask orders at ['0.5 SOL, 118.2835 USDT']` / `01:48:39 Canceling the limit order buy://…` /
  `01:48:40 Creating 1 bid orders at ['0.5 SOL, 117.1364 USDT']`
- **2절 `appnope` 정상 종료 로그 전문** — `ERROR - Error during graceful stop.` 뒤에
  `INFO - Strategy stopped successfully` → `OrderCancelledEvent` ×2 → `INFO - Removed connector: binance_paper_trade`
  → `INFO - Trading core shutdown complete`
- **S6 고치는 한 줄** — `hbot deploy conf_pmm_tut13.yml --set bid_spread=0.01 --set ask_spread=0.01 --set order_refresh_time=15`.
  `--set` 은 설정 파일을 **주석을 남긴 채로** 고친다
- **S7 kill switch 코드** — `hummingbot/core/utils/kill_switch.py` 의
  `self._kill_switch_rate = kill_switch_rate / Decimal(100)` 와
  `if (self._profitability <= self._kill_switch_rate < Decimal("0.0")) or …: await self._trading_core.shutdown()`
- **S8 재기동 시점 원문** — `01:57:43 killed` · `hbot status → state: stopped` ·
  `hbot start conf_pmm_tut13.yml` (01:57:52, pid 157) · `01:57:57 매수 체결 0.5 SOL @ 117.6632`

### 3절 「막히실 만한 것」에서 뺀 두 행

| 증상 | 원인 | 해결 |
|---|---|---|
| 호가가 한 건도 안 걸림 | 주문 금액이 거래소 최소 주문 금액 미만 | `order_amount` 를 올린다 |
| 봇이 두 개 안 뜸 | **설치 하나당 봇 하나**가 설계 | `--replace` 로 갈아타거나 설치를 따로 |

`No active maker orders` 가 계속 보이는 것은 갱신 주기 사이의 빈 구간일 수 있다 — 몇 초 뒤 다시 `hbot status`.

### 돌리지 않은 시나리오 (4절 목록 통째로 내림)

- **S2 한국 종목 005930** — **이 도구로는 안 된다.** 커넥터 63개가 전부 암호화폐 거래소이고 주식 경로가 없다
- **S3 내 실행 기록 복기** — 해당 없음. hummingbot 은 자기 기록을 자기 sqlite 에 갖고 있다
- **S4 여러 종목 훑기** — `scripts/screener_volatility.py` 가 들어 있어 될 것으로 보이나 **미확인**
- **S9 수수료 바꿔 다시 재기** — `conf/conf_fee_overrides.yml` 로 될 것으로 보이나 **미확인**. 다만 시나리오 D 가 보여 주듯 이 도구에서 제일 값있는 실험이 그쪽이다
- **S10** — 별도 트랙
- **`cross_exchange_market_making` · `amm_arb`** — 거래소 두 곳에 동시에 붙어야 하고 DEX 쪽은 별도 Gateway 서비스가 필요해 **미확인**

### 그 밖에 뺀 문장

- 1절 「README 는 사용자들이 140+ unique trading venues 에서 거래했다고 적고 있다 — 이건 확인한 값이 아니라 그쪽 주장」
- 1절 V1 전략 9개 이름 열거 — `pure_market_making` · `avellaneda_market_making` · `cross_exchange_market_making` ·
  `cross_exchange_mining` · `liquidity_mining` · `perpetual_market_making` · `amm_arb` · `spot_perpetual_arbitrage` · `hedge`
- 1절 README 인용문 원문 — "Then create a config and run the `simple_pmm` **paper trading script** — it simulates trading against live Binance market data, so no API keys are required"
- 5절 네 단계 그림(① 분석 ② 시스템화·장착 ③ 페이퍼 ④ 거래 분석 — hummingbot 이 ②③을 한 상자에)
- 5절 「이 편의 앞뒤 단계에서 제대로 붙는 글은 1편 alpaca-mcp-server·2편 ai-hedge-fund 이고, hummingbot 은 4편 freqtrade 와 같은 자리」
- 3절 대시보드 「막혔을 때 우회」 표의 한 행 — 백엔드가 다른 포트에 있으면
  `BACKEND_API_PORT=9041 streamlit run main.py --server.port 9040` (`BACKEND_API_HOST`·`_USERNAME`·`_PASSWORD` 도 같은 방식)
- 3절 대시보드 의존성 버전 — Streamlit **1.64.0**, 공식 안내는 `make install`(conda) 또는 도커이며 위 명령은 `environment_conda.yml` 의 pip 목록을 uv 로 옮긴 것
