//+------------------------------------------------------------------+ //| MT4-LevelStop-Reverse | //| Version Beta 0.2 | //| Copyright © 2007, Bruce Hellstrom (brucehvn) | //| bhweb@speakeasy.net | //| http://www.metaquotes.net/ | //+------------------------------------------------------------------+ ///////////////////////////////////////////////////////////////////// // Version 0.2 Beta // // This is a port of the VTTrader VT-LevelStop-Reverse trading system. // This is ported as an MT4 indicator only and perhaps can be evolved // into an EA later. // // This is a beta version // ///////////////////////////////////////////////////////////////////// /* This is a combination of two VT Trader trading systems. The first is the default VT-LevelStop-Reverse and the second is one that was modified to allow customizing the ATR settings for calculating the stop line. I've tried to combine these 2 versions into a single MT4 indicator. The default VT version allows you to use two modes, optimized, and manual. Optimized mode calculates the stop line by using a 14 period EMA smoothed ATR(14) multiplied by a fixed multiplier of 2.824. In manual mode, you set a fixed number of pips you want the stop line to be drawn. In my MT4 version, there are two modes: 1. ATR mode (customizable ATR period, multiplier, and smoothing) 2. Fixed stop mode (customizable fixed stop) The input parameters are as follows: * UseATRMode - This calculates the stop line based on ATR using customizable period, multiplier and smoothing. * NonATRStopPips - If "UseATRMode" is false, then this value is the number of fixed pips to place the stop line. * ATRPeriod - If "UseATRMode" is true, then this sets the ATR period. * ATRMultiplier - If "UseATRMode" is true, then the ATR value will be multiplied by this value when calculating the stop line. * ATRSmoothing - If "UseATRMode" is true, then this will smooth the selected ATR with an EMA of this smoothing period. * UpArrowColor - The color the Up arrows will display in. * DnArrowColor - The color the Down arrows will display in. * ArrowDistance - The number of pips away from the high or low of the bar that the arrow should display. On the colors tab, only the first color is used. It is the color of the dotted stop line. For the default VT-LevelStop-Reverse behavior, set the following: UseATRMode = true ATRPeriod = 14 ATRMultiplier = 2.824 ATRSmoothing = 14 To use this indicator, copy it to your <MetaTrader Folder>\experts\indicators folder. Then restart MT4. It will appear in the custom indicators list. This is version Beta 0.2. As I get feedback, I will release newer versions as needed. */ #property copyright "Copyright © 2007, Bruce Hellstrom (brucehvn)" #property link "http: //www.metaquotes.net/" #property indicator_chart_window #property indicator_buffers 5 #property indicator_color1 Magenta #property indicator_style1 STYLE_DOT #define INDICATOR_VERSION "vB0.2" //---- input parameters extern bool UseATRMode = true; extern int NonATRStopPips = 40; extern int ATRPeriod = 9; extern double ATRMultiplier = 3.0; extern int ATRSmoothing = 0; extern color UpArrowColor = DodgerBlue; extern color DnArrowColor = OrangeRed; extern int ArrowDistance = 25; //---- buffers double TrStopLevel[]; double UpSignal[]; double DnSignal[]; double ATRBuffer[]; double SmoothBuffer[]; //---- variables int ArrowObjects[50]; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int init() { string ShortName; int DrawBegin = 0; if ( UseATRMode ) { DrawBegin = ATRPeriod; } IndicatorBuffers( 5 ); SetIndexStyle( 0, DRAW_LINE, STYLE_DOT, 1 ); SetIndexBuffer( 0, TrStopLevel ); SetIndexDrawBegin( 0, DrawBegin ); SetIndexStyle( 1, DRAW_NONE ); SetIndexBuffer( 1, UpSignal ); SetIndexDrawBegin( 1, DrawBegin ); SetIndexStyle( 2, DRAW_NONE ); SetIndexBuffer( 2, DnSignal ); SetIndexDrawBegin( 2, DrawBegin ); SetIndexStyle( 3, DRAW_NONE ); SetIndexBuffer( 3, ATRBuffer ); SetIndexDrawBegin( 3, DrawBegin ); SetIndexStyle( 4, DRAW_NONE ); SetIndexBuffer( 4, SmoothBuffer ); SetIndexDrawBegin( 4, DrawBegin ); ShortName = "MT4-LevelStop-Reverse-" + INDICATOR_VERSION + "( "; if ( UseATRMode ) { ShortName = StringConcatenate( ShortName, "ATRMode ", ATRPeriod, ", ", ATRMultiplier, ", ", ATRSmoothing, " )" ); } else { ShortName = StringConcatenate( ShortName, "Manual Mode Stop = ", NonATRStopPips, " )" ); } IndicatorShortName( ShortName ); SetIndexLabel( 0, ShortName ); Print( ShortName ); Print( "Copyright (c) 2007 - Bruce Hellstrom, bhweb@speakeasy.net" ); for ( int ictr = 0; ictr < 50; ictr++ ) { ArrowObjects[ictr] = 0; } MathSrand( TimeLocal() ); return( 0 ); } //+------------------------------------------------------------------+ //| Custom indicator deinitialization function | //+------------------------------------------------------------------+ int deinit() { int num_elems = ArraySize( ArrowObjects ); Print( "deinit() - number of objects to delete: ", num_elems ); for ( int ictr = 0; ictr < num_elems; ictr++ ) { if ( ArrowObjects[ ictr ] == 0 ) { Print( "ArrowObjects[", ictr, "] is zero" ); break; } string ObjName = "VTS-" + ArrowObjects[ictr]; ObjectDelete( ObjName ); } return( 0 ); } //+------------------------------------------------------------------+ //| Momentum | //+------------------------------------------------------------------+ int start() { Comment( "\nMT4-LevelStop-Reverse Beta v0.2" ); int ictr; int counted_bars = IndicatorCounted(); // Check for errors if ( counted_bars < 0 ) { return( -1 ); } // Last bar will be recounted if ( counted_bars > 0 ) { counted_bars--; } int limit = Bars - counted_bars; ictr = limit - 1; if ( UseATRMode && Bars < ATRPeriod ) { return( 0 ); } int xctr; if ( UseATRMode ) { // First calculate the ATR for ( xctr = 0; xctr < limit; xctr++ ) { ATRBuffer[xctr] = iATR( NULL, 0, ATRPeriod, xctr ); } // Smooth the ATR if necessary if ( ATRSmoothing > 0 ) { for ( xctr = 0; xctr < limit; xctr++ ) { SmoothBuffer[xctr] = Wilders( ATRBuffer, ATRSmoothing, xctr ); } } } for ( xctr = ictr; xctr >= 0; xctr-- ) { // Calculate the stop amount double DeltaStop = NonATRStopPips * Point; // Calculate our stop value based on ATR if required if ( UseATRMode ) { if ( ATRSmoothing > 0 ) { DeltaStop = NormalizeDouble( SmoothBuffer[xctr] * ATRMultiplier, 4 ); } else { DeltaStop = NormalizeDouble( ATRBuffer[xctr] * ATRMultiplier, 4 ); } } // Figure out where the current bar's stop level should be double NewStopLevel; double PrevStop = TrStopLevel[xctr + 1]; if ( Close[xctr] == PrevStop ) { NewStopLevel = PrevStop; } else { if ( Close[xctr + 1] <= PrevStop && Close[xctr] < PrevStop ) { NewStopLevel = MathMin( PrevStop, ( Close[xctr] + DeltaStop ) ); } else { if ( Close[xctr + 1] >= PrevStop && Close[xctr] > PrevStop ) { NewStopLevel = MathMax( PrevStop, ( Close[xctr] - DeltaStop ) ); } else { if ( Close[xctr] > PrevStop ) { NewStopLevel = Close[xctr] - DeltaStop; } else { NewStopLevel = Close[xctr] + DeltaStop; } } } } TrStopLevel[xctr] = NewStopLevel; // Figure out the up/down arrows bool Up = false; bool Dn = false; if ( Close[xctr] > TrStopLevel[xctr] && Close[xctr + 1] <= TrStopLevel[xctr + 1] ) { Up = true; UpSignal[xctr] = Low[xctr] - ( ArrowDistance * Point ); int next_ind = GetNextObjectIndex(); int obj_id = MathRand() + 1; string ObjName = "VTS-" + obj_id; ObjectCreate( ObjName, OBJ_ARROW, 0, Time[xctr], UpSignal[xctr] ); ObjectSet( ObjName, OBJPROP_COLOR, UpArrowColor ); ObjectSet( ObjName, OBJPROP_ARROWCODE, 233 ); ArrowObjects[next_ind] = obj_id; } if ( Close[xctr] < TrStopLevel[xctr] && Close[xctr + 1] >= TrStopLevel[xctr + 1] ) { Dn = true; DnSignal[xctr] = High[xctr] + ( ( ArrowDistance + 10 ) * Point ); next_ind = GetNextObjectIndex(); obj_id = MathRand() + 1; ObjName = "VTS-" + obj_id; ObjectCreate( ObjName, OBJ_ARROW, 0, Time[xctr], DnSignal[xctr] ); ObjectSet( ObjName, OBJPROP_COLOR, DnArrowColor ); ObjectSet( ObjName, OBJPROP_ARROWCODE, 234 ); ArrowObjects[next_ind] = obj_id; } // Reverse TrStopLevel According to Up and Down Signals if ( Up ) { TrStopLevel[xctr] = Close[xctr] - DeltaStop; } else { if ( Dn ) { TrStopLevel[xctr] = Close[xctr] + DeltaStop; } } } return( 0 ); } //+------------------------------------------------------------------+ //| Gets the next object index so they can be deleted later | //+------------------------------------------------------------------+ int GetNextObjectIndex() { int retval = 0; int arr_size = ArraySize( ArrowObjects ); int max_elem = arr_size - 1; if ( ArrowObjects[max_elem] != 0 ) { // Resize the array ArrayResize( ArrowObjects, arr_size + 10 ); for ( int xctr = arr_size; xctr < ( arr_size + 10 ); xctr++ ) { ArrowObjects[xctr] = 0; } retval = arr_size; arr_size += 10; } else { for ( int ictr = 0; ictr < arr_size; ictr++ ) { if ( ArrowObjects[ ictr ] == 0 ) { retval = ictr; break; } } } return( retval ); } //+------------------------------------------------------------------+ //| Wilders Calculation | //+------------------------------------------------------------------+ double Wilders( double& indBuffer[], int Periods, int shift ) { double retval = 0.0; retval = iMAOnArray( indBuffer, 0, ( Periods * 2 ) - 1, 0, MODE_EMA, shift ); return( retval ); } //+------------------------------------------------------------------+
Sample
Analysis
Market Information Used:
Series array that contains close prices for each bar
Series array that contains the lowest prices of each bar
Series array that contains open time of each bar
Series array that contains the highest prices of each bar
Indicator Curves created:
Implements a curve of type DRAW_LINE
Implements a curve of type DRAW_NONE
Indicators Used:
Indicator of the average true range
Moving average indicator
Custom Indicators Used:
Order Management characteristics:
Other Features: