CREATE_ORDER
Place a buy or sell order on the Upbit exchange. Specify market, side, order type, and optional parameters for advanced trading.
Instructions
Create an Upbit order (requires private API)
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| market | Yes | ||
| side | Yes | ||
| ord_type | Yes | ||
| volume | No | ||
| price | No | ||
| time_in_force | No | ||
| smp_type | No | ||
| identifier | No |
Implementation Reference
- src/tools/create-order.ts:32-67 (handler)The full tool definition including the 'execute' handler that creates an Upbit order by calling POST /orders with a signed JWT token. Returns the response as JSON.
export const createOrderTool = { name: "CREATE_ORDER", description: "Create an Upbit order (requires private API)", parameters: paramsSchema, execute: async ({ market, side, ord_type, volume, price, time_in_force, smp_type, identifier, }: Params) => { ensurePrivateEnabled(); const baseURL = `${config.upbit.baseUrl}${config.upbit.apiBasePath}`; const client = createHttpClient(baseURL); const body = { market, side, ord_type, volume, price, time_in_force, smp_type, identifier, }; const token = signJwtToken(body); const data = await fetchJson<unknown>(client, "/orders", { method: "POST", data: body, headers: { Authorization: `Bearer ${token}` }, }); return JSON.stringify(data, null, 2); }, } as const; - src/tools/create-order.ts:6-28 (schema)Zod schema (paramsSchema) defining input validation for CREATE_ORDER: market, side (bid/ask), ord_type (limit/price/market), volume, price, time_in_force, smp_type, identifier with refine validations for limit/price/market order constraints.
const paramsSchema = z .object({ market: z.string(), side: z.enum(["bid", "ask"]), ord_type: z.enum(["limit", "price", "market"]), volume: z.string().optional(), price: z.string().optional(), time_in_force: z.enum(["ioc", "fok", "post_only"]).optional(), smp_type: z.enum(["cancel_maker", "cancel_taker", "reduce"]).optional(), identifier: z.string().optional(), }) .refine((p) => (p.ord_type === "limit" ? p.volume && p.price : true), { message: "Limit orders require both volume and price", }) .refine((p) => (p.ord_type === "price" ? !!p.price : true), { message: "Market buy (price) requires price", }) .refine((p) => (p.ord_type === "market" ? !!p.volume : true), { message: "Market sell (market) requires volume", }) .refine((p) => !(p.time_in_force === "post_only" && p.smp_type), { message: "post_only cannot be used with smp_type", }); - src/index.ts:35-35 (registration)Registration of the order tool via server.addTool(createOrderTool) in the main index.ts file.
server.addTool(createOrderTool); - src/lib/upbit-auth.ts:18-41 (helper)signJwtToken helper that signs the order parameters into a JWT token using the Upbit secret key (query hash for SHA512). Used by the handler to authenticate the API call.
export function signJwtToken( params?: Record<string, string | number | boolean | undefined>, ): string { const payload: Record<string, unknown> = { access_key: config.upbit.accessKey, nonce: crypto.randomUUID(), }; if (params && Object.keys(params).length > 0) { const searchParams = new URLSearchParams(); const sortedKeys = Object.keys(params).sort(); for (const key of sortedKeys) { const value = params[key]; if (value === undefined) continue; searchParams.append(key, String(value)); } const encoded = searchParams.toString(); const queryHash = crypto.createHash("sha512").update(encoded).digest("hex"); payload.query_hash = queryHash; payload.query_hash_alg = "SHA512"; } return jwt.sign(payload, config.upbit.secretKey as string); } - src/lib/http.ts:32-67 (helper)fetchJson helper that performs the actual HTTP POST request to Upbit's /orders endpoint with retry logic.
export async function fetchJson<T>( client: AxiosInstance, url: string, options: { method?: "GET" | "POST" | "DELETE" | "PUT" | "PATCH"; params?: Record<string, unknown>; data?: unknown; headers?: Record<string, string>; } = {}, schema?: z.ZodType<T>, ): Promise<T> { try { const response = await client.request({ url, method: options.method ?? "GET", params: options.params, data: options.data, headers: options.headers, }); const data = response.data; if (schema) { return schema.parse(data); } return data as T; } catch (err) { if (axios.isAxiosError(err)) { const ae = err as AxiosError; const status = ae.response?.status ?? 0; const message = ae.message || "HTTP request failed"; const data = ae.response?.data; throw new HttpError(status, message, data); } throw err; } }