chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
|
||||
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using QuantConnect.Data;
|
||||
|
||||
namespace QuantConnect.Indicators
|
||||
{
|
||||
/// <summary>
|
||||
/// KEEPING THIS INTERFACE FOR BACKWARDS COMPATIBILITY.
|
||||
/// Represents an indicator that can receive data updates and emit events when the value of
|
||||
/// the indicator has changed.
|
||||
/// </summary>
|
||||
public interface IIndicator<T> : IComparable<IIndicator<T>>, IIndicator
|
||||
where T : IBaseData
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents an indicator that can receive data updates and emit events when the value of
|
||||
/// the indicator has changed.
|
||||
/// </summary>
|
||||
public interface IIndicator : IComparable
|
||||
{
|
||||
/// <summary>
|
||||
/// Event handler that fires after this indicator is updated
|
||||
/// </summary>
|
||||
event IndicatorUpdatedHandler Updated;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a name for this indicator
|
||||
/// </summary>
|
||||
string Name { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag indicating when this indicator is ready and fully initialized
|
||||
/// </summary>
|
||||
bool IsReady { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current state of this indicator. If the state has not been updated
|
||||
/// then the time on the value will equal DateTime.MinValue.
|
||||
/// </summary>
|
||||
IndicatorDataPoint Current { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of samples processed by this indicator
|
||||
/// </summary>
|
||||
long Samples { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Updates the state of this indicator with the given value and returns true
|
||||
/// if this indicator is ready, false otherwise
|
||||
/// </summary>
|
||||
/// <param name="input">The value to use to update this indicator</param>
|
||||
/// <returns>True if this indicator is ready, false otherwise</returns>
|
||||
bool Update(IBaseData input);
|
||||
|
||||
/// <summary>
|
||||
/// Resets this indicator to its initial state
|
||||
/// </summary>
|
||||
void Reset();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
|
||||
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
namespace QuantConnect.Indicators
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents an indicator with a warm up period provider.
|
||||
/// </summary>
|
||||
public interface IIndicatorWarmUpPeriodProvider
|
||||
{
|
||||
/// <summary>
|
||||
/// Required period, in data points, for the indicator to be ready and fully initialized.
|
||||
/// </summary>
|
||||
int WarmUpPeriod { get; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
|
||||
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace QuantConnect.Indicators
|
||||
{
|
||||
/// <summary>
|
||||
/// Interface type used to pass windows around without worry of external modification
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of data in the window</typeparam>
|
||||
public interface IReadOnlyWindow<out T> : IEnumerable<T>
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the size of this window
|
||||
/// </summary>
|
||||
int Size { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current number of elements in this window
|
||||
/// </summary>
|
||||
int Count { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of samples that have been added to this window over its lifetime
|
||||
/// </summary>
|
||||
int Samples { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Indexes into this window, where index 0 is the most recently
|
||||
/// entered value
|
||||
/// </summary>
|
||||
/// <param name="i">the index, i</param>
|
||||
/// <returns>the ith most recent entry</returns>
|
||||
T this[int i] { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether or not this window is ready, i.e,
|
||||
/// it has been filled to its capacity, this is when the Size==Count
|
||||
/// </summary>
|
||||
bool IsReady { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the most recently removed item from the window. This is the
|
||||
/// piece of data that just 'fell off' as a result of the most recent
|
||||
/// add. If no items have been removed, this will throw an exception.
|
||||
/// </summary>
|
||||
T MostRecentlyRemoved { get; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
|
||||
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System;
|
||||
|
||||
using QuantConnect.Data;
|
||||
|
||||
namespace QuantConnect.Indicators
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a piece of data at a specific time
|
||||
/// </summary>
|
||||
public class IndicatorDataPoint : BaseData, IEquatable<IndicatorDataPoint>, IComparable<IndicatorDataPoint>, IComparable
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new default instance of IndicatorDataPoint with a time of
|
||||
/// DateTime.MinValue and a Value of 0m.
|
||||
/// </summary>
|
||||
public IndicatorDataPoint()
|
||||
{
|
||||
Value = 0m;
|
||||
Time = DateTime.MinValue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the DataPoint type using the specified time/data
|
||||
/// </summary>
|
||||
/// <param name="time">The time this data was produced</param>
|
||||
/// <param name="value">The data</param>
|
||||
public IndicatorDataPoint(DateTime time, decimal value)
|
||||
{
|
||||
Time = time;
|
||||
Value = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the DataPoint type using the specified time/data
|
||||
/// </summary>
|
||||
/// <param name="symbol">The symbol associated with this data</param>
|
||||
/// <param name="time">The time this data was produced</param>
|
||||
/// <param name="value">The data</param>
|
||||
public IndicatorDataPoint(Symbol symbol, DateTime time, decimal value)
|
||||
{
|
||||
Symbol = symbol;
|
||||
Time = time;
|
||||
Value = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the current object is equal to another object of the same type.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// true if the current object is equal to the <paramref name="other" /> parameter; otherwise, false.
|
||||
/// </returns>
|
||||
/// <param name="other">An object to compare with this object.</param>
|
||||
public bool Equals(IndicatorDataPoint other)
|
||||
{
|
||||
if (other == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return other.Time == Time && other.Value == Value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares the current object with another object of the same type.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A value that indicates the relative order of the objects being compared. The return value has the following meanings: Value Meaning Less than zero This object is less than the <paramref name="other"/> parameter.Zero This object is equal to <paramref name="other"/>. Greater than zero This object is greater than <paramref name="other"/>.
|
||||
/// </returns>
|
||||
/// <param name="other">An object to compare with this object.</param>
|
||||
public int CompareTo(IndicatorDataPoint other)
|
||||
{
|
||||
if (ReferenceEquals(other, null))
|
||||
{
|
||||
// everything is greater than null via MSDN
|
||||
return 1;
|
||||
}
|
||||
return Value.CompareTo(other.Value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares the current instance with another object of the same type and returns an integer that indicates whether the current instance precedes, follows, or occurs in the same position in the sort order as the other object.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A value that indicates the relative order of the objects being compared. The return value has these meanings: Value Meaning Less than zero This instance precedes <paramref name="obj"/> in the sort order. Zero This instance occurs in the same position in the sort order as <paramref name="obj"/>. Greater than zero This instance follows <paramref name="obj"/> in the sort order.
|
||||
/// </returns>
|
||||
/// <param name="obj">An object to compare with this instance. </param><exception cref="T:System.ArgumentException"><paramref name="obj"/> is not the same type as this instance. </exception><filterpriority>2</filterpriority>
|
||||
public int CompareTo(object obj)
|
||||
{
|
||||
var other = obj as IndicatorDataPoint;
|
||||
if (other == null)
|
||||
{
|
||||
throw new ArgumentException(Messages.IndicatorDataPoint.InvalidObjectTypeToCompareTo(GetType()));
|
||||
}
|
||||
return CompareTo(other);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a string representation of this DataPoint instance using ISO8601 formatting for the date
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A <see cref="T:System.String" /> containing a fully qualified type name.
|
||||
/// </returns>
|
||||
/// <filterpriority>2</filterpriority>
|
||||
public override string ToString()
|
||||
{
|
||||
return Messages.IndicatorDataPoint.ToString(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether this instance and a specified object are equal.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// true if <paramref name="obj" /> and this instance are the same type and represent the same value; otherwise, false.
|
||||
/// </returns>
|
||||
/// <param name="obj">Another object to compare to. </param>
|
||||
/// <filterpriority>2</filterpriority>
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (ReferenceEquals(null, obj)) return false;
|
||||
return obj is IndicatorDataPoint && Equals((IndicatorDataPoint) obj);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the hash code for this instance.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A 32-bit signed integer that is the hash code for this instance.
|
||||
/// </returns>
|
||||
/// <filterpriority>2</filterpriority>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
return (Value.GetHashCode()*397) ^ Time.GetHashCode();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the data held within the instance
|
||||
/// </summary>
|
||||
/// <param name="instance">The DataPoint instance</param>
|
||||
/// <returns>The data held within the instance</returns>
|
||||
public static implicit operator decimal(IndicatorDataPoint instance)
|
||||
{
|
||||
return instance.Value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function is purposefully not implemented.
|
||||
/// </summary>
|
||||
public override BaseData Reader(SubscriptionDataConfig config, string line, DateTime date, bool isLiveMode)
|
||||
{
|
||||
throw new NotImplementedException(Messages.IndicatorDataPoint.UnsupportedMethod(nameof(Reader)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function is purposefully not implemented.
|
||||
/// </summary>
|
||||
public override SubscriptionDataSource GetSource(SubscriptionDataConfig config, DateTime date, bool isLiveMode)
|
||||
{
|
||||
throw new NotImplementedException(Messages.IndicatorDataPoint.UnsupportedMethod(nameof(GetSource)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
|
||||
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
namespace QuantConnect.Indicators
|
||||
{
|
||||
/// <summary>
|
||||
/// Event handler type for the IndicatorBase.Updated event
|
||||
/// </summary>
|
||||
/// <param name="sender">The indicator that fired the event</param>
|
||||
/// <param name="updated">The new piece of data produced by the indicator</param>
|
||||
public delegate void IndicatorUpdatedHandler(object sender, IndicatorDataPoint updated);
|
||||
}
|
||||
@@ -0,0 +1,192 @@
|
||||
/*
|
||||
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
|
||||
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using QuantConnect.Data;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace QuantConnect.Indicators
|
||||
{
|
||||
/// <summary>
|
||||
/// Collection of indicator data points for a given time
|
||||
/// </summary>
|
||||
public class IndicatorDataPoints : DynamicData
|
||||
{
|
||||
/// <summary>
|
||||
/// The indicator value at a given point
|
||||
/// </summary>
|
||||
public IndicatorDataPoint Current => (IndicatorDataPoint)GetProperty("Current");
|
||||
|
||||
/// <summary>
|
||||
/// The indicator value at a given point
|
||||
/// </summary>
|
||||
public override decimal Value => Current.Value;
|
||||
|
||||
/// <summary>
|
||||
/// Access the historical indicator values per indicator property name
|
||||
/// </summary>
|
||||
public IndicatorDataPoint this[string name]
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetProperty(name) as IndicatorDataPoint;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// String representation
|
||||
/// </summary>
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{EndTime} {string.Join(", ", GetStorageDictionary().OrderBy(x => x.Key).Select(x => $"{x.Key}: {HandleObjectStorage(x.Value)}"))}";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the current data value held within the instance
|
||||
/// </summary>
|
||||
/// <param name="instance">The DataPoint instance</param>
|
||||
/// <returns>The current data value held within the instance</returns>
|
||||
public static implicit operator decimal(IndicatorDataPoints instance)
|
||||
{
|
||||
return instance.Value;
|
||||
}
|
||||
|
||||
private static string HandleObjectStorage(object storedObject)
|
||||
{
|
||||
if (storedObject is IndicatorDataPoint point)
|
||||
{
|
||||
return point.Value.SmartRounding().ToStringInvariant();
|
||||
}
|
||||
return storedObject?.ToString() ?? string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Internal carrier of an indicator values by property name
|
||||
/// </summary>
|
||||
public class InternalIndicatorValues : IEnumerable<IndicatorDataPoint>
|
||||
{
|
||||
/// <summary>
|
||||
/// The name of the values associated to this dto
|
||||
/// </summary>
|
||||
public string Name { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The indicator values
|
||||
/// </summary>
|
||||
public List<IndicatorDataPoint> Values { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The target indicator
|
||||
/// </summary>
|
||||
protected IIndicator Indicator { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance
|
||||
/// </summary>
|
||||
public InternalIndicatorValues(IIndicator indicator, string name)
|
||||
{
|
||||
Name = name;
|
||||
Values = new();
|
||||
Indicator = indicator;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update with a new indicator point
|
||||
/// </summary>
|
||||
public virtual IndicatorDataPoint UpdateValue()
|
||||
{
|
||||
Values.Add(Indicator.Current);
|
||||
return Indicator.Current;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance
|
||||
/// </summary>
|
||||
public static InternalIndicatorValues Create(IIndicator indicator, string name)
|
||||
{
|
||||
return new InternalIndicatorValues(indicator, name);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance
|
||||
/// </summary>
|
||||
public static InternalIndicatorValues Create(IIndicator indicator, PropertyInfo propertyInfo)
|
||||
{
|
||||
return new IndicatorPropertyValues(indicator, propertyInfo);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// String representation
|
||||
/// </summary>
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{Name} {Values.Count} indicator values";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns an enumerator for the indicator values
|
||||
/// </summary>
|
||||
public IEnumerator<IndicatorDataPoint> GetEnumerator()
|
||||
{
|
||||
return ((IEnumerable<IndicatorDataPoint>)Values).GetEnumerator();
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return ((IEnumerable)Values).GetEnumerator();
|
||||
}
|
||||
|
||||
private class IndicatorPropertyValues : InternalIndicatorValues
|
||||
{
|
||||
private readonly PropertyInfo _currentInfo;
|
||||
private readonly PropertyInfo _propertyInfo;
|
||||
public IndicatorPropertyValues(IIndicator indicator, PropertyInfo propertyInfo) : base(indicator, propertyInfo.Name)
|
||||
{
|
||||
_propertyInfo = propertyInfo;
|
||||
_currentInfo = _propertyInfo.PropertyType.GetProperty("Current");
|
||||
}
|
||||
public override IndicatorDataPoint UpdateValue()
|
||||
{
|
||||
var value = _propertyInfo.GetValue(Indicator);
|
||||
if (value == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (_currentInfo != null)
|
||||
{
|
||||
value = _currentInfo.GetValue(value);
|
||||
}
|
||||
var point = value as IndicatorDataPoint;
|
||||
|
||||
if (Values.Count == 0 || point.EndTime != Values[^1].EndTime)
|
||||
{
|
||||
// If the list is empty or the new point has a different EndTime, add it to the list
|
||||
Values.Add(point);
|
||||
}
|
||||
else
|
||||
{
|
||||
// If the new point has the same EndTime as the last point, update the last point
|
||||
Values[^1] = point;
|
||||
}
|
||||
|
||||
return point;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
|
||||
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
namespace QuantConnect.Indicators
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines different types of option pricing model
|
||||
/// </summary>
|
||||
public enum OptionPricingModelType
|
||||
{
|
||||
/// <summary>
|
||||
/// Vanilla Black Scholes Model
|
||||
/// </summary>
|
||||
/// <remarks>Preferred on calculating greeks for European options, and IV for all options</remarks>
|
||||
BlackScholes,
|
||||
/// <summary>
|
||||
/// The Cox-Ross-Rubinstein binomial tree model (CRR model)
|
||||
/// </summary>
|
||||
/// <remarks>Preferred on calculating greeks for American options</remarks>
|
||||
BinomialCoxRossRubinstein,
|
||||
/// <summary>
|
||||
/// The forward binomial tree model, or Cox-Ross-Rubinstein with drift model
|
||||
/// </summary>
|
||||
/// <remarks>Preferred on replicating IB IV for American options</remarks>
|
||||
ForwardTree
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,396 @@
|
||||
/*
|
||||
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
|
||||
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Threading;
|
||||
using Python.Runtime;
|
||||
|
||||
namespace QuantConnect.Indicators
|
||||
{
|
||||
/// <summary>
|
||||
/// This is generic rolling window.
|
||||
/// </summary>
|
||||
public class RollingWindow : RollingWindow<object>
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new RollingWindow with the specified size.
|
||||
/// </summary>
|
||||
/// <param name="size">The number of elements to store in the window</param>
|
||||
public RollingWindow(int size) : base(size)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is a window that allows for list access semantics,
|
||||
/// where this[0] refers to the most recent item in the
|
||||
/// window and this[Count-1] refers to the last item in the window
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of data in the window</typeparam>
|
||||
public class RollingWindow<T> : IReadOnlyWindow<T>
|
||||
{
|
||||
// the backing list object used to hold the data
|
||||
private readonly List<T> _list;
|
||||
// read-write lock used for controlling access to the underlying list data structure
|
||||
private readonly ReaderWriterLockSlim _listLock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
|
||||
// the most recently removed item from the window (fell off the back)
|
||||
private T _mostRecentlyRemoved;
|
||||
// the total number of samples taken by this indicator
|
||||
private int _samples;
|
||||
// used to locate the last item in the window as an indexer into the _list
|
||||
private int _tail;
|
||||
// the size or capacity of the window
|
||||
private int _size;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the RollwingWindow class with the specified window size.
|
||||
/// </summary>
|
||||
/// <param name="size">The number of items to hold in the window</param>
|
||||
public RollingWindow(int size)
|
||||
{
|
||||
if (size < 0)
|
||||
{
|
||||
throw new ArgumentException(Messages.RollingWindow.InvalidSize(0), nameof(size));
|
||||
}
|
||||
_list = new List<T>(size);
|
||||
_size = size;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the size of this window
|
||||
/// </summary>
|
||||
public virtual int Size
|
||||
{
|
||||
get
|
||||
{
|
||||
try
|
||||
{
|
||||
_listLock.EnterReadLock();
|
||||
return _size;
|
||||
}
|
||||
finally
|
||||
{
|
||||
_listLock.ExitReadLock();
|
||||
}
|
||||
}
|
||||
set
|
||||
{
|
||||
Resize(value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current number of elements in this window
|
||||
/// </summary>
|
||||
public int Count
|
||||
{
|
||||
get
|
||||
{
|
||||
try
|
||||
{
|
||||
_listLock.EnterReadLock();
|
||||
return _list.Count;
|
||||
}
|
||||
finally
|
||||
{
|
||||
_listLock.ExitReadLock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of samples that have been added to this window over its lifetime
|
||||
/// </summary>
|
||||
public int Samples
|
||||
{
|
||||
get
|
||||
{
|
||||
try
|
||||
{
|
||||
_listLock.EnterReadLock();
|
||||
return _samples;
|
||||
}
|
||||
finally
|
||||
{
|
||||
_listLock.ExitReadLock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the most recently removed item from the window. This is the
|
||||
/// piece of data that just 'fell off' as a result of the most recent
|
||||
/// add. If no items have been removed, this will throw an exception.
|
||||
/// </summary>
|
||||
public T MostRecentlyRemoved
|
||||
{
|
||||
get
|
||||
{
|
||||
try
|
||||
{
|
||||
_listLock.EnterReadLock();
|
||||
|
||||
if (_samples <= _size)
|
||||
{
|
||||
throw new InvalidOperationException(Messages.RollingWindow.NoItemsRemovedYet);
|
||||
}
|
||||
return _mostRecentlyRemoved;
|
||||
}
|
||||
finally
|
||||
{
|
||||
_listLock.ExitReadLock();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indexes into this window, where index 0 is the most recently
|
||||
/// entered value
|
||||
/// </summary>
|
||||
/// <param name="i">the index, i</param>
|
||||
/// <returns>the ith most recent entry</returns>
|
||||
public T this[int i]
|
||||
{
|
||||
get
|
||||
{
|
||||
try
|
||||
{
|
||||
_listLock.EnterReadLock();
|
||||
|
||||
if (i < 0)
|
||||
{
|
||||
if (_size + i < 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(i), i, Messages.RollingWindow.IndexOutOfSizeRange);
|
||||
}
|
||||
i = _list.Count + i;
|
||||
|
||||
if (i < 0)
|
||||
{
|
||||
return default;
|
||||
}
|
||||
}
|
||||
|
||||
if (i > _list.Count - 1)
|
||||
{
|
||||
if (i > _size - 1)
|
||||
{
|
||||
_listLock.ExitReadLock();
|
||||
Resize(i + 1);
|
||||
_listLock.EnterReadLock();
|
||||
}
|
||||
|
||||
return default;
|
||||
}
|
||||
|
||||
return _list[GetListIndex(i, _list.Count, _tail)];
|
||||
}
|
||||
finally
|
||||
{
|
||||
_listLock.ExitReadLock();
|
||||
}
|
||||
}
|
||||
set
|
||||
{
|
||||
try
|
||||
{
|
||||
_listLock.EnterWriteLock();
|
||||
|
||||
if (i < 0)
|
||||
{
|
||||
if (_size + i < 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(i), i, Messages.RollingWindow.IndexOutOfSizeRange);
|
||||
}
|
||||
i = _size + i;
|
||||
}
|
||||
|
||||
if (i > _list.Count - 1)
|
||||
{
|
||||
if (i > _size - 1)
|
||||
{
|
||||
Resize(i + 1);
|
||||
}
|
||||
|
||||
var count = _list.Count;
|
||||
for (var j = 0; j < i - count + 1; j++)
|
||||
{
|
||||
Add(default);
|
||||
}
|
||||
}
|
||||
|
||||
_list[GetListIndex(i, _list.Count, _tail)] = value;
|
||||
}
|
||||
finally
|
||||
{
|
||||
_listLock.ExitWriteLock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether or not this window is ready, i.e,
|
||||
/// it has been filled to its capacity
|
||||
/// </summary>
|
||||
public bool IsReady
|
||||
{
|
||||
get
|
||||
{
|
||||
try
|
||||
{
|
||||
_listLock.EnterReadLock();
|
||||
return _samples >= _size;
|
||||
}
|
||||
finally
|
||||
{
|
||||
_listLock.ExitReadLock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns an enumerator that iterates through the collection.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A <see cref="T:System.Collections.Generic.IEnumerator`1" /> that can be used to iterate through the collection.
|
||||
/// </returns>
|
||||
/// <filterpriority>1</filterpriority>
|
||||
public IEnumerator<T> GetEnumerator()
|
||||
{
|
||||
try
|
||||
{
|
||||
_listLock.EnterReadLock();
|
||||
|
||||
// we make a copy on purpose so the enumerator isn't tied
|
||||
// to a mutable object, well it is still mutable but out of scope
|
||||
var count = _list.Count;
|
||||
var temp = new T[count];
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
temp[i] = _list[GetListIndex(i, count, _tail)];
|
||||
}
|
||||
|
||||
return ((IEnumerable<T>)temp).GetEnumerator();
|
||||
}
|
||||
finally
|
||||
{
|
||||
_listLock.ExitReadLock();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns an enumerator that iterates through a collection.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// An <see cref="T:System.Collections.IEnumerator" /> object that can be used to iterate through the collection.
|
||||
/// </returns>
|
||||
/// <filterpriority>2</filterpriority>
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds an item to this window and shifts all other elements
|
||||
/// </summary>
|
||||
/// <param name="item">The item to be added</param>
|
||||
public void Add(T item)
|
||||
{
|
||||
try
|
||||
{
|
||||
_listLock.EnterWriteLock();
|
||||
|
||||
_samples++;
|
||||
if (_size == _list.Count)
|
||||
{
|
||||
// keep track of what's the last element
|
||||
// so we can reindex on this[ int ]
|
||||
_mostRecentlyRemoved = _list[_tail];
|
||||
_list[_tail] = item;
|
||||
_tail = (_tail + 1) % _size;
|
||||
}
|
||||
else
|
||||
{
|
||||
_list.Add(item);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
_listLock.ExitWriteLock();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears this window of all data
|
||||
/// </summary>
|
||||
public virtual void Reset()
|
||||
{
|
||||
try
|
||||
{
|
||||
_listLock.EnterWriteLock();
|
||||
|
||||
_samples = 0;
|
||||
_list.Clear();
|
||||
_tail = 0;
|
||||
}
|
||||
finally
|
||||
{
|
||||
_listLock.ExitWriteLock();
|
||||
}
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private static int GetListIndex(int index, int listCount, int tail)
|
||||
{
|
||||
return (listCount + tail - index - 1) % listCount;
|
||||
}
|
||||
|
||||
private void Resize(int size)
|
||||
{
|
||||
try
|
||||
{
|
||||
_listLock.EnterWriteLock();
|
||||
|
||||
if (size < _list.Count)
|
||||
{
|
||||
if (_tail != 0)
|
||||
{
|
||||
// The _list is out of order due to circular overwrites
|
||||
// Restore oldest to newest order and reset _tail before resizing
|
||||
var count = _list.Count;
|
||||
_list.Reverse(0, _tail);
|
||||
_list.Reverse(_tail, count - _tail);
|
||||
_list.Reverse(0, count);
|
||||
_tail = 0;
|
||||
}
|
||||
|
||||
_list.RemoveRange(0, _list.Count - size);
|
||||
}
|
||||
|
||||
_list.EnsureCapacity(size);
|
||||
_size = size;
|
||||
}
|
||||
finally
|
||||
{
|
||||
_listLock.ExitWriteLock();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
|
||||
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace QuantConnect.Indicators
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides a base class for types that maintain a rolling window history of values.
|
||||
/// This is the single source of truth for window logic shared between indicators and consolidators.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of value stored in the rolling window</typeparam>
|
||||
public abstract class WindowBase<T> : IEnumerable<T>
|
||||
{
|
||||
private RollingWindow<T> _window;
|
||||
|
||||
/// <summary>
|
||||
/// The default number of values to keep in the rolling window history
|
||||
/// </summary>
|
||||
public static int DefaultWindowSize { get; } = 2;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="WindowBase{T}"/> class.
|
||||
/// </summary>
|
||||
protected WindowBase() { }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the rolling window with the given size.
|
||||
/// </summary>
|
||||
protected WindowBase(int windowSize)
|
||||
{
|
||||
_window = new RollingWindow<T>(windowSize);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A rolling window keeping a history of values. The most recent value is at index 0.
|
||||
/// Uses lazy initialization to support Python subclasses that do not call base constructors.
|
||||
/// </summary>
|
||||
public virtual RollingWindow<T> Window => _window ??= new RollingWindow<T>(DefaultWindowSize);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the most recent value. The protected setter adds the value to the rolling window.
|
||||
/// </summary>
|
||||
public virtual T Current
|
||||
{
|
||||
get
|
||||
{
|
||||
return Window[0];
|
||||
}
|
||||
protected set
|
||||
{
|
||||
Window.Add(value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the previous value, or default if fewer than two values have been produced.
|
||||
/// </summary>
|
||||
public virtual T Previous => Window.Count > 1 ? Window[1] : default;
|
||||
|
||||
/// <summary>
|
||||
/// Indexes the history window, where index 0 is the most recent value.
|
||||
/// </summary>
|
||||
/// <param name="i">The index</param>
|
||||
/// <returns>The ith most recent value</returns>
|
||||
public T this[int i] => Window[i];
|
||||
|
||||
/// <summary>
|
||||
/// Returns an enumerator that iterates through the history window.
|
||||
/// </summary>
|
||||
public IEnumerator<T> GetEnumerator() => Window.GetEnumerator();
|
||||
|
||||
/// <summary>
|
||||
/// Returns an enumerator that iterates through the history window.
|
||||
/// </summary>
|
||||
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
|
||||
|
||||
/// <summary>
|
||||
/// Resets the rolling window, clearing all stored values.
|
||||
/// </summary>
|
||||
protected void ResetWindow()
|
||||
{
|
||||
_window?.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user