In questo listato var CONFIG = {
ORDER_SIDE: 'BID',
SIZE: 1,
MAX_OPERATIONS: 8,
LEVELS: { BID: 6, ASK: 6 },
SECONDS: 5,
MONITORING_MODE: 'MONITORA_yourlevel'
};

var separator = "---------------------------------------------------\r\n";
var cachedBookState = null;
var lastBidPrice = null, lastBidQuantity = null, lastAskPrice = null, lastAskQuantity = null;

function isValidSideData(sideData) {
return typeof sideData.Price === 'function' && typeof sideData.Quantity === 'function';
}

function mapSideData(side, sideData, maxLevel) {
var prices = {}, quantities = {};
var isValid = isValidSideData(sideData); // Controllo eseguito una sola volta
for (var level = maxLevel; level >= 0; level--) {
prices[level] = isValid ? sideData.Price(level) : 0;
quantities[level] = isValid ? sideData.Quantity(level) : 0;
}
return { Prices: prices, Quantities: quantities };
}

function mapBookData(originalBook) {
return {
BID: mapSideData('BID', originalBook.Bid, CONFIG.LEVELS.BID),
ASK: mapSideData('ASK', originalBook.Ask, CONFIG.LEVELS.ASK)
};
}


function calculateTick(prices) {
var differences = [];
var maxLevel = CONFIG.LEVELS.BID; // Adatta per ASK se necessario


// Calcola le differenze tra livelli adiacenti
for (var i = 0; i < maxLevel; i++) {
    var diff = prices[i] - prices[i + 1];
    if (diff > 0) { // Assicurati che la differenza sia positiva
        differences.push(diff);
    }
}

// Definisci la dimensione del bin
var binSize = 0.01; // Adatta questa dimensione in base ai tuoi dati
var bins = {};

// Raggruppa le differenze in bin
for (var j = 0; j < differences.length; j++) {
    var bin = Math.floor(differences[j] / binSize) * binSize;
    if (bins[bin]) {
        bins[bin]++;
    } else {
        bins[bin] = 1;
    }
}

// Trova il bin con la frequenza massima
var maxCount = 0;
var prevalentDiff = 0;
for (var binKey in bins) {
    if (bins.hasOwnProperty(binKey)) {
        if (bins[binKey] > maxCount) {
            maxCount = bins[binKey];
            prevalentDiff = parseFloat(binKey);
        }
    }
}

// Imposta il Tick come il centro del bin più frequente
var tick = prevalentDiff + (binSize / 2);

// Log del Tick calcolato
Log("Tick calcolato: " + tick);

return tick;
}



function addLevels(logParts, side, book) {
var maxLevel = CONFIG.LEVELS[side];
var prices = book[side].Prices;
var quantities = book[side].Quantities;
for (var level = 0; level <= maxLevel; level++) {
logParts.push("Level " + level + ": Price = " + prices[level] +
", Quantity = " + quantities[level] + "\n");
}


// Calcola e logga il Tick
var tick = calculateTick(prices);
logParts.push("Tick: " + tick + "\n");
}

function logFullBook() {
var book = UserContext.book, logParts = [separator, "BID:\n"];
addLevels(logParts, 'BID', book);
logParts.push(separator, "ASK:\n");
addLevels(logParts, 'ASK', book);
logParts.push(separator);
Log(logParts.join(''));
}

var BookUtils = {
getData: function(book, side, level, type) {
return (book && book[side] && book[side][type + 's']) ? book[side][type + 's'][level] : null;
},
hasBookStateChanged: function(newState) {
return cachedBookState === null ||
cachedBookState.book !== newState.book ||
lastBidPrice !== newState.bidPrice ||
lastBidQuantity !== newState.bidQuantity ||
lastAskPrice !== newState.askPrice ||
lastAskQuantity !== newState.askQuantity;
},
getBookState: function(book) {
var newState = {
book: book,
bidPrice: this.getData(book, 'BID', CONFIG.LEVELS.BID, 'Price'),
bidQuantity: this.getData(book, 'BID', CONFIG.LEVELS.BID, 'Quantity'),
askPrice: this.getData(book, 'ASK', CONFIG.LEVELS.ASK, 'Price'),
askQuantity: this.getData(book, 'ASK', CONFIG.LEVELS.ASK, 'Quantity')
};
if (this.hasBookStateChanged(newState)) {
cachedBookState = newState;
lastBidPrice = newState.bidPrice;
lastBidQuantity = newState.bidQuantity;
lastAskPrice = newState.askPrice;
lastAskQuantity = newState.askQuantity;
}
return cachedBookState;
}
};

var OrderUtils = {
execOrder: function(side, stock, price, size) {
return (side === 'BID') ? OrderManager.Buy(stock, price, size) : OrderManager.Sell(stock, price, size);
},
updateOrderContext: function(order, side, price) {
UserContext.order.current = order;
UserContext.prices[side].oldLevel = price;
return order;
},
processOrModOrder: function(side, stock, price) {
var currentOrder = UserContext.order.current;
if (currentOrder) {
if (currentOrder.Price === price) return currentOrder;
return this.updateOrderContext(OrderManager.Modify(currentOrder.OrderCode, price), side, price);
}
return this.updateOrderContext(this.execOrder(side, stock, price, CONFIG.SIZE), side, price);
},
deleteOrder: function(orderCode) {
return OrderManager.Delete(orderCode);
}
};

var Helper = {
messages: {
'Initialization Complete': "Inizializzazione completata:\nBid Price 0: {bidPrice}\nAsk Price 0: {askPrice}\n",
'Order Action': 'Ordine {action}: {orderCode}\n',
'Order Deleted': 'Ordine cancellato: {orderCode}\n',
'LevelChange': "Livello da {lastLevel} all'attuale livello {priceLevel}\n",
'PriceChange': "Prezzo da {previousPrice} all'attuale prezzo {currentPrice}\nOra: {currentTime}\r\n" + separator,
'message': "{message}\r\n" + separator
},
formatMessage: function(template, data) {
return template.replace(/{(\w+)}/g, function(match, key) {
return data[key] || match;
});
},
formatState: function(bookState) {
var book = UserContext.book;
return separator +
"Bid Price \tBid Quant.\tAsk Price \tAsk Quant.\r\n" +
separator +
book.BID.Prices[0] + "\t\t" + book.BID.Quantities[0] +
"\t\t" + book.ASK.Prices[0] + "\t\t" + book.ASK.Quantities[0] + "\r\n" +
separator +
"Numero Operazione: " + UserContext.status.numOperazione + "\r\n" +
separator;
},
log: function(type, data, includeFormattedState) {
includeFormattedState = typeof includeFormattedState !== 'undefined' ? includeFormattedState : true;
var template = this.messages[type];
if (!template) return;
var message = separator + this.formatMessage(template, data || {});
if (includeFormattedState && (type === 'Initialization Complete' || type === 'LevelChange')) {
message += this.formatState(BookUtils.getBookState(UserContext.book));
}
Log(message);
},


priceDirection: function(targetPrice, oldPrice) {
    return (targetPrice > oldPrice) ? 1 : ((targetPrice < oldPrice) ? -1 : 0);
}
};

function getTargetPriceLevel(side) {
return (CONFIG.MONITORING_MODE === 'MONITORA_1Level' ? 0 : CONFIG.LEVELS[side] - 1);
}

function setupTradeContext() {
var originalBook = mapBookData(Book(ps));
var sideLevels = {
BID: (CONFIG.MONITORING_MODE === 'MONITORA_1Level' ? 0 : CONFIG.LEVELS.BID - 1),
ASK: (CONFIG.MONITORING_MODE === 'MONITORA_1Level' ? 0 : CONFIG.LEVELS.ASK - 1)
};
var pricesBID = originalBook.BID.Prices;
var pricesASK = originalBook.ASK.Prices;


UserContext = {
    book: originalBook,
    order: { current: null },
    status: { run: true, secondCount: 0, numOperazione: 0 },
    prices: {
        BID: {
            current: pricesBID[0],
            oldLevel: pricesBID[sideLevels.BID]
        },
        ASK: {
            current: pricesASK[0],
            oldLevel: pricesASK[sideLevels.ASK]
        }
    },
    targetPriceLevels: sideLevels
};

var side = CONFIG.ORDER_SIDE;  // Prendiamo il lato configurato (BID o ASK)
var price = BookUtils.getData(originalBook, side, sideLevels[side], 'Price');  // Prezzo target
var initialOrder = OrderUtils.execOrder(side, stock, price, CONFIG.SIZE);  // Eseguiamo l'ordine

OrderUtils.updateOrderContext(initialOrder, side, price);

Helper.log('Initialization Complete', {
    bidPrice: UserContext.prices.BID.current,
    askPrice: UserContext.prices.ASK.current
}, true); 
Helper.log('Order Action', { action: 'inserito', orderCode: initialOrder.OrderCode }, false);
logFullBook();

manageCycle();  
}

