×

Search anything:

Trading Application in C++ [Software Development Project with source code]

Binary Tree book by OpenGenus

Open-Source Internship opportunity by OpenGenus for programmers. Apply now.

Table of content

  • Introduction
  • Pre-requisites
    • Getting API key from Twelve Data API
    • Installation of cURL Library
    • Installation of JsonCpp Library
  • Approach to Implement
  • Final Implementation
  • Sample Output
  • Time and Space Complexity

Introduction

A Trading App, sometimes called a stock trading or investment app, is a handy tool that allows people to easily buy, sell, and manage various types of financial assets like stocks, bonds, cryptocurrencies, and commodities using their smartphones or tablets. It's like having a virtual stock market right at your fingertips.

Creating a Trading App is a big and complex task, but in this article at OpenGenus, we'll break it down into simple steps and use C++ to create a basic version. This simplified prototype will fetch real-time data every three milliseconds from a company's stock symbol(ticker symbol) that the user inputs. We'll also add a feature that provides buy or sell signals when it's a good time to trade stocks. Plus, we'll display the total price of the stocks whenever the signal function sends a signal. So, by the end of this article, You'll have a better understanding of how a Trading App works.

Key Takeaways

  • Real-time Data Retrieval: The prototype involves fetching real-time data at a rapid rate of every three milliseconds. This emphasizes the system's ability to provide up-to-the-minute information.
  • User-Inputted Stock Symbol: Users can input a company's stock symbol (ticker symbol) into the system, indicating a user-friendly interface.
  • Trading Signals: The prototype includes a feature that generates buy or sell signals, helping users make informed decisions about when to trade stocks.
  • Total Stock Price Display: Whenever a trading signal is generated, the system will display the total price of the stocks, enhancing transparency and user understanding.
  • Simplified Prototype: The article will explore a prototype version of a trading application, offering insight into the initial steps towards the development of a fully-fledged trading platform.

Get the code here on GitHub: Trading App in C++

Functionality:

  • User Input: Users will have the option to enter the stock symbol (ticker symbol) of the company they want to track or trade.
  • Data Retrieval and updates: The app will establish a connection with the stock exchange or a data provider to fetch real-time data in every three milliseconds, ensuring that users receive the most recent information of the selected stock data.
  • Display: The real-time data will be displayed in a user-friendly and easily digestible format.
  • Trading Signals: As part of our prototype, we mentioned that the app will provide buy or sell signals. The Real-time Data Feed will play a crucial role in generating these signals by analyzing the real-time data and market conditions. For instance, the app might generate a buy signal when certain technical indicators align positively.
  • Total Investment Value: Whenever the signal function sends a buy or sell signal, the app will calculate and display the total value of the user's investment in the selected stock. This allows users to track the impact of their trading decisions on their portfolio's overall value.

Benefits: The Real-time Data Feed feature provides users with a competitive edge in the stock market by ensuring they have access to the most current and accurate information. It enables them to make timely decisions, execute trades, and potentially maximize their investment returns.
By incorporating this feature into our Trading App prototype, users will gain a better understanding of how real-time data plays a crucial role in trading and investment decisions.

Screenshot-from-2023-09-19-17-42-27

Ticker symbol: A ticker symbol is a unique code of letters (and sometimes numbers) used to identify publicly traded companies on stock exchanges. It serves as a shorthand way to refer to and trade stocks in financial markets.

Pre-requisites

Before we can start using this, we have to take three important steps, installing JsonCpp and cURL libraries, and getting our own API key to fetch data. Let's break down each of these steps and see how to do them one by one:

  • Getting API key from Twelve Data API: To obtain your API key from Twelve Data, start by visiting their website at Twelve Data Stocks. Register for an account by providing your email, creating a password, and following the account verification process via email. Once your account is verified, log in and navigate to the "API Key" section which is in left side of your page. Here, you can get your unique API key by clicking on "reveal" button. This key is essential for accessing financial data through Twelve Data's API, so keep it secure and don't share it with unauthorized individuals.

  • Installation of cURL Library: The libcurl library in C++ is a versatile tool for making network requests and handling data transfer over various protocols like HTTP, FTP, and more. It provides an easy-to-use API, supports both synchronous and asynchronous operations, works on multiple platforms, and offers extensive customization options. It's a valuable tool for developers who need to incorporate network communication into their C++ applications.
    To install the curl library on your system, you'll need to use the package manager that is appropriate for your operating system. Here are instructions for some popular operating systems:

    • Ubuntu/Debian: On Ubuntu or Debian-based systems, you can use the apt-get command to install the curl library:

      • sudo apt-get update
      • sudo apt-get install libcurl4
    • macOS (using Homebrew): You can install the curl library with the following command:

      • brew install curl
    • Windows: On Windows, you can install libcurl as part of a development environment like MinGW or MSYS2. You can also download precompiled binaries from the libcurl website.

  • Installation of JsonCpp Library: JSONCpp is a C++ library for working with JSON data. It allows you to parse JSON, create JSON objects, access and manipulate JSON data, and serialize C++ data structures to JSON format. It's a helpful tool for handling JSON in C++ applications. Now, Go to your terminal and follow the below command:

Approach to implement

Summary

The implementation comprises a set of functions developed to access and analyze stock data using the Twelve Data API, using the company's ticker symbol as input. Each function has a specific role within the application.
Here's the order and conditions in which these functions are called:

  • Main Function:

    • Obtains user's ticker symbol input.
    • Retrieves API key from a JSON file.
    • Fetches current stock price using get_price.
    • Retrieves detailed stock data using get_stock_quote.
    • Calls print_data, ProfitLoss, and Sendsignal functions.
    • Repeats every 3 milliseconds.
  • get_price Function: Gets stock's current price from Twelve Data API.

  • get_stock_quote Function: Retrieves detailed stock information from Twelve Data API.

  • print_data Function: Neatly prints stock data to the console.

  • ProfitLoss Function: Calculates and reports profit/loss percentage.

  • Sendsignal Function: Analyzes stock price and sends buy/sell signals.

  • wantTransact Function: Calculates cost of buying/selling stock based on user input, if Sendsignal sends signal of buying/selling.

Let's begin and gain an deep understanding of each implemented functions:

WriteCallback function:

In C++ is commonly used as a callback when working with I/O libraries or frameworks, such as for HTTP requests or file operations. Its job is to handle data received during an operation, usually in chunks.

Purpose: This function serves as a callback to handle data received during I/O operations, such as HTTP requests.

Functionality: The function calculates the total size of the data, appends it to the output string, and returns the processed data size.

Parameters: WriteCallback takes four parameters
1. contents: A pointer to received data (e.g., HTTP response).
2. size: Size of each data element.
3. nmemb: Number of data elements.
4. output: A pointer to a C++ string where data is stored.

These parameters are essential for processing data received from external sources.

Implemetation:
lets understand the implementation from below breakdown:

  • totalSize calculates the data block's total size in bytes.
  • output->append(static_cast<char*>(contents), totalSize) adds the received data to the output string.
  • static_cast<char*>(contents) casts the data pointer to a character array.
    totalSize specifies the number of characters to append.
  • At last, the function returns totalSize, indicating the processed data size.
size_t WriteCallback(void* contents, size_t size, size_t nmemb, string* output) {
    size_t totalSize = size * nmemb;
    output->append(static_cast<char*>(contents), totalSize);
    return totalSize;
}

get_price method:

Purpose: To retrieve the current price of a stock using the Twelve Data API.

Functionality: This function utilizes cURL to make an HTTP request to the API, handles the JSON response, and returns the stock price as a string.
Parameters: It takes ticker_symbol and api as inputs, representing the stock symbol and API key, respectively.
Implementation:
lets understand the implementation step by step:

  • Function Definition: This function is called "get_price" and takes a stock symbol and an API key. It returns the stock's price as a string.
  • Initializing cURL: We set up a tool called cURL to make web requests. If there's an issue, we print an error and stop.
  • Creating the URL: We create a web address (URL) for fetching stock price data.
  • Setting Up Data Handling: We tell cURL how to handle the data from the web.
  • Preparing for Response: We create an empty string to store the web response.
  • Making the Request: We request the stock price data from the web. If something goes wrong, we report an error.
  • Cleaning Up: After the request, we clean up and release resources.
  • Parsing JSON: We use a library called JsonCpp to understand the data in JSON format.
  • Handling Parsing Errors: If there are issues with understanding the data, we report errors.
  • Getting the Price: Finally, we extract and return the stock price as a string. If anything went wrong, we return an empty string.

As This code fetches a stock's price from the web, reads it in JSON format, and returns the price as a string. If reports errors that means anything goes wrong. We will see all the above explaination as a comment in our implementation of get_price method below:

string get_price(const string& ticker_symbol, const string& api) {

    //intializing cURL
    CURL* curl = curl_easy_init();
    if (!curl) {
        cerr << "Failed to initialize cURL." << endl;
        return "";
    }

    // Set up the URL
    string url = "https://api.twelvedata.com/price?symbol=" + ticker_symbol + "&apikey=" + api;
    curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);

    // Create a string to store the JSON response
    string jsonResponse;

    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &jsonResponse);

    // Perform the HTTP request
    CURLcode res = curl_easy_perform(curl);
    if (res != CURLE_OK) {
        cerr << "cURL request failed: " << curl_easy_strerror(res) << endl;
        return "";
    }

    // Clean up cURL
    curl_easy_cleanup(curl);

    // Parse the JSON data using JsonCpp
    Json::CharReaderBuilder builder;
    Json::CharReader* reader = builder.newCharReader();
    Json::Value root;
    string errors;
    if (!reader->parse(jsonResponse.c_str(), jsonResponse.c_str() + jsonResponse.size(), &root, &errors)) {
        cerr << "Failed to parse JSON: " << errors << endl;
        delete reader;
        return "";
    }
    delete reader;

    // Extract and return the price
    string price = root["price"].asString();
    return price;
}

get_stock_quote method:

This code C++ function retrieves stock quotes using the cURL library to make an HTTP request to the Twelve Data API and then parses the JSON response
using the JsonCpp library.

Purpose: To fetch detailed stock information using the Twelve Data API.
Functionality: This function uses cURL to request stock data, parses the JSON response, and returns the data as a Json::Value object.
Parameters: It takes ticker_symbol and api as inputs, similar to the get_price function.

Implementation:
Here's a explanation of what each part of the code does:

  • Initialize cURL: It starts by initializing the cURL library using curl_easy_init(). If the initialization fails, it prints an error message and returns an empty JSON object.
  • Set up the API URL: It constructs the URL for the API request using the provided ticker_symbol (stock symbol) and api key.
  • Configure cURL: It sets various options for the cURL request, including the URL to fetch (CURLOPT_URL) and a callback function (WriteCallback) to handle the response data.
  • Create a string to store the JSON response: It creates an empty string called jsonResponse to store the JSON data received from the API.
  • Perform the HTTP request: It uses curl_easy_perform to execute the HTTP request. If the request fails, it prints an error message and returns an empty JSON object.
  • Clean up cURL: After the request is complete, it cleans up and releases the cURL resources with curl_easy_cleanup.
  • Parse JSON response: It uses JsonCpp to parse the JSON data stored in jsonResponse. If parsing fails, it prints an error message and returns an empty JSON object.
  • Return the parsed JSON: Finally, it returns the parsed JSON data as a Json::Value object, which can be used to access the stock quote information.

This function essentially fetches stock quotes from the Twelve Data API, handles errors gracefully, and provides the parsed JSON data for further processing.

Json::Value get_stock_quote(const string& ticker_symbol, const string& api) {
    CURL* curl = curl_easy_init();
    if (!curl) {
        cerr << "Failed to initialize cURL." << endl;
        return Json::Value(); // Return an empty JSON value on error
    }

    // Set up the URL
    string url = "https://api.twelvedata.com/quote?symbol=" + ticker_symbol + "&apikey=" + api;
    curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);

    // Create a string to store the JSON response
    string jsonResponse;

    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &jsonResponse);

    // Perform the HTTP request
    CURLcode res = curl_easy_perform(curl);
    if (res != CURLE_OK) {
        cerr << "cURL request failed: " << curl_easy_strerror(res) << endl;
        return Json::Value(); // Return an empty JSON value on error
    }

    // Clean up cURL
    curl_easy_cleanup(curl);

    // Parse the JSON data using JsonCpp
    Json::CharReaderBuilder builder;
    Json::CharReader* reader = builder.newCharReader();
    Json::Value root;
    string errors;
    if (!reader->parse(jsonResponse.c_str(), jsonResponse.c_str() + jsonResponse.size(), &root, &errors)) {
        cerr << "Failed to parse JSON: " << errors << endl;
        delete reader;
        return Json::Value(); // Return an empty JSON value on error
    }
    delete reader;

    return root;
}

profitLoss function:

This function calculates and reports the profit or loss percentage for a stock based on its opening and closing prices. It then displays a user-friendly message indicating whether the stock is in profit, loss, or a neutral state along with the calculated percentage.

Purpose: To calculate and report the profit or loss percentage based on opening and closing prices.
Functionality: Calculates the percentage change and provides a user-friendly message indicating whether the stock is in profit, loss, or a neutral state.
Parameters: It takes open, close, and company's name as inputs.

void ProfitLoss(float open, float close, std::string name) {
    float percentage_change = ((close - open) / open) * 100;

    if (percentage_change > 0) {
        cout << "\nThe " + name + " stocks is in profit of " << percentage_change << "%\n";
    } else if (percentage_change < 0) {
        cout << "\nThe " + name + " stocks is in loss of " << percentage_change << "%\n";
    } else {
        cout << "\nThe " + name + " stocks is in a neutral state of " << percentage_change << "%\n";
    }
}

wantTransact function:

It calculates the cost of buying or selling stock based on user input. It asks the user for the amount of stock, whether they want to see the cost, and then calculates and displays the cost or an "OKAY" message based on their choice. If the user's input is not "Y" or "N," it reports an invalid choice.

Purpose: To calculate the cost of buying or selling stock based on user input.
Functionality: Interacts with the user to determine if they want to see the cost of buying or selling stock and provides relevant information accordingly.
Parameters: It takes ans (user choice), amount (amount of stock), and price (stock price) as inputs.

void wantTransact(string ans, int amount, float price) {
    cout << "Enter the amount of stock of buying selling limit: ";
    cin >> amount;
    cout << "\nWant to know the cost of buying or selling stock? Enter Y for yes and N for no\n";
    cout << "Your Response: ";
    cin >> ans;
    transform(ans.begin(), ans.end(), ans.begin(), ::toupper);
    if (ans == "Y") {
        cout << "\nThe stock cost: " << amount * price << "\n";
    } else if (ans == "N") {
        cout << "\nOKAY\n\n";
    } else {
        cout << "\nInvalid Choice\n";
    }
}

A function that takes various pieces of financial data as input and neatly prints them to the console, making it easy for users to see information like stock names, prices, and trading volume in a well-organized format.

Purpose: To neatly print various financial data about a stock to the console.
Functionality: Formats and displays the data in an organized manner for the user's convenience.
Parameters: It takes several parameters, including name, exchange, currency, open, high, low, close, volume, change, and price.

void print_data(string name, string exchange, string currency, float open, float high, float low, float close, float volume, float change, float price) {
    cout << "\nGenerating Data....\n\n";
    cout <<
        "name: " << name << "\n" <<
        "exchange: " << exchange << "\n" <<
        "currency:" << currency << "\n" <<
        "Open price: " << open << "\n" <<
        "High price: " << high << "\n" <<
        "Low price: " << low << "\n" <<
        "Close price: " << close << "\n" <<
        "Volume:" << volume << "\n" <<
        "Change: " << change << "\n" <<
        "Current Price: " << price << "\n";
}

