Overall Statistics
Total Trades
50463
Average Win
0.03%
Average Loss
-0.06%
Compounding Annual Return
642.964%
Drawdown
3.300%
Expectancy
0.090
Net Profit
502.965%
Sharpe Ratio
10.295
Loss Rate
29%
Win Rate
71%
Profit-Loss Ratio
0.53
Alpha
1.403
Beta
-0.011
Annual Standard Deviation
0.136
Annual Variance
0.019
Information Ratio
7.507
Tracking Error
0.178
Treynor Ratio
-122.888
Total Fees
$0.00
// Accord.NET Extensions Framework
// https://github.com/dajuric/accord-net-extensions
//
// Copyright © Darko Jurić, 2014-2015 
// darko.juric2@gmail.com
//
//   This program is free software: you can redistribute it and/or modify
//   it under the terms of the GNU Lesser General Public License as published by
//   the Free Software Foundation, either version 3 of the License, or
//   (at your option) any later version.
//
//   This program is distributed in the hope that it will be useful,
//   but WITHOUT ANY WARRANTY; without even the implied warranty of
//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//   GNU Lesser General Public License for more details.
// 
//   You should have received a copy of the GNU Lesser General Public License
//   along with this program.  If not, see <https://www.gnu.org/licenses/lgpl.txt>.
//

using System;
using System.Collections.Generic;

namespace Accord.Extensions330
{
    /// <summary>
    /// <para>Defined functions can be used as object extensions.</para>
    /// Provides methods for finding the index of the max element in a sequence.
    /// </summary>
    public static class IndexOfMaxExtensions
    {

        /// <summary>
        /// Finds the index of the max element in a sequence.
        /// <para>Default comparer is used for a selected key.</para>
        /// </summary>
        /// <typeparam name="TSource">Collection type.</typeparam>
        /// <param name="collection">Collection.</param>
        /// <returns>
        /// The index of the maximum element.
        /// </returns>
        /// <exception cref="InvalidOperationException">in case when the collection is empty.</exception>
        public static int IndexOfMax<TSource>(this IEnumerable<TSource> collection)
        {
            return collection.IndexOfMax((x, i) => x, Comparer<TSource>.Default);
        }

        /// <summary>
        /// Finds the index of the max element in a sequence.
        /// <para>Default comparer is used for a selected key.</para>
        /// </summary>
        /// <typeparam name="TSource">Collection type.</typeparam>
        /// <typeparam name="TKey">Key type.</typeparam>
        /// <param name="collection">Collection.</param>
        /// <param name="selector">Key selector. Parameters are: the current element and an index of an element in the sequence.</param>
        /// <returns>
        /// The index of the maximum element.
        /// </returns>
        /// <exception cref="InvalidOperationException">in case when the collection is empty.</exception>
        public static int IndexOfMax<TSource, TKey>(this IEnumerable<TSource> collection, Func<TSource, int, TKey> selector)
        {
          return collection.IndexOfMax(selector, Comparer<TKey>.Default);
        }

        /// <summary>
        /// Finds the index of the max element in a sequence.
        /// </summary>
        /// <typeparam name="TSource">Collection type.</typeparam>
        /// <typeparam name="TKey">Key type.</typeparam>
        /// <param name="collection">Collection.</param>
        /// <param name="selector">Key selector. Parameters are: the current element and an index of an element in the sequence.</param>
        /// <param name="comparer">Comparer for the selected key type.</param>
        /// <returns>
        /// The index of the maximum element.
        /// </returns>
        /// <exception cref="InvalidOperationException">in case when the collection is empty.</exception>
        public static int IndexOfMax<TSource, TKey>(this IEnumerable<TSource> collection, Func<TSource, int, TKey> selector, IComparer<TKey> comparer)
        {
            int idx = 0;
            int idxOfMax = 0;
            using (var sourceIterator = collection.GetEnumerator())
            {
                if (!sourceIterator.MoveNext())
                    throw new InvalidOperationException("Sequence contains no elements");

                var minKey = selector(sourceIterator.Current, idx);

                while (sourceIterator.MoveNext())
                {
                    idx++;

                    var item = sourceIterator.Current;
                    var key = selector(item, idx);

                    if (comparer.Compare(key, minKey) > 0)
                    {
                        minKey = key;
                        idxOfMax = idx;
                    }
                }

                return idxOfMax;
            }
        }
    }
}
// Accord.NET Extensions Framework
// https://github.com/dajuric/accord-net-extensions
//
// Copyright © Darko Jurić, 2014-2015 
// darko.juric2@gmail.com
//
//   This program is free software: you can redistribute it and/or modify
//   it under the terms of the GNU Lesser General Public License as published by
//   the Free Software Foundation, either version 3 of the License, or
//   (at your option) any later version.
//
//   This program is distributed in the hope that it will be useful,
//   but WITHOUT ANY WARRANTY; without even the implied warranty of
//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//   GNU Lesser General Public License for more details.
// 
//   You should have received a copy of the GNU Lesser General Public License
//   along with this program.  If not, see <https://www.gnu.org/licenses/lgpl.txt>.
//

using System;
using System.Collections.Generic;

