Skip to content

Commit

Permalink
Merge pull request #3 from michaelibrd/feature/candle-support
Browse files Browse the repository at this point in the history
Adding support for candles (ohlc)
  • Loading branch information
michaelibrd committed Apr 12, 2021
2 parents c46a8fd + 795e221 commit 39c4f77
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 1 deletion.
34 changes: 34 additions & 0 deletions Sources/CoinGecko/Models/Candle.swift
@@ -0,0 +1,34 @@
//
// Candle.swift
//
//
// Created by stringcode on 05/04/2021.
//

import Foundation

public typealias CandleList = [Candle]

public struct Candle: Codable {
public let date: Date
public let open: Double
public let high: Double
public let low: Double
public let close: Double

public init(arrayData: [Double]) {
date = Date(timeIntervalSince1970: Double(arrayData[0]) / 1000)
open = arrayData[1]
high = arrayData[2]
low = arrayData[3]
close = arrayData[4]
}

public init(date: Date, open: Double, high: Double, low: Double, close: Double) {
self.date = date
self.open = open
self.high = high
self.low = low
self.close = close
}
}
22 changes: 21 additions & 1 deletion Sources/CoinGecko/Resources.swift
Expand Up @@ -15,7 +15,8 @@ public enum Endpoint: String {

case coinsList = "/coins/list"
case coinsMarketChart = "/coins/%@/market_chart"
case coin = "/coins/%@"
case coin = "/coins/%@"
case ohlc = "/coins/%@/ohlc"
}

public enum Resources {}
Expand Down Expand Up @@ -81,4 +82,23 @@ extension Resources {
URLQueryItem(name: "days", value: "\(days)")]
return Resource(.coinsMarketChart, method: .GET, pathParam: currencyId, params: params, completion: callback)
}

// Coin Gecko API returns candles of diffrent duration based on `days` parameter
// ```
// 1 - 2 days: 30 minutes
// 3 - 30 days: 4 hours
// 31 and before: 4 days
// ```
public static func candles<CandleList>(currencyId: String, vs: String, days: Int, callback: @escaping Callback<CandleList>) -> Resource<CandleList> {
let params = [URLQueryItem(name: "vs_currency", value: vs),
URLQueryItem(name: "days", value: "\(days)")]

let parse: (Data) -> CandleList = { data in
let decoder = JSONDecoder()
let arrayData = try? decoder.decode([[Double]].self, from: data)
return (arrayData ?? []).map { Candle(arrayData: $0) } as! CandleList
}

return Resource(.ohlc, method: .GET, pathParam: currencyId, params: params, parse: parse, completion: callback)
}
}
25 changes: 25 additions & 0 deletions Tests/CoinGeckoTests/CandleTest.swift
@@ -0,0 +1,25 @@
import XCTest
@testable import CoinGecko

final class CandleTests: XCTestCase {

private let client = CoinGeckoClient()

func testCandles() {
let exp = XCTestExpectation()
let id = "bitcoin"
let vs = "usd"
let candles = Resources.candles(currencyId: id, vs: vs, days: 180) { (result: Result<CandleList, CoinGeckoError>) in
switch result {
case let .success(candleList):
XCTAssertTrue(candleList.count > 44 && candleList.count < 49,
"Unexpected candle count")
case let .failure(error):
XCTFail(error.localizedDescription)
}
exp.fulfill()
}
client.load(candles)
wait(for: [exp], timeout: 10.0)
}
}

0 comments on commit 39c4f77

Please sign in to comment.