This indicator uses the Oanda’s OrderBook API to draw a set of horizontal lines, each one representing the number of trapped open positions at a given price. More specifically, above the current price it shows the open buy orders and below the current price it shows the open sell orders.
Input Parameters
- Height: indicates how many pips above and below the current price it should draw.
- Width: represents the scale of the drawn lines.
- Token: this is a token string required to use Oanda’s API. To get one, you must register for either a free demo or a live account. More info at https://developer.oanda.com/rest-live-v20/introduction/
Screenshots
Code
using System; using System.Net; using cAlgo.API; using cAlgo.API.Internals; using cAlgo.API.Indicators; using cAlgo.Indicators; using Newtonsoft.Json.Linq; using System.Collections.Generic; using System.Globalization; using System.IO; using System.IO.Compression; using System.Text; namespace cAlgo { [Indicator(IsOverlay = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.Internet)] public class OandaOrderBook : Indicator { [Parameter(DefaultValue = 200)] public int Height { get; set; } [Parameter(DefaultValue = 30)] public int Width { get; set; } [Parameter(DefaultValue = "")] public string Token { get; set; } private static string apiurl = "https://api-fxpractice.oanda.com/v3/instruments/"; private int line_index = 0; //private DateTime orderbook_dt; protected override void Initialize() { LoadOrderBook(); } private void LoadOrderBook() { using (WebClient webClient = new WebClient()) { webClient.Headers.Add("Content-Type", "application/json"); webClient.Headers.Add("Authorization", "Bearer " + Token); webClient.Headers.Add("Accept-Encoding", "gzip"); byte[] data = webClient.DownloadData(apiurl + Symbol.Name.Insert(3, "_") + "/positionBook"); using (var compressedStream = new MemoryStream(data)) using (var unzipStream = new GZipStream(compressedStream, CompressionMode.Decompress)) using (var resultStream = new MemoryStream()) { unzipStream.CopyTo(resultStream); var json = JObject.Parse(Encoding.ASCII.GetString(resultStream.ToArray())); DrawOrderBook(json); } } } private void DrawOrderBook(JObject json) { int index = Bars.OpenTimes.GetIndexByTime(Bars.OpenTimes.LastValue) + 20; double refprice = double.Parse(json["positionBook"]["price"].ToString().Replace(".", ",")); var buckets = json["positionBook"]["buckets"]; foreach (var bucket in buckets) { double price = double.Parse(bucket["price"].ToString().Replace(".", ",")); double count = Width * double.Parse(bucket[price > refprice ? "longCountPercent" : "shortCountPercent"].ToString().Replace(".", ",")); if (Math.Abs(price - refprice) / Symbol.PipSize < Height) { int startindex = index - (int)Math.Floor(count); Chart.DrawTrendLine("bucket" + line_index++, startindex, price, index, price, price > refprice ? Color.Blue : Color.Red, 1); } } } public override void Calculate(int index) { } } }