Skip to content
This repository has been archived by the owner on Feb 16, 2020. It is now read-only.

Add Tulip and Talib Indicator-Results to 'stratUpdate' event #2483

Merged
merged 6 commits into from
Sep 4, 2018
Merged

Add Tulip and Talib Indicator-Results to 'stratUpdate' event #2483

merged 6 commits into from
Sep 4, 2018

Conversation

H256
Copy link
Contributor

@H256 H256 commented Aug 28, 2018

  • What kind of change does this PR introduce? (Bug fix, feature, docs update, ...)
    It add TULIP and TALIB indicator results to the stratUpdate event - emitter.

  • What is the current behavior? (You can also link to an open issue here)
    Currently only native indicators can be retrieved via stratUpdate event.

  • What is the new behavior (if this is a feature change)?
    TULIP and TALIB indicator results are added as [name of the indicator]-[resulting value incl. name], e.g.

{
"bb_bbandsLower":0.004675088145539005,
"bb_bbandsMiddle":0.0048078500000000015,
"bb_bbandsUpper":0.004940611854460998,
"rsi_result":67.55973723993439,
"dmi_dmPlus":0.0002359228110744004,
"dmi_dmLow":0.00006889755136314626
}

Now they can be displayed or evaluated in the GUI client.

@askmike
Copy link
Owner

askmike commented Aug 28, 2018

great idea!

Just tiny style nits:

  • In case of multiple return values, would you mind nesting them inside an object? So you get something like this:

    {
      bb: {
        "bbandsLower":0.004675088145539005,
        "bbandsMiddle":0.0048078500000000015,
        "bbandsUpper":0.004940611854460998,
      },
      rsi: 67.55973723993439,
      dmi: {
        "dmPlus":0.0002359228110744004,
        "dmLow":0.00006889755136314626
      }
    }
    

That way they are easier to use for the UI since all indicators are fully encapsulated. If we than have UI elements that can draw bbands we can simply pass the object (per stratUpdate).

  • would you mind using _.each instead of Object.keys(x).forEach? _.each can also loop over objects.
  • would you mind fixing indenting? It renders like this on github.com:

screen shot 2018-08-28 at 22 39 22

@H256
Copy link
Contributor Author

H256 commented Aug 28, 2018

Nice ideas! I'll change a few things ;)

@H256
Copy link
Contributor Author

H256 commented Aug 28, 2018

Omg, Github didn't show the changes... :( But these commits lead to the suggested structure.

@askmike
Copy link
Owner

askmike commented Aug 28, 2018 via email

@askmike
Copy link
Owner

askmike commented Aug 29, 2018

I tested this and would you mind doing one more tiny tweak?

A lot of indicators only have one result (I quickly spotted ADR, RSI, DEMA, EMA, etc), which TA-lib nests in an object with a single prop called outReal. In case there is outReal we don't need to include that property name. For example:

2018-08-29 18:46:46 (INFO):         [EVENT stratUpdate]
 { date: moment("2018-06-09T01:00:00.000"),
  indicators: 
   { 'native-dema': 7614.425573253256,
     'tulip-dema': 7614.405146256687,
     'talib-dema': { outReal: 7614.460945819434 } } }

@H256
Copy link
Contributor Author

H256 commented Aug 29, 2018

Hmmm... I think it needs a more generic approach then.
The best would be to check if the indicator result is an object.
Then check if it's _.size() is 1.
If so, directly insert the first key into result, otherwise insert the whole object.
If size is 0, set result null to show, that is not set..

This should deal with all eventualities.

@askmike
Copy link
Owner

askmike commented Aug 29, 2018 via email

@H256
Copy link
Contributor Author

H256 commented Aug 29, 2018

Ok, so now the code considers empty objects and inserts single-property objects directly. It uses _.forOwn() to iterate through properties, but only if there's a _.size() of one (for obvious performance reasons). ;)

@askmike
Copy link
Owner

