A Kotlin Tutorial to Fetch Market Data
14 August 2024
In today's globalized economy, currency exchange rates play a crucial role in various aspects of the financial sector. For developers, accessing accurate and real-time currency data is essential for building financial applications. TraderMade offers a comprehensive API that provides real-time, historical forex data, and currency conversion data for numerous currency pairs.
In this Kotlin tutorial, we will guide you through the process of using Kotlin to interact with the TraderMade API, covering everything from setting up your development environment to fetching and displaying currency data.
API Key
To use the TraderMade API, sign up for an account, navigate to the API section, choose a subscription plan, and copy your API key.
Let’s Code
We are dividing our Kotlin language tutorial into several steps to make it easy to understand. Now, let us begin the code part by establishing the environment.
Setting Up the Environment
The code begins by importing several key libraries:
1) Retrofit: This library is essential for making HTTP requests to a REST API. It simplifies the process by allowing you to define your API calls as Kotlin interfaces.
2) GsonConverterFactory: This converter parses the JSON response from the API into Kotlin objects. Gson, a popular library, handles the conversion.
3) OkHttpClient: This is the HTTP client used by Retrofit under the hood. It allows you to configure aspects of the HTTP requests, such as setting connection timeouts.
4) Logger: The Logger logs messages during the program's execution, which is useful for debugging and tracking the flow of execution.
import retrofit2.Retrofit import retrofit2.converter.gson.GsonConverterFactory import retrofit2.Call import retrofit2.http.GET import retrofit2.http.Query import okhttp3.OkHttpClient import java.util.concurrent.TimeUnit import java.util.logging.Logger
Defining Data Models
Here, we define two data classes that represent the structure of the API's response:
1) LiveCurrencyResponse: This class represents the API's overall response. It contains a list of Quote objects, each corresponding to specific live forex prices.
2) Quote: The Quote class holds individual data points for currency exchange rates, including:
a) Ask: The asking price for the currency.
b) Bid: The bidding price.
c) Mid: The mid-market rate, calculated as an average of the bid and ask prices.
d) base_currency and quote_currency: Represent the currencies involved in the exchange (e.g., USD and EUR).
data class LiveCurrencyResponse(val quotes: List<Quote>) data class Quote(val ask: Double, val bid: Double, val mid: Double, val base_currency: String, val quote_currency: String)
Creating the API Interface
This interface defines the API endpoints and the methods used to interact with them:
1) @GET("live"): This annotation specifies that we are making a GET request to the API's "live" endpoint.
2) getLiveCurrencyData: This function defines the parameters for the GET request:
a) apiKey: Your API key for authentication.
b) currencyPair: The currency pair you want to retrieve data for (e.g., "USDEUR").
3) The function returns a Call<LiveCurrencyResponse>, which is an asynchronous call object that can be executed to get the response from the API.
interface LiveCurrencyApiService { @GET("live") fun getLiveCurrencyData(@Query("api_key") apiKey: String, @Query("currency") currencyPair: String): Call<LiveCurrencyResponse> }
Setting Up the Main Function
The main function starts by initializing a Logger instance. Then, you declare your API key and the currency pair you want to monitor (in this case, USD to EUR). This setup is crucial because you'll be using these values to make the API request.
fun main() { val logger = Logger.getLogger("TraderMadeLogger") // Replace your API key val apiKey = "API_KEY" val baseCurrency = "USD" val quoteCurrency = "EUR"
Configuring OkHttpClient
Here, we configure the OkHttpClient:
1) Connect timeout: The maximum time to wait to establish a connection.
2) writeTimeout: The maximum time to wait for sending data to the server.
3) readTimeout: The maximum time to wait for receiving data from the server.
These settings ensure that the application does not hang indefinitely and handles network issues gracefully.
// OkHttpClient setup val client = OkHttpClient.Builder() .connectTimeout(10, TimeUnit.SECONDS) .writeTimeout(10, TimeUnit.SECONDS) .readTimeout(30, TimeUnit.SECONDS) .build()
Configuring Retrofit
Next, we set up Retrofit:
1) baseUrl: This is the base URL of the API you're working with. In this case, it's the TraderMade API. Note that this URL points to the endpoint where you can access live currency data, but you could modify the URL to access other services like currency conversions or forex historical data.
2) Client: The OkHttpClient instance was configured earlier.
3) addConverterFactory: We add the GsonConverterFactory to handle JSON-to-Kotlin object conversion.
// Retrofit setup val retrofit = Retrofit.Builder() .baseUrl("https://marketdata.tradermade.com/api/v1/") .client(client) .addConverterFactory(GsonConverterFactory.create()) .build()
Making the API Request
Here's where the API request is made:
1) Create: We create an instance of LiveCurrencyApiService using the Retrofit instance.
2) getLiveCurrencyData: We call this method, passing in the API key and the currency pair. This returns a Call object that we can execute to get the response.
3) execute: The execute method makes a synchronous request. The logger helps track the request's progress.
// Fetch live currency data val liveCurrencyService = retrofit.create(LiveCurrencyApiService::class.java) val liveCurrencyCall = liveCurrencyService.getLiveCurrencyData(apiKey, "$baseCurrency$quoteCurrency") logger.info("Starting live currency request...") val liveCurrencyResponse = liveCurrencyCall.execute() logger.info("Live currency request finished.")
Handling the Response
After the request is complete, the response is checked:
1) isSuccessful: This checks if the request was successful.
2) Quote: If successful, the first Quote in the list is extracted.
3) resultText: The quote details are printed out (ask, bid, and mid-price).
4) If no quotes are found or the request fails, appropriate messages are printed.
if (liveCurrencyResponse.isSuccessful) { val quote = liveCurrencyResponse.body()?.quotes?.firstOrNull() if (quote != null) { val resultText = "Ask: ${quote.ask}\nBid: ${quote.bid}\nMid: ${quote.mid}" println(resultText) } else { println("No quotes found.") } } else { println("Live currency request failed with code: ${liveCurrencyResponse.code()}") }
Cleaning Up
Finally, the OkHttpClient resources are cleaned up to prevent any potential memory leaks:
1) shutdown: This shuts down the executor service that manages network requests.
2) Evict all: This evicts all idle connections from the connection pool.
3) The logger marks the end of the program execution.
client.dispatcher.executorService.shutdown() client.connectionPool.evictAll() logger.info("Program finished.") }
Note: In this Kotlin programming language tutorial, we covered the live currency data endpoint using the base URL (https://marketdata.tradermade.com/api/v1/). However, TraderMade offers other endpoints that you can access by changing the URL. For example, you can perform currency conversions or retrieve historical data by modifying the endpoint accordingly.
Compiling the Kotlin Code
This command is used to compile your Kotlin source file (Realtime.kt) into bytecode which is available to be executed by the Java Virtual Machine (JVM).
1) kotlinc: This is the Kotlin compiler. It compiles Kotlin code into Java bytecode, which can then be run on the JVM.
2) -cp: This stands for "classpath," which is a parameter that tells the compiler where to find external libraries required for your project. In this case, you've specified multiple JAR files located in the libs/ directory.
3) -d out: This specifies the output directory where the compiled bytecode will be saved. In this case, the compiled files will be placed in the out directory.
4) src/Realtime.kt: This is the path to the Kotlin source file that you want to compile. The file is located in the src directory.
kotlinc -cp "libs/okio-jvm-3.9.0.jar;libs/retrofit-2.11.0.jar;libs/converter-gson-2.11.0.jar;libs/okhttp-4.12.0.jar;libs/okhttp-urlconnection-4.12.0.jar;libs/gson-2.11.0.jar;libs/annotations-24.1.0.jar;libs/kotlin-stdlib-2.0.0.jar" -d out src/Realtime.kt
Running the Compiled Kotlin Code
This command runs the compiled Kotlin program using the Java Virtual Machine (JVM).
1) Java: This is the command to run Java programs. It starts the JVM and executes the specified class.
2) -cp "out; libs/...": The -cp flag specifies the classpath, including the out directory for compiled classes and the libs/ directory for external libraries, telling the JVM where to find everything needed to run the program.
3) Com. api.RealtimeKt: This is the fully qualified name of the Kotlin class containing your main function, with Kt appended to the filename (e.g., Realtime.kt becomes RealtimeKt).
java -cp "out;libs/okio-jvm-3.9.0.jar;libs/retrofit-2.11.0.jar;libs/converter-gson-2.11.0.jar;libs/okhttp-4.12.0.jar;libs/okhttp-urlconnection-4.12.0.jar;libs/gson-2.11.0.jar;libs/annotations-24.1.0.jar;libs/kotlin-stdlib-2.0.0.jar" com.api.RealtimeKt
Together, these commands first compile your Kotlin code into bytecode, resolving all dependencies from the specified JAR files, and then execute the resulting program using the same dependencies during runtime.
Output
Here is our output.
Aug 09, 2024 4:04:10 PM com.api.RealtimeKt main INFO: Starting live currency request... Aug 09, 2024 4:04:12 PM com.api.RealtimeKt main INFO: Live currency request finished. Ask: 0.9155665 Bid: 0.9155581 Mid: 0.9155581 Aug 09, 2024 4:04:12 PM com.api.RealtimeKt main INFO: Program finished.
Conclusion
You've now successfully navigated the process of using Kotlin to interact with the TraderMade API. This Kotlin programming tutorial has equipped you with the knowledge to work with real-time forex data, a crucial skill for building modern financial applications.
With the flexibility to adapt this setup for currency conversions or forex historical data, you now have a powerful tool at your disposal. As you continue to explore and build upon this foundation, you'll be able to create more dynamic and responsive applications tailored to various financial needs.
If you have any questions or need further assistance, don't hesitate to contact us through our live chat or via email.