HEX
Server: nginx/1.18.0
System: Linux test-ipsremont 5.4.0-214-generic #234-Ubuntu SMP Fri Mar 14 23:50:27 UTC 2025 x86_64
User: ips (1000)
PHP: 8.0.30
Disabled: pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare,
Upload Files
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');
            }
		}
}