وسائل لوڈ ہو رہے ہیں... لوڈنگ...

منافع حاصل کرنے والے کی حکمت عملی کا تجزیہ (1)

مصنف:نینا باداس, تخلیق: 2022-04-26 11:31:51, تازہ کاری:

منافع حاصل کرنے والے کی حکمت عملی کا تجزیہ (1)

حال ہی میں، FMZ Quant WeChat گروپ میں صارفین نے بوٹ کے بارے میں تبادلہ خیال کیاprint moneyبحث بہت گرم تھی، اور ایک بہت پرانی حکمت عملی کوانٹ کے وژن میں دوبارہ داخل ہوئی ہے:منافع ہاروسٹر. کے روبوٹ ٹریڈنگ اصولprint moneyمنافع کاٹنے کی حکمت عملی پر مبنی ہے۔ میں اپنے آپ کو اس وقت منافع کاٹنے کی حکمت عملی کو بہت اچھی طرح سے نہ سمجھنے کا الزام دیتا ہوں۔ لہذا ، میں نے اصل حکمت عملی کو دوبارہ سنجیدگی سے پڑھا ، اور پورٹ شدہ ورژن بھی پڑھا:OKCoin منافع کٹائی کرنے والا پورٹنگ. مثال کے طور پر ایف ایم زیڈ کی منافع حاصل کرنے والی حکمت عملی کا پورٹ ورژن لیتے ہوئے ، ہم اس حکمت عملی کا تجزیہ کرنے اور اس حکمت عملی کے خیالات کو نکالنے جارہے ہیں ، تاکہ ہمارے پلیٹ فارم کے صارفین اس حکمت عملی کے خیال کو سیکھ سکیں۔ اس مضمون میں ، ہم اسٹریٹجک سوچ ، ارادے وغیرہ کی سطح سے زیادہ تجزیہ کرتے ہیں ، تاکہ پروگرامنگ سے متعلق بورنگ مواد کو کم سے کم کیا جاسکے۔

[پورٹ OKCoin منافع کاٹنے والا] حکمت عملی ماخذ کوڈ:

function LeeksReaper() {
    var self = {}
    self.numTick = 0
    self.lastTradeId = 0
    self.vol = 0
    self.askPrice = 0
    self.bidPrice = 0
    self.orderBook = {Asks:[], Bids:[]}
    self.prices = []
    self.tradeOrderId = 0
    self.p = 0.5
    self.account = null
    self.preCalc = 0
    self.preNet = 0

    self.updateTrades = function() {
        var trades = _C(exchange.GetTrades)
        if (self.prices.length == 0) {
            while (trades.length == 0) {
                trades = trades.concat(_C(exchange.GetTrades))
            }
            for (var i = 0; i < 15; i++) {
                self.prices[i] = trades[trades.length - 1].Price
            }
        }
        self.vol = 0.7 * self.vol + 0.3 * _.reduce(trades, function(mem, trade) {
            // Huobi not support trade.Id
            if ((trade.Id > self.lastTradeId) || (trade.Id == 0 && trade.Time > self.lastTradeId)) {
                self.lastTradeId = Math.max(trade.Id == 0 ? trade.Time : trade.Id, self.lastTradeId)
                mem += trade.Amount
            }
            return mem
        }, 0)

    }
    self.updateOrderBook = function() {
        var orderBook = _C(exchange.GetDepth)
        self.orderBook = orderBook
        if (orderBook.Bids.length < 3 || orderBook.Asks.length < 3) {
            return
        }
        self.bidPrice = orderBook.Bids[0].Price * 0.618 + orderBook.Asks[0].Price * 0.382 + 0.01
        self.askPrice = orderBook.Bids[0].Price * 0.382 + orderBook.Asks[0].Price * 0.618 - 0.01
        self.prices.shift()
        self.prices.push(_N((orderBook.Bids[0].Price + orderBook.Asks[0].Price) * 0.35 +
            (orderBook.Bids[1].Price + orderBook.Asks[1].Price) * 0.1 +
            (orderBook.Bids[2].Price + orderBook.Asks[2].Price) * 0.05))
    }
    self.balanceAccount = function() {
        var account = exchange.GetAccount()
        if (!account) {
            return
        }
        self.account = account
        var now = new Date().getTime()
        if (self.orderBook.Bids.length > 0 && now - self.preCalc > (CalcNetInterval * 1000)) {
            self.preCalc = now
            var net = _N(account.Balance + account.FrozenBalance + self.orderBook.Bids[0].Price * (account.Stocks + account.FrozenStocks))
            if (net != self.preNet) {
                self.preNet = net
                LogProfit(net)
            }
        }
        self.btc = account.Stocks
        self.cny = account.Balance
        self.p = self.btc * self.prices[self.prices.length-1] / (self.btc * self.prices[self.prices.length-1] + self.cny)
        var balanced = false
        
        if (self.p < 0.48) {
            Log("start to balance", self.p)
            self.cny -= 300
            if (self.orderBook.Bids.length >0) {
                exchange.Buy(self.orderBook.Bids[0].Price + 0.00, 0.01)
                exchange.Buy(self.orderBook.Bids[0].Price + 0.01, 0.01)
                exchange.Buy(self.orderBook.Bids[0].Price + 0.02, 0.01)
            }
        } else if (self.p > 0.52) {
            Log("start to balance", self.p)
            self.btc -= 0.03
            if (self.orderBook.Asks.length >0) {
                exchange.Sell(self.orderBook.Asks[0].Price - 0.00, 0.01)
                exchange.Sell(self.orderBook.Asks[0].Price - 0.01, 0.01)
                exchange.Sell(self.orderBook.Asks[0].Price - 0.02, 0.01)
            }
        }
        Sleep(BalanceTimeout)
        var orders = exchange.GetOrders()
        if (orders) {
            for (var i = 0; i < orders.length; i++) {
                if (orders[i].Id != self.tradeOrderId) {
                    exchange.CancelOrder(orders[i].Id)
                }
            }
        }
    }

    self.poll = function() {
        self.numTick++
        self.updateTrades()
        self.updateOrderBook()
        self.balanceAccount()
        
        var burstPrice = self.prices[self.prices.length-1] * BurstThresholdPct
        var bull = false
        var bear = false
        var tradeAmount = 0
        if (self.account) {
            LogStatus(self.account, 'Tick:', self.numTick, ', lastPrice:', self.prices[self.prices.length-1], ', burstPrice: ', burstPrice)
        }
        
        if (self.numTick > 2 && (
            self.prices[self.prices.length-1] - _.max(self.prices.slice(-6, -1)) > burstPrice ||
            self.prices[self.prices.length-1] - _.max(self.prices.slice(-6, -2)) > burstPrice && self.prices[self.prices.length-1] > self.prices[self.prices.length-2]
            )) {
            bull = true
            tradeAmount = self.cny / self.bidPrice * 0.99
        } else if (self.numTick > 2 && (
            self.prices[self.prices.length-1] - _.min(self.prices.slice(-6, -1)) < -burstPrice ||
            self.prices[self.prices.length-1] - _.min(self.prices.slice(-6, -2)) < -burstPrice && self.prices[self.prices.length-1] < self.prices[self.prices.length-2]
            )) {
            bear = true
            tradeAmount = self.btc
        }
        if (self.vol < BurstThresholdVol) {
            tradeAmount *= self.vol / BurstThresholdVol
        }
        
        if (self.numTick < 5) {
            tradeAmount *= 0.8
        }
        
        if (self.numTick < 10) {
            tradeAmount *= 0.8
        }
        
        if ((!bull && !bear) || tradeAmount < MinStock) {
            return
        }
        var tradePrice = bull ? self.bidPrice : self.askPrice
        while (tradeAmount >= MinStock) {
            var orderId = bull ? exchange.Buy(self.bidPrice, tradeAmount) : exchange.Sell(self.askPrice, tradeAmount)
            Sleep(200)
            if (orderId) {
                self.tradeOrderId = orderId
                var order = null
                while (true) {
                    order = exchange.GetOrder(orderId)
                    if (order) {
                        if (order.Status == ORDER_STATE_PENDING) {
                            exchange.CancelOrder(orderId)
                            Sleep(200)
                        } else {
                            break
                        }
                    }
                }
                self.tradeOrderId = 0
                tradeAmount -= order.DealAmount
                tradeAmount *= 0.9
                if (order.Status == ORDER_STATE_CANCELED) {
                    self.updateOrderBook()
                    while (bull && self.bidPrice - tradePrice > 0.1) {
                        tradeAmount *= 0.99
                        tradePrice += 0.1
                    }
                    while (bear && self.askPrice - tradePrice < -0.1) {
                        tradeAmount *= 0.99
                        tradePrice -= 0.1
                    }
                }
            }
        }
        self.numTick = 0
    }
    return self
}

function main() {
    var reaper = LeeksReaper()
    while (true) {
        reaper.poll()
        Sleep(TickInterval)
    }
}

حکمت عملی کا جائزہ

عام طور پر ، جب آپ سیکھنے کے لئے حکمت عملی حاصل کرتے ہیں تو ، پڑھنے کے وقت ، پہلے پروگرام کی مجموعی ساخت کو دیکھیں۔ حکمت عملی کا کوڈ لمبا نہیں ہے ، 200 لائنوں سے کم ہے۔ یہ کہا جاسکتا ہے کہ یہ بہت آسان ہے ، اور اس کی اصل ورژن کی حکمت عملی کے لئے اعلی بحالی ہے ، جو بنیادی طور پر اس کے برابر ہے۔ جب حکمت عملی کا کوڈ چل رہا ہے تو ، یہ شروع ہوتا ہےmain()فنکشن. پورے حکمت عملی کوڈ، سوائےmain()، صرف نامی ایک تقریب ہےLeeksReaper().LeeksReaper()اس فنکشن کو سمجھنا بھی بہت آسان ہے۔ اس فنکشن کو منافع کٹائی کرنے والے حکمت عملی منطق ماڈیول (ایک اعتراض) کے کنسٹرکٹر کے طور پر سمجھا جاسکتا ہے۔LeeksReaper()منافع کاٹنے والے کے تجارتی منطق کی تعمیر کے لئے ذمہ دار ہے.

  • کی پہلی سطرmainحکمت عملی میں کردار:var reaper = LeeksReaper(); کوڈ ایک مقامی متغیر کا اعلان کرتا ہےreaper، اور پھر ایک حکمت عملی منطق اعتراض کی تعمیر کے لئے LeeksReaper() تقریب بلاتا ہے اور اس کے لئے تفویض کرتا ہےreaper.

  • مندرجہ ذیل حصے میںmainفنکشن:

    while (true) {
        reaper.poll()
        Sleep(TickInterval)
    }
    

    درج کریںwhileلامحدود لوپ، مسلسل عملدرآمد کی تقریب کو انجام دینے کےreaperچیزpoll()، اورpoll()فنکشن حکمت عملی کا بنیادی منطق ہے، تو پوری حکمت عملی پروگرام مسلسل ٹریڈنگ منطق کو انجام دینے کے لئے شروع ہوتا ہے.

    اور لائن کے بارے میںSleep(TickInterval)، سمجھنے میں آسان ہے، جس کا مقصد مجموعی طور پر ٹریڈنگ منطق کے ہر عمل کے بعد وقفے کے وقت کو کنٹرول کرنا ہے، اور جس کا مقصد ٹریڈنگ منطق کی گردش کی تعدد کو کنٹرول کرنا ہے.

تخلیق کار کا تجزیہ کریںLeeksReaper()

چلو دیکھتے ہیں کہ کس طرح فنکشنLeeksReaper()حکمت عملی منطق میں ایک اعتراض کی تعمیر کرتا ہے.

کےLeeksReaper()فنکشن شروع ہوتا ہے اور ایک null اعتراض کا اعلان کرتا ہے،var self = {}کے نفاذ کے دورانLeeksReaper()فنکشن ، اس نل آبجیکٹ کو آہستہ آہستہ اس میں کچھ طریقے اور صفات شامل کرکے تبدیل کیا جائے گا۔ آخر میں ، آبجیکٹ کی تعمیر مکمل ہوجاتی ہے ، اور آبجیکٹ واپس کردیا جاتا ہے (یعنی ،var reaper = LeeksReaper()میںmain()تقریب، اور واپس کیا اعتراض کے لئے تفویض کیا جاتا ہےreaper).

آبجیکٹ میں وصف شامل کریںself

اگلا، میں نے بہت سے صفات کو شامل کیاselfمیں ذیل میں ہر خصوصیت کی وضاحت کروں گا۔ آپ ان خصوصیات اور متغیرات کے مقصد اور ارادے کو جلدی سے سمجھ سکتے ہیں ، جس سے حکمت عملی کو سمجھنا آسان ہوجائے گا ، اور جب آپ کوڈ کے ڈھیر کو دیکھیں گے تو الجھن سے بچیں گے۔

    self.numTick = 0         # it is used to record the number of times that the trading is not triggered when the poll function is called. When placing an order is triggered and the order logic is executed, reset self.numTick to 0
    self.lastTradeId = 0     # the trading record ID of the order that has been executed in the trading market; this variable records the current latest execution record ID in the market
    self.vol = 0             # after the weighted average calculation, the trading volume reference of the market at each inspection (the market data is obtained once per time of the loop, which can be understood as the inspection of the market once)
    self.askPrice = 0        # ask price of delivery order, which can be understood as the price of the pending sell order calculated by the strategy 
    self.bidPrice = 0        # bid price of delivery order
    self.orderBook = {Asks:[], Bids:[]}    # record the currently obtained order book data, that is, depth data (sell 1...sell n, buy 1...buy n)
    self.prices = []                       # an array that records the price in the time series after the weighted average calculation of the first three levels in the order book. Simply put, it is the weighted average price of the first three levels of the order book obtained by storing each time, and put them in an array as reference of the subsequent strategic trading signals. Therefore, the variable name is "prices", plural, which means a set of prices
    self.tradeOrderId = 0    # record the order ID after currently lading and ordering 
    self.p = 0.5             # position proportion; when the currency value is exactly half of the total asset value, the value of it is 0.5, which means the balanced state 
    self.account = null      # record the account asset data, which will be returned by the function GetAccount()
    self.preCalc = 0         # record the timestamp when calculating the return of the latest time, in milliseconds, which is used to control the frequency of triggering execution of the return calculation code
    self.preNet = 0          # record the current return value  

آبجیکٹ میں طریقہ شامل کریںself

self کو ان صفات کو شامل کرنے کے بعد، میں طریقوں کو شامل کرنے کے لئے شروعselfاعتراض، تاکہ یہ اعتراض کچھ آپریشنز کر سکتا ہے اور کچھ افعال ہیں.

پہلا شامل فنکشن:

    self.updateTrades = function() {
        var trades = _C(exchange.GetTrades)  # call the encapsulated interface "GetTrades" of FMZ, to obtain the currently latest execution data in the market
        if (self.prices.length == 0) {       # when self.prices.length == 0, you need to fill values in the array of self.prices, which is only triggered when the strategy is started 
            while (trades.length == 0) {     # if there is no latest execution record in the market, the while loop will run infinitely, until there is new execution data; the, update the variable "trades"
                trades = trades.concat(_C(exchange.GetTrades))   # "concat" is a method of JS array type, which is used to match two arrays; here we use it to match the array "trades" and the array returned by "_C(exchange.GetTrades)" into one array 
            }
            for (var i = 0; i < 15; i++) {   # fill in values for "self.prices"; fill 15 latest execution prices 
                self.prices[i] = trades[trades.length - 1].Price
            }
        }
        self.vol = 0.7 * self.vol + 0.3 * _.reduce(trades, function(mem, trade) {  # _.reduce function iteratively calculates the accumulated execution volume of the latest execution record 
            // Huobi not support trade.Id
            if ((trade.Id > self.lastTradeId) || (trade.Id == 0 && trade.Time > self.lastTradeId)) {
                self.lastTradeId = Math.max(trade.Id == 0 ? trade.Time : trade.Id, self.lastTradeId)
                mem += trade.Amount
            }
            return mem
        }, 0)

    }

کے کردارupdateTradesمارکیٹ میں تازہ ترین عملدرآمد کے اعداد و شمار حاصل کرنے، اور کچھ حساب کتاب کرنے اور اعداد و شمار کے مطابق ریکارڈ کرنے، اور بعد میں حکمت عملی منطق میں استعمال کے لئے نتائج فراہم کرنے کے لئے ہے. میں نے براہ راست مندرجہ بالا کوڈ میں لائن کی طرف سے لائن تبصرے لکھا ہے. طالب علموں کو جو پروگرامنگ کی بنیاد نہیں ہے ہو سکتا ہے کے بارے میں الجھن میں ہو جائے گا_.reduce، تو یہاں ایک مختصر تعارف ہے._.reduceکا ایک فنکشن ہےUnderscore.jsلائبریری، FMZJS حکمت عملی کی طرف سے حمایت کی. لہذا، یہ iterative حساب کرنے کے لئے اس کا استعمال کرنے کے لئے بہت آسان ہے.Underscore.js کا معلوماتی لنک

بہت آسان سمجھنے کے لئے، مثال کے طور پر:

function main () {
   var arr = [1, 2, 3, 4]
   var sum = _.reduce(arr, function(ret, ele){
       ret += ele
       
       return ret
   }, 0)

   Log("sum:", sum)    # sum is 10
}

یہ صفوں میں ہر نمبر کا اضافہ ہے ، یعنی[1, 2, 3, 4]واپس ہماری حکمت عملی کے لئے، یہ میں ہر عملدرآمد ریکارڈ کے اعداد و شمار کے حجم کی قدر جمع کرنے کے لئے ہےtradesصف، جس کے نتیجے میں تازہ ترین عملدرآمد کے حجم کی کل.self.vol = 0.7 * self.vol + 0.3 * _.reduce(...)، مجھے اس کوڈ کے ٹکڑے کو تبدیل کرنے کی اجازت...یہاں یہ دیکھنا مشکل نہیں ہے کہ حساب کتاب کا حساب کتاب کرنا مشکل ہے.self.volیہ بھی ایک وزن شدہ اوسط ہے۔ یعنی ، نئی تخلیق شدہ کل عمل درآمد کا حجم 30٪ ہے اور پچھلے عمل درآمد کے حجم کا حساب کتاب 70٪ ہے۔ یہ تناسب حکمت عملی کے ڈویلپر کے ذریعہ مصنوعی طور پر طے کیا جاتا ہے ، جو مارکیٹ کے قوانین کے مشاہدے سے متعلق ہوسکتا ہے۔

آپ کے سوال کے بارے میں اگر تازہ ترین عملدرآمد کے اعداد و شمار حاصل کرنے کے لئے انٹرفیس مجھے پرانے اعداد و شمار کی نقل واپس کرتا ہے تو مجھے کیا کرنا چاہئے؟ پھر ، حاصل کردہ اعداد و شمار غلط ہیں ، لہذا کیا استعمال کرنے کا کوئی مطلب ہے؟ " فکر نہ کرو ، حکمت عملی کو اس کے ذہن میں ڈیزائن کیا گیا ہے ، لہذا کوڈ میں مندرجہ ذیل مواد ہے:

if ((trade.Id > self.lastTradeId) || (trade.Id == 0 && trade.Time > self.lastTradeId)) {
    ...
}

فیصلہ ٹریڈنگ کے عملدرآمد کے ریکارڈ میں عملدرآمد کی شناخت پر مبنی ہوسکتا ہے۔ صرف اس صورت میں جب ID آخری بار کی شناخت سے بڑا ہو ، جمع ہوجاتا ہے۔ یا ، اگر پلیٹ فارم انٹرفیس ID فراہم نہیں کرتا ہے ، یعنی ،trade.Id == 0، فیصلہ کرنے کے لئے ٹریڈنگ عملدرآمد ریکارڈ میں ٹائم اسٹیمپ کا استعمال کریں.self.lastTradeIdعملدرآمد ریکارڈ کا ٹائم اسٹیمپ ہے، شناخت نہیں.

دوسرا اضافی فنکشن:

    self.updateOrderBook = function() {
        var orderBook = _C(exchange.GetDepth)
        self.orderBook = orderBook
        if (orderBook.Bids.length < 3 || orderBook.Asks.length < 3) {
            return
        }
        self.bidPrice = orderBook.Bids[0].Price * 0.618 + orderBook.Asks[0].Price * 0.382 + 0.01
        self.askPrice = orderBook.Bids[0].Price * 0.382 + orderBook.Asks[0].Price * 0.618 - 0.01
        self.prices.shift()
        self.prices.push(_N((orderBook.Bids[0].Price + orderBook.Asks[0].Price) * 0.35 +
            (orderBook.Bids[1].Price + orderBook.Asks[1].Price) * 0.1 +
            (orderBook.Bids[2].Price + orderBook.Asks[2].Price) * 0.05))
    }

اگلا، آئیے اس پر نظر ڈالتے ہیںupdateOrderBookفنکشن۔ فنکشن کے نام کے معنی سے ، یہ دیکھا جاسکتا ہے کہ فنکشن آرڈر بک کو اپ ڈیٹ کرنا ہے۔ تاہم ، یہ صرف آرڈر بک کو اپ ڈیٹ نہیں کرتا ہے۔ فنکشن ، پہلے ، ایف ایم زیڈ API فنکشن کو کال کرتا ہےGetDepth()موجودہ مارکیٹ آرڈر بک کے اعداد و شمار (فروخت 1...فروخت n، خرید 1...خرید n) حاصل کرنے اور آرڈر بک کے اعداد و شمار کو ریکارڈ کرنے کے لئےin self.orderBookاگلا، یہ فیصلہ کرتا ہے کہ آیا آرڈر بک کے اعداد و شمار کی سطح خرید آرڈرز اور فروخت کے احکامات کے لئے 3 سطح سے کم ہے؛ اگر ایسا ہے تو، یہ ایک غلط فنکشن ہے، اور براہ راست واپس آتا ہے.

اس کے بعد، دو اعداد و شمار کے حسابات کئے گئے تھے:

  • ترسیل کے آرڈر کی قیمت کا حساب لگائیں ترسیل کی قیمت کا حساب بھی وزن شدہ اوسط حساب پر مبنی ہے۔ خرید آرڈر کی بولی کی قیمت کا حساب کرتے وقت ، خرید 1 کی قیمت کو زیادہ وزن دیں ، یعنی 61.8٪ (0.618) ، اور فروخت 1 کی قیمت باقی وزن 38.2٪ (0.382) کا حساب دیتی ہے۔ ترسیل کے آرڈر کی مانگ کی قیمت کا حساب کرتے وقت بھی یہی سچ ہے ، فروخت 1 کی قیمت کو زیادہ وزن دیتے ہوئے۔ اس کی وجہ 0.618 ہے۔ یہ ہوسکتا ہے کہ ڈویلپر سنہری تناسب کو ترجیح دیتا ہے۔ آخر میں قیمت (0.01) کے تھوڑا سا اضافہ یا گھٹانے کے ل it ، یہ مارکیٹ کے وسط میں تھوڑا سا آگے کی طرف آفسیٹ کرنا ہے۔

  • ٹائم سیریز پر آرڈر بک کی پہلی تین سطحوں کی وزن شدہ اوسط قیمت کو اپ ڈیٹ کریں آرڈر بک میں خریداری کے احکامات اور فروخت کے احکامات کی پہلی تین سطحوں کے لئے ، ایک وزن شدہ اوسط حساب کتاب انجام دیا جاتا ہے۔ پہلی سطح کا وزن 0.7 ہے ، دوسری سطح کا وزن 0.2 ہے ، اور تیسری سطح کا وزن 0.1 ہے۔ کچھ طلباء کہہ سکتے ہیں: اوہ ، غلط ، کوڈ میں 0.7 ، 0.2 ، یا 0.1 نہیں ہے!

    آئیے توسیع شدہ حساب دیکھیں:

    (Buy 1 + Sell 1) * 0.35 + (Buy 2 + Sell 2) * 0.1 + (Buy 3 + Sell 3) * 0.05
    ->
    (Buy 1 + Sell 1) / 2 * 2 * 0.35 + (Buy 2 + Sell 2) / 2 * 2 * 0.1 + (Buy 3 + Sell 3) / 2 * 2 * 0.05
    ->
    (Buy 1 + Sell 1) / 2 * 0.7 + (Buy 2 + Sell 2) / 2 * 0.2 + (Buy 3 + Sell 3) / 2 * 0.1
    ->
    average price of the first level * 0.7 + average price of the second level * 0.2 + average price of the third level * 0.1
    

    یہاں یہ دیکھا جاسکتا ہے کہ حتمی حساب کی قیمت اصل میں موجودہ مارکیٹ میں تیسری سطح کی درمیانی قیمت کی پوزیشن کو ظاہر کرتی ہے۔ پھر اس حساب کی قیمت کو اپ ڈیٹ کرنے کے لئے استعمال کریںself.pricesصف، سب سے پرانے اعداد و شمار (کی طرف سے باہر ککshift()کے مطابق) ، اور اسے تازہ ترین اعداد و شمار کے ساتھ اپ ڈیٹ کریں (بعد میںpush()فنکشن؛ shift اور push افعال JS صف اشیاء کے تمام طریقوں ہیں، آپ مزید تفصیلات کے لئے JS سے متعلق مواد تلاش کر سکتے ہیں). اس طرح پیدا صفself.pricesوقت سیریز کے حکم میں ایک ڈیٹا فلو ہے.

    ایک وقفہ لے لو۔ چلو یہاں تجزیہ ختم کرتے ہیں، اور اگلی بار ملتے ہیں!


مزید