You need to enable JavaScript in order to visit our site!
 
Logo PTMC
NAVIGATION
CANCEL
 
or via PTMC account
Restore password
or via PTMC account
Logo PTMC
NAVIGATION
or via PTMC account
Restore password
or via PTMC account
or via PTMC account
Restore password
or via PTMC account
PTMC team 07.12 2013

Creating a script that uses Level 2 quotes

Besides using best Bid and Ask, Protrader also gives you the chance to use information about ticket volume for buy and sell orders that are available on the market. The number of market levels shown in the in the Matrix and Market Depth panels are set on the broker side. Below are the files that I will reference in this article.

CustomTickAggregator_en.cs

Level2Test.cs

Matrix EUR/USD

MATRIX EUR/USD in Protrader

Market Depth 6E[Z3]

Market Depth in Protrader

Accessing Level 2 quotes

Level 2 can be accessed using the following functions:

int GetLevel2Count(string symbol, int fieldType) is the number of available market depth levels for a given instrument

int GetLevel2Count(int fieldType) is the same thing, current instrument

GetLevel2Price(string symol, int fieldType, int offset) is a price of speficied instrument, type, and level

GetLevel2Price(int fieldType, int offset) is the same thing, for current instrument

string GetLevel2MMID(string symol, int fieldType, int offset) is an ECN or exchange where there was a set order

GetLevel2MMID(int fieldType, int offset) is the same thing, for current instrument

GetLevel2Size(string symol, int fieldType, int offset) is an instrument volume at the given level

GetLevel2Size(int fieldType, int offset) is the same thing, for current instrument

GetLevel2VWAPByQuantity(string symol, int fieldType, double amount) is the weighted price of a total quantity across all required volume levels

GetLevel2VWAPByQuantity(int fieldType, double amount) is the same thing, for current instrument

Using these functions allows you to make your tech analysis more “3-dimensional” and use market maker strategies that didn’t used to be available to traders. For example, you can use this for instantaneous distribution of volumes, creating a custom instrument based on quotes of a few less liquid instruments, or for analyzing the market depth direction of instruments, etc. Of course, to really maximize the effectiveness of this type of strategy, you’d need to have very low latency for data and order sending.

A simple trend indicator For an example of using Level 2 information we’ll look at the CustomTickAggregator indicator. The difference between a standard chart, this is going to show us only changes in price without time. Upon doing this the indicator filters out minor price fluctuations, highlighting significant movement and market reversals. The basis of this filtration algorithm is that the upward trend, which usually starts as a growing number of buyers (Ask), must be confirmed by a rising number of sellers (Bid). Likewise, a downward trend must be confirmed by a decline in sale (Ask). In the end we get an indicator comprised of one line which rises if there is a rising number of Bid quotes and falls if there is a falling number of Ask. However, if we modify the indicator a bit to use the best Ask and best Bid it will be a bit too sensitive and react to minor price fluctuations. So we will try to use the average price from a few levels of the market depth (VWAP). Also we’ll add a limit to volume – meaning above a certain volume the indicator will react to changing prices and below it will not. This will help us avoid opening positions based on false signals from an illiquid market.

Editing the indicator code...

Input parameters:

//the number of levels to average is by default 5
[InputParameter("Quantity Price Levels for Averaging",0)]
public int QuantityPriceLevelsForAveraging = 5;
//minimal level of volume that indicator will react to
[InputParameter("Minimum Volume Threshold",1)]
public int MinimumVolumeThreshold = 0;

Calculating VWAP:

for (int i = 0; i<QuantityPriceLevelsForAveraging; i++)
{
    //summarization of Ask prices at each level
    summAskVolume += GetLevel2Price(ASK, i)*GetLevel2Size(ASK, i);
    //summarization volume of Ask
    askVolume += GetLevel2Size(ASK, i);
    //summarization of Bid prices at each level
    summBidVolume += GetLevel2Price(BID, i)*GetLevel2Size(BID, i);
    //summarization volume of Bid
    bidVolume += GetLevel2Size(BID, i);}
