SmartQuant Discussion
http://www.smartquant.com/forums/

Order book visualization
http://www.smartquant.com/forums/viewtopic.php?f=46&t=7951
Page 1 of 1

Author:  macin [ Wed Mar 10, 2010 12:04 am ]
Post subject:  Order book visualization

Hi,
I recently wrote some piece of code to visualize order book in a TT like style. Feel free to comment on it or add something valuable and, most important, please correct me if I made any errors in coding, so the ladder can run faster or more efficient.
Maybe this could be attached to OQ as a sample code.
All the best
Martin

P.S. This works only if you have access to order book data (i.e. TTFIX).
Here is the code (sorry for minimum amount of comments):


Code:
using System;
using System.Drawing;
using System.Collections.Generic;
using System.Timers;
using OpenQuant.API;
using OpenQuant.API.Indicators;
using System.Xml;
using System.ComponentModel;

using System.Data;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using System.Reflection;
using System.Threading;


namespace Strat
{
   public class MyStrategy : Strategy
   {
      public delegate void updateGridCallback(DataTable tbl);
      RunForm runForm;
      Thread oThread;

      public bool canGo = false;

      int currVol = 0;
      int cumVol = 0;

      DataTable tbl = new DataTable();
      DataRow t;
      DataView vtbl;

      private static int queueSize = 10000;

      private Dictionary<double, Queue<int>> dqBidVol = new
         Dictionary<double, Queue<int>>();
      private Dictionary<double, Queue<int>> dqAskVol = new
         Dictionary<double, Queue<int>>();
      private Dictionary<double, Queue<int>> dqTradedVol = new
         Dictionary<double, Queue<int>>();
      private Dictionary<double, int> bidOrderList = new
         Dictionary<double, int>();
      private Dictionary<double, int> askOrderList = new
         Dictionary<double, int>();
      
      private Queue<int> qBidVol = new Queue<int>(queueSize);
      private Queue<int> qAskVol = new Queue<int>(queueSize);
      private Queue<int> qTradedVol = new Queue<int>(queueSize);

      double p; // traded price
      int v;   // traded volume
      
      
      double volAvg;
      
      int tp; // row number of currently traded price
      int ptp; // row number of previously traded price
      
      Stopwatch sw = new Stopwatch();
      Stopwatch swt = new Stopwatch();

      public override void OnStrategyStart()
      {
         tbl.Columns.Add("Bid", typeof(int));
         tbl.Columns.Add("Price", typeof(System.Decimal));
         DataColumn[] PrimaryKeyColumns = new DataColumn[1];
         PrimaryKeyColumns[0] = tbl.Columns["Price"];
         tbl.PrimaryKey = PrimaryKeyColumns;

         tbl.Columns.Add("Ask", typeof(int));

         tbl.Columns.Add("Curr Volume", typeof(int));
         tbl.Columns.Add("Cum Volume", typeof(int));

         vtbl = new DataView(tbl);
         vtbl.Sort = "Price DESC";

         runForm = new RunForm();

         oThread = new Thread(new ThreadStart(runForm.startForm));
         oThread.Start();
         canGo = true;

         Thread.Sleep(2000);
            
         runForm.sampleForm.Invoke(runForm.sampleForm.dDelegateInitializeGrid,
            vtbl);
         if (Instrument.TickSize < 1)
            runForm.sampleForm.dataGridView1.Columns["Price"].DefaultCellStyle.Format = "0.00";
         else
            runForm.sampleForm.dataGridView1.Columns["Price"].DefaultCellStyle.Format = "0";
         runForm.sampleForm.Name = Instrument.Symbol.ToString();
         runForm.sampleForm.Text = Instrument.Symbol.ToString();
         
      }
      public override void OnTrade(Trade trade)
      {
         swt.Start();
      
         p = trade.Price;
         v = trade.Size;
         
         if (Trades.Count > 2)
         {
            if (p==Trades[Trades.Count-2].Price)
               currVol = currVol+v;
            else
               currVol = v;
         }
               
         t = tbl.Rows.Find(p);
         if (t != null)
         {
            t["Curr Volume"] = currVol;
            
            if (t["Cum Volume"] != DBNull.Value)
            {
               cumVol = (int)t["Cum Volume"];
               t["Cum Volume"] = cumVol+v;
            }
            else
               t["Cum Volume"] = v;
         }
         else
         {
            DataRow tRow = tbl.NewRow();
            tRow["Price"] = p;
            tRow["Cum Volume"] = v;
            tbl.Rows.Add(tRow);
         }
            

         tp = vtbl.Find(p);
         
         if (Trades.Count == 1)
            ptp = tp;
         
         runForm.sampleForm.Invoke(runForm.sampleForm.dDelegateUpdateTradePrice, new Object[]{tp, ptp});
         ptp = tp;
         
         Console.WriteLine("Trade: " + swt.Elapsed);
         swt.Reset();
         
      }