function manageCycle() {
var status = UserContext.status;
if (checkOps() || status.secondCount < CONFIG.SECONDS) {
return;
}
var side = CONFIG.ORDER_SIDE;
var originalBook = Book(ps);
var mappedBook = mapBookData(originalBook);
UserContext.book = mappedBook;


priceUpdate(side, mappedBook);
status.secondCount = 0;
}

function priceUpdate(side, book) {
var status = UserContext.status;
var pricesSide = UserContext.prices[side];
var targetPriceLevel = UserContext.targetPriceLevels[side];
var targetPrice = book[side].Prices[targetPriceLevel];
var oldPrice = pricesSide.oldLevel;
var maxLevel = CONFIG.LEVELS[side];


if (targetPrice === oldPrice) return;

var newOrder = OrderUtils.processOrModOrder(side, ps, targetPrice);
if (!newOrder) return;

pricesSide.current = targetPrice;
var direction = Helper.priceDirection(targetPrice, oldPrice);
var levelDifference = maxLevel + direction;
Helper.log('LevelChange', { lastLevel: levelDifference, priceLevel: targetPriceLevel }, true);
status.secondCount = 0;
status.numOperazione++;
}

function checkOps() {
var status = UserContext.status;
if (status.numOperazione < CONFIG.MAX_OPERATIONS) {
return false;
}
var currentOrder = UserContext.order.current;
if (currentOrder) {
OrderUtils.deleteOrder(currentOrder.OrderCode);
Helper.log('Order Deleted', { orderCode: currentOrder.OrderCode });
status.run = false;
return true;
}
return false;
}

function handleEvent(context, eventType) {
switch(eventType) {
case TSEventType.Price:
var currentPrice = Val(ps, "LAST");
if (context.lastPrice !== currentPrice) {
var currentTime = Now().ToString("HH:mm:ss.ff");
Helper.log('PriceChange', {
previousPrice: context.lastPrice,
currentPrice: currentPrice,
currentTime: currentTime
});
context.lastPrice = currentPrice;
}
break;
case TSEventType.Time:
context.status.secondCount++;
manageCycle();
break;
}
}

function marketEvent() {
if (!UserContext.status.run) return;
var originalBook = Book(ps);
var mappedBook = mapBookData(originalBook);
UserContext.book = mappedBook;


handleEvent(UserContext, SystemContext.EventType);
}

if (SystemContext.IsFirst) {
setupTradeContext();
}

marketEvent();  nella function calculateTick il tick calcolato Bid e ask su questo book BID:
Level 0: Price = 34860, Quantity = 1
Level 1: Price = 34855, Quantity = 3
Level 2: Price = 34850, Quantity = 6
Level 3: Price = 34845, Quantity = 18
Level 4: Price = 34840, Quantity = 8
Level 5: Price = 34835, Quantity = 5
Level 6: Price = 34830, Quantity = 5
Tick: 5.005
---------------------------------------------------
ASK:
Level 0: Price = 34865, Quantity = 3
Level 1: Price = 34870, Quantity = 6
Level 2: Price = 34875, Quantity = 5
Level 3: Price = 34880, Quantity = 8
Level 4: Price = 34885, Quantity = 3
Level 5: Price = 34890, Quantity = 4
Level 6: Price = 34895, Quantity = 6
Tick: 0.005
dovrebbe essere 5 per il bid invece e' 5.005 e 5 per l'ask dove invece e' 0,005. PUOI CORREGGERE LE FORMULE ?