Sendsignal function

It checks a given "price" against predefined "high" and "low" thresholds. If the price is lower than or equal to the low threshold, it signals to buy. If the price is higher than or equal to the high threshold, it signals to sell. Otherwise, it suggests that it's not a good time to buy or sell and wishes the user "Happy Trading!!!" The function also calls another function named "wantTransact" to potentially perform the trading action with additional information like "ans" and "amount."

Purpose: To analyze the stock price and send signals based on predefined high and low thresholds.
Functionality: Checks if the price is within the defined thresholds and sends signals for buying or selling accordingly. It also calls the wantTransact function for potential trading actions.
Parameters: It takes price, high, low, ans, and amount as inputs.

void Sendsignal(float price, float high, float low, string ans, int amount){
    if(price <= low){
        cout << "Sending Buying signal\n\n";
        wantTransact(ans, amount, price);
    }
    else if(price >= high){
        cout << "Sending Selling signal\n\n";
        wantTransact(ans, amount, price);
    }
    else{
        cout << "Not suitable for buying and selling\nHappy Trading!!!\n\n";
    }
}

main() function:

Understanding our main function is crucial, as it involves several key tasks. These tasks include retrieving an API key from a JSON file (where we've securely hidden it), making requests to fetch stock prices, and obtaining various data about a company's stock.
Purpose: The main function coordinates the entire process of fetching stock data, performing analysis, and interacting with the user.

Workflow:

  • Obtains the ticker symbol from the user.
  • Retrieves the API key from a JSON file.
  • Fetches the current stock price using the get_price function.
  • Retrieves detailed stock data using the get_stock_quote function.
  • Calls the print_data, ProfitLoss, and Sendsignal functions to provide information and trading signals.
  • Repeats this process every 3 milliseconds using a loop to continuously monitor the stock.

Let's break down these steps for a clearer understanding:

  • Getting ticker symbol from user
    string ticker;
    cout << "\nEnter Ticker symbol of a company: ";
    cin >> ticker;
    

Under infinite loop

  • Retrieving API key value:In below code, It attempts to open a file named "config.json" to read JSON data. If it can't open the file, it prints an error message and exits the program with a return code of 1. Otherwise, it reads the JSON data and stores it in a variable called config. then we convert JSON data data stored in config to string.

    Json::Value config;
    ifstream config_file("config.json", ifstream::binary);
    if (!config_file.is_open()) {
        cerr << "Failed to open config file." << endl;
        return 1;
        }
    config_file >> config;
    config_file.close();
    //Extracts from config JSON object and stores the "api_key" value as a string.
    string api_key = config["api_key"].asString();
    
  • Retriving current value of company's stock: This line of code efficiently retrieves the price of a financial instrument using the get_price function and immediately converts it into a floating-point number, assigning it to the price variable in a single line of code:

    price = stof(get_price(ticker, api_key));
    
  • Retriving the stock data of a company: We will call function name stock_quote_data to fetch stock data, storing the result in a variable named stock_data of type Json::Value, commonly used for handling JSON data in C++. If the stock_data container is not empty, it extracts essential stock information, including name, exchange, currency, open price, high price, low price, close price, volume, and change. These values are then assigned to their respective variables and converted to the appropriate data types.

    Json::Value stock_data = get_stock_quote(ticker, api_key);
    if (!stock_data.empty()) {
        name = stock_data["name"].asString();
        exchange = stock_data["exchange"].asString();
        currency = stock_data["currency"].asString();
        open = stof(stock_data["open"].asString());
        high = stof(stock_data["high"].asString());
        low = stof(stock_data["low"].asString());
        close = stof(stock_data["close"].asString());
        volume = stof(stock_data["volume"].asString());
        change = stof(stock_data["change"].asString());
    } else {
        cerr << "Failed to fetch stock quote." << endl;
        return 1;
    }
    
  • Calling other functions: Now we call all other function i.e print_data(), ProfitLoss(), Sendsignal().

    print_data(name, exchange, currency, open, high, low, close, volume, change, price);
    ProfitLoss(open, close, name);
    Sendsignal(price, high, low, ans, amount);
    
  • Retrieving data in every 3 millisecond: In order to continuously retrieve data and make function calls within an infinite loop, it is necessary to include the following line of code before terminating the loop to ensure data is obtained every 3 milliseconds.

    this_thread::sleep_for(chrono::milliseconds(3000));
    

Final Implementation

Creating a prototype of a trading application can be a complex task. To make it more manageable, we can break down the implementation into separate files. Here's a simple outline of how you can structure your project with three .cpp, two .hpp files and one .json file:

curl_functions.hpp: This C++ header file, "curl_functions.h," includes declarations for two functions: get_price and get_stock_quote. These functions are used to retrieve stock-related data based on a ticker symbol and an API source. The header also includes necessary library headers, such as string and jsoncpp/json/json.h, and uses a header guard to prevent multiple inclusions of the same header file in a single source file.

#ifndef CURL_FUNCTIONS_H
#define CURL_FUNCTIONS_H

#include <string>
#include <jsoncpp/json/json.h>
using namespace std;

string get_price(const string& ticker_symbol, const string& api);
Json::Value get_stock_quote(const string& ticker_symbol, const string& api);

#endif // CURL_FUNCTIONS_H

curl_functions.cpp: This source file will contain the actual implementation of the functions declared in curl_functions.hpp. You'll write the code here that handles HTTP requests and data retrieval.

#include "curl_function.h"
#include <iostream>
#include <curl/curl.h>
#include <string>
using namespace std;


// Callback function for cURL to handle the response
size_t WriteCallback(void* contents, size_t size, size_t nmemb, string* output) {
    size_t totalSize = size * nmemb;
    output->append(static_cast<char*>(contents), totalSize);
    return totalSize;
}

string get_price(const string& ticker_symbol, const string& api) {
    CURL* curl = curl_easy_init();
    if (!curl) {
        cerr << "Failed to initialize cURL." << endl;
        return "";
    }

    // Set up the URL
    string url = "https://api.twelvedata.com/price?symbol=" + ticker_symbol + "&apikey=" + api;
    curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);

    // Create a string to store the JSON response
    string jsonResponse;

    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &jsonResponse);

    // Perform the HTTP request
    CURLcode res = curl_easy_perform(curl);
    if (res != CURLE_OK) {
        cerr << "cURL request failed: " << curl_easy_strerror(res) << endl;
        return "";
    }

    // Clean up cURL
    curl_easy_cleanup(curl);

    // Parse the JSON data using JsonCpp
    Json::CharReaderBuilder builder;
    Json::CharReader* reader = builder.newCharReader();
    Json::Value root;
    string errors;
    if (!reader->parse(jsonResponse.c_str(), jsonResponse.c_str() + jsonResponse.size(), &root, &errors)) {
        cerr << "Failed to parse JSON: " << errors << endl;
        delete reader;
        return "";
    }
    delete reader;

    // Extract and return the price
    string price = root["price"].asString();
    return price;
}

