Welcome to NexusFi: the best trading community on the planet, with over 150,000 members Sign Up Now for Free
Genuine reviews from real traders, not fake reviews from stealth vendors
Quality education from leading professional traders
We are a friendly, helpful, and positive community
We do not tolerate rude behavior, trolling, or vendors advertising in posts
We are here to help, just let us know what you need
You'll need to register in order to view the content of the threads and start contributing to our community. It's free for basic access, or support us by becoming an Elite Member -- see if you qualify for a discount below.
-- Big Mike, Site Administrator
(If you already have an account, login at the top of the page)
Can someone please post an example of drawing fib levels using stratergy in Ninjatrader 8? Can i use these fib levels and taking a postion at 50% retracement? Appreciate your help..
Can you help answer these questions from other members on NexusFi?
If you mean can a strategy be made in order to automatically enter a trade at 50% retracement of a swing? then the answer is Yes it can.
For this, you'd need an indicator capable to identify a swing and that can plot a retracement target level for a pullback entry and maybe plot a target profit level based on an extention percentage calculated from the length of the swing.
Trying to understand how to apply fib levels in a stratergy, If i use donchian channel to identify high and lows, looking for a sample code to draw a fib levels from high to low
#region Using declarations
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Xml.Serialization;
using System.Collections.Generic;
using System.Windows.Forms;
using NinjaTrader.Cbi;
using NinjaTrader.Data;
using NinjaTrader.Indicator;
using NinjaTrader.Gui.Chart;
using NinjaTrader.Strategy;
#endregion
///
/// Coded by traderpards at the direction here:
/// https://nexusfi.com/elite-circle/32758-want-your-ninjatrader-strategy-created-free-4.html
///
/// Hmmm... I seem to have forgotten to keep track of the update history.
///
/// 11-11-2014 - Added limit orders (and I have no idea if they'll work in live trading but they seem
/// to work with historical data.)
///
///
// This namespace holds all strategies and is required. Do not change it.
namespace NinjaTrader.Strategy
{
/// <summary>
/// This strategy detects when a certain Fibonacci level has been reached and then enters a trade. It exits a trade when the instrument either reaches a predetermined level or is stopped out.
/// </summary>
[Description("This strategy detects when a certain Fibonacci level has been reached and then enters a trade. It exits a trade when the instrument either reaches a predetermined level or is stopped out.")]
public class FibonacciTradeEntry : Strategy
{
#region Variables
private int iGapLower = 10;
private int iGapUpper = 50;
private int iQty = 1;
private TradeLevels entryTradeLevel = TradeLevels.p161_8;
private TradeLevels stopTradeLevel = TradeLevels.p261_8;
private TradeLevels profitTargetTradeLevel = TradeLevels.p50;
private int _161_bar = 0;
private bool b_161_barSet = false;
private int firstBar = 0;
private int tickSlop = 0;
private Color fibColor = Color.Black;
private int numbBarsLastEmail = 0;
private bool bSendEmail = true;
private int startTime = 080000; // Start trading time
private int endTime = 110000; // End trading time
private int warnTime = 210000; // Warn time if in a live trade
private string emailTo = string.Empty;
private string emailFrom = string.Empty;
private Font boldFont = new Font("Arial", 8,FontStyle.Bold);
private bool buttonsloaded = false;
#endregion
/// <summary>
/// This method is used to configure the strategy and is called once before any strategy method is called.
/// </summary>
protected override void Initialize()
{
CalculateOnBarClose = true;
levels = new Dictionary<string, double>();
tradeLevelStrings = new Dictionary<TradeLevels, string>();
#region OnBarUpdate
/// <summary>
/// Called on each bar update event (incoming tick)
/// Algorithm:
/// 1. Determine whether or not we have a bearish gap, a bullish gap or no gap and whether or not the gap is
/// within a user-defined range for trading. If it is:
/// 2. Buy at the 161.8 level
/// 3. Place a stop at the 261.8 level
/// 4. Place a profit target at the 60 level
///
/// Note: The user would also like some kind of ATM trailing stop option coded but I don't understand any
/// of that so until I do, this strategy will not attempt that.
/// </summary>
protected override void OnBarUpdate()
{
if( Bars.FirstBarOfSession )
{
dSessionOpen = Open[0];
dPrevSessionClose = BarsArray[0].GetDayBar(1).Close;
setFibLevels();
plotFibLevels();
firstBar = CurrentBar;
b_161_barSet = false;
// 1. Measure the gap
double gap = Math.Abs( dPrevSessionClose - dSessionOpen )/TickSize;
if( gap >= GapLower
&& gap <= GapUpper )
{
// We're eligible for a trade, but which type?
if( dPrevSessionClose < dSessionOpen ) {
tradeDir = TradeDir.SHORT;
}
else if( dPrevSessionClose > dSessionOpen ) {
tradeDir = TradeDir.LONG;
}
else {
tradeDir = TradeDir.NO_TRADE;
}
}
else {
tradeDir = TradeDir.NO_TRADE; // We won't be taking a trade at all today
}
}
if( tradeDir == TradeDir.NO_TRADE ) {
return;
}
// If we've filled the gap, then no trade
if( (tradeDir == TradeDir.LONG && Close[0] >= dPrevSessionClose)
|| (tradeDir == TradeDir.SHORT && Close[0] <= dPrevSessionClose) )
{
tradeDir = TradeDir.NO_TRADE;
return;
}
// Check the time (** see criteria below)
if( !( ToTime(Time[0]) > StartTime
&& ToTime(Time[0]) < EndTime) )
{
return;
}
// New algorithm:
// 1. If trade hits the 161, then set "open to trade"
// a. We will cancel and mark NO_TRADE if price hits 261
// 2. If price trades over 161 and trades down below 161 on a subsequent bar, then then enter a short trade
// a. Opposite for longs.
/*********************** Old algorithm
// If tradeDir <> NO_TRADE, then we are eligible to take a trade, if we've gotten this far.
// 1. Price has to hit the 161.8 level
if( tradeDir == TradeDir.SHORT
&& GetCurrentBid() >= levels[tradeLevelStrings[EntryTradeLevel]] )
{
doShort();
}
if( tradeDir == TradeDir.LONG
&& GetCurrentAsk() <= levels[tradeLevelStrings[EntryTradeLevel]] )
{
doLong();
}
*************************/
// More to do:
// once the ENTRY ORDER is executed should be placed other conditions to keep the trade open, apart
// from the stoploss and take proffit orders:
// * if price reaches 100% (Fibonacci level, where 0%= G1 and 100%=G2) and goes back to 150%
// (Fibonacci level, where 0%= G1 and 100%=G2) then CLOSE the trade At 150% and cancel All orders.
// In other words, when the price gets to the 100% level, just move the stop to the 150 level.
if( MoveStop )
{
if( tradeDir == TradeDir.SHORT
&& Close[0] <= levels[tradeLevelStrings[PriceHitTradeLevel]] )
{
SetStopLoss( CalculationMode.Price, levels[tradeLevelStrings[MoveStopTradeLevel]] );
}
else if( tradeDir == TradeDir.LONG
&& Close[0] >= levels[tradeLevelStrings[PriceHitTradeLevel]] )
{
SetStopLoss( CalculationMode.Price, levels[tradeLevelStrings[MoveStopTradeLevel]] );
}
}
// ** if trade has not entered at 11:30am then CANCELL ORDER.
// In other words, if the time is passed the user set time, then return like we did above.
// *** if trade is entered (ongoing) and it is one hour before closing the market (for example with
// FDAX 22:00 would be 21:00) then send an email alert whit chart and text "TRADE STILL OPEN"
// Easier to just let the user enter that time...
if( Position.MarketPosition != MarketPosition.Flat
&& ToTime(Time[0]) >= LiveTradeWarnTime )
{
if( bSendEmail
&& (CurrentBar - numbBarsLastEmail) > 2)
{
string text = "There is an open trade after the warn period.";
SendMail( EmailFrom, EmailTo, "Trade warning", text );
numbBarsLastEmail = CurrentBar;
}
}
}
#endregion
#region OnExecution
/// <summary>
/// Hmmm... We need to prevent successive losses, one right after the other if the market gaps down
/// and keeps on going. This override halts the carnage.
/// </summary>
/// <param name="exe"></param>
protected override void OnExecution( IExecution exe )
{
Trade lastTrade = null;
try
{
lastTrade = Performance.AllTrades[Performance.AllTrades.Count - 1];
if( lastTrade != null
&& lastTrade.ExitExecution == exe )
{
// Any trade, whether a winner or a loser should cause the strategy to not take any more trades.
// Only one trade allowed per day.
tradeDir = TradeDir.NO_TRADE;
// Send an email
if( bSendEmail
&& (CurrentBar - numbBarsLastEmail) > 2 )
{
string text = "Trade for today has closed.";
SendMail( EmailFrom, EmailTo, "Trade exit", text );
numbBarsLastEmail = CurrentBar;
}
}
}
catch {}
}
#endregion
#region OnTermination()
/// <summary>
/// Overridden in order to remove the toolbar stuff so the controls don't repaint on refresh
/// </summary>
protected override void OnTermination()
{
if( buttonsloaded == true )
{
strip.Items.Remove(btnEmail);
strip.Items.Remove(sepL);
strip.Items.Remove(sepR);
buttonsloaded = false;
}
}
#endregion
/// <summary>
/// We just want to draw a tiny line with a label on the chart so the user can know when to expect
/// a trade to occur.
/// </summary>
private void plotFibLevels()
{
int i = 0;
foreach (KeyValuePair<string, double> pair in levels)
{
DrawLine(pair.Key+CurrentBar, 3, pair.Value, 1, pair.Value, FibLevelColor );
DrawText( "txt"+(i++)+CurrentBar, pair.Key, 5, pair.Value, FibLevelColor );
}
}
#endregion
if( bSendEmail
&& (CurrentBar - numbBarsLastEmail) > 2 )
{
// Send an email
string text = "Trade has been initialized.";
SendMail( EmailFrom, EmailTo, "Trade entry", text );
numbBarsLastEmail = CurrentBar;
}
}
#endregion
#region Properties
[Description("Lower boundary (in ticks) for the gap range to determine whether we will consider a trade")]
[GridCategory("Parameters")]
[Gui.Design.DisplayNameAttribute("\t\t\t\t\t\t\t\tGap - lower bound")]
public int GapLower
{
get { return iGapLower; }
set { iGapLower = Math.Max(1, value); }
}
[Description("Upper boundary (in ticks) for the gap range to determine whether we will consider a trade")]
[GridCategory("Parameters")]
[Gui.Design.DisplayNameAttribute("\t\t\t\t\t\t\tGap - upper bound")]
public int GapUpper
{
get { return iGapUpper; }
set { iGapUpper = Math.Max(1, value); }
}
[Description("Number of contracts to trade")]
[GridCategory("Parameters")]
[Gui.Design.DisplayNameAttribute("\t\t\t\t\t\tQuantity")]
public int Qty
{
get { return iQty; }
set { iQty = Math.Max(1, value); }
}
[Description("The Fibonacci level at which to enter")]
[GridCategory("Parameters")]
[Gui.Design.DisplayNameAttribute("\t\t\t\t\tEnter trade level")]
public TradeLevels EntryTradeLevel
{
get { return entryTradeLevel; }
set { entryTradeLevel = value; }
}
[Description("The Fibonacci level at which to place a stop loss")]
[GridCategory("Parameters")]
[Gui.Design.DisplayNameAttribute("\t\t\t\tStop loss trade level")]
public TradeLevels StopTradeLevel
{
get { return stopTradeLevel; }
set { stopTradeLevel = value; }
}
[Description("The Fibonacci level at which to place a profit target")]
[GridCategory("Parameters")]
[Gui.Design.DisplayNameAttribute("\t\t\tProfit target trade level")]
public TradeLevels ProfitTradeLevel
{
get { return profitTargetTradeLevel; }
set { profitTargetTradeLevel = value; }
}
[Description("True to move stop if certain level is hit.")]
[GridCategory("Parameters")]
[Gui.Design.DisplayNameAttribute("\t\tMove stop")]
public bool MoveStop
{
get { return bMoveStop; }
set { bMoveStop = value; }
}
[Description("If \"Move stop\" is true, the Fibonacci level that price needs to reach before we move the stop loss to a different level.")]
[GridCategory("Parameters")]
[Gui.Design.DisplayNameAttribute("\tPrice hit trade level")]
public TradeLevels PriceHitTradeLevel
{
get { return priceHitTradeLevel; }
set { priceHitTradeLevel = value; }
}
[Description("If \"Move stop\" is true, the Fibonacci level to which move the stop loss after a certain level is hit")]
[GridCategory("Parameters")]
[Gui.Design.DisplayNameAttribute("'Move stop to' trade level")]
public TradeLevels MoveStopTradeLevel
{
get { return moveStopTradeLevel; }
set { moveStopTradeLevel = value; }
}
[Description("Fib level color as it appears on the session open axis")]
[GridCategory("Parameters")]
[Gui.Design.DisplayName("Fib level color")]
public Color FibLevelColor
{
get { return fibColor; }
set { fibColor = value; }
}
[Description("The amount of \"slop\" to allow for a limit order to be placed a tick or two below the actual target entry.")]
[GridCategory("Parameters")]
[Gui.Design.DisplayName("Tick slop")]
public int TickSlop
{
get { return tickSlop; }
set { tickSlop = value; }
}
// Serialize Color object
[Browsable(false)]
public string FibColorSerialize
{
get { return NinjaTrader.Gui.Design.SerializableColor.ToString(fibColor); }
set { fibColor = NinjaTrader.Gui.Design.SerializableColor.FromString(value); }
}
#region Time settings
[Description("Start trading time. Format is HHMMSS and is on a 24 hour scale so 2:30 PM should be entered as 143000")]
[GridCategory("Time settings")]
[Gui.Design.DisplayName("\tTime1: Strategy begin time")]
public int StartTime
{
get { return startTime; }
set { startTime = Math.Max(000000, value); }
}
[Description("End trading time. Format is HHMMSS and is on a 24 hour scale so 2:30 PM should be entered as 143000")]
[GridCategory("Time settings")]
[Gui.Design.DisplayName("Time2: Strategy end time")]
public int EndTime
{
get { return endTime; }
set { endTime = Math.Max(000000, value); }
}
[Description("If we're still in a trade after this time, send an email warning. Format is HHMMSS and is on a 24 hour scale so 2:30 PM should be entered as 143000")]
[GridCategory("Time settings")]
[Gui.Design.DisplayName("Time3: Warn of live trade when:")]
public int LiveTradeWarnTime
{
get { return warnTime; }
set { warnTime = Math.Max(000000, value); }
}
#endregion TradeLevels
[Description("Email \"From\" address")]
[GridCategory("Email info")]
[Gui.Design.DisplayName("Email from")]
public string EmailFrom
{
get { return emailFrom; }
set { emailTo = value; }
}
[Description("Email \"To\" address")]
[GridCategory("Email info")]
[Gui.Design.DisplayName("Email to")]
public string EmailTo
{
get { return emailTo; }
set { emailTo = value; }
}