namespace Accord.Extensions330
{
    /// <summary>
    /// Contains extension methods for determining the index of the minimum element in collection.
    /// <para>All methods can be used as extensions.</para>
    /// </summary>
    public static class IndexOfMinExtensions
    {
        /// <summary>
        /// Finds the index of the min element in a sequence.
        /// <para>Default comparer is used for a selected key.</para>
        /// </summary>
        /// <typeparam name="TSource">Collection type.</typeparam>
        /// <param name="collection">Collection.</param>
        /// <returns>
        /// The index of the minimum element.
        /// </returns>
        /// <exception cref="InvalidOperationException">in case when the collection is empty.</exception>
        public static int IndexOfMin<TSource>(this IEnumerable<TSource> collection)
        {
            return collection.IndexOfMin((x, i) => x, Comparer<TSource>.Default);
        }

        /// <summary>
        /// Finds the index of the min element in a sequence.
        /// <para>Default comparer is used for a selected key.</para>
        /// </summary>
        /// <typeparam name="TSource">Collection type.</typeparam>
        /// <typeparam name="TKey">Key type.</typeparam>
        /// <param name="collection">Collection.</param>
        /// <param name="selector">Key selector. Parameters are: the current element and an index of an element in the sequence.</param>
        /// <returns>
        /// The index of the minimum element.
        /// </returns>
        /// <exception cref="InvalidOperationException">in case when the collection is empty.</exception>
        public static int IndexOfMin<TSource, TKey>(this IEnumerable<TSource> collection, Func<TSource, int, TKey> selector)
        {
            return collection.IndexOfMin(selector, Comparer<TKey>.Default);
        }

        /// <summary>
        /// Finds the index of the min element in a sequence.
        /// </summary>
        /// <typeparam name="TSource">Collection type.</typeparam>
        /// <typeparam name="TKey">Key type.</typeparam>
        /// <param name="collection">Collection.</param>
        /// <param name="selector">Key selector. Parameters are: the current element and an index of an element in the sequence.</param>
        /// <param name="comparer">Comparer for the selected key type.</param>
        /// <returns>
        /// The index of the minimum element.
        /// </returns>
        /// <exception cref="InvalidOperationException">in case when the collection is empty.</exception>
        public static int IndexOfMin<TSource, TKey>(this IEnumerable<TSource> collection, Func<TSource, int, TKey> selector, IComparer<TKey> comparer)
        {
            int idx = 0;
            int idxOfMin = 0;
            using (var sourceIterator = collection.GetEnumerator())
            {
                if (!sourceIterator.MoveNext())
                    throw new InvalidOperationException("Sequence contains no elements");

                var minKey = selector(sourceIterator.Current, idx);

                while (sourceIterator.MoveNext())
                {
                    idx++;

                    var item = sourceIterator.Current;
                    var key = selector(item, idx);

                    if (comparer.Compare(key, minKey) < 0)
                    {
                        minKey = key;
                        idxOfMin = idx;
                    }
                }

                return idxOfMin;
            }
        }
    }
}
using Accord.Extensions330;
using QuantConnect.Data.Market;

namespace QuantConnect.Indicators
{
    public class WilliamsFractals : TradeBarIndicator
    {
        private readonly RollingWindow<TradeBar> _fractal;
        private readonly int _fractalMidIndex;

        private decimal _barryUp;
        private decimal _barryDown;

        public decimal BarryUp => _barryUp;
        public decimal BarryDown => _barryDown;
        public decimal MidPoint => (_barryUp - _barryDown) / 2m;

        public override bool IsReady => _fractal.IsReady;

        public WilliamsFractals(int fractalLength = 5) : this("WilliamsFractals" + fractalLength, fractalLength)
        {
        }

        public WilliamsFractals(string name, int fractalLength = 5) : base(name)
        {
            _fractal = new RollingWindow<TradeBar>(fractalLength);
            _fractalMidIndex = fractalLength / 2 - (fractalLength % 2 == 0 ? 1 : 0);
        }

        protected override decimal ComputeNextValue(TradeBar input)
        {
            _fractal.Add(input);

            if (!_fractal.IsReady) return MidPoint;

            if (_fractal.IndexOfMax((bar, index) => bar.High) == _fractalMidIndex)
            {
                _barryUp = input.High;
            }

            if (_fractal.IndexOfMin((bar, index) => bar.Low) == _fractalMidIndex)
            {
                _barryDown = input.Low;
            }

            return MidPoint;
        }
    }
}
namespace QuantConnect.CSharp.Algorithms
{   
    public class ScalpingAlgorithm : QCAlgorithm
    {
    	private WilliamsFractals _wf;
    	
    	private string symbol = "NZDCHF";
    	
        public override void Initialize() 
        {
            SetStartDate(2016, 1, 1);         
            SetEndDate(DateTime.Now);
            
            SetCash(3000);
            
            AddSecurity(SecurityType.Forex, symbol, Resolution.Minute);
            
            Securities[symbol].FeeModel = new ConstantFeeModel(0.0m);
            
            _wf = new WilliamsFractals();
        }

        public void OnData(TradeBars data) 
        {   
        	_wf.Update(data[symbol]);
        	
            if (_wf.IsReady)
            {
				if (data[symbol].Price >= _wf.BarryUp)
				{
					SetHoldings(symbol, -1.0m);
				}
				else if (data[symbol].Price <= _wf.BarryDown)
				{
					SetHoldings(symbol, 1.0m);
				}
            }
        }
    }
}