Json::Value get_stock_quote(const string& ticker_symbol, const string& api) {
    CURL* curl = curl_easy_init();
    if (!curl) {
        cerr << "Failed to initialize cURL." << endl;
        return Json::Value(); // Return an empty JSON value on error
    }

    // Set up the URL
    string url = "https://api.twelvedata.com/quote?symbol=" + ticker_symbol + "&apikey=" + api;
    curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);

    // Create a string to store the JSON response
    string jsonResponse;

    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &jsonResponse);

    // Perform the HTTP request
    CURLcode res = curl_easy_perform(curl);
    if (res != CURLE_OK) {
        cerr << "cURL request failed: " << curl_easy_strerror(res) << endl;
        return Json::Value(); // Return an empty JSON value on error
    }

    // Clean up cURL
    curl_easy_cleanup(curl);

    // Parse the JSON data using JsonCpp
    Json::CharReaderBuilder builder;
    Json::CharReader* reader = builder.newCharReader();
    Json::Value root;
    string errors;
    if (!reader->parse(jsonResponse.c_str(), jsonResponse.c_str() + jsonResponse.size(), &root, &errors)) {
        cerr << "Failed to parse JSON: " << errors << endl;
        delete reader;
        return Json::Value(); // Return an empty JSON value on error
    }
    delete reader;

    return root;
}

functions.hpp: This header file will contain declarations for functions that are specific to your trading application's business logic. These functions might include things like buy/sell orders, trade strategies, or risk management.

#ifndef FUNCTIONS_H
#define FUNCTIONS_H

#include <string>
#include <jsoncpp/json/json.h>
using namespace std;
void ProfitLoss(float open, float close, string name);
void wantTransact(string ans, int amount, float price);
void print_data(string name, string exchange, string currency, float open, float high, float low, float close, float volume, float change, float price);
void Sendsignal(float price, float high, float low, string ans, int amount);
#endif // FUNCTIONS_H

functions.cpp: In this source file, you will provide the actual implementation of the trading-related functions declared in functions.hpp. This is where you'll write the core logic of your trading application.

#include "functions.h"
#include <iostream>
#include<bits/stdc++.h>
using namespace std;

void ProfitLoss(float open, float close, std::string name) {
    float percentage_change = ((close - open) / open) * 100;

    if (percentage_change > 0) {
        cout << "\nThe " + name + " stocks is in profit of " << percentage_change << "%\n";
    } else if (percentage_change < 0) {
        cout << "\nThe " + name + " stocks is in loss of " << percentage_change << "%\n";
    } else {
        cout << "\nThe " + name + " stocks is in a neutral state of " << percentage_change << "%\n";
    }
}

void wantTransact(string ans, int amount, float price) {
    cout << "Enter the amount of stock of buying selling limit: ";
    cin >> amount;
    cout << "\nWant to know the cost of buying or selling stock? Enter Y for yes and N for no\n";
    cout << "Your Response: ";
    cin >> ans;
    transform(ans.begin(), ans.end(), ans.begin(), ::toupper);
    if (ans == "Y") {
        cout << "\nThe stock cost: " << amount * price << "\n";
    } else if (ans == "N") {
        cout << "\nOKAY\n\n";
    } else {
        cout << "\nInvalid Choice\n";
    }
}

void print_data(string name, string exchange, string currency, float open, float high, float low, float close, float volume, float change, float price) {
    cout << "\nGenerating Data....\n\n";
    cout <<
        "name: " << name << "\n" <<
        "exchange: " << exchange << "\n" <<
        "currency:" << currency << "\n" <<
        "Open price: " << open << "\n" <<
        "High price: " << high << "\n" <<
        "Low price: " << low << "\n" <<
        "Close price: " << close << "\n" <<
        "Volume:" << volume << "\n" <<
        "Change: " << change << "\n" <<
        "Current Price: " << price << "\n";
}

void Sendsignal(float price, float high, float low, string ans, int amount){
    if(price <= low){
        cout << "Sending Buying signal\n\n";
        wantTransact(ans, amount, price);
    }
    else if(price >= high){
        cout << "Sending Selling signal\n\n";
        wantTransact(ans, amount, price);
    }
    else{
        cout << "Not suitable for buying and selling\nHappy Trading!!!\n\n";
    }
}

main.cpp: In this source file, you'll define the main function, where your program execution begins. This is where you'll set up your trading application, call functions from other files, and manage program flow.

#include <bits/stdc++.h>
#include <jsoncpp/json/json.h>
#include <fstream>
#include "functions.h"
#include "curl_function.h"
using namespace std;

int main() {
    string ticker;
    cout << "\nEnter Ticker symbol of a company: ";
    cin >> ticker;

    while (true) {
        Json::Value config;
        ifstream config_file("config.json", ifstream::binary);

        if (!config_file.is_open()) {
            cerr << "Failed to open config file." << endl;
            return 1;
        }

        config_file >> config;
        config_file.close();
    
        string api_key = config["api_key"].asString();
        string name, exchange, currency, ans;
        float open, high, low, close, volume, change, price;
        int amount;
        

        price = stof(get_price(ticker, api_key));

        Json::Value stock_data = get_stock_quote(ticker, api_key);
        if (!stock_data.empty()) {
            // std::cout << "Stock Quote for " << ticker << ": " << stock_quote.toStyledString() << std::endl;
            name = stock_data["name"].asString();
            exchange = stock_data["exchange"].asString();
            currency = stock_data["currency"].asString();
            open = stof(stock_data["open"].asString());
            high = stof(stock_data["high"].asString());
            low = stof(stock_data["low"].asString());
            close = stof(stock_data["close"].asString());
            volume = stof(stock_data["volume"].asString());
            change = stof(stock_data["change"].asString());
        } else {
            cerr << "Failed to fetch stock quote." << endl;
            return 1;
        }
            print_data(name, exchange, currency, open, high, low, close, volume, change, price);
            ProfitLoss(open, close, name);
            Sendsignal(price, high, low, ans, amount);
            this_thread::sleep_for(chrono::milliseconds(3000));
    }
    
    return 0;
}

config.json: The "config.json" file is crucial for a program, containing important settings like the "api_key" used to access internet services. It enhances security by separating sensitive information from the code and provides convenience by allowing easy updates without altering the code. When sharing your project on GitHub, remember to hide the "config.json" file by listing it in a ".gitignore" file to keep your secrets safe from public view.

{
    "api_key": "Your API key"
}

By organizing your code in this way, you can maintain a clean and modular structure for your trading application, making it easier to manage and extend as you work on different aspects of your project.

Sample Output

Commands to compile and run

Compile: g++ -o output-file-name main.cpp curl_functions.cpp functions.cpp -lcurl -ljsoncpp
Run: ./output file name

Lets check the Apple Inc data with ticker symbol "AAPL":

/*
Enter Ticker symbol of a company: AAPL

Generating Data....

name: Apple Inc
exchange: NASDAQ
currency:USD
Open price: 174.67
High price: 177.08
Low price: 174.05
Close price: 174.79
Volume:5.6663e+07
Change: 0.86
Current Price: 174.74

The Apple Inc stocks is in profit of 0.0686982%
Not suitable for buying and selling
Happy Trading!!!


Generating Data....

name: Apple Inc
exchange: NASDAQ
currency:USD
Open price: 174.67
High price: 177.08
Low price: 174.05
Close price: 174.79
Volume:5.6663e+07
Change: 0.86
Current Price: 174.74

The Apple Inc stocks is in profit of 0.0686982%
Not suitable for buying and selling
Happy Trading!!!
*/

//This will infinitely fetch data of current company in every 3 milliseconds

Time and Space Complexity

  • The Time complexity of the entire program depends on the number of iterations in the main loop (in main.cpp), which makes API requests and performs calculations. It is O(n), where n is the number of iterations.

  • The Space complexity of the program depends on the size of the JSON responses retrieved from the API during each iteration and the memory required for parsing the JSON data. It can vary based on the data retrieved and processed.

Check out my GitHub repository for more insights into trading app prototype and join me in building a complete trading application.

Get the code here on GitHub: Trading App in C++

Vidhi Srivastava

Vidhi Srivastava

Intern @ OpenGenus IQ | Algorithms & Data Structures | Exploring code and writing tech. Connect with me at https://www.linkedin.com/in/vidhisrivastava01/

Read More

Improved & Reviewed by:


Ue Kiao, PhD Ue Kiao, PhD
Trading Application in C++ [Software Development Project with source code]
Share this