trading-mcp-gateway 0.2.0-alpha.1
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/.env.example +34 -0
- package/AGENT.MD +362 -0
- package/AGENTS.md +362 -0
- package/CHANGELOG.MD +22 -0
- package/CONTRIBUTING.md +21 -0
- package/LICENSE +21 -0
- package/README.MD +420 -0
- package/SECURITY.md +36 -0
- package/dist/adapters/binance/binance-http-client.d.ts +17 -0
- package/dist/adapters/binance/binance-http-client.js +69 -0
- package/dist/adapters/binance/binance-http-client.js.map +1 -0
- package/dist/adapters/binance/binance.adapter.d.ts +14 -0
- package/dist/adapters/binance/binance.adapter.js +180 -0
- package/dist/adapters/binance/binance.adapter.js.map +1 -0
- package/dist/adapters/bybit/bybit-http-client.d.ts +33 -0
- package/dist/adapters/bybit/bybit-http-client.js +179 -0
- package/dist/adapters/bybit/bybit-http-client.js.map +1 -0
- package/dist/adapters/bybit/bybit-mapper.d.ts +22 -0
- package/dist/adapters/bybit/bybit-mapper.js +423 -0
- package/dist/adapters/bybit/bybit-mapper.js.map +1 -0
- package/dist/adapters/bybit/bybit-signer.d.ts +14 -0
- package/dist/adapters/bybit/bybit-signer.js +15 -0
- package/dist/adapters/bybit/bybit-signer.js.map +1 -0
- package/dist/adapters/bybit/bybit-types.d.ts +3231 -0
- package/dist/adapters/bybit/bybit-types.js +303 -0
- package/dist/adapters/bybit/bybit-types.js.map +1 -0
- package/dist/adapters/bybit/bybit-ws-client.d.ts +54 -0
- package/dist/adapters/bybit/bybit-ws-client.js +380 -0
- package/dist/adapters/bybit/bybit-ws-client.js.map +1 -0
- package/dist/adapters/bybit/bybit.adapter.d.ts +34 -0
- package/dist/adapters/bybit/bybit.adapter.js +206 -0
- package/dist/adapters/bybit/bybit.adapter.js.map +1 -0
- package/dist/config/env.d.ts +43 -0
- package/dist/config/env.js +102 -0
- package/dist/config/env.js.map +1 -0
- package/dist/core/account.d.ts +44 -0
- package/dist/core/account.js +2 -0
- package/dist/core/account.js.map +1 -0
- package/dist/core/active-capital.d.ts +60 -0
- package/dist/core/active-capital.js +273 -0
- package/dist/core/active-capital.js.map +1 -0
- package/dist/core/audit-logger.d.ts +26 -0
- package/dist/core/audit-logger.js +101 -0
- package/dist/core/audit-logger.js.map +1 -0
- package/dist/core/broker.d.ts +130 -0
- package/dist/core/broker.js +393 -0
- package/dist/core/broker.js.map +1 -0
- package/dist/core/errors.d.ts +37 -0
- package/dist/core/errors.js +75 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/market-order-estimator.d.ts +40 -0
- package/dist/core/market-order-estimator.js +110 -0
- package/dist/core/market-order-estimator.js.map +1 -0
- package/dist/core/market.d.ts +176 -0
- package/dist/core/market.js +26 -0
- package/dist/core/market.js.map +1 -0
- package/dist/core/order.d.ts +174 -0
- package/dist/core/order.js +119 -0
- package/dist/core/order.js.map +1 -0
- package/dist/core/position.d.ts +130 -0
- package/dist/core/position.js +88 -0
- package/dist/core/position.js.map +1 -0
- package/dist/core/risk-guard.d.ts +70 -0
- package/dist/core/risk-guard.js +331 -0
- package/dist/core/risk-guard.js.map +1 -0
- package/dist/core/strategy.d.ts +122 -0
- package/dist/core/strategy.js +298 -0
- package/dist/core/strategy.js.map +1 -0
- package/dist/core/trading-activity.d.ts +85 -0
- package/dist/core/trading-activity.js +28 -0
- package/dist/core/trading-activity.js.map +1 -0
- package/dist/core/version.d.ts +1 -0
- package/dist/core/version.js +2 -0
- package/dist/core/version.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +32 -0
- package/dist/index.js.map +1 -0
- package/dist/indicators/indicators.d.ts +88 -0
- package/dist/indicators/indicators.js +265 -0
- package/dist/indicators/indicators.js.map +1 -0
- package/dist/mcp/server.d.ts +8 -0
- package/dist/mcp/server.js +79 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/tools/account.tools.d.ts +20 -0
- package/dist/mcp/tools/account.tools.js +57 -0
- package/dist/mcp/tools/account.tools.js.map +1 -0
- package/dist/mcp/tools/broker-input.d.ts +2 -0
- package/dist/mcp/tools/broker-input.js +8 -0
- package/dist/mcp/tools/broker-input.js.map +1 -0
- package/dist/mcp/tools/indicator.tools.d.ts +219 -0
- package/dist/mcp/tools/indicator.tools.js +229 -0
- package/dist/mcp/tools/indicator.tools.js.map +1 -0
- package/dist/mcp/tools/market.tools.d.ts +107 -0
- package/dist/mcp/tools/market.tools.js +263 -0
- package/dist/mcp/tools/market.tools.js.map +1 -0
- package/dist/mcp/tools/order.tools.d.ts +656 -0
- package/dist/mcp/tools/order.tools.js +1143 -0
- package/dist/mcp/tools/order.tools.js.map +1 -0
- package/dist/mcp/tools/position.tools.d.ts +247 -0
- package/dist/mcp/tools/position.tools.js +418 -0
- package/dist/mcp/tools/position.tools.js.map +1 -0
- package/dist/mcp/tools/risk.tools.d.ts +35 -0
- package/dist/mcp/tools/risk.tools.js +256 -0
- package/dist/mcp/tools/risk.tools.js.map +1 -0
- package/dist/mcp/tools/strategy.tools.d.ts +46 -0
- package/dist/mcp/tools/strategy.tools.js +303 -0
- package/dist/mcp/tools/strategy.tools.js.map +1 -0
- package/dist/mcp/tools/system.tools.d.ts +53 -0
- package/dist/mcp/tools/system.tools.js +196 -0
- package/dist/mcp/tools/system.tools.js.map +1 -0
- package/dist/mcp/tools/trading-activity.tools.d.ts +68 -0
- package/dist/mcp/tools/trading-activity.tools.js +184 -0
- package/dist/mcp/tools/trading-activity.tools.js.map +1 -0
- package/dist/mcp/tools/ws.tools.d.ts +124 -0
- package/dist/mcp/tools/ws.tools.js +202 -0
- package/dist/mcp/tools/ws.tools.js.map +1 -0
- package/dist/utils/query-string.d.ts +3 -0
- package/dist/utils/query-string.js +8 -0
- package/dist/utils/query-string.js.map +1 -0
- package/dist/utils/redact-secret.d.ts +2 -0
- package/dist/utils/redact-secret.js +12 -0
- package/dist/utils/redact-secret.js.map +1 -0
- package/docs/00_PRODUCT_BRIEF.MD +123 -0
- package/docs/01_ARCHITECTURE.MD +300 -0
- package/docs/02_IMPLEMENTATION_GUIDE.MD +498 -0
- package/docs/03_MVP_SCOPE.MD +131 -0
- package/docs/04_ROADMAP_FINAL_GOAL.MD +155 -0
- package/docs/05_PHASE_PLAN_AND_VALIDATION.MD +163 -0
- package/docs/06_USAGE_SCENARIOS.MD +1135 -0
- package/docs/07_TEST_CASES.MD +229 -0
- package/docs/08_SECURITY_RISK_POLICY.MD +264 -0
- package/docs/09_BYBIT_ADAPTER_SPEC.MD +302 -0
- package/docs/10_RELEASE_AND_NPM_GUIDE.MD +303 -0
- package/docs/11_CONTRIBUTING_GUIDE.MD +167 -0
- package/docs/12_PHASE_QUALITY_LOOP.MD +203 -0
- package/docs/13_BTC_100USDT_WEEKLY_VALIDATION_PLAN.MD +546 -0
- package/docs/14_DERIVATIVES_OPERATION_GUIDE.MD +394 -0
- package/docs/15_UNIMPLEMENTED_TOOL_QUALITY_LOOP.MD +290 -0
- package/docs/FOLLOW_UP_ISSUES.MD +964 -0
- package/docs/MANIFEST.MD +65 -0
- package/docs/NEXT_PHASE_PROMPTS.MD +555 -0
- package/docs/PHASE_LOOP_STATUS.MD +1286 -0
- package/docs/SOURCES.MD +87 -0
- package/docs/phases/phase-00-bootstrap.MD +91 -0
- package/docs/phases/phase-01-public-market-adapter.MD +77 -0
- package/docs/phases/phase-02-private-auth-account.MD +66 -0
- package/docs/phases/phase-03-risk-order-intent.MD +74 -0
- package/docs/phases/phase-04-testnet-order-execution.MD +76 -0
- package/docs/phases/phase-05-mainnet-readiness.MD +109 -0
- package/docs/phases/phase-06-indicators.MD +60 -0
- package/docs/phases/phase-07-websocket.MD +58 -0
- package/docs/phases/phase-08-strategy-runner.MD +71 -0
- package/docs/phases/phase-09-multi-broker.MD +115 -0
- package/docs/phases/phase-10-operational-validation.MD +194 -0
- package/docs/phases/phase-11-public-package-publish.MD +100 -0
- package/docs/phases/phase-extra-active-capital-allocation.MD +427 -0
- package/docs/phases/phase-extra-binance-private-adapter.MD +86 -0
- package/docs/phases/phase-extra-broker-capability-model.MD +141 -0
- package/docs/phases/phase-extra-conditional-orders.MD +138 -0
- package/docs/phases/phase-extra-daily-usage-persistence.MD +251 -0
- package/docs/phases/phase-extra-mainnet-order-visibility.MD +197 -0
- package/docs/phases/phase-extra-market-depth.MD +174 -0
- package/docs/phases/phase-extra-market-order-safety.MD +79 -0
- package/docs/phases/phase-extra-order-amend.MD +167 -0
- package/docs/phases/phase-extra-order-history-visibility.MD +97 -0
- package/docs/phases/phase-extra-position-read-model.MD +66 -0
- package/docs/phases/phase-extra-private-order-stream.MD +71 -0
- package/docs/phases/phase-extra-strategy-market-order-safety.MD +74 -0
- package/docs/phases/phase-extra-trading-activity-history.MD +118 -0
- package/package.json +82 -0
package/.env.example
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Trading MCP Gateway example configuration.
|
|
2
|
+
# Copy values into your local MCP client env block or a local .env file.
|
|
3
|
+
# Keep API keys out of prompts, chat logs, shell history, and committed files.
|
|
4
|
+
|
|
5
|
+
TRADING_BROKER=bybit
|
|
6
|
+
TRADING_MODE=testnet
|
|
7
|
+
|
|
8
|
+
# Use keys without withdrawal permission. Public market tools work without keys.
|
|
9
|
+
BYBIT_API_KEY=your_bybit_api_key
|
|
10
|
+
BYBIT_API_SECRET=your_bybit_api_secret
|
|
11
|
+
BYBIT_RECV_WINDOW=5000
|
|
12
|
+
BYBIT_REGION=global
|
|
13
|
+
|
|
14
|
+
# Safe defaults: read-only/testnet unless explicitly changed by the user.
|
|
15
|
+
TRADING_ALLOW_ORDER=false
|
|
16
|
+
TRADING_ALLOW_LIVE=false
|
|
17
|
+
TRADING_REQUIRE_CONFIRMATION=true
|
|
18
|
+
TRADING_ALLOW_MARKET_ORDER=false
|
|
19
|
+
TRADING_ALLOW_LEVERAGE=false
|
|
20
|
+
TRADING_ALLOW_SHORT=false
|
|
21
|
+
|
|
22
|
+
# Local risk policy.
|
|
23
|
+
TRADING_ALLOWED_SYMBOLS=BTCUSDT,ETHUSDT
|
|
24
|
+
TRADING_ALLOWED_CATEGORIES=spot,linear
|
|
25
|
+
TRADING_DEFAULT_CATEGORY=linear
|
|
26
|
+
TRADING_MAX_ORDER_USDT=50
|
|
27
|
+
TRADING_MAX_ACTIVE_CAPITAL_USDT=100
|
|
28
|
+
TRADING_MAX_SINGLE_ORDER_CAPITAL_USDT=50
|
|
29
|
+
TRADING_CAPITAL_BUFFER_RATE=0.01
|
|
30
|
+
|
|
31
|
+
# Local audit logging. Audit logs must not contain raw API keys, secrets, or signatures.
|
|
32
|
+
TRADING_AUDIT_LOG=true
|
|
33
|
+
TRADING_AUDIT_LOG_DIR=~/.trading-mcp-gateway/logs
|
|
34
|
+
TRADING_LOG_LEVEL=info
|
package/AGENT.MD
ADDED
|
@@ -0,0 +1,362 @@
|
|
|
1
|
+
# AGENT.MD
|
|
2
|
+
|
|
3
|
+
이 문서는 `Trading MCP Gateway` 저장소에서 작업하는 AI Coding Agent, 인간 개발자, 리뷰어가 따라야 할 구현 규칙입니다.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 1. 프로젝트 목적
|
|
8
|
+
|
|
9
|
+
이 프로젝트는 사용자의 로컬 환경에서 실행되는 MCP 서버입니다. 서버는 사용자의 환경변수에 있는 Bybit API 인증정보를 사용해 Bybit V5 API를 호출합니다. AI Agent는 API Key/Secret을 직접 알 수 없어야 하며, MCP Tool 호출을 통해서만 거래 기능에 접근해야 합니다.
|
|
10
|
+
|
|
11
|
+
최종 목표는 다음과 같습니다.
|
|
12
|
+
|
|
13
|
+
```text
|
|
14
|
+
npx -y @your-scope/trading-mcp-gateway
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
으로 실행 가능한 로컬 Trading MCP Gateway를 제공하고, 사용자는 자신의 인증정보와 안전 정책만 설정하면 AI Agent가 로컬에서 시세 조회, 잔고 조회, 주문 검증, 테스트넷 주문, 실전 주문을 수행할 수 있게 합니다.
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## 2. 절대 원칙
|
|
22
|
+
|
|
23
|
+
### 2.1 Secret 노출 금지
|
|
24
|
+
|
|
25
|
+
절대 하지 말 것:
|
|
26
|
+
|
|
27
|
+
```text
|
|
28
|
+
- BYBIT_API_KEY / BYBIT_API_SECRET을 prompt, tool response, stdout, audit log에 그대로 기록
|
|
29
|
+
- 예외 메시지에 요청 헤더 전체 출력
|
|
30
|
+
- test fixture에 실제 API Key 저장
|
|
31
|
+
- README 예시에 실제 키처럼 보이는 값 사용
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
반드시 할 것:
|
|
35
|
+
|
|
36
|
+
```text
|
|
37
|
+
- 모든 secret은 redactSecret() 통과
|
|
38
|
+
- 로그에는 앞 4자리/뒤 4자리 정도만 표시하거나 완전 마스킹
|
|
39
|
+
- private endpoint 요청/응답 audit log에는 민감 헤더 제거
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### 2.2 stdio MCP 서버에서 stdout 로그 금지
|
|
43
|
+
|
|
44
|
+
`StdioServerTransport`를 사용하는 MCP 서버는 stdout을 JSON-RPC 통신에 사용합니다. 따라서 `console.log()`는 서버 프로토콜을 깨뜨릴 수 있습니다.
|
|
45
|
+
|
|
46
|
+
사용 금지:
|
|
47
|
+
|
|
48
|
+
```ts
|
|
49
|
+
console.log("server started");
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
사용 가능:
|
|
53
|
+
|
|
54
|
+
```ts
|
|
55
|
+
console.error("server started");
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
또는 파일 기반 logger를 사용합니다.
|
|
59
|
+
|
|
60
|
+
### 2.3 주문은 항상 Risk Guard를 통과해야 함
|
|
61
|
+
|
|
62
|
+
`order.place`, `order.place_testnet`, `order.cancel`, `order.cancel_testnet`을 포함한 모든 주문성 Tool은 반드시 아래 순서를 지켜야 합니다.
|
|
63
|
+
|
|
64
|
+
```text
|
|
65
|
+
Tool input validation
|
|
66
|
+
↓
|
|
67
|
+
normalize order request
|
|
68
|
+
↓
|
|
69
|
+
load policy
|
|
70
|
+
↓
|
|
71
|
+
riskGuard.validateOrder()
|
|
72
|
+
↓
|
|
73
|
+
audit pending event
|
|
74
|
+
↓
|
|
75
|
+
BrokerAdapter.placeOrder()
|
|
76
|
+
↓
|
|
77
|
+
audit result event
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
BrokerAdapter를 직접 호출해 risk guard를 우회하는 코드를 만들면 안 됩니다.
|
|
81
|
+
|
|
82
|
+
### 2.4 기본값은 안전해야 함
|
|
83
|
+
|
|
84
|
+
기본값:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
TRADING_MODE=testnet
|
|
88
|
+
TRADING_ALLOW_ORDER=false
|
|
89
|
+
TRADING_ALLOW_LIVE=false
|
|
90
|
+
TRADING_ALLOW_MARKET_ORDER=false
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
mainnet 주문은 다음 두 값이 모두 true일 때만 허용합니다.
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
TRADING_ALLOW_ORDER=true
|
|
97
|
+
TRADING_ALLOW_LIVE=true
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## 3. 저장소 구조 규칙
|
|
103
|
+
|
|
104
|
+
```text
|
|
105
|
+
src/
|
|
106
|
+
index.ts # entrypoint only
|
|
107
|
+
config/ # env parsing and policy loading
|
|
108
|
+
mcp/ # MCP server and tools
|
|
109
|
+
core/ # broker-neutral domain logic
|
|
110
|
+
adapters/ # broker-specific implementation
|
|
111
|
+
indicators/ # broker-neutral technical indicators
|
|
112
|
+
utils/ # pure utilities
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### 3.1 MCP Tool Layer는 얇게 유지
|
|
116
|
+
|
|
117
|
+
Tool 파일은 다음만 담당합니다.
|
|
118
|
+
|
|
119
|
+
```text
|
|
120
|
+
- input schema 선언
|
|
121
|
+
- 설명 작성
|
|
122
|
+
- service/core 호출
|
|
123
|
+
- MCP 응답 포맷 변환
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
Tool 파일에 직접 Bybit endpoint URL, 서명 로직, fetch 호출을 넣지 마세요.
|
|
127
|
+
|
|
128
|
+
### 3.2 Core는 브로커 중립
|
|
129
|
+
|
|
130
|
+
`core/`는 Bybit 전용 용어를 최대한 몰라야 합니다.
|
|
131
|
+
|
|
132
|
+
허용:
|
|
133
|
+
|
|
134
|
+
```ts
|
|
135
|
+
MarketCategory = "spot" | "linear" | "inverse" | "option" | "stock";
|
|
136
|
+
OrderSide = "Buy" | "Sell";
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
주의:
|
|
140
|
+
|
|
141
|
+
```text
|
|
142
|
+
Bybit의 특수 retCode 처리, header 이름, endpoint path는 adapters/bybit 안에 둡니다.
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### 3.3 Adapter는 브로커 전용
|
|
146
|
+
|
|
147
|
+
`adapters/bybit/`에는 다음을 둡니다.
|
|
148
|
+
|
|
149
|
+
```text
|
|
150
|
+
bybit.adapter.ts # BrokerAdapter 구현
|
|
151
|
+
bybit-http-client.ts # public/private REST 요청
|
|
152
|
+
bybit-signer.ts # HMAC/RSA signing
|
|
153
|
+
bybit-types.ts # Bybit raw request/response 타입
|
|
154
|
+
bybit-mapper.ts # raw response → core domain type
|
|
155
|
+
bybit-ws-client.ts # v0.5 이후 WebSocket
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
## 4. Tool 이름 규칙
|
|
161
|
+
|
|
162
|
+
Tool 이름은 `domain.action` 형태로 작성합니다.
|
|
163
|
+
|
|
164
|
+
```text
|
|
165
|
+
system.get_status
|
|
166
|
+
market.get_ticker
|
|
167
|
+
market.get_candles
|
|
168
|
+
market.get_instruments
|
|
169
|
+
account.get_wallet_balance
|
|
170
|
+
risk.get_policy
|
|
171
|
+
order.create_intent
|
|
172
|
+
order.validate
|
|
173
|
+
order.place_testnet
|
|
174
|
+
order.cancel_testnet
|
|
175
|
+
order.place
|
|
176
|
+
order.cancel
|
|
177
|
+
kill_switch.enable
|
|
178
|
+
kill_switch.disable
|
|
179
|
+
indicator.calculate
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
금지:
|
|
183
|
+
|
|
184
|
+
```text
|
|
185
|
+
getTicker
|
|
186
|
+
bybitGetTicker
|
|
187
|
+
placeOrderNow
|
|
188
|
+
trade
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
이유: 나중에 Binance/KIS/Alpaca Adapter가 들어와도 MCP Tool 이름을 유지해야 합니다.
|
|
192
|
+
|
|
193
|
+
---
|
|
194
|
+
|
|
195
|
+
## 5. Tool 응답 규칙
|
|
196
|
+
|
|
197
|
+
모든 Tool은 사람이 읽을 수 있는 `content`와 기계가 읽을 수 있는 `structuredContent`를 함께 반환합니다.
|
|
198
|
+
|
|
199
|
+
예시:
|
|
200
|
+
|
|
201
|
+
```ts
|
|
202
|
+
return {
|
|
203
|
+
content: [
|
|
204
|
+
{
|
|
205
|
+
type: "text",
|
|
206
|
+
text: `BTCUSDT last price: ${ticker.lastPrice}`
|
|
207
|
+
}
|
|
208
|
+
],
|
|
209
|
+
structuredContent: ticker
|
|
210
|
+
};
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
에러는 secret을 제거한 뒤 안전한 메시지로 반환합니다.
|
|
214
|
+
|
|
215
|
+
```ts
|
|
216
|
+
throw new McpError(
|
|
217
|
+
ErrorCode.InvalidRequest,
|
|
218
|
+
"Order rejected by local risk policy: symbol is not allowed"
|
|
219
|
+
);
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
---
|
|
223
|
+
|
|
224
|
+
## 6. TypeScript 규칙
|
|
225
|
+
|
|
226
|
+
- `strict: true` 유지
|
|
227
|
+
- `any` 사용 금지. 외부 raw response는 `unknown`에서 Zod 또는 타입 가드로 좁힐 것
|
|
228
|
+
- 가격/수량은 number가 아니라 string 또는 Decimal로 처리
|
|
229
|
+
- 테스트 fixture의 숫자도 string을 유지
|
|
230
|
+
- HTTP 요청 timeout을 반드시 적용
|
|
231
|
+
- 네트워크 에러, Bybit retCode 에러, MCP input validation 에러를 구분
|
|
232
|
+
|
|
233
|
+
---
|
|
234
|
+
|
|
235
|
+
## 7. 환경변수 규칙
|
|
236
|
+
|
|
237
|
+
`config/env.ts`에서만 `process.env`를 직접 읽습니다. 다른 파일에서 직접 `process.env.BYBIT_API_KEY`를 참조하지 마세요.
|
|
238
|
+
|
|
239
|
+
필수/선택 config는 시작 시 검증합니다.
|
|
240
|
+
|
|
241
|
+
```ts
|
|
242
|
+
export interface AppConfig {
|
|
243
|
+
broker: "bybit";
|
|
244
|
+
mode: "testnet" | "mainnet";
|
|
245
|
+
bybit: {
|
|
246
|
+
apiKey?: string;
|
|
247
|
+
apiSecret?: string;
|
|
248
|
+
recvWindow: string;
|
|
249
|
+
region: "global" | "nl" | "tr" | "kz" | "ge" | "ae" | "eu" | "id";
|
|
250
|
+
};
|
|
251
|
+
policy: TradingPolicy;
|
|
252
|
+
}
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
---
|
|
256
|
+
|
|
257
|
+
## 8. 구현 순서
|
|
258
|
+
|
|
259
|
+
순서를 바꾸지 않는 것을 권장합니다.
|
|
260
|
+
|
|
261
|
+
```text
|
|
262
|
+
Phase 0: MCP 서버 골격
|
|
263
|
+
Phase 1: Bybit public market adapter
|
|
264
|
+
Phase 2: Bybit private auth/account adapter
|
|
265
|
+
Phase 3: local risk guard + dry-run order intent
|
|
266
|
+
Phase 4: testnet order execution
|
|
267
|
+
Phase 5: mainnet readiness + kill switch
|
|
268
|
+
Phase Extra: market order safety
|
|
269
|
+
Phase 6: indicators
|
|
270
|
+
Phase 7: websocket
|
|
271
|
+
Phase 8: strategy runner
|
|
272
|
+
Phase 9: multi-broker
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
---
|
|
276
|
+
|
|
277
|
+
## 9. 테스트 필수 조건
|
|
278
|
+
|
|
279
|
+
PR은 아래 검증을 통과해야 합니다.
|
|
280
|
+
|
|
281
|
+
```bash
|
|
282
|
+
npm run build
|
|
283
|
+
npm test
|
|
284
|
+
npm run lint
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
필수 테스트:
|
|
288
|
+
|
|
289
|
+
```text
|
|
290
|
+
- env parser unit test
|
|
291
|
+
- Bybit signer snapshot test
|
|
292
|
+
- queryString canonicalization test
|
|
293
|
+
- secret redaction test
|
|
294
|
+
- risk guard rejection test
|
|
295
|
+
- MCP tool input validation test
|
|
296
|
+
- adapter mapper fixture test
|
|
297
|
+
- testnet integration test는 opt-in으로 분리
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
Integration test는 실제 API Key가 필요한 경우 다음 환경변수가 있을 때만 실행합니다.
|
|
301
|
+
|
|
302
|
+
```bash
|
|
303
|
+
RUN_BYBIT_TESTNET_INTEGRATION=true
|
|
304
|
+
BYBIT_API_KEY=...
|
|
305
|
+
BYBIT_API_SECRET=...
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
---
|
|
309
|
+
|
|
310
|
+
## 10. PR 리뷰 체크리스트
|
|
311
|
+
|
|
312
|
+
- [ ] `console.log()`가 없음
|
|
313
|
+
- [ ] API Key/Secret이 응답/로그/테스트에 노출되지 않음
|
|
314
|
+
- [ ] 주문 Tool은 risk guard를 통과함
|
|
315
|
+
- [ ] mainnet 주문은 `TRADING_ALLOW_LIVE=true` 없이는 불가능함
|
|
316
|
+
- [ ] 모든 Tool input은 Zod schema로 검증됨
|
|
317
|
+
- [ ] Bybit raw response는 mapper를 거쳐 core type으로 변환됨
|
|
318
|
+
- [ ] 가격/수량 연산에 floating point number를 직접 사용하지 않음
|
|
319
|
+
- [ ] 실패 케이스 테스트가 있음
|
|
320
|
+
- [ ] README 또는 docs가 변경 사항을 반영함
|
|
321
|
+
|
|
322
|
+
---
|
|
323
|
+
|
|
324
|
+
## 11. 이 저장소에서 하지 않는 것
|
|
325
|
+
|
|
326
|
+
초기 버전에서는 다음을 구현하지 않습니다.
|
|
327
|
+
|
|
328
|
+
```text
|
|
329
|
+
- 출금 API
|
|
330
|
+
- 자산 이체 API
|
|
331
|
+
- API Key 생성/관리 UI
|
|
332
|
+
- 레버리지 자동 변경
|
|
333
|
+
- 대출/마진 설정 자동화
|
|
334
|
+
- 사용자 클라우드 키 저장
|
|
335
|
+
- 수익 보장 문구
|
|
336
|
+
- 미검증 전략의 자동 mainnet 주문
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
---
|
|
340
|
+
|
|
341
|
+
## 12. Agent에게 주는 작업 방식
|
|
342
|
+
|
|
343
|
+
작업할 때는 항상 다음 형식을 지키세요.
|
|
344
|
+
|
|
345
|
+
```text
|
|
346
|
+
1. 변경 대상 phase 명시
|
|
347
|
+
2. 변경 파일 목록 제시
|
|
348
|
+
3. 구현
|
|
349
|
+
4. 테스트 추가
|
|
350
|
+
5. 로컬 검증 명령 제시
|
|
351
|
+
6. 보안 영향 요약
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
예시:
|
|
355
|
+
|
|
356
|
+
```text
|
|
357
|
+
Phase 1 market.get_ticker 구현
|
|
358
|
+
- src/adapters/bybit/bybit-http-client.ts
|
|
359
|
+
- src/adapters/bybit/bybit.adapter.ts
|
|
360
|
+
- src/mcp/tools/market.tools.ts
|
|
361
|
+
- tests/unit/bybit-market.test.ts
|
|
362
|
+
```
|