|
| 1 | +''' |
| 2 | +// ##### json_validator.py ##### |
| 3 | +// |
| 4 | +// Python utility Script to validate JSON RTD String |
| 5 | +// For Historical data, use DebugView. |
| 6 | +// |
| 7 | +// Performace penalty for Plugin to validate every permutation is unnecessary, |
| 8 | +// as a well written CLIENT=APP already performs checks on RTD. |
| 9 | +// |
| 10 | +/////////////////////////////////////////////////////////////////////// |
| 11 | +// Author: NSM51 |
| 12 | +// https://github.com/ideepcoder/Rtd_Ws_AB_plugin/ |
| 13 | +// https://forum.amibroker.com/u/nsm51/summary |
| 14 | +// |
| 15 | +// Any use of this source code must include the above notice, |
| 16 | +// in the user documentation and internal comments to the code. |
| 17 | +''' |
| 18 | + |
| 19 | + |
| 20 | +import json |
| 21 | + |
| 22 | +## Insert RTD json string in '' quotes to validate |
| 23 | +js = '[{"n":"SYM3","d":20250127,"t":230908,"o":189.45,"h":196.32,"l":181.89,"c":194.59,"v":1212,"bp":186.71,"as":10},\ |
| 24 | + {"n":"SYM2","d":20250127,"t":230908,"o":189.45,"h":196.32,"l":181.89,"c":194.59,"v":1212,"ap":186.71,"bs":10}]' |
| 25 | + |
| 26 | +############### |
| 27 | +# Fields used by RTD json |
| 28 | + |
| 29 | +Field_str = [ 'n' ] |
| 30 | +Field_num_reqd = [ 'o', 'h', 'l', 'c' ] |
| 31 | +Field_num_optional = [ 'v', 'oi', 'x1', 'x2', 's', 'pc', 'bs', 'bp', 'as', 'ap', 'do', 'dh', 'dl' ] |
| 32 | + |
| 33 | + |
| 34 | +def check_str_reqd( f, r ): |
| 35 | + if f in r: |
| 36 | + if not isinstance( r[f], str ): |
| 37 | + print( f"{f} not str in \n{r}" ); return False |
| 38 | + else: |
| 39 | + print( f"{f} not found in \n{r}" ); return False |
| 40 | + |
| 41 | + return True |
| 42 | + |
| 43 | + |
| 44 | +def check_num_reqd( f, r ): |
| 45 | + if f in r: |
| 46 | + if not isinstance( r[f], (int, float) ): |
| 47 | + print( f"{f} not NUM in \n{r}" ); return False |
| 48 | + else: |
| 49 | + print( f"{f} not found in \n{r}" ); return False |
| 50 | + |
| 51 | + return True |
| 52 | + |
| 53 | + |
| 54 | +def check_num_opt( f, r ): |
| 55 | + if f in r: |
| 56 | + if not isinstance( r[f], (int, float) ): |
| 57 | + print( f"{f} not NUM in \n{r}" ); return False |
| 58 | + |
| 59 | + return True |
| 60 | + |
| 61 | + |
| 62 | +''' |
| 63 | +Function to validate type of mandatory & optional fields |
| 64 | +''' |
| 65 | +def json_rtd_validate( js:str ): |
| 66 | + |
| 67 | + if js.startswith('[{"n"'): print(f"\nString MATCH = ok") |
| 68 | + else: print(f"\nString MATCH failed"); return |
| 69 | + |
| 70 | + try: |
| 71 | + jo = json.loads( js ) |
| 72 | + print( f"Json parsing = ok" ) |
| 73 | + except Exception as e: |
| 74 | + print( e ); return |
| 75 | + |
| 76 | + |
| 77 | + if isinstance( jo, list): |
| 78 | + print("Outer Array = ok\n") |
| 79 | + else: |
| 80 | + print( f"Not Array of Quotes"); return |
| 81 | + |
| 82 | + |
| 83 | + i = 0; |
| 84 | + for r in jo: |
| 85 | + |
| 86 | + if not isinstance( r, dict ): print(f"record should be dict"); return |
| 87 | + |
| 88 | + ## test mandatory 'n' and type |
| 89 | + if not check_str_reqd( 'n', r ): return |
| 90 | + |
| 91 | + ## OHLC, test mandatory and type |
| 92 | + for ro in Field_num_reqd: |
| 93 | + if not check_num_reqd( ro, r ): return |
| 94 | + |
| 95 | + ## Optionals, test type |
| 96 | + for ro in Field_num_optional: |
| 97 | + if not check_num_opt( ro, r ): return |
| 98 | + |
| 99 | + ## Date |
| 100 | + if 'd' in r: |
| 101 | + if type( r['d'] ) is not int: |
| 102 | + print( f"d not int \n{r}" ); return |
| 103 | + |
| 104 | + if 't' in r: |
| 105 | + if type( r['t'] ) is not int : |
| 106 | + print( f"t not int \n{r}" ); return |
| 107 | + else: |
| 108 | + print( f"t is required with d in \n{r}"); return |
| 109 | + |
| 110 | + elif 'u' in r: |
| 111 | + if type( r['u'] ) is not int : |
| 112 | + print( f"u not int \n{r}" ); return |
| 113 | + |
| 114 | + elif 'g' in r: |
| 115 | + if type( r['g'] ) is not int : |
| 116 | + print( f"g not int \n{r}" ); return |
| 117 | + |
| 118 | + else: print( f"d/u/g not found in \n{r}" ); return |
| 119 | + |
| 120 | + print( f"record {i} = ok" ); i += 1 |
| 121 | + |
| 122 | + return 1 |
| 123 | + |
| 124 | + |
| 125 | +#### main() |
| 126 | +if __name__ == '__main__': |
| 127 | + |
| 128 | + if json_rtd_validate( js ): |
| 129 | + print( f"\nFinal validation = OK\n") |
| 130 | + else: |
| 131 | + print( f"\nFinal validation = FAILED\n" ) |
| 132 | + |
| 133 | + #print( js ) ## print original string |
| 134 | + |
0 commit comments