Implemented buyPrice and sellPrice. Closes #1

This commit is contained in:
Erik C. Thauvin 2022-08-29 19:21:44 -07:00
parent c046cd7341
commit bef4b2ee20
18 changed files with 152 additions and 98 deletions

View file

@ -29,11 +29,11 @@ defaults_gradle: &defaults_gradle
- store_test_results: - store_test_results:
path: build/reports/ path: build/reports/
jobs: jobs:
build_gradle_jdk17: build_gradle_jdk18:
<<: *defaults <<: *defaults
docker: docker:
- image: cimg/openjdk:17.0 - image: cimg/openjdk:18.0
<<: *defaults_gradle <<: *defaults_gradle
@ -50,4 +50,4 @@ workflows:
gradle: gradle:
jobs: jobs:
- build_gradle_jdk11 - build_gradle_jdk11
- build_gradle_jdk17 - build_gradle_jdk18

View file

@ -12,7 +12,7 @@ jobs:
strategy: strategy:
matrix: matrix:
java-version: [ 11, 17 ] java-version: [ 11, 18 ]
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2

View file

@ -21,5 +21,10 @@
<option name="name" value="maven" /> <option name="name" value="maven" />
<option name="url" value="https://oss.sonatype.org/content/repositories/snapshots" /> <option name="url" value="https://oss.sonatype.org/content/repositories/snapshots" />
</remote-repository> </remote-repository>
<remote-repository>
<option name="id" value="MavenLocal" />
<option name="name" value="MavenLocal" />
<option name="url" value="file:$MAVEN_REPOSITORY$/" />
</remote-repository>
</component> </component>
</project> </project>

6
.idea/kotlinc.xml generated Normal file
View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="KotlinJpsPluginSettings">
<option name="version" value="1.7.10" />
</component>
</project>

5
.idea/misc.xml generated
View file

@ -1,5 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" /> <component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" project-jdk-name="17" project-jdk-type="JavaSDK" /> <component name="FrameworkDetectionExcludesConfiguration">
<file type="web" url="file://$PROJECT_DIR$" />
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" project-jdk-name="18" project-jdk-type="JavaSDK" />
</project> </project>

View file

@ -1,10 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RunConfigurationProducerService">
<option name="ignoredProducers">
<set>
<option value="com.android.tools.idea.compose.preview.runconfiguration.ComposePreviewRunConfigurationProducer" />
</set>
</option>
</component>
</project>

View file

