평범한 이야기들

[PHP] PHP를 이용해 업비트(upbit) API 통신하기 #3 매수, 매도 하기 본문

평범한 개발 이야기/PHP

[PHP] PHP를 이용해 업비트(upbit) API 통신하기 #3 매수, 매도 하기

songsariya 2021. 3. 29. 14:15
728x90

2021.03.18 - [평범한 개발 이야기/PHP] - [PHP] PHP를 이용해 업비트(upbit) API 통신하기 #1 계좌정보 가져오기

2021.03.22 - [평범한 개발 이야기/PHP] - [PHP] PHP를 이용해 업비트(upbit) API 통신하기 #2 분, 일 캔들 정보 가져오기

 

지난번에 이어서 이번에는 코인 매수, 매도를 할려고 합니다.

 

>> 관련 레퍼런스 문서 보기

 

 계좌정보, 코인의 정보를 가져왔기 때문에 실제로 매수, 매도를 통해서 코인을 사고 파는 API를 만들 예정입니다. 매수와 매도는 하나의 API를 통해서 파라미터를 통해서 구분 되어지며 주문타입에 따라서 지정가 주문, 시장가 주문 이 있습니다. 시장가 주문에서는 시장가 매수, 시장가 매수 로 구분되어있고 해당 주문타입에 따라 필수 파라미터 값이 변경됩니다. 매수, 매도에 대한 자세한 정보는 레퍼런스 문서를 확인하시면 됩니다.

 

 아래는 현재 제 업비트 계좌의 정보입니다.

업비트 현재 계좌 조회

원화로 약 39,000원 가량 있고, 넴(XEM) 이라는 코인이 현재 868.53 블록 정도 있습니다. 평균 구매가격이 440이니깐

블록 * 평균구매가격 = 약 38만원 정도 구매를 하고 있는 상태입니다. (현재는 마이너스... 입니다.. ㅠㅠ)

 

 

UpbitApi Class 수정부분

 그러면 매수를 진행하기 전에 UpbitApi Class가 바뀐 부분을 설명하도록 하겠습니다.

<?php

// in UpbitApi class 안
    
    /**
     * UPBIT 토큰을 만드는 메서드
     *
     * @param string $queryParam
     * @return string
     */
    private function makeToken($queryParam = "")
    {

        $addPayload = [];
        if (isset($queryParam) && $queryParam != "") {

            $queryString = http_build_query($queryParam);
                    
            $query_hash =  hash('sha512', $queryString, false) ; //hash("sha512", $queryString);

            $addPayload = [
                "query_hash" => $query_hash,
                "query_hash_alg" => "SHA512",
            ];
        }

        $payload = [
            "access_key" => $this->accessKey,
            "nonce" => "SSR_" . uniqid(),            
        ];

        $mergePayload = array_merge ($payload, $addPayload);    

        $token = JWT::encode($mergePayload, $this->secretKey);
                
        return $token;
    }

    /**
     * 실제 UPBIT API 서버와 통신하는 메서드
     *
     * @param [type] $param
     * @return void
     */
    private function call($param)
    {

        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL,  $param["url"]);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($curl, CURLOPT_HTTPHEADER, $param["header"]);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        
        if( isset($param["method"]) ){
            curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $param["method"]);
        }
        
        if( isset($param["param"])) {
            curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($param["param"]));
        }
          
        $result = curl_exec($curl);
        $httpcode = curl_getinfo($curl, CURLINFO_HTTP_CODE);

        curl_close($curl);

        $responseData = json_decode($result, true);
        $httpCodeData = json_decode($httpcode, true);

        $returnData["responseData"] = $responseData;
        $returnData["httpCode"] = $httpCodeData;

        return $returnData;
    }​

 먼저 makeToken은 업비트 API 통신 헤더에 들어가는 토큰을 생성해주는 메서드 입니다. 따로 메서드로 만든 이유는 API 사용시 파라미터가 유무로 인해 query_string의 암호화가 필수적으로 진행되어야 하며, 공통적으로 헤더에 사용됩니다. 따라서 하나의 메서드를 통해서 컨트롤 하기 위함입니다. 그리고 실제 업비트 API와 통신하는 call 메서드에도 API통신시 필요한 파라미터나 HTTP method의 상태를 바꿔줘야하기 하기 때문에 call 메서드에서 조건을 주어 전송 전에 변경해주는 작업을 추가했습니다.

 

업비트 API 매수, 매도 하기

그러면 매수, 매도를 진행하는 메서드를 확인해보겠습니다.

<?php

// in UpbitApi class 안

	/**
     * 매수, 매도 주문을 넣는 메서드
     *
     * @param array $requestData
     * @return array
     */
    public function order($requestData)
    {
        $url = "https://api.upbit.com/v1/orders";

        $queryParam = [
            "market" => $requestData["market"],
            "side" => $requestData["side"],
            "volume" => (isset($requestData["volume"]) ? $requestData["volume"] : null),
            "price" => (isset($requestData["price"]) ? $requestData["price"] : null),
            "ord_type" => $requestData["ord_type"],
            "identifier" => $requestData["identifier"],
        ];        

        $token = $this->makeToken($queryParam);

        $responseData = $this->call(array(
            "url"       => $url,
            "header"    => array(
                "Authorization: Bearer {$token}"                           
            ),
            "method" => "POST",
            "param" => $queryParam,
        ));

        return $responseData;
    }

 위 소스 코드와 같이 짰습니다. 매수, 매도에 따라서, 지정가, 시장가에 따라서 필수 값이 달라지기 때문에 해당 값을 검증하는 부분을 넣고 API를 호출합니다. 위에서도 언급했지만 하나의 API에 주문 종류 파라미터 (side)에 따라서 매수, 매도가 결정됩니다.

 

 먼저 매수를 진행하도록 하겠습니다.

<?php

// 매수하기

$orderData["side"] = "bid";
$orderData["market"] = "KRW-META";
$orderData["ord_type"] = "price";
$orderData["identifier"] = "ORDER_BID_" . uniqid();

if ($requestData["ord_type"] == "limit") {
// 지정가 주문
	$orderData["volume"] = $requestData["volume"];
	$orderData["price"] = $requestData["price"];
} else if ($requestData["ord_type"] == "price") {
// 시장가 주문 (매수)
	$orderData["volume"] = null;
	$orderData["price"] = "5000"; // 테스트 5,000원
}

$responseData = $this->upbitApi->order($orderData);

테스트로 메타디움(META) 코인을 환화 5,000원 어치 매수를 하는 코드입니다. 저는 시장가로 바로 구매가 되도록 테스트 했습니다. 테스트 결과 화면은 아래와 같습니다.

 

메타디움 코인 구매완료 화면

정상적으로 매수 주문이 들어갔습니다. 'state' 값이 wait여서 주문이 완료된 상태는 아닙니다. 해당 상태는 매수 주문이 완료되면 바뀌게 됩니다. (시장가로 주문했기 때문에 그 후 바로 매수가 완료되었습니다.) 그 외 주문에 관련된 정보들을 응답받는걸 알 수 있습니다. (responseData 안의 배열정보가 실제 받은 정보입니다. 해당 화면은 call 메서드에서 가공되었습니다.)

 

그 후 계좌정보를 보면 제가 매수를 한 메타디움 코인도 함께 들어가 있는 것을 볼 수 있습니다.

매수한 메타디움 코인이 들어가 있는 모습

 

매도는 side의 값을 변경해 API를 호출 하면 됩니다. 아래는 매도 했을때 받는 응답화면입니다. 여기서 주의할 점은

매도시 코인의 block 값을 전달하게 되는데 해당 값을 환화로 변환 했을때 거래 가능 금액이 아니면 에러 응답을 보내주게 됩니다. 즉 5,000원어치 코인을 샀다고 치면 해당 팔려고 하는 코인의 블록 갯수의 환화 가치가 5,000원 이하로 평가되면 매도가 불가능합니다.

메타디움 코인을 매도하고 나서 받은 응답 화면

 

매도 후 계좌정보를 보면 제가 매도한 메타디움 코인이 사라진 것을 보실 수 있습니다.

매도 후 응답 계좌 화면

 

업비트 API를 이용해 코인의 매수, 매도하는 방법을 정리해봤습니다. 

728x90
Comments