      public override void OnOrderBookChanged(OrderBookUpdate update)
      {
         Console.WriteLine(update.Action.ToString());
         t = tbl.Rows.Find(update.Price);
         
         if (update.Action == OrderBookAction.Insert)
         {
            if (t == null && update.Side == BidAsk.Bid)
            {
               if (update.Price != null)
               tbl.Rows.Add(update.Size, update.Price,
                  DBNull.Value);
            }else if (t == null && update.Side == BidAsk.Ask)
            {
               if (update.Price != null)
               tbl.Rows.Add(DBNull.Value, update.Price,
                  update.Size);
            }
         }
         else if (update.Action == OrderBookAction.Delete)
         {
            t = tbl.Rows.Find(update.Price);
            t["Bid"] = DBNull.Value;
            t["Ask"] = DBNull.Value;
         }
         else if (update.Action == OrderBookAction.Update)
         {
            #region update the ladder
            if (update.Side == BidAsk.Bid)
            {
               if (t != null)
               {
                  t["Bid"] = update.Size;
                  t["Ask"] = DBNull.Value;
               }
               else
                  tbl.Rows.Add(DBNull.Value, DBNull.Value, update.Size, update.Price,
                     DBNull.Value, DBNull.Value, DBNull.Value);
            }                     
            else if (update.Side == BidAsk.Ask)
            {
               if (t != null)
               {
                  t["Ask"] = update.Size;
                  t["Bid"] = DBNull.Value;
               }
               else
                  tbl.Rows.Add(DBNull.Value, DBNull.Value, DBNull.Value, update.Price,
                     update.Size, DBNull.Value, DBNull.Value);
            }
            #endregion

            Console.WriteLine("Order book" + sw.ElapsedMilliseconds);
            sw.Reset();
         }
      }
   
         
      
      public override void OnStrategyStop()
      {
         runForm.stopForm();
      }


   }
}
namespace Strat
{
   public delegate void DelegateInitializeGrid(DataView tbl);
   public delegate void DelegateUpdateGrid(int rb, int ra, int srb, int sra);
   public delegate void DelegateUpdateTradePrice(int tp, int ptp);

   public class RunForm
   {

      public Form1 sampleForm = null;


      public void startForm()
      {
         Application.EnableVisualStyles();
         Application.SetCompatibleTextRenderingDefault(false);
         sampleForm = new Form1();
         Application.Run(sampleForm);
         sampleForm.Text = "Ladder";
         sampleForm.Name = "Ladder";
      }

      public void stopForm()
      {
         sampleForm.Dispose();
      }
   }

   partial class Form1
   {
      /// <summary>
      /// Required designer variable.
      /// </summary>
      private System.ComponentModel.IContainer components = null;



      /// <summary>
      /// Clean up any resources being used.
      /// </summary>
      /// <param name="disposing">true if managed resources should bedisposed; otherwise, false.</param>
      protected override void Dispose(bool disposing)
      {
         if (disposing && (components != null))
         {
            components.Dispose();
            //aTimer.Dispose();
         }
         base.Dispose(disposing);
      }

      #region Windows Form Designer generated code

      /// <summary>
      /// Required method for Designer support - do not modify
      /// the contents of this method with the code editor.
      /// </summary>
      private void InitializeComponent()
      {
         System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle1 =
            new System.Windows.Forms.DataGridViewCellStyle();
         //System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Form1));
         this.dataGridView1 = new System.Windows.Forms.DataGridView();
         ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).BeginInit();
         this.SuspendLayout();
         //
         // dataGridView1
         //
         this.dataGridView1.AllowUserToAddRows = false;
         this.dataGridView1.AllowUserToDeleteRows = false;
         this.dataGridView1.AllowUserToResizeColumns = false;
         this.dataGridView1.AllowUserToResizeRows = false;
         this.dataGridView1.AutoSizeColumnsMode =
            System.Windows.Forms.DataGridViewAutoSizeColumnsMode.Fill;
         this.dataGridView1.BorderStyle = System.Windows.Forms.BorderStyle.None;
         this.dataGridView1.ColumnHeadersHeight = 25;
         this.dataGridView1.ColumnHeadersHeightSizeMode =
            System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.DisableResizing;
         dataGridViewCellStyle1.Alignment =
            System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft;
         dataGridViewCellStyle1.BackColor = System.Drawing.SystemColors.Window;
         dataGridViewCellStyle1.Font = new System.Drawing.Font("MicrosoftSans Serif", 11F, System.Drawing.FontStyle.Bold,
            System.Drawing.GraphicsUnit.Point, ((byte)(238)));
         dataGridViewCellStyle1.ForeColor = System.Drawing.SystemColors.ControlText;
         dataGridViewCellStyle1.SelectionBackColor =
            System.Drawing.SystemColors.Highlight;
         dataGridViewCellStyle1.SelectionForeColor =
            System.Drawing.SystemColors.HighlightText;
         dataGridViewCellStyle1.WrapMode =
            System.Windows.Forms.DataGridViewTriState.False;
         this.dataGridView1.DefaultCellStyle = dataGridViewCellStyle1;
         this.dataGridView1.Dock = System.Windows.Forms.DockStyle.Fill;
         this.dataGridView1.EnableHeadersVisualStyles = false;
         this.dataGridView1.Location = new System.Drawing.Point(0, 0);
         this.dataGridView1.Name = "dataGridView1";
         this.dataGridView1.ReadOnly = true;
         this.dataGridView1.RowHeadersWidthSizeMode =
            System.Windows.Forms.DataGridViewRowHeadersWidthSizeMode.DisableResizing;
         this.dataGridView1.ScrollBars = System.Windows.Forms.ScrollBars.None;
         this.dataGridView1.Size = new System.Drawing.Size(596, 413);
         this.dataGridView1.TabIndex = 0;
         this.dataGridView1.KeyDown += new System.Windows.Forms.KeyEventHandler(this.dataGridView1_KeyDown);
         //
         // Form1
         //
         this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
         this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
         this.ClientSize = new System.Drawing.Size(596, 413);
         this.Controls.Add(this.dataGridView1);
         
         ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).EndInit();
         this.ResumeLayout(false);

      }

      #endregion
   
      private void dataGridView1_KeyDown(object sender, KeyEventArgs e)
      {
         scrollGrid();
      }

      private void scrollGrid()
      {
         int halfWay = (dataGridView1.DisplayedRowCount(false)/2);
         if (dataGridView1.FirstDisplayedScrollingRowIndex + halfWay> dataGridView1.SelectedCells[0].RowIndex ||
            (dataGridView1.FirstDisplayedScrollingRowIndex + dataGridView1.DisplayedRowCount(false)-halfWay) <= dataGridView1.SelectedCells[0].RowIndex)
         {
            int targetRow = dataGridView1.SelectedCells[0].RowIndex;
               
            targetRow = Math.Max(targetRow-halfWay, 0);
            dataGridView1.FirstDisplayedScrollingRowIndex = targetRow;

         }
      }
      
      private void initializeGrid(DataView lst)
      {
         SetDoubleBuffered(dataGridView1);

         this.dataGridView1.ReadOnly = true;
         this.dataGridView1.DataSource = lst;
         
         dataGridView1.Columns["Price"].DefaultCellStyle.BackColor = System.Drawing.Color.DarkGray;
         
         
         dataGridView1.Columns["Price"].DefaultCellStyle.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleCenter;
         dataGridView1.Columns["Price"].DefaultCellStyle.ForeColor =
            System.Drawing.Color.White;

         dataGridView1.Columns["Bid"].DefaultCellStyle.BackColor =
            System.Drawing.Color.Blue;
         dataGridView1.Columns["Bid"].DefaultCellStyle.ForeColor =
            System.Drawing.Color.White;
         dataGridView1.Columns["Bid"].DefaultCellStyle.Alignment =
            System.Windows.Forms.DataGridViewContentAlignment.MiddleRight;

         dataGridView1.Columns["Ask"].DefaultCellStyle.BackColor =
            System.Drawing.Color.Red;
         dataGridView1.Columns["Ask"].DefaultCellStyle.ForeColor =
            System.Drawing.Color.White;
         dataGridView1.Columns["Ask"].DefaultCellStyle.Alignment =
            System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft;
         this.dataGridView1.MultiSelect = false;

      }


      private void updateGrid(int rb, int ra, int srb, int sra)
      {
         
         this.dataGridView1.MultiSelect = false;
         this.dataGridView1.MultiSelect = true;
         this.dataGridView1.Rows[rb].Selected = true;
         this.dataGridView1.Rows[ra].Selected = true;
         this.dataGridView1.Refresh();


      }
      
      private void updateTradePrice(int tp, int ptp)
      {
         lock(this.dataGridView1)
         {
            this.dataGridView1.Rows[tp].Cells["Price"].Style.BackColor = Color.Gray;
            this.dataGridView1.Rows[tp].Cells["Curr volume"].Selected = true;
            this.dataGridView1.Refresh();
         }
      }

      public System.Windows.Forms.DataGridView dataGridView1;


   }


   public partial class Form1 : Form
   {
      public bool canGo = false;


      public DelegateInitializeGrid dDelegateInitializeGrid;
      public DelegateUpdateGrid dDelegateUpdateGrid;
      public DelegateUpdateTradePrice dDelegateUpdateTradePrice;

      public Form1()
      {
         InitializeComponent();
         dataGridView1.AutoGenerateColumns = true;
         dDelegateInitializeGrid = new DelegateInitializeGrid(this.initializeGrid);
         dDelegateUpdateGrid = new DelegateUpdateGrid(this.updateGrid);
         dDelegateUpdateTradePrice = new DelegateUpdateTradePrice(this.updateTradePrice);
      }

      public static void SetDoubleBuffered(Control control)
      {
         // set instance non-public property with name "DoubleBuffered" to true
         typeof(Control).InvokeMember("DoubleBuffered",
            BindingFlags.SetProperty | BindingFlags.Instance | BindingFlags.NonPublic,
            null, control, new object[] { true });
      }
   }
}

Author:  JulianneGuerry [ Tue Nov 02, 2010 11:03 pm ]
Post subject:  Re: Order book visualization

macin wrote:
Hi,
I recently read this Hydromax blog to visualize order book in a TT like style. Feel free to comment on it or add something valuable and, most important, please correct me if I made any errors in coding, so the ladder can run faster or more efficient.
Maybe this could be attached to OQ as a sample code.
All the best
Martin

P.S. This works only if you have access to order book data (i.e. TTFIX).
Here is the code (sorry for minimum amount of comments):


The code seems to work ok as it is. Thanks macin.

Author:  trader64 [ Sun Jan 16, 2011 3:42 am ]
Post subject:  Re: Order book visualization

I used the code as-is, with InteractiveBrokers as my Data Provider, and it sort of works. It builds and it shows the Order Book(s) but I get an error message like this on every order book update.

Quote:
"input array is longer than the number of columns in this table"

Page 1 of 1 All times are UTC + 3 hours
Powered by phpBB® Forum Software © phpBB Group
https://www.phpbb.com/