Author: Copyright � 2010, FXTools
ASO

The Average Sentiment Oscillator (ASO) is a custom technical analysis tool designed to provide traders with a visual representation of market sentiment by measuring the "strength" of buyers versus sellers. Unlike standard price indicators that only look at where the price ends up, this script analyzes the internal behavior of price action within specific timeframes to determine how aggressively the market is moving in either direction.

Core Logic and Functionality

The indicator operates by calculating two distinct sentiment scores—one for "Bulls" (buyers) and one for "Bears" (sellers)—and plotting them on a separate window. Here is a breakdown of how the logic processes market data:

1. Sentiment Calculation For every specific period on the chart, the script looks at the individual price movements (the High, Low, Open, and Close). It calculates a "Bullish" score by measuring how much of the candle's range was dominated by upward movement relative to its opening position. Simultaneously, it calculates a "Bearish" score based on downward pressure.

2. Contextual Comparison The script doesn't just look at a single candle in isolation; it also looks at the broader "Group" context (a larger window of time defined by the user). It compares the immediate price action against the high and low extremes of that wider period. This allows the tool to identify if current momentum is significant relative to recent history.

3. User-Defined Modes The script offers different ways to interpret this data through three specific modes:

  • Mode 0: Provides a balanced average between the immediate price action and the broader group context.
  • Mode 1: Focuses exclusively on the immediate, short-term sentiment of the current candle.
  • Mode 2: Focuses exclusively on the broader, long-term sentiment of the group context.

4. Smoothing and Visualization To ensure that the data is easy to read and less "noisy," the script applies a Moving Average to the calculated sentiment scores. This results in two smooth lines:

  • Bulls Line: Represents the prevailing buying pressure.
  • Bears Line: Represents the prevailing selling pressure.

How to Interpret the Results

The indicator operates on a scale (typically 0 to 100) with a central equilibrium level at 50.

  • When the Bulls line is high and above the 50 level, it suggests that buyers are currently dominating the market sentiment.
  • When the Bears line is high and above the 50 level, it suggests that sellers are in control.
  • The distance between these two lines helps traders visualize the "tug-of-war" between different market participants, providing a clearer picture of market psychology than price action alone.
Price Data Components
Series array that contains open prices of each bar
Indicators Used
Moving average indicator
Miscellaneous
Implements a curve of type %1
4 Views
0 Downloads
0 Favorites
ASO
//+------------------------------------------------------------------+
//|                                                          ASO.mq4 |
//|     Copyright © 2005, MetaQuotes Software Corp. © 2010, J.Arent. |
//|              http://www.metaquotes.net/, http://www.fxtools.info |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2010, FXTools"
#property link      "http://www.fxtools.info"

#property indicator_separate_window
#property indicator_minimum 0
#property indicator_maximum 100
#property indicator_buffers 2
#property indicator_color1 RoyalBlue
#property indicator_color2 Red
#property indicator_levelcolor DimGray
#property indicator_width1 1
#property indicator_width2 1
//---- input parameters
extern int AsoPeriod=10;
extern int Mode=0;
extern bool Bulls=true;
extern bool Bears=true;
//---- buffers
double AsoBufferBulls[];
double AsoBufferBears[];
double TempBufferBulls[];
double TempBufferBears[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
   string short_name;
//---- 2 additional buffers used for counting.
   IndicatorBuffers(4);
   SetIndexBuffer(2,TempBufferBulls);
   SetIndexBuffer(3,TempBufferBears);   
//---- indicator line
   SetIndexStyle(0,DRAW_LINE);
   SetIndexBuffer(0,AsoBufferBulls);
   SetIndexStyle(1,DRAW_LINE);
   SetIndexBuffer(1,AsoBufferBears);
//---- level
   SetLevelValue( 0, 50 );   
//---- name for DataWindow and indicator subwindow label
   short_name="ASO("+AsoPeriod+")";
   IndicatorShortName(short_name);
   SetIndexLabel(0,"ASO Bulls");
   SetIndexLabel(1,"ASO Bears");
//----
   SetIndexDrawBegin(0,AsoPeriod);
   SetIndexDrawBegin(1,AsoPeriod);
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Average Sentiment Oscillator                                     |
//+------------------------------------------------------------------+
int start()
  {
   int i,counted_bars=IndicatorCounted();
//----
   if(Bars<=AsoPeriod) return(0);
//---- initial zero
   if(counted_bars<1)
     {
      for(i=1;i<=AsoPeriod;i++) AsoBufferBulls[Bars-i]=0.0;
      for(i=1;i<=AsoPeriod;i++) AsoBufferBears[Bars-i]=0.0;
     }
//---- 
   i=Bars-counted_bars-1;
   while(i>=0)
     {
      double intrahigh=High[i];
      double intralow =Low[i];
      double intraopen=Open[i];
      double close =Close[i];
      double intrarange = intrahigh-intralow;
      double grouplow = Low[iLowest(NULL,0,MODE_LOW,AsoPeriod,i)];
      double grouphigh = High[iHighest(NULL,0,MODE_HIGH,AsoPeriod,i)];
      double groupopen = iOpen(NULL,0,i+AsoPeriod-1);
      double grouprange = grouphigh-grouplow;
      if (intrarange==0) {intrarange=1;}
      if (grouprange==0) {grouprange=1;}
      double intrabarbulls = ((((close-intralow)+(intrahigh-intraopen))/2)*100)/intrarange;
      double groupbulls = ((((close-grouplow)+(grouphigh-groupopen))/2)*100)/grouprange;
      double intrabarbears = ((((intrahigh-close)+(intraopen-intralow))/2)*100)/intrarange;      
      double groupbears = ((((grouphigh-close)+(groupopen-grouplow))/2)*100)/grouprange;      
      if(i==Bars-1) {TempBufferBulls[i]=intrabarbulls; TempBufferBears[i]=intrabarbears;}
      else
        {
         if (Mode==0) TempBufferBulls[i]=(intrabarbulls+groupbulls)/2; 
         if (Mode==0) TempBufferBears[i]=(intrabarbears+groupbears)/2;
         if (Mode==1) TempBufferBulls[i]=intrabarbulls;
         if (Mode==1) TempBufferBears[i]=intrabarbears;
         if (Mode==2) TempBufferBulls[i]=groupbulls;
         if (Mode==2) TempBufferBears[i]=groupbears;
        }
      i--;
     }
//----
   if(counted_bars>0) counted_bars--;
   int limit=Bars-counted_bars;
   if (Bulls) 
     {
      for(i=0; i<limit; i++)
      AsoBufferBulls[i]=iMAOnArray(TempBufferBulls,Bars,AsoPeriod,0,0,i);
     }
   if (Bears) 
     {
      for(i=0; i<limit; i++)
      AsoBufferBears[i]=iMAOnArray(TempBufferBears,Bars,AsoPeriod,0,0,i);
     } 
//----
   return(0);
  }
//+------------------------------------------------------------------+

Comments