Trade FOREX with FXCM

  • Award-Winning Platform
  • 24/7 Customer Support
  • Trade Directly on Charts
  • Free $50K Practice Account
Register


Results 1 to 2 of 2

Thread: INDICATOR ENTRY/EXIT - Keltner Channel Strategy

  1. #1
    Lucas Izidoro is offline Member
    Join Date
    Oct 2010
    Posts
    151

    INDICATOR ENTRY/EXIT - Keltner Channel Strategy

    Keltner Channel Strategy

    External Inputs and Default Values: These are parameters you will be able to change at any time prior to activating the strategy through the inputs window.

    Keltner Channel Indicator
    Length = 20
    Numatrs = 1.5 -> this value is multiplied by the average true range of the current bar to determine the distance from the upper and lower bands to the midline.

    Other inputs / default values
    Limit = 0
    Stop = 0
    Use SSL = False
    Port = 25
    Trailing Stop = 0
    Email Alert = False

    Order Notation
    KltChLE = Buy Entry Order
    KltChLE_SL = Stop loss order for a long position
    KltChLE_TP = Limit order for a long position
    KltChSE = Sell Entry Order
    KltChSE_SL = Stop loss order for a short position
    KltChSE_TP = Limit order for a short position

    Buying logic

    An entry order to buy at the high price of the current bar will be generated if the current bar crosses the upper band.

    Selling Logic

    An entry order to sell at the low price of the current bar will be generated if the current bar crosses the lower band.



    Exit Logic Long

    The strategy will automatically place a stop loss and/or take profit however many pips away from the open price as specified by the trader in the strategy inputs.

    Trailing Stop
    If a trailing stop is added by the trader, the stop value will be changed dynamically for every bullish market movement.

    Exit Logic Short

    The strategy will automatically place a stop loss and/or take profit however many pips away from the open price as specified by the trader in the strategy inputs.

    Trailing Stop
    If a trailing stop is added by the trader, the stop value will be changed dynamically for every bearish market movement.

    Code:
    using System;
    using Broker.StrategyLanguage.Function;
    namespace Broker.StrategyLanguage.Strategy
    {
    	public class KeltnerChannel : BaseStrategyAdvisor
    	{
    		private ISeries<Double> m_price;
    		private int m_length = 20;
    		private double m_numatrs = 1.5;
    		private AverageFC m_averagefc1;
    		private AvgTrueRange m_avgtruerange1;
    		private bool m_condition1;
    		private bool m_condition2;
    		private double m_avg;
    		private double m_shift;
    		private SeriesVar<Double> m_upperband;
    		private SimpleVar<Boolean> m_setupl;
    		private SimpleVar<Double> m_crossinghigh;
    		private SeriesVar<Double> m_lowerband;
    		private SimpleVar<Boolean> m_setups;
    		private SimpleVar<Double> m_crossinglow;
    		private double m_TP0;
    		private double m_SL0;
    		private double m_TP1;
    		private double m_SL1;
    		private double m_price0, m_price1;
    		private IPriceOrder m_Order0;
    		private IPriceOrder m_Order0_TP;
    		private IPriceOrder m_Order0_SL;
    		private IPriceOrder m_Order1;
    		private IPriceOrder m_Order1_TP;
    		private IPriceOrder m_Order1_SL;
    		private bool Email_lock = true;
    		public KeltnerChannel(object ctx) :
    			base(ctx) {}
    		private ISeries<Double> price{
    			get { return m_price; }
    		}
    		[Input]
    		public int length{
    			get { return m_length; }
    			set { m_length = value; }
    		}
    		[Input]
    		public double numatrs{
    			get { return m_numatrs; }
    			set { m_numatrs = value; }
    		}
    		
    		private int m_Limit = 0;
    		[Input]
    		public int Limit
    		{
    			get{return m_Limit;}
    			set{m_Limit=value;}
    		}
    
    		private int m_Stop = 0;
    		[Input]
    		public int Stop
    		{
    			get{return m_Stop;}
    			set{m_Stop=value;}
    		}
    		
    		private string m_Username = "";
    		[Input]
    		public string Username
    		{
    			get{return m_Username;}
    			set{m_Username=value;}
    		}
    
    		private string m_Password = "";
    		[Input]
    		public string Password
    		{
    			get{return m_Password;}
    			set{m_Password=value;}
    		}
    
    		private string m_Smtp = "";
    		[Input]
    		public string Smtp
    		{
    			get{return m_Smtp;}
    			set{m_Smtp=value;}
    		}
    
    		private string m_From = "";
    		[Input]
    		public string From
    		{
    			get{return m_From;}
    			set{m_From=value;}
    		}
    
    		private string m_To = "";
    		[Input]
    		public string To
    		{
    			get{return m_To;}
    			set{m_To=value;}
    		}
    
    		private bool m_UseSSL = false;
    		[Input]
    		public bool UseSSL
    		{
    			get{return m_UseSSL;}
    			set{m_UseSSL=value;}
    		}
    
    		private int m_Port = 25;
    		[Input]
    		public int Port
    		{
    			get{return m_Port;}
    			set{m_Port=value;}
    		}
    		
    		private int m_TrailingStop = 0;
    		[Input]
    		public int TrailingStop
    		{
    			get{return m_TrailingStop;}
    			set{m_TrailingStop=value;}
    		}
    		
    		private bool m_EmailAlert = false;
    		[Input]
    		public bool EmailAlert
    		{
    			get{return m_EmailAlert;}
    			set{m_EmailAlert=value;}
    		}
    		
    		protected override void Construct() {
    			m_averagefc1 = new AverageFC(this);
    			m_avgtruerange1 = new AvgTrueRange(this);
    			m_upperband = new SeriesVar<Double>(this);
    			m_setupl = new SimpleVar<Boolean>(this);
    			m_crossinghigh = new SimpleVar<Double>(this);
    			m_lowerband = new SeriesVar<Double>(this);
    			m_setups = new SimpleVar<Boolean>(this);
    			m_crossinglow = new SimpleVar<Double>(this);
    			m_Order0 = OrdersFactory.CreateStop(new OrdersCreateParams(Lots.Default, "KltChLE", OrderAction.Buy));
    			m_Order0_SL = OrdersFactory.CreateStop(new OrdersCreateParams(Lots.Default, "KltChLE_SL", OrderAction.Sell));
    			m_Order0_TP = OrdersFactory.CreateLimit(new OrdersCreateParams(Lots.Default, "KltChLE_TP", OrderAction.Sell));
    			m_Order1 = OrdersFactory.CreateStop(new OrdersCreateParams(Lots.Default, "KltChSE", OrderAction.SellShort));
    			m_Order1_SL = OrdersFactory.CreateStop(new OrdersCreateParams(Lots.Default, "KltChSE_SL", OrderAction.BuyToCover));
    			m_Order1_TP = OrdersFactory.CreateLimit(new OrdersCreateParams(Lots.Default, "KltChSE_TP", OrderAction.BuyToCover));
    		}
    		protected override void Initialize(){
    			m_price = Bars.Close;
    			m_averagefc1.price = price;
    			m_averagefc1.length = new Serie---pression<Int32>(delegate { return length; });
    			m_avgtruerange1.length = new Serie---pression<Int32>(delegate { return length; });
    			m_condition1 = default(bool);
    			m_condition2 = default(bool);
    			m_avg = 0;
    			m_shift = 0;
    			m_upperband.DefaultValue = 0;
    			m_setupl.DefaultValue = false;
    			m_crossinghigh.DefaultValue = 0;
    			m_lowerband.DefaultValue = 0;
    			m_setups.DefaultValue = false;
    			m_crossinglow.DefaultValue = 0;
    		}
    		protected override void Destroy() {}
    		protected override void Execute() {
    			if(Bars.Status == BarStatus.Close)
    				Email_lock = true;
    			
    			CheckTrailingStop();
    			CheckExitLogic();
    			
    			m_avg = m_averagefc1[0];
    			m_shift = (numatrs*m_avgtruerange1[0]);
    			m_upperband.Value = (m_avg + m_shift);
    			m_condition1 = (Functions.DoubleGreater(Bars.CurrentBar, 1) &&
    							Functions.CrossesOver(this, price, m_upperband));
    			if (m_condition1){
    				m_setupl.Value = true;
    				m_crossinghigh.Value = Bars.High[0];
    			}
    			else{
    				m_condition1 = (m_setupl.Value
    								&&
    								(Functions.DoubleLess(price[0], m_avg) ||
    									Functions.DoubleGreaterEquals(Bars.High[0], (m_crossinghigh.Value
    																				+ (1*Bars.Point)))));
    				if (m_condition1){
    					m_setupl.Value = false;
    				}
    			}
    			if(StrategyInfo.MarketPosition <= 0)
    			{
    				if (m_setupl.Value){
    					m_price0 = m_crossinghigh.Value + (1*Bars.Point);
    					if(Limit > 0) m_TP0 = m_price0 + Limit * Point;	else m_TP0 = 0;
    					if(Stop > 0) m_SL0 = m_price0 - Stop * Point;	else m_SL0 = 0;
    					if(m_EmailAlert == true && Email_lock == true) {
    						SendMail("Order0", "Order0 is traded at Price " + m_price0);
    						Email_lock = false;
    					}
    					m_Order0.Generate(m_price0);
    				}
    			}
    			m_lowerband.Value = (m_avg - m_shift);
    			m_condition2 = (Functions.DoubleGreater(Bars.CurrentBar, 1) &&
    							Functions.CrossesUnder(this, price, m_lowerband));
    			if (m_condition2){
    				m_setups.Value = true;
    				m_crossinglow.Value = Bars.Low[0];
    			}
    			else{
    				m_condition2 = (m_setups.Value
    								&&
    								(Functions.DoubleGreater(price[0], m_avg) ||
    									Functions.DoubleLessEquals(Bars.Low[0], (m_crossinglow.Value
    																			- (1*Bars.Point)))));
    				if (m_condition2){
    					m_setups.Value = false;
    				}
    			}
    			if(StrategyInfo.MarketPosition >= 0)
    			{
    				if (m_setups.Value){
    					m_price1 = m_crossinglow.Value - (1*Bars.Point);
    					if(Limit > 0) m_TP1 = m_price1 - Limit * Point;	else m_TP1 = 0;
    					if(Stop > 0) m_SL1 = m_price1 + Stop * Point;	else m_SL1 = 0;
    					if(m_EmailAlert == true && Email_lock == true) {
    						SendMail("Order1", "Order1 is traded at Price " + m_price1);
    						Email_lock = false;
    					}
    					m_Order1.Generate(m_price1);
    				}
    			}
    		}
    		
    		private void CheckExitLogic() {
    			if(StrategyInfo.MarketPosition == 0) return;
    			if(StrategyInfo.MarketPosition > 0) {
    				if(m_TP0 > 0)
    					m_Order0_TP.Generate(m_TP0);
    				if(m_SL0 > 0)
    					m_Order0_SL.Generate(m_SL0);
    			}
    			if(StrategyInfo.MarketPosition < 0) {
    				if(m_TP1 > 0)
    					m_Order1_TP.Generate(m_TP1);
    				if(m_SL1 > 0)
    					m_Order1_SL.Generate(m_SL1);
    			}
    		}
    		
    		private void CheckTrailingStop() {
    			if(m_TrailingStop == 0) return;
    			if(StrategyInfo.MarketPosition > 0) {
    				if(m_SL0 >0 && (Bars.Close[0] - m_SL0) > (Stop + m_TrailingStop) * Point)
    					m_SL0 = Bars.Close[0] - Stop * Point;
    			}
    			if(StrategyInfo.MarketPosition < 0) {
    				if(m_SL1 > 0 && (m_SL1 - Bars.Close[0]) > (Stop + m_TrailingStop) * Point)
    					m_SL1 = Bars.Close[0] + Stop * Point;
    			}
    		}
    		
    		private double Point    //Returns the point value
    		{
    			get{
    				if(Bars.Point < 0.01)
    				{
    					return(Bars.Point * 10);
    				}
    				else                        
    				{
    					return Bars.Point;
    				}
    			}
    		}
    		
    		protected void SendMail(string subject, string msgToSend)
    		{
    			try
    			{
    				System.Net.Mail.SmtpClient smtpClient = new System.Net.Mail.SmtpClient(Smtp); 
    				smtpClient.Credentials = new System.Net.NetworkCredential(Username, Password); 
    				smtpClient.EnableSsl = UseSSL;
    				smtpClient.Port = Port;
    				// send our email 
    				smtpClient.Send(From, To, subject, msgToSend); 
    			}
    			catch (Exception e) 
    			{
    				Console.WriteLine(e.Message);
    			}
    		}
    	}
    }

    Email Alerts

    Not every strategy has an email alert function embedded within its code. To verify if the strategy you are using does, open the Format Strategy Advisor window for that stEA and see if it has the fields highlighted below.



    The highlighted fields should be filled in as follows in order to activate the email alerts:

    Username – the user name of the email you would like to use as the sender
    Password – the password used to log on to your email account
    Smtp – This will vary depending on your email provider (gmail’s SMTP is smtp.gmail.com and yahoo’s is plus.smtp.mail.yahoo.com)
    From – the full email address from which the email alert will be sent
    To- the full email address to which the email alert will be sent (it can be the same as the address in the 'from' field)
    UseSSL – the use of SSL also depends on the email provider. Please verify whether or not your email provider uses SSL. If so, this field should be changed to “True.”
    EmailAlert – this field should be changed to “True,” if you would like to activate email alerts
    Attached Images Attached Images  
    Attached Files Attached Files
    Last edited by Lucas Izidoro; 11-24-2010 at 10:19 AM.

  2. #2
    cc.matt is offline Registered User
    Join Date
    Dec 2011
    Posts
    1

    Keltner for Ranges

    Hi Lucas,

    Thank you for posting this keltner channel strategy. I'm currently working with this indicator into more of a range bound situation. Could you alter this keltner strategy so that it sells on the upper band and buys on the lower band?

    Thank you very much!

    Matt

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Disclaimer: Trading foreign exchange on margin carries a high level of risk, and may not be suitable for all investors. The high degree of leverage can work against you as well as for you. Before deciding to trade foreign exchange you should carefully consider your investment objectives, level of experience, and risk appetite. The possibility exists that you could sustain a loss of some or all of your initial investment and therefore you should not invest money that you cannot afford to lose. You should be aware of all the risks associated with foreign exchange trading, and seek advice from an independent financial advisor if you have any doubts. Any opinions, news, research, analyses, prices, or other information contained on this website is provided as general market commentary and does not constitute investment advice. Forex Capital Markets LLC. will not accept liability for any loss or damage, including without limitation to, any loss of profit, which may arise directly or indirectly from use of or reliance on such information.