Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add qt/c++ example #131

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions qt/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
cmake_minimum_required(VERSION 3.5)

project(coinex_bot LANGUAGES CXX)

set(CMAKE_INCLUDE_CURRENT_DIR ON)

set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

find_package(Qt5Core)
find_package(Qt5WebSockets)

add_executable(coinex_bot
main.cpp
coinexapi.h coinexapi.cpp
)
target_link_libraries(coinex_bot Qt5::Core Qt5::WebSockets)
211 changes: 211 additions & 0 deletions qt/coinexapi.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
#include "coinexapi.h"
#include <QCryptographicHash>
#include <iostream>
#include <QObjectUserData>
#include <QJsonObject>
#include <QJsonDocument>
#include <QSslConfiguration>

CoinexAPI::CoinexAPI(QString accessId, QString secretKey, QObject *parent):
QObject(parent),
mAccessID(accessId),
mSecretKey(secretKey)
{
setObjectName("CoinexApi");

mUrl = "wss://socket.coinex.com";

}

void CoinexAPI::signin()
{
QDateTime currentDateTime = QDateTime::currentDateTimeUtc();
qint64 mtime = currentDateTime.toMSecsSinceEpoch();
auto sign = signinGenerate(mtime);
QVariantMap param;

param["id"] = 1;
param["method"] = "server.sign";
param["params"] = QVariantList() << mAccessID << sign << mtime;

QString req = variantToJson(param);

mWebSocket->sendTextMessage(req);
}

void CoinexAPI::ping()
{
QVariantMap param;

param["id"] = ++mID;
param["method"] = "server.ping";
param["params"] = "[]";

QString req = variantToJson(param);

if (mWebSocket->isValid())
{
mWebSocket->sendTextMessage(req);
}
else
{
qDebug() << "Connection faield!";
}
}

void CoinexAPI::serverTime()
{
QVariantMap param;

param["id"] = ++mID;
param["method"] = "server.time";
param["params"] = "[]";

auto req = variantToJson(param);

if (mWebSocket->isValid())
{
mWebSocket->sendTextMessage(req);
}
else
{
qDebug() << "Connection faield!";
}
}

void CoinexAPI::subscribe_depth()
{
QVariantMap param;

param["id"] = ++mID;
param["method"] = "depth.subscribe";
param["params"] = QVariantList() << "BTCUSDT" << 10 << "1";

auto req = variantToJson(param);

if (mWebSocket->isValid())
{
mWebSocket->sendTextMessage(req);
}
else
{
qDebug() << "Connection faield!";
}
}

void CoinexAPI::subscribe_asset()
{
qDebug() << "Ping start ";

QVariantMap param;

param["id"] = ++mID;
param["method"] = "asset.subscribe";
param["params"] = QVariantList() << "USDT" << "CET";

auto req = variantToJson(param);

if (mWebSocket->isValid())
{
mWebSocket->sendTextMessage(req);
qDebug() << "Ping start " << mID;
}
else
{
qDebug() << "Connection faield!";
}
}

void CoinexAPI::onConnected()
{
std::cout << "Connected to coinex ..." << std::endl;

// Authenticate
signin();

}

void CoinexAPI::error(QAbstractSocket::SocketError error)
{
std::cout << "Error : " << mWebSocket->errorString().toStdString() << std::endl;
}

void CoinexAPI::closed()
{
if (mTimer)
{
mTimer->stop();
}

std::cout << "Connection close !" << std::endl;
}

void CoinexAPI::onTextMessageReceived(QString message)
{
qDebug() << message;

QJsonDocument res = QJsonDocument::fromJson(message.toLocal8Bit());
auto js = res.object();
auto map = res.toVariant().toMap();

if (js.contains("id") && (js.value("id").toInt() == 1))
{
auto res = js["result"].toObject();

if (res.value("status").toString() == "success")
{
qDebug() << "Authenticate complete. ";

// subscribe depth
subscribe_depth();

// subscribe asset
subscribe_asset();

if (mTimer)
{
// note: important to keepalive
mTimer->start(5000);
}
}
else
{
qDebug() << "Authenticate not complete : " << js.value("error");
}
}
}

QString CoinexAPI::signinGenerate(qint64 time)
{
QString signdata = QString("access_id=%1&tonce=%2&secret_key=%3").arg(mAccessID.toUpper()).arg(time).arg(mSecretKey.toUpper());

auto hash = QCryptographicHash::hash(signdata.toLocal8Bit(), QCryptographicHash::Md5).toHex().toUpper();

return hash;
}

QString CoinexAPI::variantToJson(QVariantMap map)
{
QJsonDocument js = QJsonDocument::fromVariant(map);

return js.toJson(QJsonDocument::Compact);
}

void CoinexAPI::start()
{
mTimer = new QTimer(this);

connect(mTimer, &QTimer::timeout, this, &CoinexAPI::ping);

mWebSocket = new QWebSocket;

connect(mWebSocket, QOverload<QAbstractSocket::SocketError>::of(&QWebSocket::error), this, &CoinexAPI::error);

connect(mWebSocket, &QWebSocket::connected, this, &CoinexAPI::onConnected);
connect(mWebSocket, &QWebSocket::disconnected, this, &CoinexAPI::closed);
connect(mWebSocket, &QWebSocket::textMessageReceived, this, &CoinexAPI::onTextMessageReceived);

mWebSocket->open(QUrl(mUrl));

// signin();
}
55 changes: 55 additions & 0 deletions qt/coinexapi.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#ifndef COINEXAPI_H
#define COINEXAPI_H

#include <QAbstractSocket>
#include <QThread>
#include <QTimer>
#include <QWebSocket>


class CoinexAPI: public QObject
{
Q_OBJECT

public:
CoinexAPI(QString accessId, QString secretKey, QObject *parent = nullptr);

public slots:
void start();

void onConnected();

void error(QAbstractSocket::SocketError error);

void closed();

void onTextMessageReceived(QString message);

// Coinex API

public slots:
void signin();

void ping();

void serverTime();

void subscribe_depth();

void subscribe_asset();

private:
QString signinGenerate(qint64 time);

QString variantToJson(QVariantMap map);

private:
QWebSocket *mWebSocket = nullptr;
QUrl mUrl;
QString mAccessID;
QString mSecretKey;
quint64 mID = 0;
QTimer *mTimer = nullptr;
};

#endif // COINEXAPI_H
13 changes: 13 additions & 0 deletions qt/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#include <QCoreApplication>

#include "coinexapi.h"

int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);

CoinexAPI *coinexAPI = new CoinexAPI("ACCESS_TOKEN", "SECRET_TOKEN");
coinexAPI->start();

return a.exec();
}