Warm tip: This article is reproduced from serverfault.com, please click

TypeError: Cannot read property 'then' of undefined in Algorithmic Trading

发布于 2020-11-29 02:20:27

For some reason everytime I run this code, I catch the "TypeError: Cannot read property 'then' of undefined" error. I don't understand why. This is the code:

console.log("BUY");
exchange.marketBuy()
.then(res => {
console.log("Buy successful");
hasPosition = true
setTimeout(strategy, 1000)
})
.catch(console.error);

The marketBuy() function is

    marketBuy() {
    client.getLatestInformation()
    .then(response => {
      var price = response.result[0].last_price;
      client.placeActiveOrder({
       side: "Buy",
       symbol: "BTCUSD",
       order_type: "Market",
       qty: 20,
       time_in_force: "GoodTillCancel",
       take_profit: price * 1.5,
       stop_loss: price / 1.5})
      .then(response => console.log(response))

    })

I've tried

console.log("BUY");
exchange.marketBuy()
.then(res => {
hasPosition = true
setTimeout(strategy, 1000)
return Promise.resolve(console.log("Buy successful"));
})
.catch(console.error);

I can't seem to find the issue. Any ideas?

Questioner
R123456789
Viewed
0
Randy Casburn 2020-11-29 10:49:12

You have a couple of different issues. As others have already pointed out, you are not returning a promise from the makeBuy() method. But, it does not seem as easy as simply adding a return statement as suggested. This is because it appears you actually need to wait for the inner promise to resolve from client.placeActiveOrder() before setting hasPosition to true.

So you have two options (#2 is recommended):

  1. move the code that must wait for the inner promise to resolve, to the .then() of the inner promise thus (this creates problems of its own with the hasPosition variable):
client.placeActiveOrder({
       side: "Buy",
       symbol: "BTCUSD",
       order_type: "Market",
       qty: 20,
       time_in_force: "GoodTillCancel",
       take_profit: price * 1.5,
       stop_loss: price / 1.5})
      .then(response => {
         console.log(response);
         console.log("Buy successful");
         hasPosition = true;
         setTimeout(strategy, 1000);
         });
  1. Use async/await to make your code read like a work flow:
    async marketBuy() {
      const response = await client.getLatestInformation();
      const price = response.result[0].last_price;
      const order = await client.placeActiveOrder({
        side: "Buy",
        symbol: "BTCUSD",
        order_type: "Market",
        qty: 20,
        time_in_force: "GoodTillCancel",
        take_profit: price * 1.5,
        stop_loss: price / 1.5
      })
      return order;
    }

Choice two is recommended because it allows you to code the way you have expected things to work. Here is the calling code that will no longer throw an error:

    console.log("BUY");
    exchange.marketBuy()
      .then(res => { // res here is the order returned
        console.log("Buy successful");
        hasPosition = true
        setTimeout(strategy, 1000)
      })
      .catch(console.error);