1

Horray - got the ColdFusion to Binance API working.

Binance API Result has an Array Inside the JSON Structure.

Trying to pull the Fills data. But not having best luck.

 <cfset result = '{"symbol":"SHIBUSDT","orderId":1158141049,"orderListId":-1,"clientOrderId":"tAMnbc6XLKEMNFENUdbNvD","transactTime":1645634941287,"price":"0.00000000","origQty":"784913.00","executedQty":"784913.00","cummulativeQuoteQty":"20.72170320","status":"FILLED","timeInForce":"GTC","type":"MARKET","side":"SELL","fills":[{"price":"0.00002640","qty":"784913.00","commission":"0.02072170","commissionAsset":"USDT","tradeId":291444301}]}'>

The array I need starts at the fills with the structure inside it:

  ,"fills":[{"price":"0.00002640","qty":"784913.00","commission":"0.02072170","commissionAsset":"USDT","tradeId":291444301}]

Starting with this as easy display of the JSON result to easily get the symbol, side, etc...

 <cfscript>
   record = deserializeJSON(#result#);
   writeOutput( "<br>SYMBOL:"& record.symbol); 
   writeOutput( "<br>SIDE:"& record.side);   
 </cfscript>

Kinda trying this to get the Fills Array Data but no luck...

 <cfoutput>
 <cfset arrayOfStructs = deserializeJson(result[fills])>
 <cfloop array="#arrayOfStructs#" index="retdata">
       <cfset Price = retdata.price />
       <cfset QTY = retdata.qty />
       #price#
          <br>#qty#
 </cfloop>
 </cfoutput>

Should be an easy thing. Perhaps my brain is burned from all the API fights I've had.

Merle_the_Pearl
  • 1,391
  • 3
  • 18
  • 25

2 Answers2

1

record = deserializeJSON(#result#);
..
<cfset arrayOfStructs = deserializeJson(result[fills])>

You're very close, but no need to deserialize twice. Just use the existing record variable. Since result[fills] is already a CF array, just loop through it:

<cfscript>
  result = '{"symbol":"SHIBUSDT",....}'; 

  record = deserializeJSON(result);
  writeOutput( "<br>SYMBOL:"& record.symbol); 
  writeOutput( "<br>SIDE:"& record.side);     

  for (fill in record.fills) {
    price = fill.price;
    qty = fill.qty;
    
    writeOutput("<br>price="& price &" qty="& qty);
  }
  
</cfscript>

Update 2/29/2022: Note about Error Handling

You may have omitted cfhttp error handling for brevity, but if not ... it's always a good practice to verify the http call was actually successful (and that it contains the expected JSON string) before attempting to do anything with the response. Otherwise, the code may crash with an cryptic error if the web service is experiencing problems. Putting it all together ...

<cfscript>
  // Using all cfscript for consistency   
  cfhttp(url="#base_api##req_path#" 
         , method="POST" 
         , result="result" 
         , charset="utf-8") {
     cfhttpparam( type="header", name="X-MBX-APIKEY", value="#bn_key#");
     cfhttpparam( type="body", value=theBody );
  }
  
  if (result.statusCode eq "200 OK" && IsJSON( result.fileContent )) {
     
     response = deserializeJSON( result.fileContent );
     writeOutput( "<br>SYMBOL:"& response.symbol); 
     writeOutput( "<br>SIDE:"& response.side);     

     for (fill in response.fills) {
        price = fill.price;
        qty = fill.qty;
    
        writeOutput("<br>price="& price &" qty="& qty);
     }
    
  
  }
  else {
     WriteOutput("ERROR: Houston we have a problem...");  
     writeDump( result );
  }
</cfscript>
SOS
  • 6,430
  • 2
  • 11
  • 29
  • 1
    why are you deserializing result and assigning it to the same variable named record twice? Forgot to delete the line? – AndreasRu Feb 23 '22 at 19:38
  • It's code "in stereo"! :-) Ack... just a copy paste error. Good spot – SOS Feb 23 '22 at 19:40
1

I was able to sort out. Thx for answers. I'll look at that code as well.

Simple CFHTTP POST to the Binance API - for Trades (Buy/Sell)

 <cfhttp url="#base_api##req_path#" method="POST" result="result" charset="utf-8">
 <cfhttpparam type="header" name="X-MBX-APIKEY" value="#bn_key#"> 
 <cfhttpparam type="body" value="#thebody#">
 </cfhttp> 

 <cfset result = #result.filecontent#>

 <cfscript>
   record = deserializeJSON(#result#);

   need = record.fills;

   writeOutput("SYMBOL:"& record.symbol); 
   writeOutput("<br>SIDE:"& record.side);  

   // writeDump(need);
   // writeDump(record);

 </cfscript>

This gets the needed array [need] which has the actual buy/sell data. Then just loop it.

 <cfoutput>
 <cfloop array="#need#" index="retdata">
       <cfset Price = retdata.price />
       <cfset QTY = retdata.qty />
      PRICE : #price#
    <br>Quantity : #qty#
 </cfloop>
 </cfoutput>
Merle_the_Pearl
  • 1,391
  • 3
  • 18
  • 25
  • Yeah, that's basically the same thing, just a few extra variables. Though always check the cfhhtp call was successful and the fileContent IsJSON() before deserializing, or the code will crash if there is a temporary problem with the web service. Also, extra pound signs are only needed for the output. Glad you got it up and running! – SOS Feb 25 '22 at 15:20