//Average Ask price
double VolumeWeightedAverageAsk = (askVolume != 0.0) ? 
summAskVolume/askVolume:0.0;
Average Bid price
double VolumeWeightedAverageBid = (bidVolume != 0.0) ? 
summBidVolume/bidVolume:0.0;

Calculating the indicator lines:

//If the average Ask is not equal to zero and greater than the indicator line the volume of Ask is greater than the minimum threshold,
//then we displace the indicator line backspace and assign current value of average ask price
if(GetValue(0, 0) > VolumeWeightedAverageAsk
&& VolumeWeightedAverageAsk != 0.0 && askVolume > MinimumVolumeThreshold)
{
    for( int i = inWindowCount; i >= 1; i-- )
    {
        SetValue(0, i, GetValue(0, i-1));
    }
    SetValue(0, 0, VolumeWeightedAverageAsk);
}
//If the average Bid is not equal to zero and greater than the indicator line the volume of Bid is greater than the minimum threshold,
//then we displace the indicator line backspace and assign current value of average bid price
if(GetValue(0, 0) < VolumeWeightedAverageBid
&& VolumeWeightedAverageBid != 0.0 && bidVolume > MinimumVolumeThreshold)
{
    for( int i = inWindowCount; i >= 1; i-- )
    {
        SetValue(0, i, GetValue(0, i-1));
    }
    SetValue(0, 0, VolumeWeightedAverageBid);
}

Subscribing to Level 2 when indicator starts:

public override void Init()
{
    //subscribe to Level 2 events
    NewLevel2Quote += new NewLevel2QuoteHandler(NewLevel2QuoteComes);
    PriceSubscribe(QUOTE_LEVEL2);
}

Unsubscribe from Level 2 when removing indicator from the chart:

public override void Complete()
{
    //unsubscribing from the events before removing indicator level 2
    NewLevel2Quote -= new NewLevel2QuoteHandler(NewLevel2QuoteComes);
    PriceUnsubscribe(QUOTE_LEVEL2);
}

Optimization:

//receiving a number of visible bars from the chart
int inWindowCount = (WindowBarsPerChart() > 300) ? 300:WindowBarsPerChart();

Offsetting the indicator line forward one position when a new bar appears on the chart:

if(Count > prevCount)
{
    prevCount = Count;
    for(int i = 0; i < inWindowCount; i++)
    {
       SetValue(0, i, GetValue(0, i+1));
    }
}

Custom tick aggregator, EUR/USD 1 minute chart

Custom tick aggregator, EUR/USD 1 minute chart

Conclusions...

Besides just finding the VWAP price for a few levels of Level 2 market depth, you can try to use the indicator function GetLevel2VWAPByQuantity() - to get the average price for a given volume. An example of this can be found in the Level2Test.cs code.

I hope that you are a bit more interested now in the possibilities of Protrader and not utterly confused. Let me know if you have any questions or comments about the code or about the article by writing below.


Have not tried PTMC yet? There is no better way to boost knowledge than to use it! Start trading with PTMC now!

Discussion
Join PTMC community to post your comments
  • baag john 11.05.2016
PTMC is a professional trading platform that combines all the best charting and analytical tools to trade on different financial markets. It is developed by PFSOFT UK LTD, a global provider of trading technology for banks & brokers
© 2017. PTMC is based on Protrader technology
PFSOFT UK LTD
20 Centenary Avenue
South Shields, Tyne and Wear,
NE34 6QH
United Kingdom
Support & Development
PFSOFT Ukraine
Office #701
Mechnikova Street, 10B
49000, Dnipro, Ukraine
Contact us
Phone: +380 56 740 30 01
E-mail: info@protrader.org
Skype: PTMC_support
Find more ways to contact
Join us in social networks