areed1192 / python-trading-robot

A trading robot, that can submit basic orders in an automated fashion using the TD API.
MIT License
527 stars 311 forks source link

Issue with pulling new Candlesticks #17

Open CivilAllDay opened 3 years ago

CivilAllDay commented 3 years ago

This seems to be a great resource but I can't get over a hurdle I'm encountering.

I'm getting data using TDA's REST API through trading_robot.grab_historical_prices()

This pulls out the latest candle and adds it into the trading loop. Then it runs the indicators on the new data and processes the buy and sell signals. You show this pretty well in your Youtube tutorials.

Unfortunately TDA is pushing out INCOMPLETE candles. So if you do a request on for 15 minute candles at 9:01. The final candle, which we're basing our indicators and triggers on, is only 1 minute of data. This can bee seen in your video: https://www.youtube.com/watch?v=xF5h41CZlls @ 12:18.

Please let me know if you need anymore clarification info.

EDIT:

I think I may have fixed this by taking the following steps.

  1. In the PyRobot.grab_historical_prices() function, I've added the line: new_prices = new_prices[:-1] this strips the final (incomplete) candle from the initial function to grab the historical candles.

  2. in the Pyrobot.get_latest_bars() function, under the "#parse the candles" section, I've edited the initial for-loop from for candle in historical_prices_response['candles'][-1:]: To this: for candle in historical_prices_response['candles'][-2:-1]: The goal here is to ignore the latest incomplete candle. so the 'get_latest_bars' function will never pull an incomplete candle.

Unfortunately this breaks the PyRobot.wait_till_next_bar() function. This can be fixed in two additional steps.

  1. pass 'bar_size' as an argument into the function. The amount of seconds to wait must be dependent on size of the aggregates of the bars. def wait_till_next_bar(self, last_bar_timestamp: pd.DatetimeIndex, bar_size) -> None:

  2. We'll use the bar_size argument in assigning the next_bar_time variable: next_bar_time = last_bar_time + timedelta(seconds=60*bar_size*2) 60*bar_size represents the time until the next complete candle. ex, for 1 minute candles, wait 60 seconds (60x1) for 15 minute candles wait 60x15 seconds. we multiply this by two because of how TDA API delivers their candlesticks: for 15 minute candles, the 9:30-9:45 candle is called 9:30, we want to receive this candle at 9:45 when it is complete. We want to receive the 9:45 candle at 10:00. That's a 30 minute difference (or 60x15x2 seconds). This calculation remains as a function of the bar_size so that it works with any candle length.

I hope this make sense.

I will test it when the market opens tomorrow.

EDIT2: This works alright. It breaks down on market open when extended hours data isn't turned on, as expected. I will work on a work-around soon.