@ -1,10 +1,10 @@
[![License (3-Clause BSD)](https://img.shields.io/badge/license-BSD%203--Clause-blue.svg?style=flat-square)](https://opensource.org/licenses/BSD-3-Clause) [![Release](https://img.shields.io/github/release/ethauvin/cryptoprice.svg)](https://github.com/ethauvin/cryptoprice/releases/latest) [![Maven Central](https://img.shields.io/maven-central/v/net.thauvin.erik/cryptoprice.svg?label=maven%20central&color=blue)](https://search.maven.org/search?q=g:%22net.thauvin.erik%22%20AND%20a:%22cryptoprice%22) <!-- [![Nexus Snapshot](https://img.shields.io/nexus/s/net.thauvin.erik/cryptoprice?server=https%3A%2F%2Foss.sonatype.org%2F)](https://oss.sonatype.org/content/repositories/snapshots/net/thauvin/erik/cryptoprice/) --> [![License (3-Clause BSD)](https://img.shields.io/badge/license-BSD%203--Clause-blue.svg?style=flat-square)](https://opensource.org/licenses/BSD-3-Clause) [![Release](https://img.shields.io/github/release/ethauvin/cryptoprice.svg)](https://github.com/ethauvin/cryptoprice/releases/latest) <!-- [![Maven Central](https://img.shields.io/maven-central/v/net.thauvin.erik/cryptoprice.svg?label=maven%20central&color=blue)](https://search.maven.org/search?q=g:%22net.thauvin.erik%22%20AND%20a:%22cryptoprice%22) --> [![Nexus Snapshot](https://img.shields.io/nexus/s/net.thauvin.erik/cryptoprice?server=https%3A%2F%2Foss.sonatype.org%2F)](https://oss.sonatype.org/content/repositories/snapshots/net/thauvin/erik/cryptoprice/)
[![Known Vulnerabilities](https://snyk.io/test/github/ethauvin/cryptoprice/badge.svg?targetFile=pom.xml)](https://snyk.io/test/github/ethauvin/cryptoprice?targetFile=pom.xml) [![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=ethauvin_cryptoprice&metric=alert_status)](https://sonarcloud.io/dashboard?id=ethauvin_cryptoprice) [![GitHub CI](https://github.com/ethauvin/cryptoprice/actions/workflows/gradle.yml/badge.svg)](https://github.com/ethauvin/cryptoprice/actions/workflows/gradle.yml) [![CircleCI](https://circleci.com/gh/ethauvin/cryptoprice/tree/master.svg?style=shield)](https://circleci.com/gh/ethauvin/cryptoprice/tree/master) [![Known Vulnerabilities](https://snyk.io/test/github/ethauvin/cryptoprice/badge.svg?targetFile=pom.xml)](https://snyk.io/test/github/ethauvin/cryptoprice?targetFile=pom.xml) [![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=ethauvin_cryptoprice&metric=alert_status)](https://sonarcloud.io/dashboard?id=ethauvin_cryptoprice) [![GitHub CI](https://github.com/ethauvin/cryptoprice/actions/workflows/gradle.yml/badge.svg)](https://github.com/ethauvin/cryptoprice/actions/workflows/gradle.yml) [![CircleCI](https://circleci.com/gh/ethauvin/cryptoprice/tree/master.svg?style=shield)](https://circleci.com/gh/ethauvin/cryptoprice/tree/master)
# Retrieve cryptocurrencies current prices # Retrieve cryptocurrencies current (buy, sell or spot) prices
A simple Kotlin/Java/Android implementation of the spot price [Coinbase Public API](https://developers.coinbase.com/api/v2#get-spot-price). A simple Kotlin/Java/Android implementation of the prices [Coinbase Public API](https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-prices).
## Examples (TL;DR) ## Examples (TL;DR)
@ -16,7 +16,10 @@ import net.thauvin.erik.crypto.CryptoPrice.Companion.spotPrice
val btc = spotPrice("BTC") // Bitcoin val btc = spotPrice("BTC") // Bitcoin
println(btc.amount) println(btc.amount)
val eth = spotPrice("ETH", "EUR") // Ethereum in Euros val eth = sellPrice("ETH", "EUR") // Ethereum in Euro
println(eth.amount)
val eth = buyPrice("LTC", "GBP") // Litecoin in Pound sterling
println(eth.amount) println(eth.amount)
``` ```
@ -28,21 +31,31 @@ To use with [Gradle](https://gradle.org/), include the following dependency in y
```gradle ```gradle
dependencies { dependencies {
implementation("net.thauvin.erik:cryptoprice:0.9.0") implementation("net.thauvin.erik:cryptoprice:1.0.0-SNAPSHOT")
} }
``` ```
Instructions for using with Maven, Ivy, etc. can be found on [Maven Central](https://search.maven.org/artifact/net.thauvin.erik/cryptoprice/0.9.0/jar). Instructions for using with Maven, Ivy, etc. can be found on [Maven Central](https://search.maven.org/search?q=g:%22net.thauvin.erik%22%20AND%20a:%22cryptoprice%22).
### Spot Price ### Prices
The `spotPrice` function defines the following parameters: The `spotPrice`, `buyPrice` and `sellPrice` functions define the following parameters:
```kotlin ```kotlin
spotPrice( spotPrice(
base: String, // Required base: String, // Required
currency: String = "USD", currency: String = "USD",
date: LocalDate? = null, date: LocalDate? = null
)
buyPrice(
base: String, // Required
currency: String = "USD"
)
sellPrice(
base: String, // Required
currency: String = "USD"
) )
``` ```
@ -57,7 +70,7 @@ A `CryptoPrice` object is returned defined as follows:
```kotlin ```kotlin
CryptoPrice(val base: String, val currency: String, val amount: BigDecimal) CryptoPrice(val base: String, val currency: String, val amount: BigDecimal)
``` ```
The parameter names match the [Coinbase API](https://developers.coinbase.com/api/v2#get-spot-price). The parameter names match the [Coinbase API](https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-prices).
#### Format #### Format
@ -86,7 +99,7 @@ println(price.toJson())
{"data":{"base":"BTC","currency":"USD","amount":"34567.89"}} {"data":{"base":"BTC","currency":"USD","amount":"34567.89"}}
``` ```
The `data` object matches the [Coinbase API](https://developers.coinbase.com/api/v2#get-spot-price). To specify a different (or no) key, use: The `data` object matches the [Coinbase API](https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-prices#get-spot-price). To specify a different (or no) key, use:
```kotlin ```kotlin
println(price.toJson("bitcoin")) println(price.toJson("bitcoin"))
@ -109,15 +122,15 @@ val eth = """{"ether":{"base":"ETH","currency":"USD","amount":"2345.67"}}""".toP
### Extending ### Extending
A generic `apiCall()` function is available to access other [API data endpoints](https://developers.coinbase.com/api/v2#data-endpoints). For example to retrieve the current [buy price](https://developers.coinbase.com/api/v2#get-buy-price) of a cryptocurrency: A generic `apiCall()` function is available to access other [data API endpoints](https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-currencies). For example to retrieve the [exchange rates](https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-exchange-rates#get-exchange-rates):
```kotlin ```kotlin
apiCall(paths = listOf("prices", "BTC-USD", "buy"), params = emptyMap()) apiCall(listOf("exchange-rates"), mapOf("currency" to "usd"))
``` ```
will return something like: will return something like:
```json ```json
{"data":{"base":"BTC","currency":"USD","amount":"34554.32"}} {"data":{"currency":"BTC","rates":{"AED":"36.73","AFN":"589.50",...}}}
``` ```
See the [examples](https://github.com/ethauvin/cryptoprice/blob/master/examples/) for more details. See the [examples](https://github.com/ethauvin/cryptoprice/blob/master/examples/) for more details.

View file

@ -1,4 +1,4 @@
image: openjdk:17 image: openjdk:18
pipelines: pipelines:
default: default:

View file

@ -8,21 +8,21 @@ import org.gradle.api.tasks.testing.logging.TestLogEvent
plugins { plugins {
id("application") id("application")
id("com.github.ben-manes.versions") version "0.42.0" id("com.github.ben-manes.versions") version "0.42.0"
id("io.gitlab.arturbosch.detekt") version "1.20.0" id("io.gitlab.arturbosch.detekt") version "1.21.0"
id("java") id("java")
id("maven-publish") id("maven-publish")
id("org.jetbrains.dokka") version "1.6.21" id("org.jetbrains.dokka") version "1.7.10"
id("org.jetbrains.kotlinx.kover") version "0.5.0" id("org.jetbrains.kotlinx.kover") version "0.6.0"
id("org.sonarqube") version "3.3" id("org.sonarqube") version "3.4.0.2513"
id("signing") id("signing")
kotlin("jvm") version "1.6.21" kotlin("jvm") version "1.7.10"
} }
defaultTasks(ApplicationPlugin.TASK_RUN_NAME) defaultTasks(ApplicationPlugin.TASK_RUN_NAME)
description = "Retrieve cryptocurrencies current prices." description = "Retrieve cryptocurrencies prices."
group = "net.thauvin.erik" group = "net.thauvin.erik"
version = "0.9.0" version = "1.0.0-SNAPSHOT"
val deployDir = "deploy" val deployDir = "deploy"
val gitHub = "ethauvin/$name" val gitHub = "ethauvin/$name"
@ -43,9 +43,9 @@ repositories {
dependencies { dependencies {
implementation(platform(kotlin("bom"))) implementation(platform(kotlin("bom")))
implementation(kotlin("stdlib-jdk8")) implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
implementation("com.squareup.okhttp3:okhttp:4.9.3") implementation("com.squareup.okhttp3:okhttp:4.10.0")
implementation("org.json:json:20220320") implementation("org.json:json:20220320")
testImplementation(kotlin("test")) testImplementation(kotlin("test"))
@ -71,7 +71,7 @@ sonarqube {
property("sonar.organization", "ethauvin-github") property("sonar.organization", "ethauvin-github")
property("sonar.host.url", "https://sonarcloud.io") property("sonar.host.url", "https://sonarcloud.io")
property("sonar.sourceEncoding", "UTF-8") property("sonar.sourceEncoding", "UTF-8")
property("sonar.coverage.jacoco.xmlReportPaths", "${project.buildDir}/reports/kover/report.xml") property("sonar.coverage.jacoco.xmlReportPaths", "${project.buildDir}/reports/kover/xml/report.xml")
} }
} }
@ -132,7 +132,7 @@ tasks {
register("deploy") { register("deploy") {
description = "Copies all needed files to the $deployDir directory." description = "Copies all needed files to the $deployDir directory."
group = PublishingPlugin.PUBLISH_TASK_GROUP group = PublishingPlugin.PUBLISH_TASK_GROUP
dependsOn(build, jar) dependsOn(clean, build, jar)
outputs.dir(deployDir) outputs.dir(deployDir)
inputs.files(copyToDeploy) inputs.files(copyToDeploy)
mustRunAfter(clean) mustRunAfter(clean)

View file

@ -3,7 +3,7 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins { plugins {
id("application") id("application")
id("com.github.ben-manes.versions") version "0.42.0" id("com.github.ben-manes.versions") version "0.42.0"
kotlin("jvm") version "1.6.21" kotlin("jvm") version "1.7.10"
} }
// ./gradlew run // ./gradlew run
@ -20,7 +20,8 @@ repositories {
} }
dependencies { dependencies {
implementation("net.thauvin.erik:cryptoprice:0.9.0") implementation("net.thauvin.erik:cryptoprice:1.0.0-SNAPSHOT")
implementation("org.json:json:20220320")
} }
java { java {

View file

@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

View file

@ -2,13 +2,14 @@ package com.example;
import net.thauvin.erik.crypto.CryptoException; import net.thauvin.erik.crypto.CryptoException;
import net.thauvin.erik.crypto.CryptoPrice; import net.thauvin.erik.crypto.CryptoPrice;
import org.json.JSONObject;
import java.io.IOException; import java.io.IOException;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
public class CryptoPriceSample { public class CryptoPriceSample {
public static void main(String[] args) { public static void main(final String[] args) {
try { try {
if (args.length > 0) { if (args.length > 0) {
final CryptoPrice price; final CryptoPrice price;
@ -21,27 +22,27 @@ public class CryptoPriceSample {
+ price.getCurrency()); + price.getCurrency());
} else { } else {
// Get current Bitcoin spot price. // Get current Bitcoin spot price.
final CryptoPrice price = CryptoPrice.spotPrice("BTC"); final var price = CryptoPrice.spotPrice("BTC");
System.out.println("The current Bitcoin price is " + price.toCurrency()); System.out.println("The current Bitcoin price is " + price.toCurrency());
System.out.println(); System.out.println();
// Get current Ethereum spot price in Pound sterling. // Get current Ethereum buy price in Pound sterling.
final CryptoPrice gbpPrice = CryptoPrice.spotPrice("ETH", "GBP"); final var gbpPrice = CryptoPrice.buyPrice("ETH", "GBP");
System.out.println("The current Ethereum price is " + gbpPrice.toCurrency()); System.out.println("The current Ethereum buy price is " + gbpPrice.toCurrency());
// Get current Litecoin spot price in Euros. // Get current Litecoin sell price in Euros.
final CryptoPrice euroPrice = CryptoPrice.spotPrice("LTC", "EUR"); final var euroPrice = CryptoPrice.sellPrice("LTC", "EUR");
System.out.println("The current Litecoin price is " + euroPrice.toCurrency()); System.out.println("The current Litecoin sell price is " + euroPrice.toCurrency());
System.out.println(); System.out.println();
// Get current Bitcoin buy price using API. // Get exchange rate using API.
// See: https://developers.coinbase.com/api/v2#get-buy-price // See: https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-exchange-rates
final CryptoPrice buyPrice = CryptoPrice final var response = CryptoPrice.apiCall(List.of("exchange-rates"),
.toPrice(CryptoPrice.apiCall(List.of("prices", "BTC-USD", "buy"), Collections.emptyMap())); Collections.singletonMap("currency", "USD"));
System.out.println("The current " + buyPrice.getBase() + " buy price is " + buyPrice.getAmount() final var rates = new JSONObject(response).getJSONObject("data").getJSONObject("rates");
+ " in " + buyPrice.getCurrency()); System.out.printf("The USD-EUR exchange rate is: %s%n", rates.getString("EUR"));
} }
} catch (CryptoException e) { } catch (CryptoException e) {
System.err.println("HTTP Status Code: " + e.getStatusCode()); System.err.println("HTTP Status Code: " + e.getStatusCode());

View file

@ -2,9 +2,10 @@ package com.example
import net.thauvin.erik.crypto.CryptoException import net.thauvin.erik.crypto.CryptoException
import net.thauvin.erik.crypto.CryptoPrice.Companion.apiCall import net.thauvin.erik.crypto.CryptoPrice.Companion.apiCall
import net.thauvin.erik.crypto.CryptoPrice.Companion.buyPrice
import net.thauvin.erik.crypto.CryptoPrice.Companion.sellPrice
import net.thauvin.erik.crypto.CryptoPrice.Companion.spotPrice import net.thauvin.erik.crypto.CryptoPrice.Companion.spotPrice
import net.thauvin.erik.crypto.CryptoPrice.Companion.toPrice import org.json.JSONObject
import java.io.IOException import java.io.IOException
fun main(args: Array<String>) { fun main(args: Array<String>) {
@ -19,20 +20,21 @@ fun main(args: Array<String>) {
println() println()
// Get current Ethereum spot price in Pound sterling. // Get current Ethereum sell price in Pound sterling.
val gbpPrice = spotPrice("ETH", "GBP") val gbpPrice = sellPrice("ETH", "GBP")
println("The current Ethereum price is ${gbpPrice.toCurrency()}") println("The current Ethereum sell price is ${gbpPrice.toCurrency()}")
// Get current Litecoin spot price in Euro. // Get current Litecoin buy price in Euro.
val euroPrice = spotPrice("LTC", "EUR") val euroPrice = buyPrice("LTC", "EUR")
println("The current Litecoin price is ${euroPrice.toCurrency()}") println("The current Litecoin buy price is ${euroPrice.toCurrency()}")
println() println()
// Get current Bitcoin buy price using API. // Get exchange rate using API.
// See: https://developers.coinbase.com/api/v2#get-buy-price // See: https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-exchange-rates
val buyPrice = apiCall(listOf("prices", "BTC-USD", "buy"), emptyMap()).toPrice() val response = apiCall(listOf("exchange-rates"), mapOf("currency" to "usd"))
println("The current ${buyPrice.base} buy price is ${buyPrice.amount} in ${buyPrice.currency}") val rates = JSONObject(response).getJSONObject("data").getJSONObject("rates")
println("The USD-EUR exchange rate is: ${rates.getString("EUR")}")
} }
} catch (e: CryptoException) { } catch (e: CryptoException) {
System.err.println("HTTP Status Code: ${e.statusCode}") System.err.println("HTTP Status Code: ${e.statusCode}")

View file

@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

12
pom.xml
View file

@ -8,9 +8,9 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>net.thauvin.erik</groupId> <groupId>net.thauvin.erik</groupId>
<artifactId>cryptoprice</artifactId> <artifactId>cryptoprice</artifactId>
<version>0.9.0</version> <version>1.0.0-SNAPSHOT</version>
<name>cryptoprice</name> <name>cryptoprice</name>
<description>Retrieve cryptocurrencies current prices.</description> <description>Retrieve cryptocurrencies prices.</description>
<url>https://github.com/ethauvin/cryptoprice</url> <url>https://github.com/ethauvin/cryptoprice</url>
<licenses> <licenses>
<license> <license>
@ -40,7 +40,7 @@
<dependency> <dependency>
<groupId>org.jetbrains.kotlin</groupId> <groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-bom</artifactId> <artifactId>kotlin-bom</artifactId>
<version>1.6.10</version> <version>1.7.10</version>
<type>pom</type> <type>pom</type>
<scope>import</scope> <scope>import</scope>
</dependency> </dependency>
@ -50,19 +50,19 @@
<dependency> <dependency>
<groupId>org.jetbrains.kotlin</groupId> <groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib-jdk8</artifactId> <artifactId>kotlin-stdlib-jdk8</artifactId>
<version>1.6.10</version> <version>1.7.10</version>
<scope>runtime</scope> <scope>runtime</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.squareup.okhttp3</groupId> <groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId> <artifactId>okhttp</artifactId>
<version>4.9.3</version> <version>4.10.0</version>
<scope>runtime</scope> <scope>runtime</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.json</groupId> <groupId>org.json</groupId>
<artifactId>json</artifactId> <artifactId>json</artifactId>
<version>20211205</version> <version>20220320</version>
<scope>runtime</scope> <scope>runtime</scope>
</dependency> </dependency>
</dependencies> </dependencies>

View file

@ -42,11 +42,10 @@ import java.io.IOException
import java.math.BigDecimal import java.math.BigDecimal
import java.text.NumberFormat import java.text.NumberFormat
import java.time.LocalDate import java.time.LocalDate
import java.util.Currency import java.util.*
import java.util.Locale
/** /**
* Retrieves and holds a cryptocurrency current spot price. * Retrieves and holds a cryptocurrency price.
* *
* @constructor Constructs a new [CryptoPrice] object. * @constructor Constructs a new [CryptoPrice] object.
* *
@ -116,6 +115,19 @@ open class CryptoPrice(val base: String, val currency: String, val amount: BigDe
} }
} }
/**
* Retrieves the buy price.
*
* @param base The cryptocurrency ticker symbol, such as `BTC`, `ETH`, `LTC`, etc.
* @param currency The fiat currency ISO 4217 code, such as `USD`, `GPB`, `EUR`, etc.
*/
@JvmStatic
@JvmOverloads
@Throws(CryptoException::class, IOException::class)
fun buyPrice(base: String, currency: String = "USD"): CryptoPrice {
return apiCall(listOf("prices", "$base-$currency", "buy"), emptyMap()).toPrice()
}
/** /**
* Prints the current prices for the specified cryptocurrencies. * Prints the current prices for the specified cryptocurrencies.
*/ */
@ -129,7 +141,20 @@ open class CryptoPrice(val base: String, val currency: String, val amount: BigDe
} }
/** /**
* Retrieves the current spot price. * Retrieves the sell price.
*
* @param base The cryptocurrency ticker symbol, such as `BTC`, `ETH`, `LTC`, etc.
* @param currency The fiat currency ISO 4217 code, such as `USD`, `GPB`, `EUR`, etc.
*/
@JvmStatic
@JvmOverloads
@Throws(CryptoException::class, IOException::class)
fun sellPrice(base: String, currency: String = "USD"): CryptoPrice {
return apiCall(listOf("prices", "$base-$currency", "sell"), emptyMap()).toPrice()
}
/**
* Retrieves the spot price.
* *
* @param base The cryptocurrency ticker symbol, such as `BTC`, `ETH`, `LTC`, etc. * @param base The cryptocurrency ticker symbol, such as `BTC`, `ETH`, `LTC`, etc.
* @param currency The fiat currency ISO 4217 code, such as `USD`, `GPB`, `EUR`, etc. * @param currency The fiat currency ISO 4217 code, such as `USD`, `GPB`, `EUR`, etc.

View file

@ -33,11 +33,13 @@
package net.thauvin.erik.crypto package net.thauvin.erik.crypto
import net.thauvin.erik.crypto.CryptoPrice.Companion.apiCall import net.thauvin.erik.crypto.CryptoPrice.Companion.apiCall
import net.thauvin.erik.crypto.CryptoPrice.Companion.buyPrice
import net.thauvin.erik.crypto.CryptoPrice.Companion.sellPrice
import net.thauvin.erik.crypto.CryptoPrice.Companion.spotPrice import net.thauvin.erik.crypto.CryptoPrice.Companion.spotPrice
import net.thauvin.erik.crypto.CryptoPrice.Companion.toPrice import net.thauvin.erik.crypto.CryptoPrice.Companion.toPrice
import org.json.JSONObject import org.json.JSONObject
import java.time.LocalDate import java.time.LocalDate
import java.util.Locale import java.util.*
import kotlin.test.Test import kotlin.test.Test
import kotlin.test.assertEquals import kotlin.test.assertEquals
import kotlin.test.assertFailsWith import kotlin.test.assertFailsWith
@ -54,29 +56,35 @@ class CryptoPriceTest {
@Test @Test
@Throws(CryptoException::class) @Throws(CryptoException::class)
fun testBitcoinPrice() { fun testBitcoinPrice() {
val price = spotPrice("BTC") val prices = listOf(spotPrice("BTC"), buyPrice("BTC"), sellPrice("BTC"))
for (price in prices) {
assertEquals("BTC", price.base, "BTC") assertEquals("BTC", price.base, "BTC")
assertEquals("USD", price.currency, "is USD") assertEquals("USD", price.currency, "is USD")
assertTrue(price.amount.signum() > 0, "BTC > 0") assertTrue(price.amount.signum() > 0, "BTC > 0")
} }
}
@Test @Test
@Throws(CryptoException::class) @Throws(CryptoException::class)
fun testEtherPrice() { fun testEtherPrice() {
val price = spotPrice("ETH", "EUR") val prices = listOf(spotPrice("ETH", "EUR"), buyPrice("ETH", "EUR"), sellPrice("ETH", "EUR"))
for (price in prices) {
assertEquals("ETH", price.base, "ETH") assertEquals("ETH", price.base, "ETH")
assertEquals("EUR", price.currency, "is EUR") assertEquals("EUR", price.currency, "is EUR")
assertTrue(price.amount.signum() > 0, "ETH > 0") assertTrue(price.amount.signum() > 0, "ETH > 0")
} }
}
@Test @Test
@Throws(CryptoException::class) @Throws(CryptoException::class)
fun testLitecoinPrice() { fun testLitecoinPrice() {
val price = spotPrice("LTC", "GBP") val prices = listOf(spotPrice("LTC", "GBP"), buyPrice("LTC", "GBP"), sellPrice("LTC", "GBP"))
for (price in prices) {
assertEquals("LTC", price.base, "LTC") assertEquals("LTC", price.base, "LTC")
assertEquals("GBP", price.currency, "is GBP") assertEquals("GBP", price.currency, "is GBP")
assertTrue(price.amount.signum() > 0, "LTC > 0") assertTrue(price.amount.signum() > 0, "LTC > 0")
} }
}
@Test @Test
@Throws(CryptoException::class) @Throws(CryptoException::class)
@ -102,7 +110,7 @@ class CryptoPriceTest {
@Test @Test
@Throws(CryptoException::class) @Throws(CryptoException::class)
fun testSpotPrice() { fun testPrices() {
assertFailsWith( assertFailsWith(
message = "FOO did not fail", message = "FOO did not fail",
exceptionClass = CryptoException::class, exceptionClass = CryptoException::class,
@ -112,11 +120,11 @@ class CryptoPriceTest {
assertFailsWith( assertFailsWith(
message = "BAR did not fail", message = "BAR did not fail",
exceptionClass = CryptoException::class, exceptionClass = CryptoException::class,
block = { spotPrice("BTC", "BAR") } block = { buyPrice("BTC", "BAR") }
) )
try { try {
spotPrice("FOOBAR") sellPrice("FOOBAR")
} catch (e: CryptoException) { } catch (e: CryptoException) {
assertNotEquals(400, e.statusCode, "FOOBAR status code is not 400") assertNotEquals(400, e.statusCode, "FOOBAR status code is not 400")
} }