Q: Which headers should I fill?
A:
Content-type: application/json
Accept: application/json
Accept-encoding: gzip, deflate
Authorization: HMAC webApiId:webApiKey:unix_timestamp_in_ms:Base64HMACSignature
Q: How to perform HMAC authentication?
A:
Signature = unix_timestamp_in_ms + webApiId + webApiKey + req.getMethod() + req.getURI() + content;
Base64HMACSignature = Base64(HmacSHA256(Signature, webApiSecret));
Header = "Authorization: HMAC:webApiId:webApiKey:unix_timestamp_in_ms:Base64HMACSignature"
Example: Signature = "1509018187496b3a113e4-77d2-4118-941d-3168803612abRCsr8eCZsyR59emhGEThttps://localhost:8443/api/v1/account";
There is a sample JavaScript code:
long timestamp = new Date(System.currentTimeMillis()).getTime();
String signature = timestamp + _webApiId + _webApiKey + req.getMethod() + req.getURI() + _content;
byte[] messageBytes = signature.getBytes(StandardCharsets.US_ASCII);
byte[] hmacKeyByte = _webApiSecret.getBytes(StandardCharsets.US_ASCII);
Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
SecretKeySpec secret_key = new SecretKeySpec(hmacKeyByte, "HmacSHA256");
sha256_HMAC.init(secret_key);
byte[] mac_data = sha256_HMAC.doFinal(messageBytes);
byte[] valueDecoded = Base64.encodeBase64(mac_data);
String base64HMACStr = new String(valueDecoded);
req.setHeader(HttpHeaders.AUTHORIZATION, String.format("%1$s %2$s:%3$s:%4$s:%5$s", "HMAC ", _webApiId, _webApiKey, timestamp, base64HMACStr));
Q: How to download content using Curl, Wget, PowerShell?
A: All responses of the Web API is compressed using gzip stream.
You have to add "Accept: application/json" and "Accept-encoding: gzip, deflate"
headers to your request and use gunzip tool to decompress the stream.
Unix curl:
curl -v -H "Content-type: application/json" -H "Accept: application/json" -H "Accept-encoding: gzip, deflate" apimethod | gunzip -
Unix wget:
wget -S -q --header "Content-type: application/json" --header "Accept: application/json" --header "Accept-encoding: gzip, deflate" -O - apimethod | gunzip -
Windows PowerShell:
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.Add("Content-type","application/json")
$headers.Add("Accept","application/json")
$headers.Add("Accept-Encoding","gzip")
Invoke-RestMethod -Method Get 'apimethod' -Headers $headers
Add-Type -AssemblyName System.Web;
Add-Type -AssemblyName System.Net.Http;
Add-Type @"
using System.Net;
using System.Security.Cryptography.X509Certificates;
public class TrustAllCertsPolicy : ICertificatePolicy {
public bool CheckValidationResult(
ServicePoint srvPoint, X509Certificate certificate,
WebRequest request, int certificateProblem) {
return true;
}
}
"@
class WebClient {
[string] $Id
[string] $Key
[string] $Secret
[string] $BaseAddress
[System.Net.Http.HttpClient] $client
WebClient([string] $baseAddress, [string] $id, [string] $key, [string] $secret){
$this.Id = $id
$this.Key = $key
$this.Secret = $secret
$this.BaseAddress = $baseAddress
[System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy
[System.Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Ssl3 -bor [Net.SecurityProtocolType]::Tls12
$handler = [System.Net.Http.HttpClientHandler]::new()
$handler.AutomaticDecompression = [System.Net.DecompressionMethods]::Gzip -bor [System.Net.DecompressionMethods]::Deflate
$this.client = [System.Net.Http.HttpClient]::new($handler)
$this.client.DefaultRequestHeaders.Accept.Clear()
$this.client.DefaultRequestHeaders.Accept.Add([System.Net.Http.Headers.MediaTypeWithQualityHeaderValue]::new("application/json"))
}
[long] DateTimeToTimestamp([DateTime] $time) {
return [long]($time - [DateTime]::new(1970, 1, 1, 0, 0, 0, 0, [DateTimeKind]::Utc)).TotalMilliseconds
}
[void] ExecuteGetRequest([string] $uri, [string] $outputfile){
$request = [System.Net.Http.HttpRequestMessage]::new()
$request.RequestUri = $this.BaseAddress + $uri
$request.Method = [System.Net.Http.HttpMethod]::Get
$timestamp = $this.DateTimeToTimestamp([DateTime]::UtcNow)
if ($request.Content -eq $null) {
$content = ""
}
else {
$content = $request.Content.ReadAsString()
}
$signature = $timestamp.ToString() + $this.Id + $this.Key + $request.Method.Method + $request.RequestUri + $content
$hash = $this.CalculateHmacWithSha256($signature)
$request.Headers.Authorization = [System.Net.Http.Headers.AuthenticationHeaderValue]::new("HMAC", $this.Id+':'+$this.Key+':'+$timestamp+':'+$hash)
try {
$response = $this.client.SendAsync($request).GetAwaiter().GetResult()
if ($response.IsSuccessStatusCode){
$fileStream = [System.IO.FileStream]::new($outputfile,[System.IO.FileMode]::Create)
$response.Content.CopyToAsync($fileStream).GetAwaiter().GetResult()
$fileStream.Dispose()
}
else {
Write-Host 'An error has occurred:'
Write-Host $response
}
}
catch{
Write-Host $_.Exception
}
}
[string] CalculateHmacWithSha256 ([string] $signature)
{
$encoding = [System.Text.ASCIIEncoding]::new()
$encodedSecret = $encoding.GetBytes($this.Secret)
$hmacsha = [System.Security.Cryptography.HMACSHA256]::new($encodedSecret)
try {
$message = $encoding.GetBytes($signature)
$hashBytes = $hmacsha.ComputeHash($message)
$hash = [Convert]::ToBase64String($hashBytes)
return $hash;
}
finally{
$hmacsha.Dispose();
}
}
[void] DownloadBarsInfo([string] $symbol,[string] $periodicity,[string] $priceType,[string] $outputfile) {
$uri = '/api/v2/quotehistory/download/bars/info/'+[System.Web.HttpUtility]::UrlPathEncode($symbol)+'/'+$periodicity+'/'+$priceType;
$this.ExecuteGetRequest($uri, $outputfile);
<# .DESCRIPTION
Download bars info file.
.PARAMETER symbol
Specifies symbol
.PARAMETER periodicity
Specifies bar periodicity (Supports only M1, H1)
.PARAMETER priceType
Specifies bar price type (Ask, Bid)
.EXAMPLE
PS>
DownloadBarsInfo('BTCUSD', 'M1', 'Bid', 'C:\BTCUSD_M1_Bid_info.zip');
#>
}
[void] DownloadBars([string] $symbol,[string] $periodicity,[string] $priceType,[DateTime] $time, [string] $outputfile) {
$uri = '/api/v2/quotehistory/download/bars/'+[System.Web.HttpUtility]::UrlPathEncode($symbol)+'/'+$periodicity+'/'+$priceType+'/'+$this.DateTimeToTimestamp($time)
$this.ExecuteGetRequest($uri, $outputfile);
<# .DESCRIPTION
Download bars info file.
.PARAMETER symbol
Specifies symbol
.PARAMETER periodicity
Specifies bar periodicity (Supports only M1, H1)
.PARAMETER priceType
Specifies bar price type (Ask, Bid)
.PARAMETER time
Specifies file timestamp
.EXAMPLE
PS>
DownloadBars('BTCUSD', 'M1', 'Bid', [DateTime]::new(2019,12,1), 'C:\BTCUSD_M1_Bid.zip');
#>
}
}
$symbol = 'TTT_QUOTESYMBOL';
$id = 'e32511f4-7f49-43b2-b6b4-aaa3563799cc';
$key = 'kxNdnWycKCFEERP7';
$secret = 'y2Q9CJgRx3KWQ9kYg7qRNM6hTSPYMyhBZfA7yBb2GYW4GH7fhxCnpQ3W6GpT5sd8';
$outputfile = 'D:\!\outinfo.zip';
$outputfile1 = 'D:\!\out.zip';
Clear-Host
$webClient = [WebClient]::new('https://localhost:8443', $id, $key, $secret);
$webClient.DownloadBarsInfo($symbol, 'M1', 'Bid', $outputfile);
$webClient.DownloadBars($symbol, 'M1', 'Bid', [DateTime]::new(2019,12,1), $outputfile1);