askmike commented Aug 30, 2018

Hmmm... I think it needs a more generic approach then.

I usually agree here, but in this case I think it's more important to stick to what we know the output will look like:

The current version of tulip will already spit out a number instead of an object with one result property. Do we really need all these checks (for tulip) because we know TA-lib does something different (while we know tulip does not)? I really don't think we need 15 lines of if checks for tulip indicators:

  • While this code correctly branches in the current output. It's not as fast as the previous iteration and definitely not as readable (since the current code will try to account for things that will never happen in the current version of tulip).
  • if the output format changes we will need to update Gekko most likely anyway.

Note that tulip and talib are compiled libraries that (once installed properly) give very consistent output. This is different from external APIs that can have timeouts, network errors, other API errors, etc. As such I think it's better to have very simply code that parses it according to our expectations than complex code that tries to work with anything thrown at it (I'm not sure why we need things like explicit forOwn at all: lodash already filters these when looping). I personally rather merge up to
c110daa, but given that we already know that TA-lib (and not tulip) nests single results in outReal I would like to catch that (and only that scenario) for the sake of simplicity. I rather update Gekko when they change their format.

Do you agree? What do you think?


Apologies I should have said that when you asked about, I didn't think the result would turn out to ~40 lines of if checks with as much property lookups and loops.

@H256
Copy link
Contributor Author

H256 commented Aug 30, 2018

I agree on the Tulip part. It's really very generic where it shouldn't be. On the TaLib side, if I understand it's concept correctly, there might be the chance that ot has more properties than outReal. I'll try to figure out and optimize accordingly.
It shouldn'tbe more than two or three more properties inthe worst case.

Since I don't have access to any PC for the next few days, this might take a while. 😉

1 similar comment
@H256
Copy link
Contributor Author

H256 commented Aug 30, 2018

I agree on the Tulip part. It's really very generic where it shouldn't be. On the TaLib side, if I understand it's concept correctly, there might be the chance that ot has more properties than outReal. I'll try to figure out and optimize accordingly.
It shouldn'tbe more than two or three more properties inthe worst case.

Since I don't have access to any PC for the next few days, this might take a while. 😉

@askmike
Copy link
Owner

askmike commented Aug 30, 2018

there might be the chance that ot has more properties than outReal.

Just to be sure, whether there is one property (called outReal) is not random or chance based. This happens 100% of the time for specific indicators which only have 1 output. The proper solution (imo) would be a whitelist of indicators that have one output. But that requires us now to go through all of them, and maintain a whitelist. As such as quick and easy solution would be a simple check for only the talib indicators like (pseudo code):

if(indicator.result.outReal && _.keys(indicator.result).length === 1) {
  result = indicator.result.outReal
} else {
  result = indicator.result;
}

This code is concise, easy to understand (there is 1 edge case: there is only 1 prop called outReal), all other cases don't transform output. And most likely fast enough. If speed proves a bottleneck a whitelist would be faster (since you don't need to convert an object into an array of its keys on every stratUpdate). But overkill given that we need to make and maintain one now.

If you really want to have a more generic solution, could you argue what the benefits would be?

Revert to performant variant and consider outReal in Talib
@H256
Copy link
Contributor Author

H256 commented Aug 30, 2018

I reverted to the most performant version. ´outReal´ will be considered in Talib instead of ´result´.

If there's any more properties to consider, it would be easy to implement them later with if-else or similar without using any overhead functions from lodash or requiring to iterate
through properties.

btw. Coding on mobile phone somehow works, but is tedious ;)

@H256
Copy link
Contributor Author

H256 commented Sep 2, 2018

Home again, tested it. Works! ;)

@askmike
Copy link
Owner

askmike commented Sep 4, 2018

It took me while to test this, it works great!

And apologies for going back and forth between how to solve the talib issue.

@askmike askmike merged commit fc90e80 into askmike:develop Sep 4, 2018
This was referenced Oct 25, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants