Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 14 Next capture
2021 2022 2023
2 captures
13 Jun 22 - 14 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by Dahaka666 · Jan 20 at 08:02 PM · variablesjsonapireferencingdeserialization

Deserializing a JSON file yields 0 when referencing the variables in another script

I am having trouble with an API call response where when I try to reference a variable from the JSON data, it returns 0, even though the data received is not 0. I'm using Newtonsoft.Json to deserialize it.

This is the model that I use as a reference for handling the JSON:

 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 using Newtonsoft.Json;
 
 namespace OptionsChainResponse
 {
     [System.Serializable]
     public class Greeks
     {
         public float delta;
         public float gamma;
         public float theta;
         public float vega;
         public float rho;
         public float phi;
         public float bid_iv;
         public float mid_iv;
         public float ask_iv;
         public float smv_vol;
         public string updated_at;
     }
     [System.Serializable]
     public class Quote
     {
         public string symbol;
         public string description;
         public string exch;
         public string type;
         public float last;
         public float change;
         public int volume;
         public float open;
         public float high;
         public float low;
         public float close;
         public float bid;
         public float ask;
         public string underlying;
         public float strike;
         public Greeks greeks;
         public float change_percentage;
         public int average_volume;
         public int last_volume;
         public long trade_date;
         public float prevclose;
         public float week_52_high;
         public float week_52_low;
         public int bidsize;
         public string bidexch;
         public long bid_date;
         public int asksize;
         public string askexch;
         public long ask_date;
         public int open_interest;
         public int contract_size;
         public string expiration_date;
         public string expiration_type;
         public string option_type;
         public string root_symbol;
     }
     [System.Serializable]
     public class Quotes
     {
         public Quote quote;
     }
     [System.Serializable]
     public class Root
     {
         public Quotes quotes;
     }
 }
 



As I said, when I reference any of the above variables in another script, they return a value of 0, and I cannot figure out why. The portion of the script that I am running into problems with is as below:

 IEnumerator GetOptionChainData()
     {
         ExpirationDate = (Expiration_Year.ToString() + Expiration_Month.ToString() + Expiration_Day.ToString());
         AnalyzeButton1.text = "Loading...";
         AnalyzeButton2.text = "Loading...";
         string uri = "https://api.tradier.com/v1/markets/quotes?symbols=" + Ticker + ExpirationDate + PutOrCallString + StrikePriceString + "&greeks=true";
         using (UnityWebRequest request = UnityWebRequest.Get(uri))
         {
             request.SetRequestHeader("Authorization", "Bearer " + TradierAPIKey);
             request.SetRequestHeader("Accept", "application/json");
             yield return request.SendWebRequest();
             if ((request.isNetworkError) || (request.isHttpError))
             {
                 AnalyzeButton1.text = "Error!";
                 AnalyzeButton2.text = "Error!";
                 Debug.Log("Quote Error:" + request.error);
             }
             else
             {
                 if (request.isDone)
                 {
                     var opt1 = JsonConvert.DeserializeObject<OptionsChainResponse.Greeks>(request.downloadHandler.text);
                     if (request.downloadHandler.text != null && request.downloadHandler.text != "")
                     {
                         ImpliedVolatility = opt1.mid_iv;         //Implied volatility of options
                         Theta = opt1.theta;                      //Theta of the contract
                         Gamma = opt1.gamma;                      //Gamma of the contract
                     }
                     var opt2 = JsonConvert.DeserializeObject<OptionsChainResponse.Quote>(request.downloadHandler.text);
                     if (request.downloadHandler.text != null && request.downloadHandler.text != "")
                     {
                         OptionsChainResponse = request.downloadHandler.text;
                         //MaxPain;                              //Maximum Pain Price
                         //MaxPainString;
                         OpenInterest = opt2.open_interest;       //Open interest of options
                         Bid = opt2.bid;                          //Bid price of the contract
                         Mid = ((opt2.bid + opt2.ask) / 2);        //Mid price of the contract
                         Ask = opt2.ask;                          //Ask price of the contract
                         if (Price > StrikePrice)
                         {
                             ITMText.SetActive(true);
                             OTMText.SetActive(false);
                         }
                         if (Price <= StrikePrice)
                         {
                             OTMText.SetActive(true);
                             ITMText.SetActive(false);
                         }
                         Debug.Log(OptionsChainResponse);
                     }
                 }
             }
         }
     }




I have no idea what I'm doing wrong at this point, as when I Debug.Log the response that I get, all of the data is there properly, so it has to be something with deserializing the JSON data. I'm not sure if it would help here, but the response from the API would look as follows:

 {
     "quotes": {
         "quote": {
             "symbol": "AAPL220121P00167500",
             "description": "AAPL Jan 21 2022 $167.50 Put",
             "exch": "Z",
             "type": "option",
             "last": 2.45,
             "change": 0.00,
             "volume": 0,
             "open": null,
             "high": null,
             "low": null,
             "close": null,
             "bid": 2.3,
             "ask": 2.47,
             "underlying": "AAPL",
             "strike": 167.5,
             "greeks": {
                 "delta": -0.484713,
                 "gamma": 0.0999226,
                 "theta": -0.392862,
                 "vega": 0.0498053,
                 "rho": 0.00441615,
                 "phi": -0.0044981,
                 "bid_iv": 0.335705,
                 "mid_iv": 0.337713,
                 "ask_iv": 0.339721,
                 "smv_vol": 0.332,
                 "updated_at": "2022-01-19 20:33:07"
             },
             "change_percentage": 0.00,
             "average_volume": 0,
             "last_volume": 50,
             "trade_date": 1642625993207,
             "prevclose": 2.45,
             "week_52_high": 0.0,
             "week_52_low": 0.0,
             "bidsize": 0,
             "bidexch": "W",
             "bid_date": 1642665600000,
             "asksize": 0,
             "askexch": "W",
             "ask_date": 1642665600000,
             "open_interest": 18476,
             "contract_size": 100,
             "expiration_date": "2022-01-21",
             "expiration_type": "standard",
             "option_type": "put",
             "root_symbol": "AAPL"
         }
     }
 }





Any help here would be immensely appreciated as I've tried searching for an answer but I cannot find anything about this specific problem. Thank you for your time.

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
â–¼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

2 Replies

· Add your reply
  • Sort: 
avatar image
0
Best Answer

Answer by Bunny83 · Jan 21 at 11:44 AM

So I have officially double-checked everything

Well, you have double checked everything except the fact that the class(es) you use for the deserialization does not represent your json data (assuming the information you provided above is correct).


So first establish some facts:

  • According to your explanation request.downloadHandler.text contains the given json text that you posted at the end of your question.

  • You then try to deserialize that very same text twice, once in line 22 and once again in line 29 of your middle snippet.

  • In the first case you try to deserialize the given json text into a Greeks instance, in the second case you try to deserialize the very same text into a Quote instance.


Well, here are your problems:

The json text you posted neither represents a "Greeks" nor a "Quote" instance. So it's kinda obvious that all the fields you're interested in are not loaded properly. Just take a look at the json text. The object in the json only contains a single field which is called "quotes". Your "Greeks" class does not even have that field, so it is ignored. What else do we have in the object? well, nothing else. Therefore the deserialized instance you get back are just empty initialized objects which got no data assigned from the given json text, because non of the fields match anything in that class. The same is of course true for your Quote class.


The funny thing is, you already have the other necessary classes in your project, but you don't use them. I assume you used a json to C# converter to create those classes? Well all those classes simply got named after the field name they are used in, except for the top object which is simply called "Root". This is the class that actually represents your json text and this is the class you have to use when you deserialize your json text. The Root class does have a field called "quotes". The object behind the "quotes" field contains just a single field called "quote". This sub object contains all the fields specified in the "Quote" class. The Quote class has one subfield called "greeks". This field is of your "Greeks" type and the fields in this sub object match the fields of your Greeks class.


ps: there's no need for the isDone check. Above you speculated wether that would somehow "wait" for the completion, it does not. You wait for the completion in line 11 through the yield return line. After that it's just a matter of telling if the request finished successfully or not. You handle the error cases through the if statement in line 12. So the "else" block is the success case. Checking for "isDone" is completely redundant here.


ps: If this is an actual API, I have the strong feeling that something may got wrong on the server side. a field named "quotes" indicates that this most likely is an array / collection of multiple "quote" objects. However currently your structure does only ever return a single one, since all elements in your json are objects, not arrays. Maybe that's the intended use, if it is, it would be a strange design. If it is not you will run into issues sooner or later. We don't have enough information to say anything more about this specific case. I just mentioned it as a warning.

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
â–¼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Dahaka666 · Jan 21 at 09:44 PM 0
Share

After fixing the model reference, the last thing was to handle the nullable types and it all started working properly. Thank you very much for pointing me in the right direction.

avatar image
0

Answer by mistergreen2016 · Jan 20 at 10:24 PM

Wait until you finish loading the JSON, then deserialize. The process is async not sync.

Comment
Add comment · Show 8 · Share
10 |3000 characters needed characters left characters exceeded
â–¼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Dahaka666 · Jan 20 at 10:27 PM 0
Share

Would that not be handled by line 20: if (request.isDone)? How would I accomplish this otherwise?

Thank you for the reply

avatar image mistergreen2016 Dahaka666 · Jan 20 at 11:28 PM 0
Share

Not sure, try debug inside the request.isDone block.

avatar image Dahaka666 mistergreen2016 · Jan 20 at 11:59 PM 0
Share

The weirdest part is that I've had other API calls structured the same way, that all deserialize perfectly and display their values correctly. So I don't think it's that the JSON hasn't finished loading back, I think it's the multiple classes that messes things up as I'm not sure how to deserialize the JSON properly with multiple classes as shown in the API response.

Show more comments
avatar image Dahaka666 · Jan 21 at 05:15 AM 0
Share

So I have officially double-checked everything, and the JSON file is fully loaded at the time I am trying to deserialize it. My code correctly references the variables in the classes that the deserializer references as a model. Everything is smooth and without errors, except that the data is never assigning the values to the variables properly. They remain their default value, 0. I'm not sure what to do from this point.

avatar image mistergreen2016 Dahaka666 · Jan 21 at 04:16 PM 0
Share

Double-check your JsonConvert.DeserializeObject. Maybe it has trouble with nested classes or namespace. It happens. I think the newer Unity jsonUntility can do it.

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

138 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

deserialize a json web api on top of the class or inside the start function 0 Answers

Reference specific variable from a specific gameObject? 2 Answers

Can you post a json string as a body in Unity? 2 Answers

Referencing AND affecting a variable from another script 1 Answer

Getting a variable from a specific gameobject for another script 3 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges