Will InternetPostRequest accepts raw json data?

In 6.39.0 you can send data that are NOT URL encoded as you can set headers by yourself where you can specify encoding.

I tried implementing the InternetPostRequest. However not able to pass the orders automatically. What I could be missing here?

_SECTION_BEGIN("Price");
SetChartOptions(0,chartShowArrows|chartShowDates);
_N(Title = StrFormat("{{NAME}} - {{INTERVAL}} {{DATE}} Open %g, Hi %g, Lo %g, Close %g (%.1f%%) {{VALUES}}", O, H, L, C, SelectedValue( ROC( C, 1 ) ) ));
Plot( C, "Close", ParamColor("Color", colorDefault ), styleNoTitle | ParamStyle("Style") | GetPriceStyle() ); 
_SECTION_END();

trigger = ParamTrigger("transmit order","send order");



user_apikey = ParamStr("user_apikey","234809328409284302"); //Enter your API key here
api_secret = ParamStr("api_secret","3333333333333"); //Enter your API secret key here
s_prdt_ali = ParamList("s_prdt_ali","NRML:NRML|BO:BO|CNC:CNC|CO:CO|MIS:MIS",0); 
Tsym = ParamStr("Tsym","RELIANCE-EQ");
exch = ParamList("Exchange","NFO|NSE|BSE|CDS|MCX|NCDEX|BFO|MCXSXFO|MCXSX",1);
Ret = ParamList("Ret","DAY|IOC",0);
prctyp = ParamList("prctyp","MKT|L|SL|SL-M",0);
Pcode = ParamList("Pcode","NRML|BO|CNC|CO|MIS",0);
qty = Param("Quatity",100,0,100000,1);
AMO = "NO";
placeordertype = ParamList("Place Order On","Realtime|CandleCompletion",0);
EnableAlgo = ParamList("AlgoTrading","Disable|Enable|LongOnly|ShortOnly",0);
stgy_name = ParamStr("Strategy Name","Amibroker Chart");
               
api_data ="{\"api_key\":"+ "\""+user_apikey+"\","+ "\"api_secret\":"+"\""+api_secret+"\","+"\"data\":"+"{\"stgy_name\":\""+stgy_name+"\",\"s_prdt_ali\":\""+s_prdt_ali+"\",\"Tsym\":\""+Tsym+"\",\"exch\":\""+exch+"\",\"Ttranstype\":\""+"B"+"\",\"Ret\":\""+Ret+"\",\"prctyp\":\""+prctyp+"\",\"qty\":\""+qty+"\",\"discqty\":\""+"0"+"\",\"MktPro\":\""+"NA"+"\",\"Price\":\""+"0"+"\",\"TrigPrice\":\""+"0"+"\",\"Pcode\":\""+Pcode+"\",\"AMO\":\""+AMO+"\"}}";


if(trigger)
{


InternetSetHeaders("Content-Type : application/json");
InternetSetHeaders("Accept-Encoding: gzip, deflate");
InternetSetHeaders("user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.82 Safari/537.36");



ih = InternetPostRequest("https://tjapi.algomojo.com/1.0/PlaceOrder",api_data,1);

if( ih ) 
{ 
    while( ( resp = InternetReadString(ih ) ) != "" ) 
   { 
       _TRACE(resp);
   } 
    
    InternetClose( ih ); 
} 
}

_N(Title = StrFormat("{{NAME}} - {{INTERVAL}} {{DATE}} Open %g, Hi %g, Lo %g, Close %g (%.1f%%) {{VALUES}}", O, H, L, C, SelectedValue( ROC( C, 1 ) ) ));
SetChartOptions(0,chartShowArrows|chartShowDates);  //Enable X-Axis (Date/Time Axis)

Plot(Close,"Candles",colorDefault,styleCandle); //Plot Candles


1 Like

Your code is syntactically incorrect (misses parameters). Your first step is to get the syntax right at minimum.

The devil is in the details, you should pay close attention to the format of the headers.
There are many errors in your formula:

  1. InternetSetHeaders is NOT accumulative, it does NOT ADD the headers, it SETS the headers. If you call it twice it will REPLACE previous header. So you should create ALL headers and set it once
headers = "Content-Type: application/json\r\n" +
          "Accept-Encoding: gzip, deflate\r\n"; // ALL headers in one string

InternetSetHeaders( headers ); // call once 
  1. Agent is not set via headers by via InternetSetAgent call

  2. You need to make sure exact spelling of the headers. Every letter, every space and every punctuation mark must be correct otherwise the remote server will ignore request.

4 Likes

Is it possible to get headers after first InternetPostRequest? I ask becouse some sites needs specific data to another POST.

1 Like

No. InternetPostRequest allows you to read normal HTTP response content. The response headers are not part of it. To read response headers one would need different API (HttpQueryInfo). I can add that in the future, but please check if the server you are using is not providing normal reponse because using headers for response content is rather unusual.

1 Like

From your post

and from RC thread it is:

Can you kindly clarify the parameters required ?
Thanks.

Edit: Found in the AFL Code editor, it is the latter. Had to update my version :slight_smile:

1 Like

5 posts were split to a new topic: Handling cookies in Internet functions

I checked it. After first login I have to set header "Cookie" (received after logging in) with next post e.g "send trade". Of course, I can use external applications to get this data.

Since this thread went off topic to the discussion about cookies I have moved it to new one with proper subject: Handling cookies in Internet functions

You need to read the readme not only the forum post. Readme contains a lot more info and examples.

1 Like

Thanks, Tomaz it worked like a charm. My Mistake thought InternetSetHeaders is accumulative.
Now Iam able to send ordres.

And Im using Amibroker 6.39.1 version. However still Intellisense shows only the InternetSetHeaders("headers") parameters and not the with InternetSetHeaders( ih, headers );

image

anyways still used InternetSetHeaders("headers") and still worked.

1 Like

Yes, that is correct, InternetSetHeaders is unique you don't need internet handle.
Originally (in development version) it required internet handle but in the final version that you got it works without it. The readme, docs and tooltips are all correct. My memory isn't.

5 Likes

Hello Tomasz, InternetSetHeaders is nice new function Thank You!
If i understand correctly, functions

  • InternetOpenURL() - GET request
  • InternetPostRequest - POST request

but didnt found function for PUT request. Is there some option how to do it?

Thank You.

1 Like

Currently you can only do GET and POST.

1 Like

AmiBroker 6.40.0 released now features updated Javascript engine that features native JSON object that you can use to parse JSON strings:

// insert this as indicator and chart title will display content of JSON 

Version(6.40); // minimum AmiBroker version required
EnableScript("jscript");
<%
 string_holding_json = '{ "firstName": "John",  "lastName": "Smith" }';
 
 obj = JSON.parse( string_holding_json );

 firstName = obj.firstName;
%>

scr = GetScriptObject(); 
Title = scr.firstName;
5 Likes

Another example of universal ParseJSON function that can be called directly from AFL:

// reusable function definition (can be placed in include)
EnableScript("jscript");

<%
  function _Parse( json_string )
  {
	return JSON.parse( json_string );
  }
%>

function ParseJSON( json_string )
{
   script = GetScriptObject();
   return script._Parse( json_string );
}
//////////////////

// example usage - direct parsing of string into object
obj = ParseJSON( "{ \"firstName\": \"John\",  \"lastName\": \"Smith\" }" );

Title = "First name is " +  obj.firstName + ", Last name is " + obj.lastName;
5 Likes

@Tomasz, did you consider adding support for the backtick character (or some other alternatives) in AFL to avoid the need to escape double quotes in strings?

Example:

obj = ParseJSON( `{ "firstName": "John",  "lastName": "Smith" }` );

Back tick would work, but I am considering Python-like r'string' and/or "raw string literal" that was recently added to C++ standard as well to avoid escaping.

1 Like

This is a cool feature. Will solve a lot of JSON string-based automation.

1 Like

This topic was automatically closed 100 days after the last reply. New replies are no longer allowed.