File: /var/www/exnova-telegram-bot-v2/autotrading.js
import { createClient } from 'redis';
import pkg from 'node-laravel-queue';
const nodelaravel = pkg;
import { fromString } from 'uuidv4';
import {SsidAuthMethod, ClientSdk, BlitzOptionsDirection, UserProfile, Balances, Balance, BalanceType, BlitzOptions, InstrumentType} from "@tradecodehub/client-sdk-js";
try {
let requestData = process.argv[2]
requestData = new URLSearchParams(requestData);
let ssid = requestData.get('ssid')
let email = requestData.get('email')
let bot_id = requestData.get('bot_id')
let balance_type = requestData.get('balance_type')
let blitzBetPrice = process.argv[3];
let blitzDirection = process.argv[4];
let balancesObject = '';
let blitzOptions = '';
let positions = '';
const sdk = await ClientSdk.create(
'wss://ws.trade.exnova.com/echo/websocket',
303,
new SsidAuthMethod(ssid)
)
let profile = {};
const redisClient = createClient();
redisClient.rpush = redisClient.rPush;
redisClient.on('error', (err) => console.log('Redis Client Error', err));
await redisClient.connect();
let tradePair = requestData.get('trade_pair')
let expirationTime = requestData.get('option_expiration_time')*1;
balancesObject = await sdk.balances()
let balanceObject = balancesObject.getBalances().find((balance) => balance.type === balance_type);
blitzOptions = await sdk.blitzOptions()
const blitzOptionsActives = blitzOptions.getActives()
const blitzOptionsFirstAvailableActive = blitzOptionsActives.find((active) => active.canBeBoughtAt(new Date()) && active.ticker.indexOf(tradePair) == 0) //
let dealData = {},
queueName = 'telegram-bot-autotrading';
queueName += '-' + (Math.floor(Math.random() * 5) + 1);
if (blitzBetPrice*1 != 0) {
if (blitzDirection === 'up') {
// GO UP
dealData = await blitzOptions.buy(
blitzOptionsFirstAvailableActive,
BlitzOptionsDirection.Call,
expirationTime,
blitzBetPrice*1,
balanceObject
)
} else if (blitzDirection === 'down') {
// GO DOWN
dealData = await blitzOptions.buy(
blitzOptionsFirstAvailableActive,
BlitzOptionsDirection.Put,
expirationTime,
blitzBetPrice*1,
balanceObject
)
}
}
const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));
await sleep(500);
profile = sdk.userProfile;
positions = await sdk.positions()
dealData.direction = blitzDirection;
dealData.result = {};
dealData = JSON.parse(JSON.stringify(dealData));
dealData.email = email;
if (positions.getAllPositions().length > 0) {
positions.subscribeOnUpdatePosition((position) => {
processPosition(sdk, position, dealData, profile, redisClient, queueName, bot_id);
})
} else {
console.log('Error: Trade not found');
console.log(dealData);
if (typeof redisClient !== 'undefined') {
redisClient.quit();
}
if (typeof sdk !== 'undefined') {
sdk.shutdown();
}
}
console.log('completed');
} catch (error) {
if (typeof redisClient !== 'undefined') {
redisClient.quit();
}
if (typeof sdk !== 'undefined') {
sdk.shutdown();
}
console.error('Fatal error', error.message);
process.exit(1);
}
function processPosition(sdk, position, dealData, profile, redisClient, queueName, bot_id) {
let queueLaravelWorker = {};
if (position.instrumentType === InstrumentType.BlitzOption) {
dealData.externalId = position.externalId;
if (position.closeProfit !== undefined) { // && dealData.id === position.externalId) {
// Removing Undefined values
Object.keys(position).forEach(key => position[key] === undefined && delete position[key]);
dealData.result = position;
position.wsApiClient = '';
let Job = nodelaravel.Job;
let Queue = nodelaravel.Queue;
queueLaravelWorker = new Queue({
client: redisClient,
appname: 'exnova',
driver: 'redis',
queue: queueName,
displayName: 'App\\Jobs\\ProcessExnovaData',
scope: {
'App\\Jobs\\ProcessExnovaData': Job
}
});
let data = {data: dealData, bot_id: bot_id}
let job = new Job(data);
queueLaravelWorker.redisPush('App\\Jobs\\ProcessExnovaData', job);
}
if (position.status !== 'open') { // && dealData.id === position.externalId) {
sdk.shutdown();
redisClient.quit();
console.log('success');
}
}
}