Jeffy Lee
Jeffy Lee

Reputation: 87

Firebase Realtime Database Query is not working with larger number

I am making query for my orders list, here is the data structure and my database rules: enter image description here

enter image description here

I use a query like this to find out whether the latest price hit the tp or sl price like this:

function GetBuyList(symbol, currentPrice) {
    //Less than or equal to, for buying search tp lesser than current price
    var buy_tp = db.ref(`orders/active_orders/${symbol}`).orderByChild("tp").startAt(`buy_tp_${0}`).endAt(`buy_tp_${currentPrice}`)

    //More than or equal to, for buying search sl higher than current price
    var buy_sl = db.ref(`orders/active_orders/${symbol}`).orderByChild("sl").startAt(`buy_sl_${currentPrice}`).endAt(`buy_sl_${100000000}`)

    buy_tp.once("value", function (snapshot) {
        // do some stuff once
        if (snapshot.val() !== null) {
            ProcessOrders(snapshot.val(), 'tpHit', currentPrice)
        }
    });

    buy_sl.once("value", function (snapshot) {
        // do some stuff once
        if (snapshot.val() !== null) {
            ProcessOrders(snapshot.val(), 'slHit', currentPrice)
        }
    });
}

For price that is in lower value like 1.211, it working fine, but when the price goes larger, the buy_sl query is not working, but the buy_tp query is still working fine. Example, when I query for the price like 34886 for the data below the buy_sl is not working:

enter image description here

Edit: Hi Frank, herein the json exported:

{
  "active_orders" : {
    "BTCUSD" : {
      "-Masii03kq9LvuLfWOyG" : {
        "close_type" : "None",
        "lot_size" : 1,
        "order_price" : 34888.17,
        "sl" : "buy_sl_34887",
        "symbol" : "BTCUSD",
        "tp" : "buy_tp_34889",
        "ts" : 1622301925456,
        "type" : "buy",
        "uid" : "6XaKYgXCsuMNg1d5bWYHg6ej5sd2"
      }
    },
    "EURUSD" : {
      "-MasVPCtD4sdPCcdF9S9" : {
        "close_type" : "None",
        "lot_size" : 1,
        "order_price" : 1.211,
        "sl" : "buy_sl_1.210",
        "symbol" : "EURUSD",
        "tp" : "buy_tp_1.23",
        "ts" : 1622298174339,
        "type" : "buy",
        "uid" : "6XaKYgXCsuMNg1d5bWYHg6ej5sd2"
      }
    },
    "USDJPY" : {
      "-MasWoRREHQhvOR6iQ8G" : {
        "close_type" : "None",
        "lot_size" : 1,
        "order_price" : 109.861,
        "sl" : "buy_sl_107.0",
        "symbol" : "USDJPY",
        "tp" : "buy_tp_110",
        "ts" : 1622298543910,
        "type" : "buy",
        "uid" : "6XaKYgXCsuMNg1d5bWYHg6ej5sd2"
      }
    }
  }
}

Example, when I perform the function GetBuyList("EURUSD", 1.3) or GetBuyList("EURUSD", 1.1), the result returned as:

{
  '-MasVPCtD4sdPCcdF9S9': {
    close_type: 'None',
    lot_size: 1,
    order_price: 1.211,
    sl: 'buy_sl_1.210',
    symbol: 'EURUSD',
    tp: 'buy_tp_1.23',
    ts: 1622298174339,
    type: 'buy',
    uid: '6XaKYgXCsuMNg1d5bWYHg6ej5sd2'
  }
}

When I perform the function like this, GetBuyList("BTCUSD", 34890), it would return:

{
  '-Masii03kq9LvuLfWOyG': {
    close_type: 'None',
    lot_size: 1,
    order_price: 34888.17,
    sl: 'buy_sl_34887',
    symbol: 'BTCUSD',
    tp: 'buy_tp_34889',
    ts: 1622301925456,
    type: 'buy',
    uid: '6XaKYgXCsuMNg1d5bWYHg6ej5sd2'
  }
}

But when I run this, GetBuyList("BTCUSD", 34886), nothing is return.

Upvotes: 0

Views: 387

Answers (1)

samthecodingman
samthecodingman

Reputation: 26246

sl and tp are both strings and because they are, they won't be parsed as numbers and instead are subject to lexiographic sorting.

One of the most common examples of this happening is if you look at a file list in a folder:

0.jpg
1.jpg
10.jpg
11.jpg
12.jpg
2.jpg
3.jpg
4.jpg
5.jpg
6.jpg
7.jpg
8.jpg
9.jpg

If you can't switch from using strings, you need to pad the number with your expected maximum number:

000.jpg
001.jpg
002.jpg
003.jpg
004.jpg
005.jpg
006.jpg
007.jpg
008.jpg
009.jpg
010.jpg
011.jpg
012.jpg
const formatWithPadding = (inp, digits) => {
  let n = Number(inp), nStr = `${Math.abs(n)}`, sign = n<0;
  return (sign ? '+' : '-') + (
    nStr.length > digits
      ? nStr
      : `${"0".repeat((digits || 1) - 1)}${nStr}`.slice(-digits)
  )
};

const tpVal = 1.210;
const [integerPart, fractionalPart] = String(tpVal).split(".");
const tp = `buy_tp_${formatWithPadding(integerPart, 6)}.${fractionalPart || 0}`;

// tp is "buy_tp_+000001.210"

Upvotes: 2

Related Questions