├── DotNet └── QuantSys │ ├── Analytics │ ├── StatisticalModeling │ │ ├── GARCH.cs │ │ ├── LinearRegression.cs │ │ ├── PolynomialRegression.cs │ │ ├── VarianceRatio.cs │ │ ├── ARMA.cs │ │ ├── HurstEstimation.cs │ │ └── PCA │ │ │ └── PCA.cs │ ├── Timeseries │ │ └── Indicators │ │ │ ├── Averages │ │ │ ├── WMA.cs │ │ │ ├── QEMA.cs │ │ │ ├── GDEMA.cs │ │ │ ├── AdaptiveSmoothing.cs │ │ │ ├── TEMA.cs │ │ │ ├── SMA.cs │ │ │ ├── ZLEMA.cs │ │ │ ├── QSPolyMA.cs │ │ │ ├── EMA.cs │ │ │ └── KAMA.cs │ │ │ ├── Oscillators │ │ │ ├── Aroon.cs │ │ │ ├── STOCH.cs │ │ │ ├── ADX.cs │ │ │ ├── CMO.cs │ │ │ ├── AC.cs │ │ │ ├── AO.cs │ │ │ ├── CCI.cs │ │ │ ├── TRIX.cs │ │ │ ├── WilliamsR.cs │ │ │ ├── MACD.cs │ │ │ ├── Chaikin.cs │ │ │ ├── PFE.cs │ │ │ ├── ATR.cs │ │ │ ├── RSI.cs │ │ │ ├── DI.cs │ │ │ ├── KST.cs │ │ │ ├── RWI.cs │ │ │ └── UltimateOscillator.cs │ │ │ ├── SRLevels │ │ │ ├── DenmarkLevels.cs │ │ │ ├── FibonacciLevels.cs │ │ │ └── PivotLevels.cs │ │ │ ├── Misc │ │ │ ├── ParabolicSAR.cs │ │ │ ├── RVI.cs │ │ │ ├── MFM.cs │ │ │ ├── GenericContainer.cs │ │ │ ├── ForceIndex.cs │ │ │ ├── Covariance.cs │ │ │ ├── HurstIndicator.cs │ │ │ ├── HistoricalVol.cs │ │ │ ├── CrossoverIndex.cs │ │ │ ├── ROC.cs │ │ │ ├── RSquared.cs │ │ │ ├── ReversalGenesis.cs │ │ │ ├── Genesis.cs │ │ │ ├── MFI.cs │ │ │ ├── HeikenAshi.cs │ │ │ └── Divergence.cs │ │ │ ├── Abstraction │ │ │ ├── IIndicator.cs │ │ │ ├── AbstractAverage.cs │ │ │ ├── AbstractChannel.cs │ │ │ ├── AbstractIndicator.cs │ │ │ ├── AbstractMultiSymbolIndicator.cs │ │ │ └── AbstractPivotPoints.cs │ │ │ ├── Channels │ │ │ ├── GannHiLo.cs │ │ │ ├── QSVWChannel.cs │ │ │ ├── BollingerBands.cs │ │ │ ├── KirshenbaumBands.cs │ │ │ └── QSPolyChannel.cs │ │ │ └── Transforms │ │ │ ├── DWT.cs │ │ │ └── PercentileRank.cs │ ├── DenseVectorExtension.cs │ ├── SignalProcessing │ │ └── SignalTransform.cs │ └── IndicatorMatrix.cs │ ├── TradeEngine │ ├── Simulation │ │ ├── Account │ │ │ ├── Order │ │ │ │ ├── IOrder.cs │ │ │ │ ├── MarketOrder.cs │ │ │ │ ├── LimitOrder.cs │ │ │ │ └── StopOrder.cs │ │ │ ├── Position.cs │ │ │ └── Portfolio.cs │ │ └── Performance │ │ │ ├── TradeRecord.cs │ │ │ └── BacktestPerformance.cs │ ├── MarketInterface │ │ └── FXCMInterface │ │ │ ├── Functions │ │ │ ├── Jobs │ │ │ │ ├── IJob.cs │ │ │ │ ├── Job_IndicatorSet.cs │ │ │ │ ├── Job_OptimalPortfolio.cs │ │ │ │ ├── Job_SingleStatistic.cs │ │ │ │ └── Job_SymbolSet.cs │ │ │ ├── AccountInformation.cs │ │ │ └── HistoricPriceEngine.cs │ │ │ ├── EventArguments │ │ │ ├── AccountInformationEventArg.cs │ │ │ └── MarketDataEventArg.cs │ │ │ └── Listener │ │ │ ├── SessionStatusListener.cs │ │ │ └── ResponseListener.cs │ ├── AccountManagement │ │ ├── IAccountManager.cs │ │ └── LiveAccountManager.cs │ └── Strategy │ │ ├── MACrossExit.cs │ │ ├── AbstractStrategy.cs │ │ ├── RSIStrategy.cs │ │ ├── MACrossEntry.cs │ │ ├── ACStrat.cs │ │ ├── Pyramid.cs │ │ ├── ChannelStrategy.cs │ │ ├── NeuralNetworkStrategy.cs │ │ └── GenesisStrategy.cs │ ├── MarketData │ ├── Symbol.cs │ ├── Tick.cs │ ├── MultiQuantum.cs │ ├── Quantum.cs │ └── Timeframe.cs │ ├── QuantSys.csproj.user │ ├── Visualization │ ├── TableGeneration.cs │ └── Highstocks │ │ ├── ChartOption.cs │ │ └── HighstockFlag.cs │ ├── MachineLearning │ ├── GeneticAlgorithm │ │ ├── Genes │ │ │ ├── Constraints │ │ │ │ └── GeneConstraint.cs │ │ │ ├── Gene.cs │ │ │ ├── BinaryGene.cs │ │ │ └── RealCodedGene.cs │ │ ├── Crossover.cs │ │ ├── Chromosome.cs │ │ ├── Population.cs │ │ └── Selection.cs │ ├── SupportVectorMachine │ │ └── Predict.cs │ └── NeuralNetwork │ │ ├── PSO.cs │ │ └── TwoStageNN.cs │ ├── Util │ ├── DateTimeUtils.cs │ └── ExcelUtil.cs │ └── DataStructures │ └── MovingQueue.cs └── README.md /DotNet/QuantSys/Analytics/StatisticalModeling/GARCH.cs: -------------------------------------------------------------------------------- 1 | namespace QuantSys.Analytics.StatisticalModeling 2 | { 3 | class GARCH 4 | { 5 | 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /DotNet/QuantSys/Analytics/Timeseries/Indicators/Averages/WMA.cs: -------------------------------------------------------------------------------- 1 | namespace QuantSys.Analytics.Timeseries.Indicators.Averages 2 | { 3 | class WMA 4 | { 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /DotNet/QuantSys/Analytics/Timeseries/Indicators/Averages/QEMA.cs: -------------------------------------------------------------------------------- 1 | namespace QuantSys.Analytics.Timeseries.Indicators.Averages 2 | { 3 | public class QEMA 4 | { 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /DotNet/QuantSys/Analytics/Timeseries/Indicators/Oscillators/Aroon.cs: -------------------------------------------------------------------------------- 1 | namespace QuantSys.Analytics.Timeseries.Indicators.Oscillators 2 | { 3 | class Aroon 4 | { 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /DotNet/QuantSys/Analytics/Timeseries/Indicators/Oscillators/STOCH.cs: -------------------------------------------------------------------------------- 1 | namespace QuantSys.Analytics.Timeseries.Indicators.Oscillators 2 | { 3 | internal class STOCH 4 | { 5 | } 6 | } -------------------------------------------------------------------------------- /DotNet/QuantSys/TradeEngine/Simulation/Account/Order/IOrder.cs: -------------------------------------------------------------------------------- 1 | namespace QuantSys.TradeEngine.Simulation.Account.Order 2 | { 3 | public interface IOrder 4 | { 5 | 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /DotNet/QuantSys/Analytics/Timeseries/Indicators/SRLevels/DenmarkLevels.cs: -------------------------------------------------------------------------------- 1 | namespace QuantSys.Analytics.Timeseries.Indicators.SRLevels 2 | { 3 | class DenmarkLevels 4 | { 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /DotNet/QuantSys/Analytics/Timeseries/Indicators/Misc/ParabolicSAR.cs: -------------------------------------------------------------------------------- 1 | namespace QuantSys.Analytics.Timeseries.Indicators.Misc 2 | { 3 | public class ParabolicSAR 4 | { 5 | 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /DotNet/QuantSys/Analytics/Timeseries/Indicators/Misc/RVI.cs: -------------------------------------------------------------------------------- 1 | namespace QuantSys.Analytics.Timeseries.Indicators.Misc 2 | { 3 | //Relative Vigor Index 4 | class RVI 5 | { 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /DotNet/QuantSys/Analytics/Timeseries/Indicators/SRLevels/FibonacciLevels.cs: -------------------------------------------------------------------------------- 1 | namespace QuantSys.Analytics.Timeseries.Indicators.SRLevels 2 | { 3 | class FibonacciLevels 4 | { 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /DotNet/QuantSys/Analytics/Timeseries/Indicators/Oscillators/ADX.cs: -------------------------------------------------------------------------------- 1 | namespace QuantSys.Analytics.Timeseries.Indicators.Oscillators 2 | { 3 | public class ADX //Average Directional Index 4 | { 5 | } 6 | } -------------------------------------------------------------------------------- /DotNet/QuantSys/Analytics/Timeseries/Indicators/Abstraction/IIndicator.cs: -------------------------------------------------------------------------------- 1 | using QuantSys.MarketData; 2 | 3 | namespace QuantSys.Indicators.Abstraction 4 | { 5 | public interface IIndicator 6 | { 7 | double this[int index] { get; } 8 | double HandleNextTick(Tick t); 9 | 10 | } 11 | } -------------------------------------------------------------------------------- /DotNet/QuantSys/TradeEngine/MarketInterface/FXCMInterface/Functions/Jobs/IJob.cs: -------------------------------------------------------------------------------- 1 | namespace QuantSys.TradeEngine.MarketInterface.FXCMInterface.Functions.Jobs 2 | { 3 | public interface IJob 4 | { 5 | void RunJob(FXSession fxsession); 6 | bool UpdateJob(object data); 7 | void FinishAndProcess(); 8 | } 9 | } -------------------------------------------------------------------------------- /DotNet/QuantSys/MarketData/Symbol.cs: -------------------------------------------------------------------------------- 1 | namespace QuantSys.MarketData 2 | { 3 | public class Symbol 4 | { 5 | public Symbol(string symbol) 6 | { 7 | SymbolString = symbol; 8 | } 9 | 10 | public string SymbolString { get; set; } 11 | 12 | 13 | public override int GetHashCode() 14 | { 15 | return SymbolString.GetHashCode(); 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /DotNet/QuantSys/Analytics/Timeseries/Indicators/Oscillators/CMO.cs: -------------------------------------------------------------------------------- 1 | namespace QuantSys.Analytics.Timeseries.Indicators.Oscillators 2 | { 3 | public class CMO //Chande Momentum Oscillator 4 | { 5 | // 100 * (s_u - s_d) / (s_u + s_d) 6 | //Su is the sum of the difference between today’s close and yesterday’s close on up days. 7 | //Sd represents the absolute value of the difference between today’s 8 | // close and yesterday’s close on down days. 9 | } 10 | } -------------------------------------------------------------------------------- /DotNet/QuantSys/QuantSys.csproj.user: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | publish\ 5 | 6 | 7 | 8 | 9 | 10 | en-US 11 | false 12 | 13 | -------------------------------------------------------------------------------- /DotNet/QuantSys/Visualization/TableGeneration.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.Web; 7 | using System.Web.UI.HtmlControls; 8 | 9 | namespace QuantSys.Visualization 10 | { 11 | class TableGeneration 12 | { 13 | HtmlTable table = new HtmlTable(); 14 | 15 | public HtmlTable Table 16 | { 17 | get { return table; } 18 | set { table = value; } 19 | } 20 | 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /DotNet/QuantSys/Visualization/Highstocks/ChartOption.cs: -------------------------------------------------------------------------------- 1 | namespace QuantSys.Visualization.Highstocks 2 | { 3 | public class ChartOption 4 | { 5 | public int YPosition { get; set; } 6 | public int Height { get; set; } 7 | public string ChartType { get; set; } 8 | public bool Layover { get; set; } 9 | public ChartOption() 10 | { 11 | YPosition = 0; 12 | Height = 200; 13 | ChartType = "spline"; 14 | Layover = false; 15 | } 16 | 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /DotNet/QuantSys/Analytics/DenseVectorExtension.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using MathNet.Numerics.LinearAlgebra.Double; 7 | 8 | namespace QuantSys.Analytics 9 | { 10 | public static class DenseVectorExtension 11 | { 12 | public static DenseVector SubVector(this DenseVector d, int startIndex, int endIndex) 13 | { 14 | return (DenseVector)d.SubVector(startIndex, d.Count - endIndex); 15 | } 16 | 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /DotNet/QuantSys/MachineLearning/GeneticAlgorithm/Genes/Constraints/GeneConstraint.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace QuantSys.MachineLearning.GeneticAlgorithm.Genes.Constraints 4 | { 5 | public class GeneConstraint 6 | { 7 | public Func ConstraintFunction { get; set; } 8 | 9 | public object HI { get; set; } 10 | 11 | public object LOW { get; set; } 12 | public GeneConstraint(Func constraintFunction) 13 | { 14 | ConstraintFunction = constraintFunction; 15 | } 16 | 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /DotNet/QuantSys/Visualization/Highstocks/HighstockFlag.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace QuantSys.Visualization.Highstocks 4 | { 5 | public class HighstockFlag 6 | { 7 | public string Shape { get; set; } 8 | public string Text { get; set; } 9 | public string Title { get; set; } 10 | public DateTime Date { get; set; } 11 | 12 | public HighstockFlag(string title, string text, DateTime date) 13 | { 14 | Title = title; 15 | Text = text; 16 | Date = date; 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /DotNet/QuantSys/TradeEngine/MarketInterface/FXCMInterface/EventArguments/AccountInformationEventArg.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using fxcore2; 3 | 4 | namespace QuantSys.TradeEngine.MarketInterface.FXCMInterface.EventArguments 5 | { 6 | public class AccountInformationEventArg : EventArgs 7 | { 8 | 9 | public AccountInformationEventArg() 10 | { 11 | 12 | } 13 | 14 | public static AccountInformationEventArg ProcessData(FXSession connection, O2GResponse response) 15 | { 16 | return new AccountInformationEventArg(); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /DotNet/QuantSys/TradeEngine/MarketInterface/FXCMInterface/Functions/Jobs/Job_IndicatorSet.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace QuantSys.TradeEngine.MarketInterface.FXCMInterface.Functions.Jobs 4 | { 5 | public class Job_IndicatorSet : IJob 6 | { 7 | public void RunJob(FXSession fxsession) 8 | { 9 | throw new NotImplementedException(); 10 | } 11 | 12 | public bool UpdateJob(object data) 13 | { 14 | throw new NotImplementedException(); 15 | } 16 | 17 | public void FinishAndProcess() 18 | { 19 | throw new NotImplementedException(); 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /DotNet/QuantSys/TradeEngine/MarketInterface/FXCMInterface/Functions/Jobs/Job_OptimalPortfolio.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace QuantSys.TradeEngine.MarketInterface.FXCMInterface.Functions.Jobs 4 | { 5 | internal class Job_OptimalPortfolio : IJob 6 | { 7 | public void RunJob(FXSession fxsession) 8 | { 9 | throw new NotImplementedException(); 10 | } 11 | 12 | public bool UpdateJob(object data) 13 | { 14 | throw new NotImplementedException(); 15 | } 16 | 17 | public void FinishAndProcess() 18 | { 19 | throw new NotImplementedException(); 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /DotNet/QuantSys/Analytics/Timeseries/Indicators/Misc/MFM.cs: -------------------------------------------------------------------------------- 1 | using QuantSys.Analytics.Timeseries.Indicators.Abstraction; 2 | using QuantSys.MarketData; 3 | 4 | namespace QuantSys.Analytics.Timeseries.Indicators.Misc 5 | { 6 | public class MFM : AbstractIndicator //Money Flow Multiplier 7 | { 8 | public MFM(int n) : base(n) 9 | { 10 | 11 | } 12 | 13 | public override double HandleNextTick(Tick t) 14 | { 15 | return ((t.BidClose - t.BidLow) - (t.BidHigh - t.BidClose))/(t.BidHigh - t.BidLow); 16 | } 17 | 18 | 19 | public override string ToString() 20 | { 21 | return "MFM"; 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /DotNet/QuantSys/Analytics/Timeseries/Indicators/SRLevels/PivotLevels.cs: -------------------------------------------------------------------------------- 1 | using QuantSys.Analytics.Timeseries.Indicators.Abstraction; 2 | using QuantSys.MarketData; 3 | 4 | namespace QuantSys.Analytics.Timeseries.Indicators.SRLevels 5 | { 6 | /// 7 | /// Pivot Point (P) = (High + Low + Close)/3 8 | /// Support 1 (S1) = (P x 2) - High 9 | /// Support 2 (S2) = P - (High - Low) 10 | /// Resistance 1 (R1) = (P x 2) - Low 11 | /// Resistance 2 (R2) = P + (High - Low) 12 | /// 13 | public class PivotLevels : AbstractPivotPoints 14 | { 15 | public PivotLevels(Timeframe.Period p) : base(p) 16 | { 17 | 18 | } 19 | 20 | 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /DotNet/QuantSys/TradeEngine/Simulation/Performance/TradeRecord.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using QuantSys.MarketData; 3 | using QuantSys.TradeEngine.Simulation.Account; 4 | 5 | namespace QuantSys.TradeEngine.Simulation.Performance 6 | { 7 | 8 | 9 | public class TradeRecord 10 | { 11 | 12 | public Symbol Symbol { get; set; } 13 | public DateTime TransactionDate { get; set; } 14 | public Position.PositionSide PositionTaken { get; set; } 15 | public bool IsStop { get; set; } 16 | public bool IsLimit { get; set; } 17 | public double TradeSize { get; set; } 18 | public double TradePrice { get; set; } 19 | public bool OpenOrClose { get; set; } 20 | public double PNL { get; set; } 21 | 22 | 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | QuantSys 2 | ======== 3 | A C# platform for designing, simulating, and trading algorithms. 4 | 5 | V0.1 - First commit. Included Packages: 6 | 7 | - Analytics: statistical modelling, signal processing, technical indicator calculation 8 | - MachineLearning: genetic algorithm, experimentation with neural networks 9 | - MarketData: Generic classes for manipulation of time series data 10 | - TradeEngine: 11 | -AccountManagement: Managing trade accounts (simulated and live) 12 | -Strategy: Structure for executing algorithms. Includes various strategies in progress 13 | -MarketInterface: Interface to Broker 14 | -Simulation: Engine for backtesting and performance measurements 15 | -Visualization: For integration with Highcharts and Highstocks in order to visualize data 16 | -------------------------------------------------------------------------------- /DotNet/QuantSys/Analytics/Timeseries/Indicators/Misc/GenericContainer.cs: -------------------------------------------------------------------------------- 1 | using QuantSys.Analytics.Timeseries.Indicators.Abstraction; 2 | using QuantSys.MarketData; 3 | 4 | namespace QuantSys.Analytics.Timeseries.Indicators.Misc 5 | { 6 | public class GenericContainer : AbstractIndicator 7 | { 8 | public GenericContainer(int n) : base(n) 9 | { 10 | 11 | } 12 | public override double HandleNextTick(Tick t) 13 | { 14 | return HandleNextTick(t.BidClose); 15 | } 16 | 17 | public double HandleNextTick(double d) 18 | { 19 | indicatorData.Enqueue(d); 20 | return d; 21 | } 22 | public override string ToString() 23 | { 24 | return "Container"; 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /DotNet/QuantSys/TradeEngine/AccountManagement/IAccountManager.cs: -------------------------------------------------------------------------------- 1 | using QuantSys.MarketData; 2 | using QuantSys.TradeEngine.Simulation.Account; 3 | 4 | namespace QuantSys.TradeEngine.AccountManagement 5 | { 6 | public interface IAccountManager 7 | { 8 | 9 | 10 | void PlaceMarketOrder(Symbol sym, int size, Position.PositionSide side, double stopPips = double.NaN, double LimitPips = double.NaN); 11 | 12 | void ModifyStopOrder(); 13 | 14 | void SetTrailingStop(); 15 | 16 | void PlaceStopOrder(); 17 | 18 | bool ExistsPositionForSymbol(Symbol s); 19 | 20 | bool ExistsLongPositionForSymbol(Symbol s); 21 | 22 | bool ExistsShortPositionForSymbol(Symbol s); 23 | 24 | void ClosePosition(Symbol s); 25 | 26 | //void increasePosition; 27 | 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /DotNet/QuantSys/TradeEngine/Simulation/Account/Order/MarketOrder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using QuantSys.MarketData; 3 | 4 | namespace QuantSys.TradeEngine.Simulation.Account.Order 5 | { 6 | public class MarketOrder 7 | { 8 | public MarketOrder(Tick t, Position.PositionSide side, double orderSize) 9 | { 10 | Symbol = t.Symbol; 11 | Side = side; 12 | Price = (side.Equals(Position.PositionSide.Long)) ? t.AskClose : t.BidClose; 13 | Size = orderSize; 14 | OrderDate = t.Time; 15 | } 16 | 17 | public Symbol Symbol { get; set; } 18 | public Position.PositionSide Side { get; set; } 19 | public double Price { get; set; } 20 | public double Size { get; set; } 21 | public DateTime OrderDate { get; set; } 22 | } 23 | } -------------------------------------------------------------------------------- /DotNet/QuantSys/Analytics/Timeseries/Indicators/Channels/GannHiLo.cs: -------------------------------------------------------------------------------- 1 | using QuantSys.Analytics.Timeseries.Indicators.Abstraction; 2 | using QuantSys.Analytics.Timeseries.Indicators.Averages; 3 | using QuantSys.MarketData; 4 | 5 | namespace QuantSys.Analytics.Timeseries.Indicators.Channels 6 | { 7 | public class GannHiLo: AbstractIndicator 8 | { 9 | public SMA SMAHi; 10 | public SMA SMALow; 11 | public GannHiLo(int n) : base(n) 12 | { 13 | SMAHi = new SMA(n); 14 | SMALow = new SMA(n); 15 | } 16 | 17 | public override double HandleNextTick(Tick t) 18 | { 19 | SMAHi.HandleNextTick(t.BidHigh); 20 | SMALow.HandleNextTick(t.BidLow); 21 | 22 | return SMALow[0]; 23 | } 24 | 25 | public override string ToString() 26 | { 27 | return "GannHiLo" + Period; 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /DotNet/QuantSys/MachineLearning/GeneticAlgorithm/Genes/Gene.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using QuantSys.MachineLearning.GeneticAlgorithm.Genes.Constraints; 3 | 4 | namespace QuantSys.MachineLearning.GeneticAlgorithm.Genes 5 | { 6 | /// 7 | /// Represents an abstraction of a Gene. Must be implemented by 8 | /// a Gene type such as RealCodedGene. 9 | /// 10 | public abstract class Gene 11 | { 12 | //public object GeneValue { get; set; } 13 | 14 | protected Random _randomSeed; 15 | public GeneConstraint GeneConstraint { get; set; } 16 | public Gene(Random r) 17 | { 18 | _randomSeed = r; 19 | } 20 | 21 | public abstract bool WithinConstraints(); 22 | public abstract void InitializeGene(); 23 | public abstract bool Mutate(double mRate); 24 | public abstract override string ToString(); 25 | public abstract void Crossover(Gene gene2, out Gene child1, out Gene child2); 26 | public abstract Gene Clone(); 27 | 28 | } 29 | } -------------------------------------------------------------------------------- /DotNet/QuantSys/Analytics/Timeseries/Indicators/Misc/ForceIndex.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using QuantSys.Analytics.Timeseries.Indicators.Abstraction; 3 | using QuantSys.Analytics.Timeseries.Indicators.Averages; 4 | using QuantSys.MarketData; 5 | 6 | namespace QuantSys.Analytics.Timeseries.Indicators.Misc 7 | { 8 | public class ForceIndex: AbstractIndicator 9 | { 10 | private EMA EMA; 11 | private Tick prevTick; 12 | public ForceIndex(int n) : base(n) 13 | { 14 | EMA = new EMA(n); 15 | } 16 | public override double HandleNextTick(Tick t) 17 | { 18 | double value = Double.NaN; 19 | 20 | if (prevTick != null) 21 | { 22 | value = EMA.HandleNextTick(t.Volume*(t.BidClose - prevTick.BidClose)); 23 | } 24 | 25 | prevTick = t; 26 | indicatorData.Enqueue(value); 27 | return value; 28 | } 29 | 30 | public override string ToString() 31 | { 32 | return "Force Index" + Period; 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /DotNet/QuantSys/Analytics/Timeseries/Indicators/Misc/Covariance.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using QuantSys.Analytics.Timeseries.Indicators.Abstraction; 7 | using QuantSys.MarketData; 8 | 9 | namespace QuantSys.Analytics.Timeseries.Indicators.Misc 10 | { 11 | class Covariance: AbstractMultiSymbolIndicator 12 | { 13 | 14 | public Covariance(int n) : base(n) 15 | { 16 | 17 | } 18 | 19 | public override double HandleNextTicks(Tick[] t) 20 | { 21 | foreach (Tick tick in t) 22 | { 23 | if (!subIndicators.ContainsKey(tick.Symbol.SymbolString)) 24 | { 25 | subIndicators.Add(tick.Symbol.SymbolString, new GenericContainer(Period)); 26 | } 27 | 28 | 29 | } 30 | return 0; 31 | 32 | } 33 | 34 | public override string ToString() 35 | { 36 | return "Covariance"; 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /DotNet/QuantSys/Util/DateTimeUtils.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace QuantSys.Util 4 | { 5 | public class DateTimeUtils 6 | { 7 | public static TimeSpan TimeFrameToTimeSpan(string timeframe) 8 | { 9 | switch (timeframe) 10 | { 11 | case "m1": 12 | return new TimeSpan(0, 1, 0); 13 | case "m5": 14 | return new TimeSpan(0, 5, 0); 15 | case "m15": 16 | return new TimeSpan(0, 15, 0); 17 | case "m30": 18 | return new TimeSpan(0, 30, 0); 19 | case "H1": 20 | return new TimeSpan(1, 0, 0); 21 | default: 22 | return new TimeSpan(1, 0, 0); 23 | } 24 | } 25 | 26 | public static double[] ReverseArray(double[] array) 27 | { 28 | var reverse = new double[array.Length]; 29 | for (int i = array.Length - 1; i >= 0; i--) reverse[array.Length - 1 - i] = array[i]; 30 | return reverse; 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /DotNet/QuantSys/Analytics/Timeseries/Indicators/Abstraction/AbstractAverage.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using QuantSys.DataStructures; 3 | using QuantSys.MarketData; 4 | 5 | namespace QuantSys.Analytics.Timeseries.Indicators.Abstraction 6 | { 7 | public abstract class AbstractAverage 8 | { 9 | 10 | public double this[int index] 11 | { 12 | get { return (averageData.Count > index) ? averageData.ToArray()[averageData.Count - index - 1] : double.NaN; } 13 | } 14 | 15 | 16 | protected MovingQueue averageData; 17 | protected AbstractIndicator indicator; 18 | 19 | public int Period; 20 | 21 | protected AbstractAverage(int n) 22 | { 23 | averageData = new MovingQueue(n); 24 | Period = n; 25 | } 26 | 27 | public double[] ToArray() 28 | { 29 | return averageData.ToArray(); 30 | } 31 | 32 | public abstract double HandleNextTick(Tick t); 33 | 34 | //public abstract double Peek(Tick t); 35 | public abstract override string ToString(); 36 | 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /DotNet/QuantSys/Analytics/Timeseries/Indicators/Misc/HurstIndicator.cs: -------------------------------------------------------------------------------- 1 | using QuantSys.Analytics.StatisticalModeling; 2 | using QuantSys.Analytics.Timeseries.Indicators.Abstraction; 3 | using QuantSys.DataStructures; 4 | using QuantSys.MarketData; 5 | 6 | namespace QuantSys.Analytics.Timeseries.Indicators.Misc 7 | { 8 | public class HurstIndicator : AbstractIndicator 9 | { 10 | private MovingQueue priceData; 11 | public HurstIndicator(int n) : base(n) 12 | { 13 | priceData = new MovingQueue(n); 14 | } 15 | 16 | public override double HandleNextTick(Tick t) 17 | { 18 | priceData.Enqueue(t.BidClose); 19 | 20 | double value = double.NaN; 21 | if (priceData.Count.Equals(priceData.Capacity)) 22 | { 23 | value = HurstEstimation.CalculateHurstEstimate(priceData.ToArray()); 24 | } 25 | indicatorData.Enqueue(value); 26 | return value; 27 | } 28 | 29 | public override string ToString() 30 | { 31 | return "Hurst"; 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /DotNet/QuantSys/Analytics/Timeseries/Indicators/Channels/QSVWChannel.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using QuantSys.Analytics.Timeseries.Indicators.Abstraction; 3 | using QuantSys.Analytics.Timeseries.Indicators.Averages; 4 | using QuantSys.DataStructures; 5 | using QuantSys.MarketData; 6 | 7 | namespace QuantSys.Analytics.Timeseries.Indicators.Channels 8 | { 9 | public class QSVWChannel : AbstractChannel 10 | { 11 | private EMA EMA; 12 | private MovingQueue LRValues; 13 | private double[] X; 14 | private double STDEV; 15 | 16 | public QSVWChannel(int n = 20, int l = 30, double dev = 1.5) 17 | : base(n) 18 | { 19 | EMA = new EMA(n); 20 | LRValues = new MovingQueue(l); 21 | X = new double[l]; 22 | for (int i = 0; i < X.Count(); i++) X[i] = i; 23 | STDEV = dev; 24 | } 25 | 26 | public override void HandleNextTick(Tick t) 27 | { 28 | 29 | } 30 | 31 | public override string ToString() 32 | { 33 | return "QSPoly Bands" + Period; 34 | } 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /DotNet/QuantSys/MachineLearning/GeneticAlgorithm/Crossover.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using QuantSys.MachineLearning.GeneticAlgorithm.Genes; 5 | 6 | namespace QuantSys.MachineLearning.GeneticAlgorithm 7 | { 8 | public static class Crossover 9 | { 10 | 11 | public static Population BinaryCrossover(Chromosome x1, Chromosome x2, Random r) 12 | { 13 | var genelist1 = new List(); 14 | var genelist2 = new List(); 15 | 16 | //for each gene in the chromosomes, we crossover 17 | for (int i = 0; i < x1.Count(); i++) 18 | { 19 | Gene c1, c2; 20 | x1[i].Crossover(x2[i], out c1, out c2); 21 | genelist1.Add(c1); 22 | genelist2.Add(c2); 23 | } 24 | 25 | var x1_t = new Chromosome(genelist1); 26 | var x2_t = new Chromosome(genelist2); 27 | 28 | var l1 = new List(); 29 | l1.Add(x1_t); 30 | l1.Add(x2_t); 31 | 32 | return new Population(l1); 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /DotNet/QuantSys/TradeEngine/Simulation/Account/Order/LimitOrder.cs: -------------------------------------------------------------------------------- 1 | using QuantSys.MarketData; 2 | 3 | namespace QuantSys.TradeEngine.Simulation.Account.Order 4 | { 5 | public class LimitOrder 6 | { 7 | public Position.PositionSide Side { get; set; } 8 | public double TriggerPrice { get; set; } 9 | public bool Trailing { get; set; } 10 | public Symbol Symbol { get; set; } 11 | 12 | public double TrailSize { get; set; } 13 | 14 | public LimitOrder(Symbol s, Position.PositionSide side, double price, bool trailing = false, double trailsize = 0) 15 | { 16 | Symbol = s; 17 | TriggerPrice = price; 18 | Side = side; 19 | Trailing = trailing; 20 | TrailSize = trailsize; 21 | } 22 | 23 | public void RecalculateTrail(Tick t) 24 | { 25 | 26 | } 27 | 28 | public bool IsBuyLimit() 29 | { 30 | return Side.Equals(Position.PositionSide.Long); 31 | } 32 | 33 | public bool IsSellLimit() 34 | { 35 | return Side.Equals(Position.PositionSide.Short); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /DotNet/QuantSys/Analytics/Timeseries/Indicators/Oscillators/AC.cs: -------------------------------------------------------------------------------- 1 | using QuantSys.Analytics.Timeseries.Indicators.Abstraction; 2 | using QuantSys.Analytics.Timeseries.Indicators.Averages; 3 | using QuantSys.MarketData; 4 | 5 | namespace QuantSys.Analytics.Timeseries.Indicators.Oscillators 6 | { 7 | 8 | /// 9 | /// AC = AO-SMA(AO, 5) 10 | /// 11 | 12 | public class AC : AbstractIndicator 13 | { 14 | 15 | private SMA SMA; 16 | private AO AO; 17 | 18 | public AC():this(5){} 19 | 20 | public AC(int n = 5, int y = 5, int z = 34) : base(n) 21 | { 22 | SMA = new SMA(n); 23 | AO = new AO(y, z); 24 | } 25 | 26 | public override double HandleNextTick(Tick t) 27 | { 28 | double value = double.NaN; 29 | double aonext = AO.HandleNextTick(t); 30 | double smanext = SMA.HandleNextTick(aonext); 31 | 32 | value = aonext - smanext; 33 | indicatorData.Enqueue(value); 34 | return value; 35 | } 36 | 37 | public override string ToString() 38 | { 39 | return "AC" + Period; 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /DotNet/QuantSys/Analytics/Timeseries/Indicators/Channels/BollingerBands.cs: -------------------------------------------------------------------------------- 1 | using QuantSys.Analytics.StatisticalModeling; 2 | using QuantSys.Analytics.Timeseries.Indicators.Abstraction; 3 | using QuantSys.Analytics.Timeseries.Indicators.Averages; 4 | using QuantSys.MarketData; 5 | 6 | namespace QuantSys.Analytics.Timeseries.Indicators.Channels 7 | { 8 | /// 9 | /// Middle Band = 20-day simple moving average (SMA) 10 | /// Upper Band = 20-day SMA + (20-day standard deviation of price x 2) 11 | /// Lower Band = 20-day SMA - (20-day standard deviation of price x 2) 12 | /// 13 | class BollingerBands : AbstractChannel 14 | { 15 | private SMA MIDDLE; 16 | public BollingerBands(int n = 20): base(n) 17 | { 18 | MIDDLE = new SMA(n); 19 | } 20 | 21 | public override void HandleNextTick(Tick t) 22 | { 23 | MiddleData.Enqueue(MIDDLE.HandleNextTick(t)); 24 | var stdev = MIDDLE.ToArray().StandardDeviation(); 25 | HighData.Enqueue(MIDDLE[0] + stdev * 2); 26 | LowData.Enqueue(MIDDLE[0] - stdev * 2); 27 | } 28 | 29 | public override string ToString() 30 | { 31 | return "Bollinger Bands" + Period; 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /DotNet/QuantSys/DataStructures/MovingQueue.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | 4 | namespace QuantSys.DataStructures 5 | { 6 | public class MovingQueue : IEnumerable 7 | { 8 | public int Count {get { return _queueData.Count; }} 9 | public int Capacity {get { return _capacity; }} 10 | public Queue Data { get { return _queueData; } } 11 | 12 | 13 | private Queue _queueData; 14 | private readonly int _capacity; 15 | 16 | public MovingQueue(int capacity) 17 | { 18 | _queueData = new Queue(capacity); 19 | _capacity = capacity; 20 | } 21 | 22 | public void Enqueue(T item) 23 | { 24 | 25 | if (_queueData.Count >= _capacity) 26 | { 27 | _queueData.Dequeue(); 28 | } 29 | 30 | _queueData.Enqueue(item); 31 | } 32 | 33 | public T[] ToArray() 34 | { 35 | return _queueData.ToArray(); 36 | } 37 | 38 | public IEnumerator GetEnumerator() 39 | { 40 | return _queueData.GetEnumerator(); 41 | } 42 | 43 | IEnumerator IEnumerable.GetEnumerator() 44 | { 45 | return GetEnumerator(); 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /DotNet/QuantSys/Analytics/Timeseries/Indicators/Misc/HistoricalVol.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using QuantSys.Analytics.StatisticalModeling; 3 | using QuantSys.Analytics.Timeseries.Indicators.Abstraction; 4 | using QuantSys.DataStructures; 5 | using QuantSys.MarketData; 6 | 7 | namespace QuantSys.Analytics.Timeseries.Indicators.Misc 8 | { 9 | public class HistoricalVol : AbstractIndicator 10 | { 11 | private double prevTick; 12 | private MovingQueue returnsData; 13 | private MovingQueue volData; 14 | private int n; 15 | 16 | public HistoricalVol(int n) : base(n) 17 | { 18 | returnsData = new MovingQueue(n); 19 | prevTick = double.NaN; 20 | } 21 | 22 | public string Indicator { get { return "Historical Vol" + n; }} 23 | 24 | public override double HandleNextTick(Tick t) 25 | { 26 | returnsData.Enqueue((t.BidClose-prevTick)/prevTick); 27 | double value = returnsData.ToArray().StandardDeviation(); 28 | indicatorData.Enqueue(value); 29 | 30 | prevTick = t.BidClose; 31 | return value; 32 | } 33 | 34 | 35 | public override string ToString() 36 | { 37 | throw new NotImplementedException(); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /DotNet/QuantSys/Analytics/Timeseries/Indicators/Oscillators/AO.cs: -------------------------------------------------------------------------------- 1 | using QuantSys.Analytics.Timeseries.Indicators.Abstraction; 2 | using QuantSys.Analytics.Timeseries.Indicators.Averages; 3 | using QuantSys.MarketData; 4 | 5 | namespace QuantSys.Analytics.Timeseries.Indicators.Oscillators 6 | { 7 | 8 | /// 9 | /// MEDIAN PRICE = (HIGH+LOW)/2 10 | /// AO = SMA(MEDIAN PRICE, 5)-SMA(MEDIAN PRICE, 34) 11 | /// 12 | public class AO : AbstractIndicator 13 | { 14 | private SMA SMA1; 15 | private SMA SMA2; 16 | 17 | public AO() : this(5, 34){} 18 | 19 | public AO(int p1 = 5, int p2 = 34) : base(p2) 20 | { 21 | SMA1 = new SMA(p1); 22 | SMA2 = new SMA(p2); 23 | } 24 | 25 | public override double HandleNextTick(Tick t) 26 | { 27 | double value = double.NaN; 28 | value = SMA1[0] - SMA2[0]; 29 | indicatorData.Enqueue(value); 30 | 31 | double MEDIANPRICE = (t.BidHigh + t.BidLow)/2; 32 | SMA1.HandleNextTick(MEDIANPRICE); 33 | SMA2.HandleNextTick(MEDIANPRICE); 34 | 35 | return value; 36 | } 37 | 38 | public override string ToString() 39 | { 40 | return "AO" + Period; 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /DotNet/QuantSys/Analytics/Timeseries/Indicators/Misc/CrossoverIndex.cs: -------------------------------------------------------------------------------- 1 | using QuantSys.Analytics.Timeseries.Indicators.Abstraction; 2 | using QuantSys.Analytics.Timeseries.Indicators.Averages; 3 | using QuantSys.MarketData; 4 | 5 | namespace QuantSys.Analytics.Timeseries.Indicators.Misc 6 | { 7 | public class CrossoverIndex : AbstractIndicator 8 | { 9 | private QSPolyMA POLYMA; 10 | private SMA SMA; 11 | public CrossoverIndex(int n) : base(n) 12 | { 13 | POLYMA = new QSPolyMA(n); 14 | SMA = new SMA(n); 15 | } 16 | 17 | 18 | public override double HandleNextTick(Tick t) 19 | { 20 | POLYMA.HandleNextTick(t); 21 | SMA.HandleNextTick(t); 22 | 23 | double[] a = POLYMA.ToArray(); 24 | double[] b = SMA.ToArray(); 25 | double value = 0; 26 | 27 | for (int i = 1; i < a.Length; i++) 28 | { 29 | if (a[i] > b[i] && a[i - 1] < b[i - 1]) value++; 30 | if (a[i] < b[i] && a[i - 1] > b[i - 1]) value++; 31 | } 32 | 33 | indicatorData.Enqueue(value); 34 | return value; 35 | } 36 | 37 | public override string ToString() 38 | { 39 | return "CrossNumber" + Period; 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /DotNet/QuantSys/Analytics/Timeseries/Indicators/Misc/ROC.cs: -------------------------------------------------------------------------------- 1 | using QuantSys.Analytics.Timeseries.Indicators.Abstraction; 2 | using QuantSys.DataStructures; 3 | using QuantSys.MarketData; 4 | 5 | namespace QuantSys.Analytics.Timeseries.Indicators.Misc 6 | { 7 | public class ROC : AbstractIndicator 8 | { 9 | private readonly MovingQueue tickData; 10 | private AbstractIndicator indicator; 11 | public ROC(int n, AbstractIndicator indicator = null) : base(n) 12 | { 13 | tickData = new MovingQueue(n); 14 | this.indicator = indicator; 15 | } 16 | 17 | public override double HandleNextTick(Tick t) 18 | { 19 | if (indicator != null) return HandleNextTick(indicator.HandleNextTick(t)); 20 | return HandleNextTick(t.BidClose); 21 | } 22 | 23 | public double HandleNextTick(double d) 24 | { 25 | double value = double.NaN; 26 | tickData.Enqueue(d); 27 | if (tickData.Count >= Period) 28 | value = (d - tickData.ToArray()[1]) / tickData.ToArray()[1]; 29 | 30 | indicatorData.Enqueue(value); 31 | return value; 32 | } 33 | 34 | public override string ToString() 35 | { 36 | return "ROC" + Period; 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /DotNet/QuantSys/Analytics/Timeseries/Indicators/Averages/GDEMA.cs: -------------------------------------------------------------------------------- 1 | using QuantSys.Analytics.Timeseries.Indicators.Abstraction; 2 | using QuantSys.MarketData; 3 | 4 | namespace QuantSys.Analytics.Timeseries.Indicators.Averages 5 | { 6 | public class GDEMA : AbstractIndicator 7 | { 8 | private EMA EMA1; 9 | private EMA EMA2; 10 | 11 | private AbstractIndicator indicator; 12 | private double v; 13 | 14 | public GDEMA(int n, double v = 1, AbstractIndicator indicator = null) : base(n) 15 | { 16 | EMA1 = new EMA(n); 17 | EMA2 = new EMA(n); 18 | this.indicator = indicator; 19 | } 20 | 21 | public override double HandleNextTick(Tick t) 22 | { 23 | if (indicator != null) return HandleNextTick(indicator.HandleNextTick(t)); 24 | return HandleNextTick(t.BidClose); 25 | } 26 | 27 | public double HandleNextTick(double d) 28 | { 29 | double value = double.NaN; 30 | 31 | double v1 = EMA1.HandleNextTick(d); 32 | double v2 = EMA2.HandleNextTick(v1); 33 | 34 | value = (1 + v) * v1 - (v * v2); 35 | indicatorData.Enqueue(value); 36 | return value; 37 | } 38 | 39 | public override string ToString() 40 | { 41 | return "GDEMA" + Period; 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /DotNet/QuantSys/Analytics/Timeseries/Indicators/Abstraction/AbstractChannel.cs: -------------------------------------------------------------------------------- 1 | using QuantSys.DataStructures; 2 | using QuantSys.MarketData; 3 | 4 | namespace QuantSys.Analytics.Timeseries.Indicators.Abstraction 5 | { 6 | public abstract class AbstractChannel 7 | { 8 | public double HI(int index){ 9 | return (HighData.Count > index) ? HighData.ToArray()[HighData.Count - index - 1] : double.NaN; 10 | } 11 | public double LOW(int index) 12 | { 13 | return (LowData.Count > index) ? LowData.ToArray()[LowData.Count - index - 1] : double.NaN; 14 | } 15 | public double MID(int index) 16 | { 17 | return (MiddleData.Count > index) ? MiddleData.ToArray()[MiddleData.Count - index - 1] : double.NaN; 18 | } 19 | 20 | protected MovingQueue HighData; 21 | protected MovingQueue MiddleData; 22 | protected MovingQueue LowData; 23 | 24 | public int Period; 25 | protected AbstractChannel(int n) 26 | { 27 | HighData = new MovingQueue(n); 28 | MiddleData = new MovingQueue(n); 29 | LowData = new MovingQueue(n); 30 | Period = n; 31 | } 32 | 33 | public abstract void HandleNextTick(Tick t); 34 | 35 | public abstract override string ToString(); 36 | 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /DotNet/QuantSys/Analytics/Timeseries/Indicators/Abstraction/AbstractIndicator.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using QuantSys.DataStructures; 3 | using QuantSys.MarketData; 4 | 5 | namespace QuantSys.Analytics.Timeseries.Indicators.Abstraction 6 | { 7 | public abstract class AbstractIndicator 8 | { 9 | public double this[int index] 10 | { 11 | get { return (indicatorData.Count > index) ? indicatorData.ToArray()[indicatorData.Count - index - 1] : double.NaN; } 12 | } 13 | 14 | public int SubIndicatorSize{get { return subIndicators.Count; }} 15 | public Dictionary SubIndicators { get { return subIndicators; } } 16 | protected Dictionary subIndicators; 17 | 18 | 19 | protected MovingQueue indicatorData; 20 | public int Period; 21 | 22 | protected AbstractIndicator(int n) 23 | { 24 | subIndicators = new Dictionary(); 25 | indicatorData = new MovingQueue(n); 26 | Period = n; 27 | } 28 | 29 | public double[] ToArray() 30 | { 31 | return indicatorData.ToArray(); 32 | } 33 | 34 | public abstract double HandleNextTick(Tick t); 35 | 36 | //public abstract double Peek(Tick t); 37 | 38 | public abstract override string ToString(); 39 | 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /DotNet/QuantSys/Analytics/Timeseries/Indicators/Averages/AdaptiveSmoothing.cs: -------------------------------------------------------------------------------- 1 | using QuantSys.Analytics.Timeseries.Indicators.Abstraction; 2 | using QuantSys.MarketData; 3 | 4 | namespace QuantSys.Analytics.Timeseries.Indicators.Averages 5 | { 6 | public class AdaptiveSmoothing : AbstractIndicator 7 | { 8 | private GDEMA[] GDS; 9 | private AbstractIndicator indicator; 10 | 11 | public AdaptiveSmoothing(int n, double v = 0.7, int t = 3, AbstractIndicator indicator = null) 12 | : base(n) 13 | { 14 | this.indicator = indicator; 15 | GDS = new GDEMA[t]; 16 | for(int i = 0 ; i < t; i++) GDS[i] = new GDEMA(n, v, indicator); 17 | } 18 | 19 | public override double HandleNextTick(Tick t) 20 | { 21 | if (indicator != null) return HandleNextTick(indicator.HandleNextTick(t)); 22 | return HandleNextTick(t.BidClose); 23 | } 24 | 25 | public double HandleNextTick(double d) 26 | { 27 | double value = double.NaN; 28 | 29 | for (int i = 1; i < GDS.Length; i++) 30 | { 31 | value = GDS[i].HandleNextTick(GDS[i - 1].HandleNextTick(d)); 32 | } 33 | 34 | indicatorData.Enqueue(value); 35 | return value; 36 | } 37 | 38 | public override string ToString() 39 | { 40 | return "T" + GDS.Length; 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /DotNet/QuantSys/Analytics/Timeseries/Indicators/Oscillators/CCI.cs: -------------------------------------------------------------------------------- 1 | using QuantSys.Analytics.StatisticalModeling; 2 | using QuantSys.Analytics.Timeseries.Indicators.Abstraction; 3 | using QuantSys.Analytics.Timeseries.Indicators.Averages; 4 | using QuantSys.DataStructures; 5 | using QuantSys.MarketData; 6 | 7 | namespace QuantSys.Analytics.Timeseries.Indicators.Oscillators 8 | { 9 | public class CCI : AbstractIndicator 10 | { 11 | private SMA SMA; 12 | private double constant; 13 | private MovingQueue priceData; 14 | 15 | public CCI(int n = 20, double constant = 0.015) : base(n) 16 | { 17 | SMA = new SMA(n); 18 | priceData = new MovingQueue(n); 19 | this.constant = constant; 20 | } 21 | 22 | public override double HandleNextTick(Tick t) 23 | { 24 | double value = double.NaN; 25 | 26 | double typicalPrice = (t.BidClose + t.BidHigh + t.BidLow)/3; 27 | priceData.Enqueue(typicalPrice); 28 | SMA.HandleNextTick(typicalPrice); 29 | 30 | if(priceData.Capacity.Equals(priceData.Count)) 31 | value = (1/constant)*(typicalPrice - SMA[0])/priceData.ToArray().StandardDeviation(); 32 | 33 | indicatorData.Enqueue(value); 34 | return value; 35 | } 36 | public override string ToString() 37 | { 38 | return "CCI" + Period; 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /DotNet/QuantSys/TradeEngine/Strategy/MACrossExit.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using QuantSys.MarketData; 7 | using QuantSys.PortfolioEngine; 8 | using QuantSys.PortfolioEngine.Order; 9 | using QuantSys.Analytics.Indicators; 10 | 11 | namespace QuantSys.Strategy 12 | { 13 | public class MACrossExit : AbstractStrategy, IStrategy 14 | { 15 | 16 | private AccountManager _am; 17 | public AccountManager AccountManager { get { return _am; } set { _am = value; } } 18 | 19 | private ExponentialMovingAverage EMA1 = new ExponentialMovingAverage(5); 20 | private ExponentialMovingAverage EMA2 = new ExponentialMovingAverage(30); 21 | 22 | 23 | public MACrossExit(int p1, int p2) 24 | : base() 25 | { 26 | EMA1 = new ExponentialMovingAverage(p1); 27 | EMA2 = new ExponentialMovingAverage(p2); 28 | } 29 | 30 | public void OnTick(params Tick[] t) 31 | { 32 | EMA1.HandleNextTick(t[0].AskClose); 33 | EMA2.HandleNextTick(t[0].AskClose); 34 | 35 | if (EMA1[0] > EMA2[0] && EMA1[1] < EMA2[1] && _am.ExistsPositionForSymbol(t[0].Symbol)) 36 | { 37 | _am.CloseOrder(t[0]); 38 | //Console.WriteLine("Close short Trade at " + t[0].AskClose); 39 | } 40 | 41 | 42 | } 43 | 44 | 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /DotNet/QuantSys/Analytics/Timeseries/Indicators/Abstraction/AbstractMultiSymbolIndicator.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using QuantSys.DataStructures; 3 | using QuantSys.MarketData; 4 | 5 | namespace QuantSys.Analytics.Timeseries.Indicators.Abstraction 6 | { 7 | public abstract class AbstractMultiSymbolIndicator 8 | { 9 | public double this[int index] 10 | { 11 | get { return (indicatorData.Count > index) ? indicatorData.ToArray()[indicatorData.Count - index - 1] : double.NaN; } 12 | } 13 | 14 | public int SubIndicatorSize { get { return subIndicators.Count; } } 15 | public Dictionary SubIndicators { get { return subIndicators; } } 16 | protected Dictionary subIndicators; 17 | 18 | 19 | protected MovingQueue indicatorData; 20 | public int Period; 21 | 22 | protected AbstractMultiSymbolIndicator(int n) 23 | { 24 | subIndicators = new Dictionary(); 25 | indicatorData = new MovingQueue(n); 26 | Period = n; 27 | } 28 | 29 | public double[] ToArray() 30 | { 31 | return indicatorData.ToArray(); 32 | } 33 | 34 | public abstract double HandleNextTicks(Tick[] t); 35 | 36 | //public abstract double Peek(Tick t); 37 | 38 | public abstract override string ToString(); 39 | 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /DotNet/QuantSys/Analytics/Timeseries/Indicators/Averages/TEMA.cs: -------------------------------------------------------------------------------- 1 | using QuantSys.Analytics.Timeseries.Indicators.Abstraction; 2 | using QuantSys.MarketData; 3 | 4 | namespace QuantSys.Analytics.Timeseries.Indicators.Averages 5 | { 6 | public class TEMA : AbstractIndicator 7 | { 8 | private EMA EMA1; 9 | private EMA EMA2; 10 | private EMA EMA3; 11 | 12 | private AbstractIndicator indicator; 13 | 14 | public TEMA(int n, AbstractIndicator indicator = null) 15 | : base(n) 16 | { 17 | EMA1 = new EMA(n); 18 | EMA2 = new EMA(n); 19 | EMA3 = new EMA(n); 20 | this.indicator = indicator; 21 | } 22 | 23 | public override double HandleNextTick(Tick t) 24 | { 25 | if (indicator != null) return HandleNextTick(indicator.HandleNextTick(t)); 26 | return HandleNextTick(t.BidClose); 27 | } 28 | 29 | public double HandleNextTick(double d) 30 | { 31 | double value = double.NaN; 32 | 33 | double v1 = EMA1.HandleNextTick(d); 34 | double v2 = EMA2.HandleNextTick(v1); 35 | double v3 = EMA3.HandleNextTick(v2); 36 | 37 | value = 3 * v1 - 3 * v2 + v3; 38 | indicatorData.Enqueue(value); 39 | return value; 40 | } 41 | 42 | public override string ToString() 43 | { 44 | return "TEMA" + Period; 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /DotNet/QuantSys/TradeEngine/Strategy/AbstractStrategy.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using QuantSys.Analytics.Timeseries.Indicators.Abstraction; 3 | using QuantSys.MarketData; 4 | using QuantSys.TradeEngine.AccountManagement; 5 | 6 | namespace QuantSys.TradeEngine.Strategy 7 | { 8 | public abstract class AbstractStrategy 9 | { 10 | public const double DEFAULT_LOT_SIZE = 10000; 11 | 12 | 13 | public Dictionary indicatorList; 14 | public Dictionary channelList; 15 | 16 | public bool IsLive { get; set; } 17 | 18 | protected IAccountManager IAccountManager; 19 | //protected IIAccountManager IAccountManager {get;set;} 20 | public void SetAccountManager(IAccountManager am) 21 | { 22 | this.IAccountManager = am; 23 | } 24 | public AbstractStrategy() 25 | { 26 | indicatorList = new Dictionary(); 27 | } 28 | 29 | protected void AttachIndicator(string indicatorName, AbstractIndicator i) 30 | { 31 | indicatorList.Add(indicatorName, i); 32 | } 33 | 34 | protected void AttachChannel(string indicatorName, AbstractChannel i) 35 | { 36 | channelList.Add(indicatorName, i); 37 | } 38 | 39 | public abstract void OnTick(params Tick[] t); 40 | 41 | //public abstract void OnPeek(params Tick[] t); 42 | 43 | 44 | } 45 | 46 | } -------------------------------------------------------------------------------- /DotNet/QuantSys/Analytics/Timeseries/Indicators/Averages/SMA.cs: -------------------------------------------------------------------------------- 1 | using QuantSys.Analytics.StatisticalModeling; 2 | using QuantSys.Analytics.Timeseries.Indicators.Abstraction; 3 | using QuantSys.DataStructures; 4 | using QuantSys.MarketData; 5 | 6 | namespace QuantSys.Analytics.Timeseries.Indicators.Averages 7 | { 8 | public class SMA : AbstractIndicator 9 | { 10 | private readonly MovingQueue tickdata; 11 | private AbstractIndicator indicator; 12 | 13 | public SMA(int N, AbstractIndicator indicator = null) : base(N) 14 | { 15 | tickdata = new MovingQueue(N); 16 | this.indicator = indicator; 17 | } 18 | 19 | public override double HandleNextTick(Tick t) 20 | { 21 | if (indicator != null) return HandleNextTick(indicator.HandleNextTick(t)); 22 | return HandleNextTick(t.BidClose); 23 | } 24 | 25 | public double HandleNextTick(double currentTick) 26 | { 27 | if (!currentTick.Equals(double.NaN)) 28 | { 29 | double value = double.NaN; 30 | 31 | tickdata.Enqueue(currentTick); 32 | value = tickdata.ToArray().Average(); 33 | indicatorData.Enqueue(value); 34 | 35 | return value; 36 | } 37 | 38 | return double.NaN; 39 | } 40 | 41 | public override string ToString() 42 | { 43 | return "SMA" + Period; 44 | } 45 | } 46 | } -------------------------------------------------------------------------------- /DotNet/QuantSys/Analytics/Timeseries/Indicators/Channels/KirshenbaumBands.cs: -------------------------------------------------------------------------------- 1 | using QuantSys.Analytics.StatisticalModeling; 2 | using QuantSys.Analytics.Timeseries.Indicators.Abstraction; 3 | using QuantSys.Analytics.Timeseries.Indicators.Averages; 4 | using QuantSys.DataStructures; 5 | using QuantSys.MarketData; 6 | 7 | namespace QuantSys.Analytics.Timeseries.Indicators.Channels 8 | { 9 | public class KirshenbaumBands : AbstractChannel 10 | { 11 | 12 | private EMA EMA; 13 | private MovingQueue LRValues; 14 | private double STDEV; 15 | 16 | public KirshenbaumBands(int n = 20, int l = 30, double dev = 1.75) 17 | : base(n) 18 | { 19 | EMA = new EMA(n); 20 | LRValues= new MovingQueue(l); 21 | STDEV = dev; 22 | } 23 | 24 | public override void HandleNextTick(Tick t) 25 | { 26 | double emaVal = EMA.HandleNextTick(t); 27 | LRValues.Enqueue(emaVal); 28 | 29 | double[] Y = LRValues.ToArray(); 30 | 31 | LinearRegression l = new LinearRegression(); 32 | l.Model(Y); 33 | 34 | HighData.Enqueue(EMA[0]+STDEV * l.STDERR); 35 | MiddleData.Enqueue(EMA[0]); 36 | LowData.Enqueue(EMA[0] - STDEV * l.STDERR); 37 | 38 | } 39 | 40 | public override string ToString() 41 | { 42 | return "Kirshenbaum Bands" + Period; 43 | } 44 | 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /DotNet/QuantSys/MachineLearning/SupportVectorMachine/Predict.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using libsvm; 4 | 5 | namespace QuantSys.MachineLearning.SupportVectorMachine 6 | { 7 | public class Predict 8 | { 9 | public static string TRAINING_FILE = "C:/Sangar/quantopian/svm/heart_scale"; 10 | public static string TEST_FILE = "C:/Sangar/quantopian/svm/heart_scale"; 11 | public static double gamma = 1.0; 12 | public static double C = 1.0; 13 | public static int nr_fold = 5; 14 | 15 | private static readonly svm_problem prob = ProblemHelper.ReadAndScaleProblem(TRAINING_FILE); 16 | private static readonly svm_problem test = ProblemHelper.ReadAndScaleProblem(TEST_FILE); 17 | 18 | public static void SVMPredict() 19 | { 20 | var svm = new C_SVC(prob, KernelHelper.RadialBasisFunctionKernel(gamma), C); 21 | double accuracy = svm.GetCrossValidationAccuracy(nr_fold); 22 | 23 | for (int i = 0; i < test.l; i++) 24 | { 25 | svm_node[] x = test.x[i]; 26 | double y = test.y[i]; 27 | double predict = svm.Predict(x); // returns the predicted value 'y' 28 | Dictionary probabilities = svm.PredictProbabilities(x); 29 | // returns the probabilities for each 'y' value 30 | Console.WriteLine(predict + " :" + probabilities[1]); 31 | } 32 | Console.ReadKey(); 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /DotNet/QuantSys/Analytics/Timeseries/Indicators/Averages/ZLEMA.cs: -------------------------------------------------------------------------------- 1 | using QuantSys.Analytics.Timeseries.Indicators.Abstraction; 2 | using QuantSys.DataStructures; 3 | using QuantSys.MarketData; 4 | 5 | namespace QuantSys.Analytics.Timeseries.Indicators.Averages 6 | { 7 | public class ZLEMA: AbstractIndicator 8 | { 9 | private EMA EMA; 10 | private MovingQueue priceData; 11 | 12 | private AbstractIndicator indicator; 13 | public ZLEMA(int n, AbstractIndicator indicator = null) : base(n) 14 | { 15 | EMA = new EMA(n); 16 | this.indicator = indicator; 17 | priceData = new MovingQueue((n-1)/2); 18 | } 19 | 20 | public override double HandleNextTick(Tick t) 21 | { 22 | if(indicator!=null) 23 | return HandleNextTick(indicator.HandleNextTick(t)); 24 | return HandleNextTick(t.BidClose); 25 | } 26 | 27 | public double HandleNextTick(double d) 28 | { 29 | priceData.Enqueue(d); 30 | 31 | double value = double.NaN; 32 | if (priceData.Count.Equals(priceData.Capacity)) 33 | { 34 | value = d + (d - priceData.ToArray()[0]); 35 | } 36 | double returnValue = EMA.HandleNextTick(value); 37 | 38 | indicatorData.Enqueue(returnValue); 39 | return returnValue; 40 | } 41 | public override string ToString() 42 | { 43 | return "ZLEMA" + Period; 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /DotNet/QuantSys/Analytics/Timeseries/Indicators/Oscillators/TRIX.cs: -------------------------------------------------------------------------------- 1 | using QuantSys.Analytics.Timeseries.Indicators.Abstraction; 2 | using QuantSys.Analytics.Timeseries.Indicators.Averages; 3 | using QuantSys.MarketData; 4 | 5 | namespace QuantSys.Analytics.Timeseries.Indicators.Oscillators 6 | { 7 | /// 8 | /// 1. Single-Smoothed EMA = 15-period EMA of the closing price 9 | /// 2. Double-Smoothed EMA = 15-period EMA of Single-Smoothed EMA 10 | /// 3. Triple-Smoothed EMA = 15-period EMA of Double-Smoothed EMA 11 | /// 4. TRIX = 1-period percent change in Triple-Smoothed EMA 12 | /// 13 | public class TRIX : AbstractIndicator 14 | { 15 | private readonly EMA EMA1; 16 | private readonly EMA EMA2; 17 | private readonly EMA EMA3; 18 | 19 | private readonly int _n; 20 | 21 | public TRIX(int n = 15) : base(n) 22 | { 23 | EMA1 = new EMA(n); 24 | EMA2 = new EMA(n); 25 | EMA3 = new EMA(n); 26 | } 27 | 28 | public override double HandleNextTick(Tick t) 29 | { 30 | double ema1 = EMA1.HandleNextTick(t); 31 | double ema2 = EMA2.HandleNextTick(ema1); 32 | double ema3 = EMA3.HandleNextTick(ema2); 33 | 34 | double value = 100 * (ema3 - EMA3[1]) / ema3; 35 | indicatorData.Enqueue(value); 36 | 37 | return value; 38 | } 39 | 40 | public override string ToString() 41 | { 42 | return "TRIX" + Period; 43 | } 44 | } 45 | } -------------------------------------------------------------------------------- /DotNet/QuantSys/TradeEngine/Simulation/Performance/BacktestPerformance.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace QuantSys.TradeEngine.Simulation.Performance 4 | { 5 | public class BacktestPerformance 6 | { 7 | public bool OutputToConsole { get; set; } 8 | public bool OutputGraph { get; set; } 9 | 10 | public double StartingBalance { get; set; } 11 | public double EndingBalance { get; set; } 12 | public double TotalPerformance { get; set; } 13 | 14 | public double MaxDrawdownPercent { get; set; } 15 | public double AverageDrawdownPercent { get; set; } 16 | 17 | public double AverageProfit { get; set; } 18 | public double AverageLoss { get; set; } 19 | public double MaxProfitTrade { get; set; } 20 | public double MinProfitTrade { get; set; } 21 | public double MaxLossTrade { get; set; } 22 | public double MinLossTrade { get; set; } 23 | 24 | public int TradesClosed { get; set; } 25 | public int TotalTrades { get; set; } 26 | public int ProfitTrades { get; set; } 27 | public int LossTrades { get; set; } 28 | public int StopsHit { get; set; } 29 | 30 | public double AnnualizedSharpeRatio { get; set; } 31 | public double AnnualizedSortinoRatio { get; set; } 32 | public double AnnualizedVolatility { get; set; } 33 | 34 | private List _records; 35 | 36 | public BacktestPerformance() 37 | { 38 | 39 | } 40 | 41 | 42 | 43 | 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /DotNet/QuantSys/Analytics/Timeseries/Indicators/Abstraction/AbstractPivotPoints.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using QuantSys.MarketData; 4 | 5 | namespace QuantSys.Analytics.Timeseries.Indicators.Abstraction 6 | { 7 | public abstract class AbstractPivotPoints 8 | { 9 | private Timeframe.Period _period; 10 | private SortedList priceData; 11 | protected AbstractPivotPoints(Timeframe.Period period) 12 | { 13 | _period = period; 14 | 15 | switch (period) 16 | { 17 | case Timeframe.Period.T: 18 | case Timeframe.Period.m1: 19 | case Timeframe.Period.m15: 20 | { 21 | break; 22 | } 23 | case Timeframe.Period.m30: 24 | case Timeframe.Period.H1: 25 | case Timeframe.Period.H2: 26 | case Timeframe.Period.H3: 27 | case Timeframe.Period.H4: 28 | case Timeframe.Period.H8: 29 | { 30 | break; 31 | } 32 | case Timeframe.Period.D1: 33 | { 34 | break; 35 | } 36 | case Timeframe.Period.W1: 37 | case Timeframe.Period.M1: 38 | { 39 | break; 40 | } 41 | default: 42 | { 43 | break; 44 | } 45 | 46 | } 47 | } 48 | 49 | 50 | 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /DotNet/QuantSys/Analytics/SignalProcessing/SignalTransform.cs: -------------------------------------------------------------------------------- 1 | using System.Text; 2 | using WaveletStudio; 3 | using WaveletStudio.Blocks; 4 | 5 | namespace QuantSys.Analytics.SignalProcessing 6 | { 7 | public class SignalTransform 8 | { 9 | public double Run(double[] data, int detailLevel) 10 | { 11 | var sb = new StringBuilder(); 12 | for (int i = 0; i < data.Length; i++) 13 | { 14 | sb.Append(data[i]); 15 | if (i < data.Length - 1) sb.Append(","); 16 | } 17 | 18 | string datastring = sb.ToString(); 19 | 20 | var textBlock = new ImportFromTextBlock 21 | { 22 | Text = datastring, 23 | ColumnSeparator = ",", 24 | SignalStart = 0, 25 | SignalNameInFirstColumn = false 26 | }; 27 | 28 | var dwtBlock = new DWTBlock 29 | { 30 | WaveletName = "db10", 31 | Level = detailLevel, 32 | ExtensionMode = SignalExtension.ExtensionMode.ZeroPadding 33 | }; 34 | 35 | 36 | var b = new BlockList(); 37 | b.Add(textBlock); 38 | b.Add(dwtBlock); 39 | 40 | textBlock.ConnectTo(dwtBlock); 41 | 42 | b.ExecuteAll(); 43 | 44 | int length = dwtBlock.OutputNodes[dwtBlock.OutputNodes.Count-1].Object[detailLevel - 1].Samples.Length; 45 | 46 | double val = dwtBlock.OutputNodes[dwtBlock.OutputNodes.Count-1].Object[detailLevel - 1].Samples[length - 1]; 47 | 48 | return val; 49 | } 50 | } 51 | } -------------------------------------------------------------------------------- /DotNet/QuantSys/TradeEngine/MarketInterface/FXCMInterface/Listener/SessionStatusListener.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using fxcore2; 3 | 4 | namespace QuantSys.TradeEngine.MarketInterface.FXCMInterface.Listener 5 | { 6 | public class SessionStatusListener : IO2GSessionStatus 7 | { 8 | private readonly FXSession _connection; 9 | 10 | public SessionStatusListener(FXSession connection) 11 | { 12 | _connection = connection; 13 | } 14 | 15 | public void onLoginFailed(string s) 16 | { 17 | Console.WriteLine("\nLogin Failed. " + s); 18 | _connection.ChangeStatus(FXSession.LOGIN_STATUS.LOGIN_FAILED); 19 | } 20 | 21 | public void onSessionStatusChanged(O2GSessionStatusCode ssc) 22 | { 23 | Console.WriteLine(ssc); 24 | 25 | switch (ssc) 26 | { 27 | case O2GSessionStatusCode.Connected: 28 | { 29 | _connection.ChangeStatus(FXSession.LOGIN_STATUS.LOGGED_IN); 30 | break; 31 | } 32 | case O2GSessionStatusCode.Connecting: 33 | case O2GSessionStatusCode.Disconnected: 34 | case O2GSessionStatusCode.Disconnecting: 35 | case O2GSessionStatusCode.PriceSessionReconnecting: 36 | case O2GSessionStatusCode.Reconnecting: 37 | case O2GSessionStatusCode.SessionLost: 38 | case O2GSessionStatusCode.TradingSessionRequested: 39 | case O2GSessionStatusCode.Unknown: 40 | break; 41 | } 42 | } 43 | } 44 | } -------------------------------------------------------------------------------- /DotNet/QuantSys/MachineLearning/GeneticAlgorithm/Chromosome.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using QuantSys.MachineLearning.GeneticAlgorithm.Genes; 5 | 6 | namespace QuantSys.MachineLearning.GeneticAlgorithm 7 | { 8 | public class Chromosome : IEnumerable 9 | { 10 | private readonly List _geneList; 11 | private double _fitness; 12 | 13 | public Chromosome() 14 | { 15 | _fitness = double.NaN; 16 | _geneList = new List(); 17 | } 18 | 19 | public Chromosome(List genes) 20 | { 21 | _fitness = double.NaN; 22 | _geneList = genes; 23 | } 24 | 25 | public double Fitness 26 | { 27 | get { return _fitness; } 28 | } 29 | 30 | public Gene this[int index] 31 | { 32 | get { return _geneList[index]; } 33 | } 34 | 35 | public void CalculateFitness(Func func) 36 | { 37 | _fitness = func(this); 38 | } 39 | 40 | public void Mutate(double mRate) 41 | { 42 | foreach (Gene gene in _geneList) 43 | { 44 | if (gene.Mutate(mRate)) 45 | { 46 | _fitness = double.NaN; 47 | } 48 | } 49 | } 50 | 51 | public IEnumerator GetEnumerator() 52 | { 53 | return _geneList.GetEnumerator(); 54 | } 55 | 56 | IEnumerator IEnumerable.GetEnumerator() 57 | { 58 | return GetEnumerator(); 59 | } 60 | } 61 | } -------------------------------------------------------------------------------- /DotNet/QuantSys/TradeEngine/Simulation/Account/Order/StopOrder.cs: -------------------------------------------------------------------------------- 1 | using QuantSys.MarketData; 2 | 3 | namespace QuantSys.TradeEngine.Simulation.Account.Order 4 | { 5 | public class StopOrder 6 | { 7 | public Position.PositionSide Side { get; set; } 8 | public double TriggerPrice { get; set; } 9 | public bool Trailing { get; set; } 10 | public Symbol Symbol { get; set; } 11 | public double TrailSize { get; set; } 12 | 13 | public StopOrder (Symbol s, Position.PositionSide side, double price, bool trailing = false, double trailsize = 0) 14 | { 15 | Symbol = s; 16 | TriggerPrice = price; 17 | Side = side; 18 | Trailing = trailing; 19 | TrailSize = trailsize; 20 | } 21 | 22 | public void RecalculateTrail(Tick t) 23 | { 24 | if (Side.Equals(Position.PositionSide.Long)) 25 | { 26 | if (t.BidClose - TrailSize > TriggerPrice) 27 | { 28 | TriggerPrice = t.BidClose - TrailSize; 29 | } 30 | } else if(Side.Equals(Position.PositionSide.Short)) 31 | { 32 | if (t.AskClose + TrailSize < TriggerPrice) 33 | { 34 | TriggerPrice = t.AskClose + TrailSize; 35 | } 36 | } 37 | } 38 | 39 | public bool IsBuyStop() 40 | { 41 | return Side.Equals(Position.PositionSide.Long); 42 | } 43 | 44 | public bool IsSellStop() 45 | { 46 | return Side.Equals(Position.PositionSide.Short); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /DotNet/QuantSys/Analytics/Timeseries/Indicators/Transforms/DWT.cs: -------------------------------------------------------------------------------- 1 | using QuantSys.Analytics.SignalProcessing; 2 | using QuantSys.Analytics.Timeseries.Indicators.Abstraction; 3 | using QuantSys.DataStructures; 4 | using QuantSys.MarketData; 5 | 6 | namespace QuantSys.Analytics.Timeseries.Indicators.Transforms 7 | { 8 | public class DWT: AbstractIndicator 9 | { 10 | private MovingQueue priceData; 11 | private SignalTransform st; 12 | private int detailLevel; 13 | private AbstractIndicator indicator; 14 | 15 | public DWT(int n, int detailLevel, AbstractIndicator indicator = null) : base(n) 16 | { 17 | priceData = new MovingQueue(n); 18 | st = new SignalTransform(); 19 | this.detailLevel = detailLevel; 20 | this.indicator = indicator; 21 | } 22 | 23 | public override double HandleNextTick(Tick t) 24 | { 25 | if (indicator != null) return HandleNextTick(indicator.HandleNextTick(t)); 26 | return HandleNextTick(t.BidClose); 27 | } 28 | 29 | public double HandleNextTick(double d) 30 | { 31 | double returnValue = double.NaN; 32 | 33 | priceData.Enqueue(d); 34 | 35 | if (priceData.Count.Equals(priceData.Capacity)) 36 | { 37 | returnValue = st.Run(priceData.ToArray(), detailLevel); 38 | indicatorData.Enqueue(returnValue); 39 | } 40 | 41 | return returnValue; 42 | } 43 | public override string ToString() 44 | { 45 | return "DWT"; 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /DotNet/QuantSys/Analytics/Timeseries/Indicators/Oscillators/WilliamsR.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using QuantSys.Analytics.Timeseries.Indicators.Abstraction; 3 | using QuantSys.DataStructures; 4 | using QuantSys.MarketData; 5 | 6 | namespace QuantSys.Analytics.Timeseries.Indicators.Oscillators 7 | { 8 | /// 9 | /// %R = (Highest High - Close)/(Highest High - Lowest Low) * -100 10 | /// Lowest Low = lowest low for the look-back period 11 | /// Highest High = highest high for the look-back period 12 | /// %R is multiplied by -100 correct the inversion and move the decimal. 13 | /// 14 | public class WilliamsR : AbstractIndicator 15 | { 16 | private readonly MovingQueue _highData; 17 | private readonly MovingQueue _lowData; 18 | 19 | public WilliamsR() : this(14) 20 | { 21 | 22 | } 23 | 24 | public WilliamsR(int n = 14):base(n) 25 | { 26 | _highData = new MovingQueue(n); 27 | _lowData = new MovingQueue(n); 28 | } 29 | 30 | 31 | public override double HandleNextTick(Tick t) 32 | { 33 | double value = double.NaN; 34 | 35 | _highData.Enqueue(t.BidHigh); 36 | _lowData.Enqueue(t.BidLow); 37 | value = (_highData.ToArray().Max() - t.BidClose)/ 38 | (_highData.ToArray().Max() - _lowData.ToArray().Min())*-100; 39 | 40 | indicatorData.Enqueue(value); 41 | 42 | return value; 43 | } 44 | public override string ToString() 45 | { 46 | return "Williams%R" + Period; 47 | } 48 | } 49 | } -------------------------------------------------------------------------------- /DotNet/QuantSys/MachineLearning/NeuralNetwork/PSO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using Encog.Engine.Network.Activation; 7 | using Encog.MathUtil.Randomize; 8 | using Encog.ML.Data; 9 | using Encog.ML.Data.Basic; 10 | using Encog.ML.Train; 11 | using Encog.Neural.Networks; 12 | using Encog.Neural.Networks.Layers; 13 | using Encog.Neural.Networks.Training; 14 | using Encog.Neural.Networks.Training.PSO; 15 | using Encog.Util.Error; 16 | 17 | namespace QuantSys.MachineLearning.NeuralNetwork 18 | { 19 | class PSO 20 | { 21 | private IMLTrain train; 22 | private BasicNetwork network; 23 | public PSO() 24 | { 25 | network = new BasicNetwork(); 26 | network.AddLayer(new BasicLayer(5)); 27 | network.AddLayer(new BasicLayer(1)); 28 | network.AddLayer(new BasicLayer(1)); 29 | network.Structure.FinalizeStructure(); 30 | network.Reset(); 31 | 32 | IMLDataSet dataSet = new BasicMLDataSet(); 33 | dataSet.Add(new BasicMLData(new double[] { 1.0, 4.0, 3.0, 4.0, 5.0}) , new BasicMLData(new double[] { 2.0, 4.0, 6.0 , 8.0, 10} )); 34 | 35 | train = new NeuralPSO(network, new RangeRandomizer(0, 10), new TrainingSetScore(dataSet),5); 36 | 37 | } 38 | 39 | public void Iterate() 40 | { 41 | train.Iteration(); 42 | } 43 | 44 | public void Compute() 45 | { 46 | var output = network.Compute(new BasicMLData(new double[] {0.5, 1, 1.5, 2, 2.5})); 47 | } 48 | 49 | 50 | 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /DotNet/QuantSys/Analytics/Timeseries/Indicators/Oscillators/MACD.cs: -------------------------------------------------------------------------------- 1 | using QuantSys.Analytics.Timeseries.Indicators.Abstraction; 2 | using QuantSys.Analytics.Timeseries.Indicators.Averages; 3 | using QuantSys.Analytics.Timeseries.Indicators.Misc; 4 | using QuantSys.MarketData; 5 | 6 | namespace QuantSys.Analytics.Timeseries.Indicators.Oscillators 7 | { 8 | public class MACD : AbstractIndicator 9 | { 10 | private int N1; 11 | private int N2; 12 | private int N3; 13 | 14 | private EMA EMA1; 15 | private EMA EMA2; 16 | 17 | public MACD() : this(12, 26, 9){} 18 | 19 | public MACD(int N1 = 12, int N2 = 26, int N3 = 9) : base(N2) 20 | { 21 | this.N1 = N1; 22 | this.N2 = N2; 23 | this.N3 = N3; 24 | EMA1 = new EMA(N1); 25 | EMA2 = new EMA(N2); 26 | 27 | subIndicators.Add("Signal", new EMA(N3)); 28 | subIndicators.Add("Histogram", new GenericContainer(N2)); 29 | } 30 | 31 | public override double HandleNextTick(Tick t) 32 | { 33 | EMA1.HandleNextTick(t.BidClose); 34 | EMA2.HandleNextTick(t.BidClose); 35 | 36 | double MACD = EMA1[0] - EMA2[0]; 37 | indicatorData.Enqueue(MACD); 38 | 39 | ((EMA)subIndicators["Signal"]).HandleNextTick(MACD); 40 | 41 | double MACDHist = MACD - subIndicators["Signal"][0]; 42 | ((GenericContainer)subIndicators["Histogram"]).HandleNextTick(MACDHist); 43 | 44 | return MACD; 45 | } 46 | 47 | public override string ToString() 48 | { 49 | return "MACD" + N1 + "-" + N2; 50 | } 51 | } 52 | } -------------------------------------------------------------------------------- /DotNet/QuantSys/Analytics/Timeseries/Indicators/Transforms/PercentileRank.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using QuantSys.Analytics.Timeseries.Indicators.Abstraction; 3 | using QuantSys.DataStructures; 4 | using QuantSys.MarketData; 5 | 6 | namespace QuantSys.Analytics.Timeseries.Indicators.Transforms 7 | { 8 | public class PercentileRank: AbstractIndicator 9 | { 10 | private MovingQueue data; 11 | private AbstractIndicator indicator; 12 | 13 | public PercentileRank(int n, AbstractIndicator indicator = null) : base(n) 14 | { 15 | data = new MovingQueue(n); 16 | if(indicator!=null) this.indicator = indicator; 17 | } 18 | 19 | public override double HandleNextTick(Tick t) 20 | { 21 | if (indicator != null) return HandleNextTick(indicator.HandleNextTick(t)); 22 | 23 | return HandleNextTick(t.BidClose); 24 | } 25 | 26 | 27 | public double HandleNextTick(double tick) 28 | { 29 | double Rankvalue = double.NaN; 30 | 31 | if (tick != double.NaN) 32 | { 33 | data.Enqueue(tick); 34 | 35 | 36 | if (indicatorData.Capacity == indicatorData.Count) 37 | { 38 | Rankvalue = 100 * (data.Data.Count(x => x < tick) + 0.5* data.Data.Count(x => x.Equals(tick))); 39 | Rankvalue /= Period; 40 | } 41 | } 42 | 43 | indicatorData.Enqueue(Rankvalue); 44 | return Rankvalue; 45 | } 46 | 47 | 48 | public override string ToString() 49 | { 50 | return "PercentRank" + Period; 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /DotNet/QuantSys/Analytics/Timeseries/Indicators/Oscillators/Chaikin.cs: -------------------------------------------------------------------------------- 1 | using QuantSys.Analytics.Timeseries.Indicators.Abstraction; 2 | using QuantSys.Analytics.Timeseries.Indicators.Averages; 3 | using QuantSys.Analytics.Timeseries.Indicators.Misc; 4 | using QuantSys.MarketData; 5 | 6 | namespace QuantSys.Analytics.Timeseries.Indicators.Oscillators 7 | { 8 | /// 9 | /// 1. Money Flow Multiplier = [(Close - Low) - (High - Close)] /(High - Low) 10 | /// 2. Money Flow Volume = Money Flow Multiplier x Volume for the Period 11 | /// 3. ADL = Previous ADL + Current Period's Money Flow Volume 12 | /// 4. Chaikin Oscillator = (3-day EMA of ADL) - (10-day EMA of ADL) 13 | /// 14 | public class Chaikin : AbstractIndicator 15 | { 16 | private readonly EMA ADL1; 17 | private readonly EMA ADL2; 18 | private readonly MFM MoneyFlowMultiplier; 19 | 20 | private double ADL; 21 | 22 | public Chaikin(int n1 = 3, int n2 = 10) : base(n2) 23 | { 24 | ADL1 = new EMA(n1); 25 | ADL2 = new EMA(n2); 26 | MoneyFlowMultiplier = new MFM(1); 27 | 28 | } 29 | 30 | public override double HandleNextTick(Tick t) 31 | { 32 | double mfm = MoneyFlowMultiplier.HandleNextTick(t); 33 | double mfv = mfm*t.Volume; 34 | ADL += mfv; 35 | 36 | double a1 = ADL1.HandleNextTick(ADL); 37 | double a2 = ADL2.HandleNextTick(ADL); 38 | 39 | indicatorData.Enqueue(a1 - a2); 40 | return a1 - a2; 41 | } 42 | 43 | public override string ToString() 44 | { 45 | return "Chaikin Oscillator" + Period; 46 | } 47 | } 48 | } -------------------------------------------------------------------------------- /DotNet/QuantSys/Analytics/Timeseries/Indicators/Misc/RSquared.cs: -------------------------------------------------------------------------------- 1 | using MathNet.Numerics.LinearAlgebra.Double; 2 | using MathNet.Numerics.Statistics; 3 | using QuantSys.Analytics.StatisticalModeling; 4 | using QuantSys.Analytics.Timeseries.Indicators.Abstraction; 5 | using QuantSys.DataStructures; 6 | using QuantSys.MarketData; 7 | 8 | namespace QuantSys.Analytics.Timeseries.Indicators.Misc 9 | { 10 | public class RSquared : AbstractIndicator 11 | { 12 | private DenseVector Y; 13 | private MovingQueue X; 14 | private AbstractIndicator indicator; 15 | 16 | public RSquared(int n, AbstractIndicator indicator = null) : base(n) 17 | { 18 | X = new MovingQueue(n); 19 | Y = new DenseVector(n); 20 | int counter = 0; 21 | for (double i = (double)-Y.Count / 2 + 0.5; i < (double)Y.Count / 2; i++) Y[counter++] = i; 22 | this.indicator = indicator; 23 | } 24 | 25 | public override double HandleNextTick(Tick t) 26 | { 27 | if (indicator != null) return HandleNextTick(indicator.HandleNextTick(t)); 28 | return HandleNextTick(t.BidClose); 29 | } 30 | 31 | public double HandleNextTick(double d) 32 | { 33 | double value = double.NaN; 34 | 35 | X.Enqueue(d); 36 | 37 | if (X.Count.Equals(X.Capacity)) 38 | { 39 | double cov = StatisticsExtension.Covariance(new DenseVector(X.ToArray()), Y); 40 | value = cov / (X.ToArray().Variance() * Y.Variance()); 41 | } 42 | 43 | indicatorData.Enqueue(value); 44 | return value; 45 | } 46 | public override string ToString() 47 | { 48 | return "RSquared" + Period; 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /DotNet/QuantSys/Analytics/Timeseries/Indicators/Oscillators/PFE.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using QuantSys.Analytics.Timeseries.Indicators.Abstraction; 3 | using QuantSys.DataStructures; 4 | using QuantSys.MarketData; 5 | 6 | namespace QuantSys.Analytics.Timeseries.Indicators.Oscillators 7 | { 8 | public class PFE : AbstractIndicator 9 | { 10 | private MovingQueue priceData; 11 | public PFE(int n) : base(n) 12 | { 13 | priceData = new MovingQueue(n); 14 | } 15 | 16 | public override double HandleNextTick(Tick t) 17 | { 18 | double value = double.NaN; 19 | priceData.Enqueue(t.BidClose); 20 | 21 | if (priceData.Count.Equals(priceData.Capacity)) 22 | { 23 | double[] pArray = priceData.ToArray(); 24 | double pN = pArray[0]; 25 | double sign = (t.BidClose > pN) ? 1 : -1; 26 | double hypot = Hypot(Period - 1, pChange(t.BidClose, pN)); 27 | 28 | double sumHypot = 0; 29 | for (int i = 0; i < priceData.Count - 1; i++) 30 | { 31 | sumHypot += Hypot((double) i + 1, pChange(pArray[i], pArray[i + 1])); 32 | } 33 | value = 100* (sign*hypot)/sumHypot; 34 | } 35 | 36 | indicatorData.Enqueue(value); 37 | return value; 38 | } 39 | 40 | public override string ToString() 41 | { 42 | return "PFE" + Period; 43 | } 44 | 45 | private double Hypot(double x, double y) 46 | { 47 | return Math.Sqrt(Math.Pow(x, 2) + Math.Pow(y, 2)); 48 | } 49 | 50 | private double pChange(double xnew, double xold) 51 | { 52 | return 100*(xnew - xold)/xold; 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /DotNet/QuantSys/TradeEngine/MarketInterface/FXCMInterface/Functions/AccountInformation.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using fxcore2; 3 | using QuantSys.TradeEngine.MarketInterface.FXCMInterface.EventArguments; 4 | using QuantSys.TradeEngine.MarketInterface.FXCMInterface.Listener; 5 | 6 | namespace QuantSys.TradeEngine.MarketInterface.FXCMInterface.Functions 7 | { 8 | public class AccountInformation 9 | { 10 | private FXSession session; 11 | private ResponseHandler mHandler; 12 | 13 | public AccountInformation(FXSession session) 14 | { 15 | this.session = session; 16 | mHandler = AccountInformationReceived; 17 | session.AttachHandler(mHandler); 18 | } 19 | 20 | public bool ExistsPositionFor(string symbol) 21 | { 22 | O2GResponseReaderFactory factory = session.Session.getResponseReaderFactory(); 23 | // Gets first account from login. 24 | O2GLoginRules loginRules = session.Session.getLoginRules(); 25 | O2GResponse response = loginRules.getTableRefeshResponse(O2GTable.ClosedTrades); 26 | 27 | O2GTradesTableResponseReader tradesReader = factory.createTradesTableReader(response); 28 | 29 | for (int i = 0; i < tradesReader.Count; i++) 30 | { 31 | O2GTradeRow tradeRow = tradesReader.getRow(i); 32 | Console.WriteLine("Trades---"); 33 | Console.WriteLine(tradeRow.OpenQuoteID); 34 | Console.WriteLine(tradeRow.OfferID); 35 | } 36 | 37 | return false; 38 | } 39 | 40 | 41 | 42 | public void AccountInformationReceived(object sender, EventArgs e) 43 | { 44 | AccountInformationEventArg accData = ((AccountInformationEventArg)e); 45 | 46 | } 47 | 48 | 49 | 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /DotNet/QuantSys/Analytics/StatisticalModeling/LinearRegression.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Linq; 4 | 5 | namespace QuantSys.Analytics.StatisticalModeling 6 | { 7 | public class LinearRegression 8 | { 9 | private double A; 10 | private double B; 11 | private double _stderr; 12 | 13 | public double X1{ get { return A; }} 14 | public double X2 { get { return B; } } 15 | 16 | public double STDERR{get { return _stderr; }} 17 | 18 | public LinearRegression() 19 | { 20 | A = double.NaN; 21 | B = double.NaN; 22 | } 23 | 24 | public void Model(double[] x, double[] y, bool calculateStdErr = true) 25 | { 26 | if(x.Length != y.Length) 27 | throw new InvalidDataException("Arrays X and Y must be same length."); 28 | 29 | A = y.Average(); 30 | 31 | double div = 0; 32 | for (int i = 0; i < y.Length; i++) div += x[i] * y[i]; 33 | div /= x.Sum(xi => Math.Pow(xi, 2)); 34 | B = div; 35 | 36 | //calcualte stderr 37 | _stderr = 0; 38 | for (int i = 0; i < y.Length; i++) 39 | { 40 | _stderr += Math.Pow(y[i] -(A + B*x[i]), 2); 41 | } 42 | _stderr /= y.Length; 43 | _stderr = Math.Sqrt(_stderr); 44 | } 45 | 46 | public void Model(double[] y, bool calculateStdErr = true) 47 | { 48 | double[] x = new double[y.Length]; 49 | int counter = 0; 50 | for (double i = (double)-y.Length/2 +0.5; i < (double)y.Length/2; i++) x[counter++] = i; 51 | Model(x, y, calculateStdErr); 52 | } 53 | 54 | public double Fit(double x) 55 | { 56 | return A + B*x; 57 | } 58 | 59 | 60 | 61 | 62 | 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /DotNet/QuantSys/Analytics/StatisticalModeling/PolynomialRegression.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MathNet.Numerics.LinearAlgebra; 3 | 4 | namespace QuantSys.Analytics.StatisticalModeling 5 | { 6 | public class PolynomialRegression 7 | { 8 | Vector x_data, y_data, coef; 9 | int order; 10 | 11 | public PolynomialRegression(Vector x_data, Vector y_data, int order) 12 | { 13 | if (x_data.Length != y_data.Length) 14 | { 15 | throw new IndexOutOfRangeException(); 16 | } 17 | this.x_data = x_data; 18 | this.y_data = y_data; 19 | this.order = order; 20 | int N = x_data.Length; 21 | Matrix A = new Matrix(N, order + 1); 22 | for (int i = 0; i < N; i++) 23 | { 24 | A.SetRowVector(VandermondeRow(x_data[i]), i); 25 | } 26 | 27 | // Least Squares of |y=A(x)*c| 28 | // tr(A)*y = tr(A)*A*c 29 | // inv(tr(A)*A)*tr(A)*y = c 30 | Matrix At = Matrix.Transpose(A); 31 | Matrix y2 = new Matrix(y_data, N); 32 | coef = (At * A).Solve(At * y2).GetColumnVector(0); 33 | } 34 | 35 | Vector VandermondeRow(double x) 36 | { 37 | double[] row = new double[order + 1]; 38 | for (int i = 0; i <= order; i++) 39 | { 40 | row[i] = Math.Pow(x, i); 41 | } 42 | return new Vector(row); 43 | } 44 | 45 | public double Fit(double x) 46 | { 47 | return Vector.ScalarProduct(VandermondeRow(x), coef); 48 | } 49 | 50 | public int Order { get { return order; } } 51 | public Vector Coefficients { get { return coef; } } 52 | public Vector XData { get { return x_data; } } 53 | public Vector YData { get { return y_data; } } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /DotNet/QuantSys/Analytics/Timeseries/Indicators/Oscillators/ATR.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using QuantSys.Analytics.StatisticalModeling; 3 | using QuantSys.Analytics.Timeseries.Indicators.Abstraction; 4 | using QuantSys.DataStructures; 5 | using QuantSys.MarketData; 6 | 7 | namespace QuantSys.Analytics.Timeseries.Indicators.Oscillators 8 | { 9 | //Average True Range 10 | public class ATR : AbstractIndicator 11 | { 12 | private Tick prevTick; 13 | private MovingQueue TrueRange; 14 | private int counter; 15 | public ATR(int n = 14) : base(n) 16 | { 17 | TrueRange = new MovingQueue(n); 18 | counter = 0; 19 | } 20 | 21 | public override double HandleNextTick(Tick t) 22 | { 23 | double ATR = double.NaN; 24 | 25 | if (prevTick != null) 26 | { 27 | double m1 = t.BidHigh - t.BidLow; 28 | double m2 = Math.Abs(t.BidHigh - prevTick.BidClose); 29 | double m3 = Math.Abs(t.BidLow - prevTick.BidClose); 30 | double TR = Math.Max(m1, Math.Max(m2, m3)); 31 | TrueRange.Enqueue(TR); 32 | } 33 | else 34 | { 35 | TrueRange.Enqueue(t.BidHigh - t.BidLow); 36 | } 37 | 38 | counter++; 39 | if (counter.Equals(Period)) 40 | { 41 | ATR = TrueRange.ToArray().Average(); 42 | } 43 | else if(counter > Period) 44 | { 45 | ATR = (this[0]*(Period - 1) + TrueRange.ToArray()[Period-1])/Period; 46 | } 47 | 48 | indicatorData.Enqueue(ATR); 49 | prevTick = t; 50 | return ATR; 51 | } 52 | 53 | public override string ToString() 54 | { 55 | return "ATR" + Period; 56 | } 57 | } 58 | } -------------------------------------------------------------------------------- /DotNet/QuantSys/MarketData/Tick.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace QuantSys.MarketData 4 | { 5 | public class Tick 6 | { 7 | #region members 8 | 9 | public double CurrentAsk { get; set; } 10 | public double AskOpen { get; set; } 11 | public double AskHigh { get; set; } 12 | public double AskLow { get; set; } 13 | public double AskClose { get; set; } 14 | 15 | public double CurrentBid { get; set; } 16 | public double BidOpen { get; set; } 17 | public double BidHigh { get; set; } 18 | public double BidLow { get; set; } 19 | public double BidClose { get; set; } 20 | 21 | public double Volume { get; set; } 22 | public DateTime Time { get; set; } 23 | 24 | public Symbol Symbol { get; set; } 25 | public Timeframe Period { get; set; } 26 | 27 | #endregion 28 | 29 | public Tick( 30 | double currentbid = double.NaN, 31 | double bidopen = double.NaN, 32 | double bidhigh = double.NaN, 33 | double bidlow = double.NaN, 34 | double bidclose = double.NaN, 35 | double currentask = double.NaN, 36 | double askopen = double.NaN, 37 | double askhigh = double.NaN, 38 | double asklow = double.NaN, 39 | double askclose = double.NaN, 40 | double volume = double.NaN, 41 | DateTime dateTime = new DateTime() 42 | ) 43 | { 44 | CurrentBid = currentbid; 45 | BidOpen = bidopen; 46 | BidHigh = bidhigh; 47 | BidLow = bidlow; 48 | BidClose = bidclose; 49 | CurrentAsk = currentask; 50 | AskOpen = askopen; 51 | AskHigh = askhigh; 52 | AskLow = asklow; 53 | AskClose = askclose; 54 | Volume = volume; 55 | Time = dateTime; 56 | } 57 | } 58 | } -------------------------------------------------------------------------------- /DotNet/QuantSys/Analytics/Timeseries/Indicators/Averages/QSPolyMA.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using MathNet.Numerics.LinearAlgebra; 3 | using QuantSys.Analytics.StatisticalModeling; 4 | using QuantSys.Analytics.Timeseries.Indicators.Abstraction; 5 | using QuantSys.DataStructures; 6 | using QuantSys.MarketData; 7 | 8 | namespace QuantSys.Analytics.Timeseries.Indicators.Averages 9 | { 10 | public class QSPolyMA : AbstractIndicator 11 | { 12 | 13 | private readonly MovingQueue tickdata; 14 | private double[] X; 15 | 16 | private AbstractIndicator indicator; 17 | 18 | public QSPolyMA(int N, AbstractIndicator indicator = null) 19 | : base(N) 20 | { 21 | tickdata = new MovingQueue(N); 22 | this.indicator = indicator; 23 | X = new double[N]; 24 | for (int i = 0; i < X.Count(); i++) X[i] = i; 25 | } 26 | 27 | public override double HandleNextTick(Tick t) 28 | { 29 | if (indicator != null) return HandleNextTick(indicator.HandleNextTick(t)); 30 | return HandleNextTick(t.BidClose); 31 | } 32 | 33 | public double HandleNextTick(double currentTick) 34 | { 35 | if (!currentTick.Equals(double.NaN)) 36 | { 37 | double value = double.NaN; 38 | tickdata.Enqueue(currentTick); 39 | 40 | if (tickdata.Capacity.Equals(tickdata.Count)) 41 | { 42 | Vector x_data = new Vector(X); 43 | Vector y_data = new Vector(tickdata.ToArray()); 44 | 45 | var poly = new PolynomialRegression(x_data, y_data, 2); 46 | value = poly.Fit(Period); 47 | } 48 | indicatorData.Enqueue(value); 49 | return value; 50 | } 51 | 52 | return double.NaN; 53 | } 54 | 55 | 56 | public override string ToString() 57 | { 58 | return "QSPolyMA" + Period; 59 | } 60 | 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /DotNet/QuantSys/MachineLearning/GeneticAlgorithm/Population.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace QuantSys.MachineLearning.GeneticAlgorithm 5 | { 6 | public class Population 7 | { 8 | private readonly List pop; 9 | 10 | public Population() 11 | { 12 | pop = new List(); 13 | } 14 | 15 | public Population(List l) 16 | { 17 | pop = l; 18 | } 19 | 20 | public int PopulationSize 21 | { 22 | get { return pop.Count; } 23 | } 24 | 25 | public List Chromosomes 26 | { 27 | get { return pop; } 28 | } 29 | 30 | public double BestFitness { get; set; } 31 | 32 | public Chromosome this[int index] 33 | { 34 | get { return pop[index]; } 35 | } 36 | 37 | public void MutatePopulation(double mRate, Random r) 38 | { 39 | foreach (Chromosome c in pop) 40 | { 41 | c.Mutate(mRate); 42 | } 43 | } 44 | 45 | public void JoinPopulation(Population p) 46 | { 47 | Chromosomes.AddRange(p.Chromosomes); 48 | } 49 | 50 | public void CalculateAllFitness(Func fitness) 51 | { 52 | foreach (Chromosome chromosome in Chromosomes) 53 | { 54 | chromosome.CalculateFitness(fitness); 55 | } 56 | } 57 | 58 | 59 | /* 60 | public static Population SeedPopulation(int popSize, List constraints, Random r) 61 | { 62 | List pop = new List(popSize); 63 | Population p = new Population(); 64 | 65 | //generate using seed 66 | for (int i = 0; i < popSize; i++) 67 | { 68 | List l= new List(constraints.Count); 69 | double 70 | pop[i] 71 | } 72 | 73 | return null; 74 | }*/ 75 | } 76 | } -------------------------------------------------------------------------------- /DotNet/QuantSys/Analytics/Timeseries/Indicators/Oscillators/RSI.cs: -------------------------------------------------------------------------------- 1 | using QuantSys.Analytics.StatisticalModeling; 2 | using QuantSys.Analytics.Timeseries.Indicators.Abstraction; 3 | using QuantSys.DataStructures; 4 | using QuantSys.MarketData; 5 | 6 | namespace QuantSys.Analytics.Timeseries.Indicators.Oscillators 7 | { 8 | public class RSI : AbstractIndicator 9 | { 10 | private Tick previousTick; 11 | 12 | private MovingQueue UP; 13 | private MovingQueue DOWN; 14 | private double AVGUP; 15 | private double AVGDOWN; 16 | 17 | public RSI() : this(14) 18 | { 19 | 20 | } 21 | 22 | public RSI(int n = 14) : base(n) 23 | { 24 | UP = new MovingQueue(n); 25 | DOWN = new MovingQueue(n); 26 | AVGUP = double.NaN; 27 | AVGDOWN = double.NaN; 28 | } 29 | 30 | public override double HandleNextTick(Tick currentTick) 31 | { 32 | double value = double.NaN; 33 | 34 | if (previousTick != null) 35 | { 36 | if (currentTick.BidClose < previousTick.BidClose) 37 | { 38 | DOWN.Enqueue(previousTick.BidClose - currentTick.BidClose); 39 | UP.Enqueue(0); 40 | } 41 | else if (currentTick.BidClose > previousTick.BidClose) 42 | { 43 | DOWN.Enqueue(0); 44 | UP.Enqueue(currentTick.BidClose - previousTick.BidClose); 45 | } 46 | } 47 | 48 | if (DOWN.Count.Equals(DOWN.Capacity)) 49 | { 50 | AVGUP = UP.ToArray().Average(); 51 | AVGDOWN = DOWN.ToArray().Average(); 52 | } 53 | 54 | value = 100 - 100 / (1 + AVGUP / AVGDOWN); 55 | previousTick = currentTick; 56 | 57 | indicatorData.Enqueue(value); 58 | return value; 59 | } 60 | 61 | 62 | public override string ToString() 63 | { 64 | return "RSI" + Period; 65 | } 66 | 67 | } 68 | } -------------------------------------------------------------------------------- /DotNet/QuantSys/Analytics/Timeseries/Indicators/Oscillators/DI.cs: -------------------------------------------------------------------------------- 1 | using QuantSys.Analytics.Timeseries.Indicators.Abstraction; 2 | using QuantSys.Analytics.Timeseries.Indicators.Averages; 3 | using QuantSys.Analytics.Timeseries.Indicators.Misc; 4 | using QuantSys.MarketData; 5 | 6 | namespace QuantSys.Analytics.Timeseries.Indicators.Oscillators 7 | { 8 | /// 9 | /// The directional movement index by J. Welles Wilder 10 | /// expresses so-called directional movement, from high to 11 | /// high, or low to low, as a percentage of true range 12 | /// 13 | public class DI : AbstractIndicator 14 | { 15 | private ATR ATR; 16 | private Tick prevTick; 17 | 18 | private EMA EMA_DMP; 19 | private EMA EMA_DMN; 20 | public DI(int n) :base(n) 21 | { 22 | subIndicators.Add("DIP", new GenericContainer(n)); 23 | subIndicators.Add("DIM", new GenericContainer(n)); 24 | EMA_DMN = new EMA(n); 25 | EMA_DMP = new EMA(n); 26 | ATR = new ATR(n); 27 | } 28 | 29 | public override double HandleNextTick(Tick t) 30 | { 31 | double DMP = 0; 32 | double DMN = 0; 33 | 34 | if (prevTick != null) 35 | { 36 | double upMove = t.BidHigh - prevTick.BidHigh; 37 | double downMove = prevTick.BidLow - t.BidLow; 38 | if (upMove > downMove && upMove > 0) DMP = upMove; 39 | if (downMove > upMove && downMove > 0) DMN = downMove; 40 | } 41 | 42 | double atr = ATR.HandleNextTick(t); 43 | double DIP = 100*EMA_DMP.HandleNextTick(DMP)/atr; 44 | double DIM = 100*EMA_DMN.HandleNextTick(DMN)/atr; 45 | 46 | ((GenericContainer)subIndicators["DIP"]).HandleNextTick(DIP); 47 | ((GenericContainer)subIndicators["DIM"]).HandleNextTick(DIM); 48 | 49 | prevTick = t; 50 | indicatorData.Enqueue(double.NaN); 51 | return double.NaN; 52 | } 53 | 54 | public override string ToString() 55 | { 56 | return "DI" + Period; 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /DotNet/QuantSys/Analytics/StatisticalModeling/VarianceRatio.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MathNet.Numerics.LinearAlgebra.Double; 3 | using MathNet.Numerics.Statistics; 4 | 5 | namespace QuantSys.Analytics.StatisticalModeling 6 | { 7 | 8 | public class VarianceRatio 9 | { 10 | public double ZScore { get; set; } 11 | public double VRatio { get; set; } 12 | public double PValue { get; set; } 13 | 14 | public enum TimeSeriesType 15 | { 16 | HOM, //homoskedastic 17 | HET //heteroskedastic 18 | } 19 | private static double NormCDF(double x) 20 | { 21 | return 0; 22 | } 23 | 24 | public void VarianceRatioTest(double[] data, int lag = 1, TimeSeriesType cor = TimeSeriesType.HOM) 25 | { 26 | DenseVector x = new DenseVector(data); 27 | 28 | //Mean 29 | double mu = x.Mean(); 30 | 31 | //Variance for 1st Order Difference 32 | double s1 = (x.SubVector(lag, x.Count - lag) - x.SubVector(0, x.Count - 2)).Variance(); 33 | 34 | 35 | double dLag = lag; 36 | double varvrt = double.NaN; 37 | switch (cor) 38 | { 39 | case TimeSeriesType.HOM: 40 | { 41 | varvrt = 2*(2*dLag - 1)*(dLag - 1)/(3*dLag*x.Count); 42 | break; 43 | } 44 | case TimeSeriesType.HET: 45 | { 46 | varvrt = 0; 47 | double sum2 = 0; 48 | for (int j = 0; j < lag; j++) 49 | { 50 | double sum1a = 0; //(x(j+2:n)-x(j+1:n-1)-mu).^2 51 | double sum1b = 0; //(x(2:n-j)-x(1:n-j-1)-mu).^2; 52 | double sum1 = sum1a*sum1b; 53 | double delta = sum1/(Math.Pow(sum2, 2)); 54 | varvrt += 0; //(2*(q(i)-j)/q(i))^2)*delta; 55 | } 56 | break; 57 | } 58 | } 59 | 60 | ZScore = (VRatio - 1)/Math.Sqrt(varvrt); 61 | PValue = NormCDF(ZScore); 62 | 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /DotNet/QuantSys/TradeEngine/Strategy/RSIStrategy.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using QuantSys.MarketData; 7 | using QuantSys.PortfolioEngine; 8 | using QuantSys.PortfolioEngine.Order; 9 | using QuantSys.Analytics.Indicators; 10 | 11 | namespace QuantSys.Strategy 12 | { 13 | //simple moving average strategy. buy/sell on period1 cross period2 14 | 15 | public class RSIStrategy : AbstractStrategy, IStrategy 16 | { 17 | 18 | private AccountManager _am; 19 | public AccountManager AccountManager { get { return _am; } set { _am = value; } } 20 | 21 | 22 | public RSIStrategy() : base() 23 | { 24 | AttachIndicator("RSI14", new RSI()); 25 | } 26 | 27 | 28 | public void OnTick(params Tick[] t) 29 | { 30 | double rsi1 = indicatorList["RSI14"].HandleNextTick(t[0]); 31 | double prevRSI = ((RSI)indicatorList["RSI14"])[1]; 32 | 33 | if (rsi1 >= 70 && prevRSI < 70 && !_am.ExistsPositionForSymbol(t[0].Symbol)) 34 | { 35 | _am.PlaceOrder(new MarketOrder(t[0], Position.PositionSide.Long, _am.CurrentBalance )); 36 | 37 | Console.WriteLine("Placed Long Trade at " + t[0].AskClose); 38 | } 39 | 40 | if (rsi1 <= 30 && prevRSI > 30 && !_am.ExistsPositionForSymbol(t[0].Symbol)) 41 | { 42 | _am.PlaceOrder(new MarketOrder(t[0], Position.PositionSide.Short, _am.CurrentBalance )); 43 | 44 | Console.WriteLine("Placed Short Trade at " + t[0].AskClose); 45 | } 46 | 47 | if (rsi1 < 65 && prevRSI > 65 && _am.ExistsPositionForSymbol(t[0].Symbol)) 48 | { 49 | _am.CloseOrder(t[0]); 50 | 51 | Console.WriteLine("Closed Long Trade at " + t[0].AskClose); 52 | } 53 | 54 | if (rsi1 >30 && prevRSI < 30 && _am.ExistsPositionForSymbol(t[0].Symbol)) 55 | { 56 | _am.CloseOrder(t[0]); 57 | 58 | Console.WriteLine("Closed Short Trade at " + t[0].AskClose); 59 | } 60 | 61 | } 62 | 63 | 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /DotNet/QuantSys/TradeEngine/AccountManagement/LiveAccountManager.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using QuantSys.MarketData; 3 | using QuantSys.TradeEngine.MarketInterface.FXCMInterface.Functions; 4 | using QuantSys.TradeEngine.Simulation.Account; 5 | 6 | namespace QuantSys.TradeEngine.AccountManagement 7 | { 8 | public class LiveAccountManager : IAccountManager 9 | { 10 | private OrderPlacementEngine _opEngine; 11 | public LiveAccountManager(OrderPlacementEngine opEngine) 12 | { 13 | _opEngine = opEngine; 14 | } 15 | 16 | public void PlaceMarketOrder(Symbol sym, int size, Position.PositionSide side, double stopPips, double LimitPips) 17 | { 18 | OrderPlacementEngine.OrderObject orderObject = _opEngine.prepareParamsFromLoginRules(sym.SymbolString); 19 | _opEngine.CreateTrueMarketOrder(orderObject.AccountID, orderObject.OfferID, size, 20 | (side.Equals(Position.PositionSide.Long)) ? "Buy" : "Sell"); 21 | } 22 | 23 | 24 | public void ClosePosition(Symbol s) 25 | { 26 | OrderPlacementEngine.OrderObject orderObject = _opEngine.prepareParamsFromLoginRules(s.SymbolString); 27 | /* 28 | _opEngine.CreateTrueMarketCloseOrder(orderObject.AccountID, orderObject.OfferID, size, 29 | (side.Equals(Position.PositionSide.Long)) ? "Buy" : "Sell"); 30 | */ 31 | } 32 | 33 | public void ModifyStopOrder() 34 | { 35 | throw new NotImplementedException(); 36 | } 37 | 38 | public void SetTrailingStop() 39 | { 40 | throw new NotImplementedException(); 41 | } 42 | 43 | public void PlaceStopOrder() 44 | { 45 | throw new NotImplementedException(); 46 | } 47 | 48 | public bool ExistsShortPositionForSymbol(Symbol s) 49 | { 50 | throw new NotImplementedException(); 51 | } 52 | 53 | public bool ExistsLongPositionForSymbol(Symbol s) 54 | { 55 | throw new NotImplementedException(); 56 | } 57 | 58 | public bool ExistsPositionForSymbol(Symbol s) 59 | { 60 | throw new NotImplementedException(); 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /DotNet/QuantSys/Analytics/Timeseries/Indicators/Oscillators/KST.cs: -------------------------------------------------------------------------------- 1 | using QuantSys.Analytics.Timeseries.Indicators.Abstraction; 2 | using QuantSys.Analytics.Timeseries.Indicators.Averages; 3 | using QuantSys.Analytics.Timeseries.Indicators.Misc; 4 | using QuantSys.MarketData; 5 | 6 | namespace QuantSys.Analytics.Timeseries.Indicators.Oscillators 7 | { 8 | /// 9 | /// RCMA1 = 10-Period SMA of 10-Period Rate-of-Change 10 | /// RCMA2 = 10-Period SMA of 15-Period Rate-of-Change 11 | /// RCMA3 = 10-Period SMA of 20-Period Rate-of-Change 12 | /// RCMA4 = 15-Period SMA of 30-Period Rate-of-Change 13 | /// KST = (RCMA1 x 1) + (RCMA2 x 2) + (RCMA3 x 3) + (RCMA4 x 4) 14 | /// Signal Line = 9-period SMA of KST 15 | /// 16 | public class KST : AbstractIndicator 17 | { 18 | private ROC ROC1; 19 | private ROC ROC2; 20 | private ROC ROC3; 21 | private ROC ROC4; 22 | 23 | private SMA SMA1; 24 | private SMA SMA2; 25 | private SMA SMA3; 26 | private SMA SMA4; 27 | 28 | public KST(int p1 = 10, int p2 = 15, int p3 = 20, int p4 = 30, int n = 10) : base(n) 29 | { 30 | ROC1 = new ROC(p1); 31 | ROC2 = new ROC(p2); 32 | ROC3 = new ROC(p3); 33 | ROC4 = new ROC(p4); 34 | 35 | SMA1 = new SMA(p1); 36 | SMA2 = new SMA(p2); 37 | SMA3 = new SMA(p3); 38 | SMA4 = new SMA(p4); 39 | 40 | } 41 | 42 | 43 | public override double HandleNextTick(Tick t) 44 | { 45 | double r1 = ROC1.HandleNextTick(t); 46 | double r2 = ROC1.HandleNextTick(t); 47 | double r3 = ROC1.HandleNextTick(t); 48 | double r4 = ROC1.HandleNextTick(t); 49 | 50 | double s1 = SMA1.HandleNextTick(r1); 51 | double s2 = SMA1.HandleNextTick(r2); 52 | double s3 = SMA1.HandleNextTick(r3); 53 | double s4 = SMA1.HandleNextTick(r4); 54 | 55 | double KST = (s1*1) + (s2*2) + (s3*3) + (s4*4); 56 | 57 | indicatorData.Enqueue(KST); 58 | return KST; 59 | } 60 | 61 | public override string ToString() 62 | { 63 | return "KST" + Period; 64 | } 65 | } 66 | } -------------------------------------------------------------------------------- /DotNet/QuantSys/MachineLearning/GeneticAlgorithm/Selection.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace QuantSys.MachineLearning.GeneticAlgorithm 5 | { 6 | public static class Selection 7 | { 8 | public static Population ElitismSelection(this Population p, int number) 9 | { 10 | Comparison comparator = ( 11 | (x, y) => 12 | { 13 | if (x.Fitness.Equals(y.Fitness)) return 0; 14 | return (x.Fitness > y.Fitness) ? -1 : 1; 15 | } 16 | ); 17 | 18 | p.Chromosomes.Sort(comparator); 19 | var elite = new List(); 20 | 21 | for (int i = 0; i < number; i++) elite.Add(p.Chromosomes[i]); 22 | 23 | return new Population(elite); 24 | } 25 | 26 | public static Population SimpleRouletteSelection(this Population pCopy, int number, Random r) 27 | { 28 | var result = new List(); 29 | var p = new Population(new List(pCopy.Chromosomes)); 30 | 31 | for (int n = 0; n < number; n++) 32 | { 33 | var fitnessProportion = new double[p.PopulationSize]; 34 | double totalFitness = 0; 35 | double totalProbability = 0; 36 | 37 | for (int i = 0; i < p.PopulationSize; i++) 38 | { 39 | totalFitness += p.Chromosomes[i].Fitness; 40 | } 41 | 42 | for (int i = 0; i < p.PopulationSize; i++) 43 | { 44 | fitnessProportion[i] = totalProbability + (p.Chromosomes[i].Fitness/totalFitness); 45 | totalProbability = fitnessProportion[i]; 46 | } 47 | 48 | double random = r.NextDouble(); 49 | for (int i = 0; i < p.PopulationSize; i++) 50 | { 51 | if (random <= fitnessProportion[i]) 52 | { 53 | result.Add(p.Chromosomes[i]); 54 | p.Chromosomes.Remove(p.Chromosomes[i]); 55 | break; 56 | } 57 | } 58 | } 59 | 60 | return new Population(result); 61 | } 62 | } 63 | } -------------------------------------------------------------------------------- /DotNet/QuantSys/Analytics/Timeseries/Indicators/Channels/QSPolyChannel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using MathNet.Numerics.LinearAlgebra; 4 | using QuantSys.Analytics.StatisticalModeling; 5 | using QuantSys.Analytics.Timeseries.Indicators.Abstraction; 6 | using QuantSys.Analytics.Timeseries.Indicators.Averages; 7 | using QuantSys.DataStructures; 8 | using QuantSys.MarketData; 9 | 10 | namespace QuantSys.Analytics.Timeseries.Indicators.Channels 11 | { 12 | /// 13 | /// Similar to Kirshenbaum Bands, but uses a polynomial 14 | /// regression to find least squares instead. 15 | /// 16 | 17 | class QSPolyChannel : AbstractChannel 18 | { 19 | private EMA EMA; 20 | private MovingQueue LRValues; 21 | private double[] X; 22 | private double STDEV; 23 | 24 | public QSPolyChannel(int n = 20, int l = 30, double dev = 1.5) 25 | : base(n) 26 | { 27 | EMA = new EMA(n); 28 | LRValues= new MovingQueue(l); 29 | X = new double[l]; 30 | for (int i = 0; i < X.Count(); i++) X[i] = i; 31 | STDEV = dev; 32 | } 33 | 34 | public override void HandleNextTick(Tick t) 35 | { 36 | double emaVal = EMA.HandleNextTick(t); 37 | LRValues.Enqueue(emaVal); 38 | 39 | double[] Y = LRValues.ToArray(); 40 | 41 | double stdErr = 0; 42 | 43 | if (Y.Count() == X.Length) 44 | { 45 | Vector x_data = new Vector(X); 46 | Vector y_data = new Vector(LRValues.ToArray()); 47 | 48 | var poly = new PolynomialRegression(x_data, y_data, 2); 49 | for (int i = 0; i < Period; i++) 50 | { 51 | double x = (i); 52 | double y = poly.Fit(x); 53 | stdErr += Math.Pow(LRValues.ToArray()[i] - y, 2); 54 | } 55 | 56 | stdErr = Math.Sqrt(stdErr); 57 | } 58 | 59 | HighData.Enqueue(EMA[0]+STDEV * stdErr); 60 | MiddleData.Enqueue(EMA[0]); 61 | LowData.Enqueue(EMA[0] - STDEV * stdErr); 62 | 63 | } 64 | 65 | public override string ToString() 66 | { 67 | return "QSPoly Bands" + Period; 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /DotNet/QuantSys/TradeEngine/Strategy/MACrossEntry.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using QuantSys.MarketData; 7 | using QuantSys.PortfolioEngine; 8 | using QuantSys.PortfolioEngine.Order; 9 | using QuantSys.Analytics.Indicators; 10 | 11 | namespace QuantSys.Strategy 12 | { 13 | public class MACrossEntry : AbstractStrategy, IStrategy 14 | { 15 | 16 | private AccountManager _am; 17 | public AccountManager AccountManager { get { return _am; } set { _am = value; } } 18 | 19 | private ExponentialMovingAverage EMA1 = new ExponentialMovingAverage(5); 20 | private ExponentialMovingAverage EMA2 = new ExponentialMovingAverage(30); 21 | private ExponentialMovingAverage EMA3 = new ExponentialMovingAverage(5); 22 | private ExponentialMovingAverage EMA4 = new ExponentialMovingAverage(30); 23 | 24 | 25 | 26 | public MACrossEntry(int p1, int p2, int p3, int p4) 27 | : base() 28 | { 29 | EMA1 = new ExponentialMovingAverage(p1); 30 | EMA2 = new ExponentialMovingAverage(p2); 31 | EMA3 = new ExponentialMovingAverage(p3); 32 | EMA4 = new ExponentialMovingAverage(p4); 33 | } 34 | 35 | public void OnTick(params Tick[] t) 36 | { 37 | EMA1.HandleNextTick(t[0].AskClose); 38 | EMA2.HandleNextTick(t[0].AskClose); 39 | EMA3.HandleNextTick(t[0].AskClose); 40 | EMA4.HandleNextTick(t[0].AskClose); 41 | 42 | if (EMA1[0] < EMA2[0] && EMA1[1] > EMA2[1]) 43 | { 44 | if (_am.ExistsPositionForSymbol(t[0].Symbol)) _am.CloseOrder(t[0]); 45 | _am.PlaceOrder(new MarketOrder(t[0], Position.PositionSide.Short, 10000)); 46 | 47 | //Console.WriteLine("Open Short Trade at " + t[0].AskClose); 48 | } 49 | 50 | if (EMA3[0] > EMA4[0] && EMA3[1] < EMA4[1] && !_am.ExistsPositionForSymbol(t[0].Symbol)) 51 | { 52 | if (_am.ExistsPositionForSymbol(t[0].Symbol)) _am.CloseOrder(t[0]); 53 | _am.PlaceOrder(new MarketOrder(t[0], Position.PositionSide.Long, 10000)); 54 | 55 | //Console.WriteLine("Open Short Trade at " + t[0].AskClose); 56 | } 57 | 58 | } 59 | 60 | 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /DotNet/QuantSys/Analytics/Timeseries/Indicators/Misc/ReversalGenesis.cs: -------------------------------------------------------------------------------- 1 | using QuantSys.Analytics.Timeseries.Indicators.Abstraction; 2 | using QuantSys.Analytics.Timeseries.Indicators.Averages; 3 | using QuantSys.Analytics.Timeseries.Indicators.Channels; 4 | using QuantSys.Analytics.Timeseries.Indicators.Oscillators; 5 | using QuantSys.MarketData; 6 | 7 | namespace QuantSys.Analytics.Timeseries.Indicators.Misc 8 | { 9 | public class ReversalGenesis : AbstractIndicator 10 | { 11 | private AdaptiveSmoothing T3; 12 | private AdaptiveSmoothing T32; 13 | private CCI CCI; 14 | private WilliamsR WILLR; 15 | private AC AC; 16 | private GannHiLo Gann; 17 | private KST KST; 18 | private Chaikin CH; 19 | private BollingerBands BB; 20 | private QSPolyChannel QChannel; 21 | private ForceIndex FI; 22 | private PFE PFE; 23 | private RWI RWI; 24 | private UltimateOscillator UO; 25 | 26 | public const double indNumber = 2; 27 | public ReversalGenesis(int n) 28 | : base(n) 29 | { 30 | T3 = new AdaptiveSmoothing(n); 31 | T32 = new AdaptiveSmoothing(5 * n); 32 | CCI = new CCI(n); 33 | WILLR = new WilliamsR(n); 34 | 35 | Gann = new GannHiLo(n); 36 | KST = new KST(); 37 | CH = new Chaikin(); 38 | BB = new BollingerBands(n); 39 | UO = new UltimateOscillator(n,2*n,3*n); 40 | 41 | } 42 | 43 | public override double HandleNextTick(Tick t) 44 | { 45 | BB.HandleNextTick(t); 46 | WILLR.HandleNextTick(t); 47 | UO.HandleNextTick(t); 48 | 49 | double value = 0; 50 | 51 | 52 | if (t.BidClose > BB.HI(0)) 53 | value--; 54 | else if (t.BidClose < BB.LOW(0)) 55 | value++; 56 | 57 | if (WILLR[0] > -20) 58 | value--; 59 | else if (WILLR[0] < -80) 60 | value++; 61 | 62 | if (UO[0] > 70) 63 | value--; 64 | else if (UO[0] < 30) 65 | value++; 66 | 67 | 68 | 69 | indicatorData.Enqueue(value); 70 | return value; 71 | } 72 | 73 | public override string ToString() 74 | { 75 | return "RGenesis" + Period; 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /DotNet/QuantSys/TradeEngine/Strategy/ACStrat.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using QuantSys.Analytics.Timeseries.Indicators.Oscillators; 3 | using QuantSys.MarketData; 4 | using QuantSys.TradeEngine.Simulation.Account; 5 | 6 | namespace QuantSys.TradeEngine.Strategy 7 | { 8 | public class ACStrat: AbstractStrategy 9 | { 10 | public ACStrat() 11 | { 12 | AttachIndicator("AC0", new AC(200, 50, 100)); 13 | AttachIndicator("SMA", new RWI(50)); 14 | } 15 | public override void OnTick(params Tick[] t) 16 | { 17 | foreach (var indicator in indicatorList) 18 | { 19 | indicator.Value.HandleNextTick(t[0]); 20 | } 21 | 22 | if (!IsLive) return; 23 | 24 | 25 | for (int i = 0; i < t.Count(); i++) 26 | { 27 | if (indicatorList["AC" + i][0] < 0) 28 | { 29 | if (IAccountManager.ExistsLongPositionForSymbol(t[i].Symbol)) 30 | { 31 | IAccountManager.ClosePosition(t[i].Symbol); 32 | } 33 | } 34 | 35 | if (indicatorList["AC" + i][0] > 0) 36 | { 37 | if (IAccountManager.ExistsShortPositionForSymbol(t[i].Symbol)) 38 | { 39 | IAccountManager.ClosePosition(t[i].Symbol); 40 | } 41 | } 42 | 43 | 44 | if (!(t[i].AskClose - t[i].BidClose < .0003)) return; 45 | 46 | 47 | if (indicatorList["AC" + i][0] > 0 && indicatorList["AC" + i][1] < 0 && t[0].BidClose > indicatorList["SMA"][0]) 48 | { 49 | if (!IAccountManager.ExistsPositionForSymbol(t[i].Symbol)) 50 | { 51 | IAccountManager.PlaceMarketOrder(t[1].Symbol, 10000, Position.PositionSide.Long, .01); 52 | } 53 | } 54 | 55 | if (indicatorList["AC" + i][0] < 0 && indicatorList["AC" + i][1] > 0 && t[0].BidClose < indicatorList["SMA"][0]) 56 | { 57 | if (!IAccountManager.ExistsPositionForSymbol(t[i].Symbol)) 58 | { 59 | IAccountManager.PlaceMarketOrder(t[1].Symbol, 10000, Position.PositionSide.Short, .01); 60 | } 61 | } 62 | 63 | 64 | 65 | } 66 | 67 | 68 | 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /DotNet/QuantSys/TradeEngine/Strategy/Pyramid.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using QuantSys.Analytics.Timeseries.Indicators.Abstraction; 3 | using QuantSys.MarketData; 4 | using QuantSys.TradeEngine.AccountManagement; 5 | 6 | namespace QuantSys.TradeEngine.Strategy 7 | { 8 | public class Pyramid: AbstractStrategy 9 | { 10 | public IAccountManager IAccountManager { get; set; } 11 | 12 | private double UpSizeChange; 13 | private double DownSizeChange; 14 | 15 | private double priceLimit; 16 | 17 | public Dictionary Indicators { get { return indicatorList; } } 18 | 19 | public Pyramid(double a = .1, double b = .1, double c = .1 / 100) 20 | { 21 | UpSizeChange = a; 22 | DownSizeChange = b; 23 | priceLimit = c; 24 | } 25 | 26 | public override void OnTick(params Tick[] t) 27 | { 28 | /* 29 | if (IAccountManager.ExistsPositionForSymbol(t[0].Symbol)) 30 | { 31 | Position p = IAccountManager.Portfolio[t[0].Symbol]; 32 | 33 | //increase long position size by x% if price has increase by y% 34 | if (p.Side.Equals(Position.PositionSide.Long)) 35 | { 36 | if ((t[0].BidClose - p.PositionPrice) / p.PositionPrice > priceLimit) 37 | { 38 | IAccountManager.IncreasePosition(t[0], p.Size * UpSizeChange); 39 | } 40 | 41 | if ((t[0].BidClose - p.PositionPrice) / p.PositionPrice < -priceLimit) 42 | { 43 | IAccountManager.ReducePosition(t[0], p.Size * DownSizeChange); 44 | } 45 | } 46 | 47 | //increase short position size by x% if price has decreased by y% 48 | else if (p.Side.Equals(Position.PositionSide.Short)) 49 | { 50 | if ((p.PositionPrice - t[0].AskClose) / p.PositionPrice > priceLimit) 51 | { 52 | IAccountManager.IncreasePosition(t[0], p.Size * UpSizeChange); 53 | } 54 | 55 | if ((p.PositionPrice - t[0].AskClose) / p.PositionPrice < -priceLimit) 56 | { 57 | IAccountManager.ReducePosition(t[0], p.Size * DownSizeChange); 58 | } 59 | } 60 | 61 | }*/ 62 | 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /DotNet/QuantSys/Analytics/Timeseries/Indicators/Averages/EMA.cs: -------------------------------------------------------------------------------- 1 | using QuantSys.Analytics.StatisticalModeling; 2 | using QuantSys.Analytics.Timeseries.Indicators.Abstraction; 3 | using QuantSys.DataStructures; 4 | using QuantSys.MarketData; 5 | 6 | namespace QuantSys.Analytics.Timeseries.Indicators.Averages 7 | { 8 | public class EMA : AbstractIndicator 9 | { 10 | private readonly double alpha; 11 | private readonly MovingQueue tickdata; 12 | private int iteration; 13 | 14 | private AbstractIndicator indicator; 15 | 16 | public EMA(int N, AbstractIndicator indicator = null) : base(N) 17 | { 18 | alpha = 2.0/(N + 1); 19 | tickdata = new MovingQueue(N); 20 | this.indicator = indicator; 21 | } 22 | 23 | public override double HandleNextTick(Tick t) 24 | { 25 | if (indicator != null) return HandleNextTick(indicator.HandleNextTick(t)); 26 | return HandleNextTick(t.BidClose); 27 | } 28 | 29 | public double HandleNextTick(double currentTick) 30 | { 31 | double value = double.NaN; 32 | 33 | if (!currentTick.Equals(double.NaN)) 34 | { 35 | tickdata.Enqueue(currentTick); 36 | 37 | if (tickdata.Count.Equals(tickdata.Capacity)) 38 | { 39 | if(indicatorData.Count.Equals(0)) 40 | value = tickdata.ToArray().Average(); 41 | else 42 | value = currentTick*alpha + this[0]*(1 - alpha); 43 | 44 | indicatorData.Enqueue(value); 45 | } 46 | 47 | } 48 | 49 | return value; 50 | } 51 | 52 | public override string ToString() 53 | { 54 | return "EMA" + Period; 55 | } 56 | 57 | 58 | public static double[] CalcEMA(double[] data, int n) 59 | { 60 | var result = new double[data.Length]; 61 | double alpha = 2.0/(n + 1); 62 | 63 | double initEMA = 0; 64 | for (int i = 0; i < n; i++) 65 | { 66 | result[i] = double.NaN; 67 | initEMA += data[i]; 68 | } 69 | 70 | initEMA /= n; 71 | 72 | result[n] = initEMA; 73 | 74 | for (int i = n + 1; i < data.Length; i++) 75 | { 76 | result[i] = data[i]*alpha + result[i - 1]*(1 - alpha); 77 | } 78 | 79 | return result; 80 | } 81 | } 82 | } -------------------------------------------------------------------------------- /DotNet/QuantSys/TradeEngine/MarketInterface/FXCMInterface/EventArguments/MarketDataEventArg.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using fxcore2; 4 | using QuantSys.MarketData; 5 | 6 | namespace QuantSys.TradeEngine.MarketInterface.FXCMInterface.EventArguments 7 | { 8 | public class MarketDataEventArg : EventArgs 9 | { 10 | public Quantum data; 11 | 12 | public MarketDataEventArg(Quantum data) 13 | { 14 | this.data = data; 15 | } 16 | 17 | public MarketDataEventArg() 18 | { 19 | data = new Quantum(); 20 | } 21 | 22 | public static MarketDataEventArg ProcessMarketData(FXSession connection, O2GResponse response) 23 | { 24 | try 25 | { 26 | O2GResponseReaderFactory rrfactory = connection.Session.getResponseReaderFactory(); 27 | O2GMarketDataSnapshotResponseReader mReader = rrfactory.createMarketDataSnapshotReader(response); 28 | 29 | var d = new SortedList(mReader.Count); 30 | 31 | for (int i = 0; i < mReader.Count; i++) 32 | { 33 | // information like reader.getDate(i), reader.getBidOpen(i), reader.getBidHigh(i), reader.getBidLow(i), reader.getBidClose(i), reader.getVolume(i) is now available 34 | //Console.WriteLine(i + ":" + mReader.getDate(i).ToString() + ":" + mReader.getBidOpen(i)); 35 | //create a quantum of ticks for the market data 36 | var tick = new Tick( 37 | mReader.getBid(i), 38 | mReader.getBidOpen(i), 39 | mReader.getBidHigh(i), 40 | mReader.getBidLow(i), 41 | mReader.getBidClose(i), 42 | mReader.getAsk(i), 43 | mReader.getAskOpen(i), 44 | mReader.getAskHigh(i), 45 | mReader.getAskLow(i), 46 | mReader.getAskClose(i), 47 | mReader.getVolume(i), 48 | mReader.getDate(i)); 49 | 50 | d.Add(mReader.getDate(i), tick); 51 | } 52 | 53 | var q = new Quantum(d); 54 | return new MarketDataEventArg(q); 55 | } 56 | catch (Exception e) 57 | { 58 | Console.WriteLine(e.Message); 59 | return new MarketDataEventArg(new Quantum(new SortedList(300))); 60 | } 61 | } 62 | } 63 | } -------------------------------------------------------------------------------- /DotNet/QuantSys/Analytics/Timeseries/Indicators/Misc/Genesis.cs: -------------------------------------------------------------------------------- 1 | using QuantSys.Analytics.Timeseries.Indicators.Abstraction; 2 | using QuantSys.Analytics.Timeseries.Indicators.Averages; 3 | using QuantSys.Analytics.Timeseries.Indicators.Channels; 4 | using QuantSys.Analytics.Timeseries.Indicators.Oscillators; 5 | using QuantSys.MarketData; 6 | 7 | namespace QuantSys.Analytics.Timeseries.Indicators.Misc 8 | { 9 | public class Genesis : AbstractIndicator 10 | { 11 | private AdaptiveSmoothing T3; 12 | private AdaptiveSmoothing T32; 13 | private CCI CCI; 14 | private WilliamsR WILLR; 15 | private AC AC; 16 | private GannHiLo Gann; 17 | private KST KST; 18 | private Chaikin CH; 19 | private BollingerBands BB; 20 | private QSPolyChannel QChannel; 21 | private ForceIndex FI; 22 | private PFE PFE; 23 | private RWI RWI; 24 | 25 | public const double indNumber = 3; 26 | public Genesis(int n) : base(n) 27 | { 28 | T3 = new AdaptiveSmoothing(n); 29 | T32 = new AdaptiveSmoothing(5 * n); 30 | CCI = new CCI(n); 31 | WILLR = new WilliamsR(n); 32 | 33 | Gann = new GannHiLo(n); 34 | KST = new KST(); 35 | CH = new Chaikin(); 36 | BB = new BollingerBands(); 37 | QChannel = new QSPolyChannel(); 38 | FI = new ForceIndex(30); 39 | PFE = new PFE(150); 40 | RWI = new RWI(30); 41 | AC = new AC(10); 42 | } 43 | 44 | public override double HandleNextTick(Tick t) 45 | { 46 | PFE.HandleNextTick(t); 47 | FI.HandleNextTick(t); 48 | RWI.HandleNextTick(t); 49 | AC.HandleNextTick(t); 50 | double value = 0; 51 | 52 | 53 | if (AC[0] > 0) 54 | value++; 55 | else if (AC[0] < 0) 56 | value--; 57 | 58 | if (PFE[0] > 0) 59 | value++; 60 | else if (PFE[0] < 0) 61 | value--; 62 | 63 | if (RWI.SubIndicators["RWHI"][0] > 1 && RWI.SubIndicators["RWHI"][0] > RWI.SubIndicators["RWLO"][0]) 64 | value++; 65 | if (RWI.SubIndicators["RWLO"][0] > 1 && RWI.SubIndicators["RWLO"][0] > RWI.SubIndicators["RWHI"][0]) 66 | value--; 67 | 68 | indicatorData.Enqueue(value); 69 | return value; 70 | } 71 | 72 | public override string ToString() 73 | { 74 | return "Genesis" + Period; 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /DotNet/QuantSys/Analytics/Timeseries/Indicators/Misc/MFI.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using QuantSys.Analytics.Timeseries.Indicators.Abstraction; 3 | using QuantSys.DataStructures; 4 | using QuantSys.MarketData; 5 | 6 | namespace QuantSys.Analytics.Timeseries.Indicators.Misc 7 | { 8 | /// 9 | /// The Money Flow Index (MFI) is an oscillator that uses both 10 | /// price and volume to measure buying and selling pressure. 11 | /// Created by Gene Quong and Avrum Soudack, MFI is also known 12 | /// as volume-weighted RSI. MFI starts with the typical price 13 | /// for each period. Money flow is positive when the typical 14 | /// price rises (buying pressure) and negative when the typical 15 | /// price declines (selling pressure). A ratio of positive and 16 | /// negative money flow is then plugged into an RSI formula to 17 | /// create an oscillator that moves between zero and one hundred. 18 | /// As a momentum oscillator tied to volume, the Money Flow Index 19 | /// (MFI) is best suited to identify reversals and price extremes 20 | /// with a variety of signals. 21 | /// 22 | /// * 1. Typical Price = (High + Low + Close)/3 23 | /// * 2. Raw Money Flow = Typical Price x Volume 24 | /// * 3. Money Flow Ratio = (14-period Positive Money Flow)/(14-period Negative Money Flow) 25 | /// * 4. Money Flow Index = 100 - 100/(1 + Money Flow Ratio) 26 | /// 27 | 28 | 29 | public class MFI : AbstractIndicator 30 | { 31 | 32 | private MovingQueue PositiveMF; 33 | private MovingQueue NegativeMF; 34 | 35 | public MFI(int n = 14) :base(n) 36 | { 37 | PositiveMF = new MovingQueue(n); 38 | NegativeMF = new MovingQueue(n); 39 | } 40 | 41 | public override double HandleNextTick(Tick t) 42 | { 43 | double MFITick = double.NaN; 44 | 45 | if (PositiveMF.Count == Period) 46 | { 47 | double MFR = PositiveMF.ToArray().Sum()/NegativeMF.ToArray().Sum(); 48 | MFITick = 100 - 100/(1 + MFR); 49 | } 50 | 51 | double tPrice = (t.BidHigh + t.BidLow + t.BidClose)/3; 52 | double rawMoneyFlow = t.Volume*tPrice; 53 | 54 | PositiveMF.Enqueue((t.BidClose >= t.BidOpen) ? rawMoneyFlow : 0); 55 | NegativeMF.Enqueue((t.BidClose < t.BidOpen) ? rawMoneyFlow : 0); 56 | 57 | indicatorData.Enqueue(MFITick); 58 | return MFITick; 59 | } 60 | 61 | public override string ToString() 62 | { 63 | throw new System.NotImplementedException(); 64 | } 65 | } 66 | } -------------------------------------------------------------------------------- /DotNet/QuantSys/TradeEngine/MarketInterface/FXCMInterface/Functions/Jobs/Job_SingleStatistic.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Threading; 4 | using MathNet.Numerics.LinearAlgebra.Double; 5 | using QuantSys.MarketData; 6 | using QuantSys.TradeEngine.MarketInterface.FXCMInterface.EventArguments; 7 | 8 | namespace QuantSys.TradeEngine.MarketInterface.FXCMInterface.Functions.Jobs 9 | { 10 | public class Job_SingleStatistic 11 | { 12 | private readonly Func function; 13 | private readonly List mktData; 14 | private readonly int numTicks; 15 | private readonly string[] symbols; 16 | private readonly string timeframe; 17 | public DenseVector results; 18 | 19 | public Job_SingleStatistic(string[] symbols, string timeframe, int numTicks, Func function) 20 | { 21 | this.symbols = symbols; 22 | this.timeframe = timeframe; 23 | this.numTicks = numTicks; 24 | mktData = new List(); 25 | results = new DenseVector(symbols.Length); 26 | this.function = function; 27 | } 28 | 29 | public void RunJob(FXSession fxsession) 30 | { 31 | foreach (string symbol in symbols) 32 | { 33 | //ResponseHandler.GetHistoricPrices(fxsession, symbol, timeframe, numTicks); 34 | Thread.Sleep(100); // don't overload api 35 | } 36 | } 37 | 38 | public bool UpdateJob(object data) 39 | { 40 | try 41 | { 42 | var m = (MarketDataEventArg)data; 43 | mktData.Add(m); 44 | if (mktData.Count != symbols.Length) 45 | return false; 46 | FinishAndProcess(); 47 | return true; 48 | } 49 | catch (Exception e) 50 | { 51 | Console.WriteLine(e.Message); 52 | } 53 | 54 | return false; 55 | } 56 | 57 | public void FinishAndProcess() 58 | { 59 | var priceData = new DenseMatrix(symbols.Length, numTicks); 60 | 61 | for (int j = 0; j < symbols.Length; j++) 62 | { 63 | SortedList d = mktData[j].data.Data; 64 | for (int k = 0; k < d.Count; k++) 65 | { 66 | priceData[j, k] = d.Values[k].BidClose; 67 | } 68 | } 69 | 70 | for (int i = 0; i < symbols.Length; i++) 71 | { 72 | results[i] = function((DenseVector) priceData.Row(i)); 73 | } 74 | } 75 | } 76 | } -------------------------------------------------------------------------------- /DotNet/QuantSys/TradeEngine/Strategy/ChannelStrategy.cs: -------------------------------------------------------------------------------- 1 | using QuantSys.Analytics.Timeseries.Indicators.Averages; 2 | using QuantSys.Analytics.Timeseries.Indicators.Channels; 3 | using QuantSys.Analytics.Timeseries.Indicators.Misc; 4 | using QuantSys.Analytics.Timeseries.Indicators.Transforms; 5 | using QuantSys.MarketData; 6 | using QuantSys.TradeEngine.Simulation.Account; 7 | 8 | namespace QuantSys.TradeEngine.Strategy 9 | { 10 | public class ChannelStrategy: AbstractStrategy 11 | { 12 | private QSPolyChannel channel; 13 | 14 | private Tick prevTick; 15 | 16 | private const double STOPLEVEL = 0.005; 17 | 18 | public ChannelStrategy() 19 | { 20 | channel = new QSPolyChannel(); 21 | AttachIndicator("EMA", new EMA(15)); 22 | AttachIndicator("HVOL", new PercentileRank(100, new HistoricalVol(20))); 23 | } 24 | public override void OnTick(params Tick[] t) 25 | { 26 | channel.HandleNextTick(t[0]); 27 | 28 | foreach (var indicator in indicatorList) 29 | { 30 | indicator.Value.HandleNextTick(t[0]); 31 | } 32 | 33 | if (prevTick != null) 34 | { 35 | 36 | if (IAccountManager.ExistsLongPositionForSymbol(t[0].Symbol)) 37 | { 38 | 39 | if (indicatorList["EMA"][0] < channel.LOW(0)) 40 | IAccountManager.ClosePosition(t[0].Symbol); 41 | 42 | } 43 | if (IAccountManager.ExistsShortPositionForSymbol(t[0].Symbol)) 44 | { 45 | 46 | if (indicatorList["EMA"][0] > channel.HI(0)) 47 | IAccountManager.ClosePosition(t[0].Symbol); 48 | } 49 | 50 | //Volatility high 51 | if (indicatorList["HVOL"][0] > 40) 52 | { 53 | if (!IAccountManager.ExistsPositionForSymbol(t[0].Symbol)) 54 | { 55 | if (indicatorList["EMA"][0] > channel.HI(0) && indicatorList["EMA"][1] < channel.HI(1)) 56 | IAccountManager.PlaceMarketOrder(t[1].Symbol, 10000, Position.PositionSide.Long, STOPLEVEL); 57 | } 58 | 59 | if (!IAccountManager.ExistsPositionForSymbol(t[0].Symbol)) 60 | { 61 | if (indicatorList["EMA"][0] < channel.LOW(0) && indicatorList["EMA"][1] > channel.LOW(1)) 62 | IAccountManager.PlaceMarketOrder(t[1].Symbol, 10000, Position.PositionSide.Short, STOPLEVEL); 63 | } 64 | 65 | } 66 | 67 | } 68 | 69 | prevTick = t[0]; 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /DotNet/QuantSys/TradeEngine/Simulation/Account/Position.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using QuantSys.MarketData; 3 | 4 | namespace QuantSys.TradeEngine.Simulation.Account 5 | { 6 | 7 | public class Position 8 | { 9 | public enum PositionSide 10 | { 11 | Long = 1, 12 | Short = 2 13 | }; 14 | 15 | public bool isLong {get { return Side.Equals(PositionSide.Long); }} 16 | public bool isShort { get { return Side.Equals(PositionSide.Short); } } 17 | 18 | public PositionSide Side; 19 | 20 | public Symbol Symbol { get; set; } 21 | public double Size { get; set; } 22 | public double PositionPrice { get; set; } 23 | public DateTime? OpenDate { get; set; } 24 | public DateTime? CloseDate { get; set; } 25 | 26 | public Position(Symbol symbol, double openPrice, double size, PositionSide side, DateTime openDate) 27 | { 28 | Symbol = symbol; 29 | PositionPrice = openPrice; 30 | Side = side; 31 | Size = size; 32 | OpenDate = openDate; 33 | } 34 | 35 | public double ClosePosition(Tick t, double price) 36 | { 37 | CloseDate = t.Time; 38 | 39 | if (Side.Equals(PositionSide.Long)) 40 | return Size * (price - PositionPrice); 41 | else 42 | return Size * (PositionPrice - price); 43 | } 44 | 45 | public double ReducePosition(Tick t, double size) 46 | { 47 | double returnAmount = 0; 48 | double newSize = this.Size - size; 49 | switch (Side) 50 | { 51 | case PositionSide.Long: 52 | { 53 | returnAmount = size * (t.BidClose - PositionPrice); 54 | break; 55 | } 56 | case PositionSide.Short: 57 | { 58 | returnAmount = size * (PositionPrice - t.AskClose); 59 | break; 60 | } 61 | } 62 | 63 | this.Size = newSize; 64 | return returnAmount; 65 | } 66 | 67 | public void IncreasePosition(Tick t, double size) 68 | { 69 | double newSize = this.Size + size; 70 | switch (Side) 71 | { 72 | case PositionSide.Long: 73 | { 74 | PositionPrice = (this.Size * PositionPrice + size * t.AskClose)/newSize; 75 | break; 76 | } 77 | case PositionSide.Short: 78 | { 79 | PositionPrice = (this.Size * PositionPrice + size * t.BidClose) / newSize; 80 | break; 81 | } 82 | } 83 | 84 | this.Size = newSize; 85 | } 86 | } 87 | } -------------------------------------------------------------------------------- /DotNet/QuantSys/TradeEngine/MarketInterface/FXCMInterface/Functions/Jobs/Job_SymbolSet.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Threading; 4 | using MathNet.Numerics.LinearAlgebra.Double; 5 | using QuantSys.Analytics.Timeseries.Indicators.Abstraction; 6 | using QuantSys.MarketData; 7 | using QuantSys.TradeEngine.MarketInterface.FXCMInterface.EventArguments; 8 | using QuantSys.Util; 9 | using QuantSys.Visualization; 10 | 11 | namespace QuantSys.TradeEngine.MarketInterface.FXCMInterface.Functions.Jobs 12 | { 13 | public class Job_SymbolSet : IJob 14 | { 15 | private readonly DenseMatrix graphData; 16 | private readonly AbstractIndicator indicator; 17 | private readonly List mktData; 18 | private readonly int numTicks; 19 | private readonly string[] symbols; 20 | private readonly string timeframe; 21 | 22 | public Job_SymbolSet(string[] symbols, string timeframe, int numTicks, AbstractIndicator indicator) 23 | { 24 | this.symbols = symbols; 25 | this.indicator = indicator; 26 | this.timeframe = timeframe; 27 | this.numTicks = numTicks; 28 | mktData = new List(); 29 | graphData = new DenseMatrix(symbols.Length, numTicks); 30 | } 31 | 32 | public void RunJob(FXSession fxsession) 33 | { 34 | foreach (string symbol in symbols) 35 | { 36 | //ResponseHandler.GetHistoricPrices(fxsession, symbol, timeframe, numTicks); 37 | Thread.Sleep(100); // don't overload api 38 | } 39 | } 40 | 41 | public bool UpdateJob(object data) 42 | { 43 | try 44 | { 45 | var m = (MarketDataEventArg) data; 46 | mktData.Add(m); 47 | if (mktData.Count != symbols.Length) 48 | return false; 49 | FinishAndProcess(); 50 | return true; 51 | } 52 | catch (Exception e) 53 | { 54 | Console.WriteLine(e.Message); 55 | } 56 | 57 | return false; 58 | } 59 | 60 | public void FinishAndProcess() 61 | { 62 | for (int i = 0; i < symbols.Length; i++) 63 | { 64 | SortedList d = mktData[i].data.Data; 65 | 66 | for (int j = 0; j < numTicks; j++) 67 | { 68 | graphData[i, j] = indicator.HandleNextTick(d.Values[j]); 69 | } 70 | } 71 | 72 | Visualize.GenerateMultiSymbolGraph(symbols, graphData, mktData[0].data.Data.Values[0].Time, 73 | DateTimeUtils.TimeFrameToTimeSpan(timeframe), "C:\\Users\\Ethan\\Work\\QuantSysdata.html"); 74 | 75 | Console.WriteLine("Done Processing symbol set."); 76 | } 77 | } 78 | } -------------------------------------------------------------------------------- /DotNet/QuantSys/TradeEngine/Strategy/NeuralNetworkStrategy.cs: -------------------------------------------------------------------------------- 1 | using QuantSys.Analytics.Timeseries.Indicators.Oscillators; 2 | using QuantSys.DataStructures; 3 | using QuantSys.MachineLearning.NeuralNetwork; 4 | using QuantSys.MarketData; 5 | using QuantSys.TradeEngine.Simulation.Account; 6 | 7 | namespace QuantSys.TradeEngine.Strategy 8 | { 9 | public class NeuralNetworkStrategy: AbstractStrategy 10 | { 11 | 12 | public Stage1NeuralNetwork NeuralNetwork { get; set; } 13 | 14 | private MovingQueue dataList; 15 | private double prevIndicatorTick = double.NaN; 16 | 17 | public NeuralNetworkStrategy(int window) 18 | { 19 | dataList = new MovingQueue(window); 20 | AttachIndicator("IND", new AC(60)); 21 | } 22 | 23 | public override void OnTick(params Tick[] t) 24 | { 25 | foreach (var indicator in indicatorList) 26 | { 27 | indicator.Value.HandleNextTick(t[0]); 28 | } 29 | 30 | if (!indicatorList["IND"][0].Equals(double.NaN)) 31 | dataList.Enqueue(indicatorList["IND"][0]); 32 | 33 | if (dataList.Count == dataList.Capacity) 34 | { 35 | double nextIndicatorTick = NeuralNetwork.PredictNext(dataList.ToArray()); 36 | 37 | //order fire logic 38 | if (nextIndicatorTick > 0 && nextIndicatorTick > prevIndicatorTick && prevIndicatorTick < 0) 39 | { 40 | if (!IAccountManager.ExistsPositionForSymbol(t[0].Symbol)) 41 | { 42 | IAccountManager.PlaceMarketOrder(t[0].Symbol, 10000, Position.PositionSide.Long, .001); 43 | } 44 | } 45 | 46 | //order fire logic 47 | if (nextIndicatorTick < prevIndicatorTick) 48 | { 49 | if (IAccountManager.ExistsLongPositionForSymbol(t[0].Symbol)) 50 | { 51 | IAccountManager.ClosePosition(t[0].Symbol); 52 | } 53 | } 54 | 55 | if (nextIndicatorTick < 0 && nextIndicatorTick < prevIndicatorTick && prevIndicatorTick > 0) 56 | { 57 | if (!IAccountManager.ExistsPositionForSymbol(t[0].Symbol)) 58 | { 59 | IAccountManager.PlaceMarketOrder(t[0].Symbol, 10000, Position.PositionSide.Short, .001); 60 | } 61 | } 62 | 63 | if (nextIndicatorTick > prevIndicatorTick) 64 | { 65 | if (IAccountManager.ExistsShortPositionForSymbol(t[0].Symbol)) 66 | { 67 | IAccountManager.ClosePosition(t[0].Symbol); 68 | } 69 | } 70 | 71 | prevIndicatorTick = nextIndicatorTick; 72 | 73 | } 74 | 75 | 76 | 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /DotNet/QuantSys/Analytics/Timeseries/Indicators/Oscillators/RWI.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using QuantSys.Analytics.Timeseries.Indicators.Abstraction; 5 | using QuantSys.Analytics.Timeseries.Indicators.Misc; 6 | using QuantSys.DataStructures; 7 | using QuantSys.MarketData; 8 | 9 | namespace QuantSys.Analytics.Timeseries.Indicators.Oscillators 10 | { 11 | //Random Walk Index 12 | public class RWI : AbstractIndicator 13 | { 14 | private MovingQueue TR; 15 | private MovingQueue priceData; 16 | private Tick prevTick = null; 17 | 18 | public RWI(int n) : base(n) 19 | { 20 | subIndicators.Add("RWHI", new GenericContainer(n)); 21 | subIndicators.Add("RWLO", new GenericContainer(n)); 22 | TR = new MovingQueue(n); 23 | priceData = new MovingQueue(n); 24 | } 25 | public override double HandleNextTick(Tick t) 26 | { 27 | double value = double.NaN; 28 | double RWIH = double.NaN; 29 | double RWIL = double.NaN; 30 | 31 | if (prevTick != null) 32 | { 33 | double m1 = t.BidHigh - t.BidLow; 34 | double m2 = Math.Abs(t.BidHigh - prevTick.BidClose); 35 | double m3 = Math.Abs(t.BidLow - prevTick.BidClose); 36 | double tr = Math.Max(m1, Math.Max(m2, m3)); 37 | TR.Enqueue(tr); 38 | } 39 | else 40 | { 41 | TR.Enqueue(t.BidHigh - t.BidLow); 42 | } 43 | 44 | if (priceData.Count.Equals(priceData.Capacity)) 45 | { 46 | List maxRWIHI = new List(Period - 1); 47 | List maxRWILO = new List(Period - 1); 48 | 49 | for (int k = 0; k < Period - 1; k++) 50 | { 51 | double avgTR = 0; 52 | for (int i = k; i < Period; i++) avgTR += TR.ToArray()[i]; 53 | avgTR /= (Period - k); 54 | 55 | double rwiHI = 1/Math.Sqrt(Period-k)*(t.BidHigh - priceData.ToArray()[k].BidLow)/avgTR; 56 | double rwiLO = 1/Math.Sqrt(Period-k)*(priceData.ToArray()[k].BidHigh - t.BidLow)/avgTR; 57 | 58 | maxRWIHI.Add(rwiHI); 59 | maxRWILO.Add(rwiLO); 60 | } 61 | RWIH = maxRWIHI.Max(); 62 | RWIL = maxRWILO.Max(); 63 | 64 | } 65 | ((GenericContainer)subIndicators["RWHI"]).HandleNextTick(RWIH); 66 | ((GenericContainer)subIndicators["RWLO"]).HandleNextTick(RWIL); 67 | 68 | prevTick = t; 69 | priceData.Enqueue(t); 70 | 71 | indicatorData.Enqueue(double.NaN); 72 | return double.NaN; 73 | } 74 | 75 | public override string ToString() 76 | { 77 | return "RWI" + Period; 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /DotNet/QuantSys/TradeEngine/Strategy/GenesisStrategy.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using QuantSys.Analytics.Timeseries.Indicators.Averages; 3 | using QuantSys.Analytics.Timeseries.Indicators.Channels; 4 | using QuantSys.Analytics.Timeseries.Indicators.Misc; 5 | using QuantSys.Analytics.Timeseries.Indicators.Transforms; 6 | using QuantSys.MarketData; 7 | using QuantSys.TradeEngine.AccountManagement; 8 | using QuantSys.TradeEngine.Simulation.Account; 9 | 10 | namespace QuantSys.TradeEngine.Strategy 11 | { 12 | public class GenesisStrategy : AbstractStrategy 13 | { 14 | private double indNumber; 15 | private double rindNumber; 16 | 17 | private QSPolyChannel QSP; 18 | 19 | public GenesisStrategy() 20 | { 21 | AttachIndicator("GENESIS", new Genesis(40)); 22 | AttachIndicator("RGENESIS", new ReversalGenesis(40)); 23 | AttachIndicator("EMA", new EMA(5)); 24 | AttachIndicator("HVOL", new PercentileRank(80, new HistoricalVol(40))); 25 | AttachIndicator("ROC", new PercentileRank(400, new ROC(50))); 26 | AttachIndicator("GDEMA", new GDEMA(252, 0.75)); 27 | 28 | QSP = new QSPolyChannel(); 29 | indNumber = Genesis.indNumber; 30 | rindNumber = ReversalGenesis.indNumber; 31 | } 32 | 33 | private double STOPLEVEL; 34 | private double LIMITLEVEL; 35 | 36 | public override void OnTick(params Tick[] t) 37 | { 38 | STOPLEVEL = 50 * t[0].BidOpen/10000; 39 | LIMITLEVEL = 100 * t[0].BidOpen/10000; 40 | int POSIZE = (int) (((AccountManager) IAccountManager).CurrentBalance); 41 | 42 | QSP.HandleNextTick(t[0]); 43 | foreach (var indicator in indicatorList) 44 | { 45 | indicator.Value.HandleNextTick(t[0]); 46 | } 47 | 48 | //Check Spread Cost before trading 49 | if ((t[0].AskClose - t[0].BidClose <= .0005)) 50 | { 51 | 52 | //Volatility high 53 | if (indicatorList["HVOL"][0] > 90) 54 | { 55 | 56 | 57 | 58 | if (indicatorList["GENESIS"][0] < -1 * (indNumber - 0.5) && 59 | indicatorList["GENESIS"][1] > -1 * (indNumber - 0.5) && 60 | indicatorList["EMA"][0] < indicatorList["GDEMA"][0]) 61 | { 62 | if (!IAccountManager.ExistsPositionForSymbol(t[0].Symbol)) 63 | { 64 | IAccountManager.PlaceMarketOrder(t[0].Symbol, POSIZE, Position.PositionSide.Short, STOPLEVEL, LIMITLEVEL); 65 | } 66 | } 67 | } 68 | 69 | } 70 | 71 | if (IAccountManager.ExistsLongPositionForSymbol(t[0].Symbol)) 72 | { 73 | 74 | } 75 | 76 | if (IAccountManager.ExistsShortPositionForSymbol(t[0].Symbol)) 77 | { 78 | 79 | } 80 | 81 | 82 | } 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /DotNet/QuantSys/Analytics/Timeseries/Indicators/Averages/KAMA.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using QuantSys.Analytics.Timeseries.Indicators.Abstraction; 4 | using QuantSys.DataStructures; 5 | using QuantSys.MarketData; 6 | 7 | namespace QuantSys.Analytics.Timeseries.Indicators.Averages 8 | { 9 | //Kaufman's Adaptive Moving Average (KAMA) 10 | /// 11 | /// KAMA is calculated by the formula: 12 | /// KAMA_{i} = KAMA_{i-1} + sc \times {Price - KAMA_{i-1}} 13 | /// where: 14 | /// operatorname{KAMA_{i}} is the value of KAMA in the current period. 15 | /// operatorname{KAMA_{i—1}} is the value of KAMA in the previous period. 16 | /// operatorname{Price} is the price in the current period. 17 | /// operatorname{sc} is the smoothing constant calculated each period by the formula: 18 | /// sc_{i} = (ER_{i} \times {(fastest - slowest) + slowest})^2 19 | /// and 20 | /// fastest = \dfrac{2}{\text {Fastest MA Period} + 1} 21 | /// slowest = \dfrac{2}{\text {Slowest MA period} + 1} 22 | /// ER_{i} = \dfrac{|Price_{t} - Price_{t-n}|}{\sum_{i}^{i-n} |Price_{t} - Price_{t-1}|} 23 | /// http://fxcodebase.com/wiki/index.php/Kaufman's_Adaptive_Moving_Average_(KAMA) 24 | /// 25 | public class KAMA : AbstractIndicator 26 | { 27 | private MovingQueue priceData; 28 | private AbstractIndicator indicator; 29 | 30 | 31 | public KAMA(int n, AbstractIndicator indicator = null) : base(n) 32 | { 33 | priceData = new MovingQueue(n); 34 | this.indicator = indicator; 35 | } 36 | 37 | public override double HandleNextTick(Tick t) 38 | { 39 | if (indicator != null) return HandleNextTick(indicator.HandleNextTick(t)); 40 | return HandleNextTick(t.BidClose); 41 | } 42 | 43 | public double HandleNextTick(double d) 44 | { 45 | double value = double.NaN; 46 | 47 | if (!d.Equals(double.NaN)) 48 | { 49 | priceData.Enqueue(d); 50 | 51 | if (priceData.Count.Equals(priceData.Capacity)) 52 | { 53 | double sum = 0; 54 | double[] array = priceData.ToArray(); 55 | for (int i = 1; i < array.Length; i++) 56 | { 57 | sum += Math.Abs(array[i] - array[i - 1]); 58 | } 59 | double ER = Math.Abs(d - priceData.ToArray()[0])/sum; 60 | 61 | double alpha = Math.Pow(ER*0.6015 + 0.0645, 2); 62 | 63 | if (indicatorData.Count.Equals(0)) 64 | value = priceData.Average(); 65 | else 66 | value = alpha*d + (1 - alpha)*this[1]; 67 | 68 | indicatorData.Enqueue(value); 69 | } 70 | } 71 | 72 | return value; 73 | } 74 | public override string ToString() 75 | { 76 | return "KAMA" + Period; 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /DotNet/QuantSys/MachineLearning/GeneticAlgorithm/Genes/BinaryGene.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using QuantSys.MachineLearning.GeneticAlgorithm.Genes.Constraints; 7 | 8 | namespace QuantSys.MachineLearning.GeneticAlgorithm.Genes 9 | { 10 | public class BinaryGene : Gene 11 | { 12 | public bool[] GeneValue { get; set; } 13 | public BinaryGene(bool[] value, Random r, GeneConstraint c) : base(r) 14 | { 15 | GeneValue = value; 16 | GeneConstraint = c; 17 | } 18 | 19 | public override bool WithinConstraints() 20 | { 21 | throw new NotImplementedException(); 22 | } 23 | 24 | public override void InitializeGene() 25 | { 26 | for (int i = 0; i < (GeneValue).Length; i++) GeneValue[i] = (_randomSeed.NextDouble() > 0.5); 27 | } 28 | 29 | public override bool Mutate(double mRate) 30 | { 31 | if (_randomSeed.NextDouble() <= mRate) 32 | { 33 | int mutateIndex = _randomSeed.Next(GeneValue.Length); 34 | GeneValue[mutateIndex] = !GeneValue[mutateIndex]; 35 | return true; 36 | } 37 | return false; 38 | } 39 | 40 | public override string ToString() 41 | { 42 | var stringBuilder = new StringBuilder(); 43 | for (int i = 0; i < GeneValue.Length; i++) 44 | { 45 | if (GeneValue[i]) stringBuilder.Append("1 "); 46 | else stringBuilder.Append("0 "); 47 | } 48 | return "[" + stringBuilder.ToString().Trim() + "]"; 49 | } 50 | 51 | public override void Crossover(Gene gene2, out Gene child1, out Gene child2) 52 | { 53 | BinaryCrossover(this, (BinaryGene)gene2, out child1, out child2); 54 | } 55 | 56 | public override Gene Clone() 57 | { 58 | return new BinaryGene((bool[])GeneValue.Clone(), _randomSeed, GeneConstraint); 59 | } 60 | 61 | 62 | private void BinaryCrossover(BinaryGene gene1, BinaryGene gene2, out Gene child1, out Gene child2) 63 | { 64 | int crossPoint = _randomSeed.Next(gene1.GeneValue.Length); 65 | 66 | bool[] a = new bool[gene1.GeneValue.Length]; 67 | bool[] b = new bool[gene1.GeneValue.Length]; 68 | 69 | do 70 | { 71 | for (int i = 0; i < crossPoint; i++) 72 | { 73 | a[i] = gene1.GeneValue[i]; 74 | b[i] = gene2.GeneValue[i]; 75 | } 76 | 77 | for (int i = crossPoint; i < gene1.GeneValue.Length; i++) 78 | { 79 | a[i] = gene2.GeneValue[i]; 80 | b[i] = gene1.GeneValue[i]; 81 | } 82 | 83 | } while (!GeneConstraint.ConstraintFunction(a) || !GeneConstraint.ConstraintFunction(b)); 84 | 85 | child1 = new BinaryGene(a, _randomSeed, gene1.GeneConstraint); 86 | child2 = new BinaryGene(b, _randomSeed, gene2.GeneConstraint); 87 | 88 | } 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /DotNet/QuantSys/Analytics/IndicatorMatrix.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Reflection; 5 | using System.Text; 6 | using System.Threading; 7 | using System.Threading.Tasks; 8 | using QuantSys.Analytics.Timeseries.Indicators.Abstraction; 9 | using QuantSys.Analytics.Timeseries.Indicators.Oscillators; 10 | using QuantSys.MarketData; 11 | using QuantSys.TradeEngine; 12 | using QuantSys.TradeEngine.MarketInterface.FXCMInterface; 13 | using QuantSys.TradeEngine.MarketInterface.FXCMInterface.Functions; 14 | 15 | namespace QuantSys.Analytics 16 | { 17 | public class IndicatorMatrix 18 | { 19 | private const int ticks = 1000; 20 | 21 | private List mData; 22 | private List indList; 23 | private string symbol; 24 | 25 | private const string S1 = "m5"; 26 | private const string S2 = "m15"; 27 | private const string M1 = "H1"; 28 | private const string M2 = "H4"; 29 | private const string L1 = "D1"; 30 | private const string L2 = "W1"; 31 | 32 | private string[] sList = new string[] {S1, S2, M1, M2, L1, L2}; 33 | 34 | public IndicatorMatrix(string symbol, List iList = null) 35 | { 36 | mData = new List(); 37 | this.symbol = symbol; 38 | indList = iList ?? new List() 39 | { 40 | typeof(MACD), 41 | typeof(RSI), 42 | typeof(WilliamsR), 43 | typeof(AC), 44 | typeof(AO), 45 | typeof(UltimateOscillator) 46 | }; 47 | } 48 | 49 | public void LoadData() 50 | { 51 | FXSession session = new FXSession(); 52 | session.InitializeSession(); 53 | 54 | foreach (string s in sList) 55 | { 56 | HistoricPriceEngine h = new HistoricPriceEngine(session); 57 | h.GetLongHistoricPrices(symbol, s, ticks); 58 | while(!h.Complete) Thread.Sleep(100); 59 | mData.Add(h.Data); 60 | } 61 | } 62 | 63 | public void Execute() 64 | { 65 | for(int i = 0; i < mData.Count; i++) 66 | { 67 | Quantum q = mData[i]; 68 | 69 | List iList = new List(); 70 | 71 | foreach (Type t in indList) 72 | { 73 | iList.Add(Activator.CreateInstance(t)); 74 | } 75 | 76 | foreach (KeyValuePair tick in q.Data) 77 | { 78 | foreach (var indicator in iList) 79 | { 80 | ((AbstractIndicator)indicator).HandleNextTick(tick.Value); 81 | } 82 | } 83 | 84 | Console.WriteLine(sList[i] + "-------------"); 85 | foreach (var indicator in iList) 86 | { 87 | Console.WriteLine(((AbstractIndicator)indicator).ToString() + ":" + ((AbstractIndicator)indicator)[0]); 88 | } 89 | 90 | } 91 | } 92 | 93 | 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /DotNet/QuantSys/Util/ExcelUtil.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Reflection; 3 | using System.Runtime.InteropServices; 4 | using MathNet.Numerics.LinearAlgebra.Double; 5 | using Microsoft.Office.Interop.Excel; 6 | 7 | namespace QuantSys.Util 8 | { 9 | public static class ExcelUtil 10 | { 11 | public static void Open(string filename, out object[,] data) 12 | { 13 | object misValue = Missing.Value; 14 | 15 | 16 | Console.WriteLine("Loading File " + filename + " ..."); 17 | var xlApp = new Application(); 18 | var xlWorkBook = xlApp.Workbooks.Open(filename, 0, true, 5, "", "", true, XlPlatform.xlWindows, "\t", false, 19 | false, 0, true, 1, 0); 20 | Console.WriteLine("Done."); 21 | 22 | var xlWorkSheet = (Worksheet) xlWorkBook.Worksheets.Item[1]; 23 | 24 | data = ParseData(xlWorkSheet); 25 | 26 | 27 | xlWorkBook.Close(true, misValue, misValue); 28 | xlApp.Quit(); 29 | 30 | ReleaseObject(xlWorkSheet); 31 | ReleaseObject(xlWorkBook); 32 | ReleaseObject(xlApp); 33 | } 34 | 35 | 36 | private static void ReleaseObject(object obj) 37 | { 38 | try 39 | { 40 | Marshal.ReleaseComObject(obj); 41 | obj = null; 42 | } 43 | catch (Exception ex) 44 | { 45 | obj = null; 46 | } 47 | finally 48 | { 49 | GC.Collect(); 50 | } 51 | } 52 | 53 | 54 | public static object[,] ParseData(Worksheet w) 55 | { 56 | try 57 | { 58 | Range usedRange = w.UsedRange; 59 | var data = new object[usedRange.Rows.Count - 1, usedRange.Columns.Count]; 60 | 61 | data = usedRange.get_Value(Type.Missing); 62 | 63 | return data; 64 | } 65 | catch (Exception e) 66 | { 67 | Console.WriteLine(e.Message); 68 | return null; 69 | } 70 | } 71 | 72 | public static DenseMatrix ToMatrix(this object[,] data, int rowStart, int rowEnd, int colStart, int colEnd, 73 | bool reverseColumns) 74 | { 75 | var d = new DenseMatrix(rowEnd - rowStart + 1, colEnd - colStart + 1); 76 | 77 | if (reverseColumns) 78 | { 79 | for (int i = rowEnd; i >= rowStart; i--) 80 | { 81 | for (int j = colStart; j <= colEnd; j++) 82 | { 83 | d[rowEnd - i, j - colStart] = (double) data[i, j]; 84 | } 85 | } 86 | } 87 | else 88 | { 89 | for (int i = rowStart; i <= rowEnd; i++) 90 | { 91 | for (int j = colStart; j <= colEnd; j++) 92 | { 93 | d[i - rowStart, j - colStart] = (double) data[i, j]; 94 | } 95 | } 96 | } 97 | 98 | return d; 99 | } 100 | } 101 | } -------------------------------------------------------------------------------- /DotNet/QuantSys/Analytics/StatisticalModeling/ARMA.cs: -------------------------------------------------------------------------------- 1 | namespace QuantSys.Analytics.StatisticalModeling 2 | { 3 | public class ARMA 4 | { 5 | /* 6 | public virtual void FitByMLE(int numIterationsLDS, int numIterationsOpt, 7 | double consistencyPenalty, 8 | Optimizer.OptimizationCallback optCallback) 9 | { 10 | var thisAsMLEEstimable = this as IMLEEstimable; 11 | if (thisAsMLEEstimable == null) 12 | throw new ApplicationException("MLE not supported for this model."); 13 | 14 | int optDimension = NumParametersOfType(Model.ParameterState.Free); 15 | int numConsequential = NumParametersOfType(Model.ParameterState.Consequential); 16 | int numIterations = numIterationsLDS + numIterationsOpt; 17 | 18 | var trialParameterList = new Vector[numIterationsLDS]; 19 | var trialCubeList = new Vector[numIterationsLDS]; 20 | 21 | var hsequence = new HaltonSequence(optDimension); 22 | 23 | for (int i = 0; i < numIterationsLDS; ++i) 24 | { 25 | Vector smallCube = hsequence.GetNext(); 26 | Vector cube = CubeInsert(smallCube); 27 | trialParameterList[i] = thisAsMLEEstimable.CubeToParameter(cube); 28 | trialCubeList[i] = cube; 29 | } 30 | 31 | var logLikes = new double[numIterationsLDS]; 32 | for (int i = 0; i < numIterationsLDS; ++i) 33 | { 34 | Vector tparms = trialParameterList[i]; 35 | if (numConsequential > 0) 36 | { 37 | tparms = ComputeConsequentialParameters(tparms); 38 | trialParameterList[i] = tparms; 39 | } 40 | 41 | double ll = LogLikelihood(tparms, consistencyPenalty); 42 | logLikes[i] = ll; 43 | 44 | if (optCallback != null) 45 | lock (logLikes) 46 | optCallback(tparms, ll, i*100/numIterations, false); 47 | } 48 | 49 | // Step 1: Just take the best value. 50 | Array.Sort(logLikes, trialParameterList); 51 | var Parameters = trialParameterList[numIterationsLDS - 1]; 52 | 53 | // Step 2: Take some of the top values and use them to create a simplex, then optimize 54 | // further in natural parameter space with the Nelder Mead algorithm. 55 | // Here we optimize in cube space, reflecting the cube when necessary to make parameters valid. 56 | var simplex = new List(); 57 | for (int i = 0; i <= optDimension; ++i) 58 | simplex.Add(FreeParameters(thisAsMLEEstimable.ParameterToCube( 59 | trialParameterList[numIterationsLDS - 1 - i]))); 60 | var nmOptimizer = new NelderMead {Callback = optCallback, StartIteration = numIterationsLDS}; 61 | currentPenalty = consistencyPenalty; 62 | nmOptimizer.Minimize(NegativeLogLikelihood, simplex, numIterationsOpt); 63 | Parameters = ComputeConsequentialParameters( 64 | thisAsMLEEstimable.CubeToParameter(CubeFix(CubeInsert(nmOptimizer.ArgMin)))); 65 | 66 | ComputeResidualsAndOutputs(); 67 | } 68 | */ 69 | } 70 | 71 | 72 | 73 | } 74 | -------------------------------------------------------------------------------- /DotNet/QuantSys/MachineLearning/GeneticAlgorithm/Genes/RealCodedGene.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using QuantSys.MachineLearning.GeneticAlgorithm.Genes.Constraints; 7 | 8 | namespace QuantSys.MachineLearning.GeneticAlgorithm.Genes 9 | { 10 | public class RealCodedGene : Gene 11 | { 12 | public double GeneValue { get; set; } 13 | public RealCodedGene(double value, Random r, GeneConstraint g) : base(r) 14 | { 15 | GeneValue = value; 16 | GeneConstraint = g; 17 | } 18 | 19 | public override bool WithinConstraints() 20 | { 21 | return GeneConstraint.ConstraintFunction(GeneValue); 22 | } 23 | 24 | public override void InitializeGene() 25 | { 26 | GeneValue = 27 | ((double) GeneConstraint.HI - 28 | _randomSeed.NextDouble()* 29 | ((double) GeneConstraint.HI - (double) GeneConstraint.LOW)); 30 | } 31 | 32 | public override bool Mutate(double mRate) 33 | { 34 | if (_randomSeed.NextDouble() <= mRate) 35 | { 36 | double tempValue = double.NaN; 37 | while (!GeneConstraint.ConstraintFunction(tempValue)) 38 | { 39 | tempValue = GeneValue + (((_randomSeed.Next(10) % 2 == 0) ? -1 : 1) * _randomSeed.NextDouble() / 10.0) * GeneValue; 40 | } 41 | 42 | GeneValue = tempValue; 43 | return true; 44 | } 45 | return false; 46 | } 47 | 48 | public override string ToString() 49 | { 50 | return GeneValue.ToString(); 51 | } 52 | 53 | public override Gene Clone() 54 | { 55 | return new RealCodedGene(this.GeneValue, this._randomSeed, this.GeneConstraint); 56 | } 57 | public override void Crossover(Gene gene2, out Gene child1, out Gene child2) 58 | { 59 | SimulatedBinaryCrossover(this, (RealCodedGene)gene2, out child1, out child2); 60 | } 61 | 62 | private void SimulatedBinaryCrossover(RealCodedGene g1, RealCodedGene g2, out Gene child1, out Gene child2) 63 | { 64 | //n_c is a parameter that controls the crossover process. A high value of the parameter will create near-parent solution 65 | const double n_c = .05; 66 | 67 | double a, b; 68 | do 69 | { 70 | double random = _randomSeed.NextDouble(); 71 | double beta = (random < 0.5) 72 | ? Math.Pow((2 * random), (1 / (n_c + 1))) 73 | : Math.Pow(1 / (2 * (1 - random)), (1 / (n_c + 1))); 74 | 75 | var x_i1 = g1.GeneValue; 76 | var x_i2 = g2.GeneValue; 77 | 78 | a = 0.5 * ((1 + beta) * x_i1 + (1 - beta) * x_i2); 79 | b = 0.5 * ((1 - beta) * x_i1 + (1 + beta) * x_i2); 80 | 81 | } while (!GeneConstraint.ConstraintFunction(a) || !GeneConstraint.ConstraintFunction(b)); 82 | 83 | 84 | child1 = new RealCodedGene(g1.GeneValue, _randomSeed, g1.GeneConstraint); 85 | child2 = new RealCodedGene(g1.GeneValue, _randomSeed, g2.GeneConstraint); 86 | 87 | } 88 | 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /DotNet/QuantSys/MarketData/MultiQuantum.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | 6 | namespace QuantSys.MarketData 7 | { 8 | public class MultiQuantum : IEnumerable> 9 | { 10 | public int Length { get { return _totalData.Keys.Count; } } 11 | private SortedList> _totalData; 12 | 13 | public List this[int index] { get { return _totalData.Values[index]; } } 14 | public IList Keys{get { return _totalData.Keys; }} 15 | public IList> Values { get { return _totalData.Values; } } 16 | protected MultiQuantum(SortedList> data) 17 | { 18 | _totalData = data; 19 | } 20 | 21 | /// 22 | /// Populates a MultiQuantum based on DateTimes that are available to all Quantums 23 | /// 24 | /// 25 | /// 26 | public static MultiQuantum OrganizeMultiQuantum(List datalist) 27 | { 28 | var totalData = new SortedList>(); 29 | 30 | //Single Entry 31 | if (datalist.Count == 1) 32 | { 33 | totalData = new SortedList>(); 34 | for (int i = 0; i < datalist[0].Data.Count; i++) 35 | { 36 | totalData.Add(datalist[0].Data.Keys[i], new List(){datalist[0].Data.Values[i]}); 37 | } 38 | return new MultiQuantum(totalData); 39 | } 40 | 41 | //Multiple Entries 42 | int num = datalist.Count; 43 | 44 | 45 | for (int i = 0; i < datalist[0].Data.Count; i++) 46 | { 47 | DateTime d = datalist[0].Data.Keys[i]; 48 | 49 | bool allContains = true; 50 | for (int j = 1; j < num; j++) 51 | { 52 | if (!datalist[j].Data.ContainsKey(d)) 53 | { 54 | allContains = false; 55 | break; 56 | } 57 | } 58 | 59 | if (allContains) 60 | { 61 | List ticks = new List(); 62 | foreach (Quantum q in datalist) ticks.Add(q.Data[d]); 63 | totalData.Add(d, ticks); 64 | } 65 | } 66 | 67 | return new MultiQuantum(totalData); 68 | 69 | } 70 | 71 | public List> RevertToList() 72 | { 73 | int count = this.First().Count; 74 | List> list = new List>(); 75 | 76 | for (int i = 0; i < count; i++) 77 | list.Add(new List()); 78 | 79 | foreach(List ticks in this) 80 | { 81 | for (int i = 0; i < count; i++) 82 | list[i].Add(ticks[i]); 83 | } 84 | 85 | return list; 86 | 87 | } 88 | public IEnumerator> GetEnumerator() 89 | { 90 | return _totalData.Values.GetEnumerator(); 91 | } 92 | 93 | IEnumerator IEnumerable.GetEnumerator() 94 | { 95 | return GetEnumerator(); 96 | } 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /DotNet/QuantSys/Analytics/Timeseries/Indicators/Misc/HeikenAshi.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using QuantSys.Analytics.Timeseries.Indicators.Abstraction; 3 | using QuantSys.DataStructures; 4 | using QuantSys.MarketData; 5 | 6 | namespace QuantSys.Analytics.Timeseries.Indicators.Misc 7 | { 8 | /// 9 | /// The Heikin-Ashi Close is simply an average of the open, 10 | /// high, low and close for the current period. 11 | /// 12 | /// HA-Close = (Open(0) + High(0) + Low(0) + Close(0)) / 4 13 | /// 14 | /// 2. The Heikin-Ashi Open is the average of the prior Heikin-Ashi 15 | /// candlestick open plus the close of the prior Heikin-Ashi candlestick. 16 | /// 17 | /// HA-Open = (HA-Open(-1) + HA-Close(-1)) / 2 18 | /// 19 | /// 3. The Heikin-Ashi High is the maximum of three data points: 20 | /// the current period's high, the current Heikin-Ashi 21 | /// candlestick open or the current Heikin-Ashi candlestick close. 22 | /// 23 | /// HA-High = Maximum of the High(0), HA-Open(0) or HA-Close(0) 24 | /// 25 | /// 4. The Heikin-Ashi low is the minimum of three data points: 26 | /// the current period's low, the current Heikin-Ashi 27 | /// candlestick open or the current Heikin-Ashi candlestick close. 28 | /// 29 | /// HA-Low = Minimum of the Low(0), HA-Open(0) or HA-Close(0) 30 | /// 31 | 32 | public class HeikenAshi : AbstractIndicator 33 | { 34 | public MovingQueue HACandle; 35 | private Tick prevTick; 36 | public Tick GetCandle(int index) 37 | { 38 | return (HACandle.Count > index) ? HACandle.ToArray()[HACandle.Count - index - 1] : null; 39 | } 40 | 41 | public HeikenAshi(int n) 42 | : base(n) 43 | { 44 | HACandle = new MovingQueue(n); 45 | prevTick = null; 46 | } 47 | 48 | public override double HandleNextTick(Tick t) 49 | { 50 | Tick hTick = null; 51 | 52 | if (HACandle.Count.Equals(0)) 53 | { 54 | hTick = t; 55 | } 56 | 57 | if (prevTick != null) 58 | { 59 | double HABidClose = (t.BidOpen + t.BidHigh + t.BidLow + t.BidClose) / 4; 60 | double HAAskClose = (t.AskOpen + t.AskHigh + t.AskLow + t.AskClose) / 4; 61 | 62 | double HABidOpen = (prevTick.BidOpen + prevTick.BidClose) / 2; 63 | double HAAskOpen = (prevTick.AskOpen + prevTick.AskClose) / 2; 64 | 65 | double HABidHigh = Math.Max(t.BidHigh, Math.Max(HABidOpen, HABidClose)); 66 | double HAAskHigh = Math.Max(t.AskHigh, Math.Max(HAAskOpen, HAAskClose)); 67 | 68 | double HABidLow = Math.Min(t.BidLow, Math.Min(HABidOpen, HABidClose)); 69 | double HAAskLow = Math.Min(t.AskLow, Math.Min(HAAskOpen, HAAskClose)); 70 | 71 | hTick = new Tick( 72 | t.CurrentBid, HABidOpen, HABidHigh, HABidLow, HABidClose, 73 | t.CurrentAsk, HAAskOpen, HAAskHigh, HAAskLow, HAAskClose, 74 | t.Volume, t.Time 75 | ); 76 | } 77 | 78 | HACandle.Enqueue(hTick); 79 | prevTick = hTick; 80 | 81 | return hTick.BidClose; 82 | } 83 | 84 | public override string ToString() 85 | { 86 | return "HeikenAshi"; 87 | } 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /DotNet/QuantSys/Analytics/Timeseries/Indicators/Oscillators/UltimateOscillator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using QuantSys.Analytics.Timeseries.Indicators.Abstraction; 4 | using QuantSys.DataStructures; 5 | using QuantSys.MarketData; 6 | 7 | namespace QuantSys.Analytics.Timeseries.Indicators.Oscillators 8 | { 9 | /// 10 | /// The Ultimate Oscillator is a momentum oscillator designed to 11 | /// capture momentum across three different time frames. The multiple time 12 | /// frame objective seeks to avoid the pitfalls of other oscillators. Many 13 | /// momentum oscillators surge at the beginning of a strong advance and then 14 | /// form bearish divergence as the advance continues. This is because they are 15 | /// stuck with one time frame. The Ultimate Oscillator attempts to correct 16 | /// this fault by incorporating longer time frames into the basic formula. 17 | /// Williams identified a buy signal a based on a bullish divergence and 18 | /// a sell signal based on a bearish divergence. 19 | /// 20 | /// BP = Close - Minimum(Low or Prior Close). 21 | /// TR = Maximum(High or Prior Close) - Minimum(Low or Prior Close) 22 | /// Average7 = (7-period BP Sum) / (7-period TR Sum) 23 | /// Average14 = (14-period BP Sum) / (14-period TR Sum) 24 | /// Average28 = (28-period BP Sum) / (28-period TR Sum) 25 | /// UO = 100 x [(4 x Average7)+(2 x Average14)+Average28]/(4+2+1) 26 | /// 27 | public class UltimateOscillator : AbstractIndicator 28 | { 29 | private readonly MovingQueue BP1; 30 | private readonly MovingQueue BP2; 31 | private readonly MovingQueue BP3; 32 | private readonly MovingQueue TR1; 33 | private readonly MovingQueue TR2; 34 | private readonly MovingQueue TR3; 35 | private Tick prevTick; 36 | 37 | 38 | public UltimateOscillator() : this(7, 14, 28) 39 | { 40 | 41 | } 42 | 43 | public UltimateOscillator(int p1 = 7, int p2 = 14, int p3 = 28):base(p3) 44 | { 45 | prevTick = null; 46 | BP1 = new MovingQueue(p1); 47 | TR1 = new MovingQueue(p1); 48 | BP2 = new MovingQueue(p2); 49 | TR2 = new MovingQueue(p2); 50 | BP3 = new MovingQueue(p3); 51 | TR3 = new MovingQueue(p3); 52 | 53 | } 54 | 55 | public override double HandleNextTick(Tick t) 56 | { 57 | double value = double.NaN; 58 | double a1 = BP1.ToArray().Sum() / TR1.ToArray().Sum(); 59 | double a2 = BP2.ToArray().Sum() / TR2.ToArray().Sum(); 60 | double a3 = BP3.ToArray().Sum() / TR3.ToArray().Sum(); 61 | 62 | if (BP3.Count == BP3.Capacity) 63 | { 64 | value = 100*((4*a1) + (2*a2) + a3)/(4 + 2 + 1); 65 | } 66 | 67 | if (prevTick != null) 68 | { 69 | double TR = Math.Max(t.BidHigh, prevTick.BidClose) - Math.Min(t.BidLow, prevTick.BidClose); 70 | double BP = t.BidClose - Math.Min(t.BidLow, prevTick.BidClose); 71 | 72 | BP1.Enqueue(BP); 73 | BP2.Enqueue(BP); 74 | BP3.Enqueue(BP); 75 | 76 | TR1.Enqueue(TR); 77 | TR2.Enqueue(TR); 78 | TR3.Enqueue(TR); 79 | } 80 | 81 | prevTick = t; 82 | indicatorData.Enqueue(value); 83 | return value; 84 | } 85 | 86 | public override string ToString() 87 | { 88 | throw new NotImplementedException(); 89 | } 90 | } 91 | } -------------------------------------------------------------------------------- /DotNet/QuantSys/Analytics/StatisticalModeling/HurstEstimation.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using MathNet.Numerics.Statistics; 6 | 7 | namespace QuantSys.Analytics.StatisticalModeling 8 | { 9 | /// 10 | /// The Hurst exponent is referred to as the "index of dependence," or 11 | /// "index of long-range dependence." It quantifies the relative tendency 12 | /// of a time series either to regress strongly to the mean or to cluster 13 | /// in a direction. A value H in the range 0.5 < H < 1 indicates a time series 14 | /// with long-term positive autocorrelation, meaning both that a high value 15 | /// in the series will probably be followed by another high value and that 16 | /// the values a long time into the future will also tend to be high. A value 17 | /// in the range 0 < H < 0.5 indicates a time series with long-term switching 18 | /// between high and low values in adjacent pairs, meaning that a single high 19 | /// value will probably be followed by a low value and that the value after 20 | /// that will tend to be high, with this tendency to switch between high and low 21 | /// values lasting a long time into the future. A value of H=0.5 can indicate a 22 | /// completely uncorrelated series, but in fact it is the value applicable to 23 | /// series for which the autocorrelations at small time lags can be positive 24 | /// or negative but where the absolute values of the autocorrelations decay 25 | /// exponentially quickly to zero. 26 | /// 27 | public class HurstEstimation 28 | { 29 | public static double CalculateHurstEstimate(double[] data, int minLength = 8) 30 | { 31 | List n = new List(); 32 | List avgRange = new List(); 33 | for (int i = 1; i <= data.Length; i *= 2) 34 | { 35 | double range = CalculateAverageRange(data, data.Length/i); 36 | if (!range.Equals(double.NaN)) 37 | { 38 | n.Add(i); 39 | avgRange.Add(range); 40 | } 41 | } 42 | 43 | LinearRegression LR = new LinearRegression(); 44 | LR.Model(n.Select(i=> Math.Log(i)).ToArray(),avgRange.Select(i=> Math.Log(i)).ToArray()); 45 | return LR.X2; 46 | } 47 | 48 | private static double CalculateAverageRange(double[] data, int seriesLength) 49 | { 50 | if(data.Length % seriesLength != 0) 51 | throw new InvalidDataException("Data length must be divisible by series length."); 52 | 53 | double[] ranges = new double[data.Length/seriesLength]; 54 | for (int i = 0; i < ranges.Length; i++) 55 | ranges[i] = CalculateRescaledRange(data.Skip(i*seriesLength).Take(seriesLength).ToArray()); 56 | 57 | double averageRange = ranges.Mean(); 58 | 59 | return averageRange; 60 | } 61 | 62 | 63 | private static double CalculateRescaledRange(double[] data) 64 | { 65 | double mean = data.Mean(); 66 | double[] meanAdjustedSeries = data.Select(i => i - mean).ToArray(); 67 | double[] cumulativeDeviateSeries = new double[data.Length]; 68 | for(int i = 0; i < data.Length; i++) 69 | for (int j = 0; j <= i; j++) cumulativeDeviateSeries[i] += meanAdjustedSeries[j]; 70 | 71 | double range = cumulativeDeviateSeries.Max() - cumulativeDeviateSeries.Min(); 72 | double stdev = data.PopulationStandardDeviation(); 73 | 74 | double rescaledRange = range/stdev; 75 | return rescaledRange; 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /DotNet/QuantSys/Analytics/Timeseries/Indicators/Misc/Divergence.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using ikvm.extensions; 4 | using QuantSys.Analytics.StatisticalModeling; 5 | using QuantSys.Analytics.Timeseries.Indicators.Abstraction; 6 | using QuantSys.Analytics.Timeseries.Indicators.Averages; 7 | using QuantSys.MarketData; 8 | 9 | namespace QuantSys.Analytics.Timeseries.Indicators.Misc 10 | { 11 | public class Divergence : AbstractIndicator 12 | { 13 | private QSPolyMA MA; 14 | private AbstractIndicator indicator; 15 | 16 | public Divergence(AbstractIndicator indicator) : base(indicator.Period) 17 | { 18 | MA = new QSPolyMA(indicator.Period); 19 | this.indicator = indicator; 20 | subIndicators.Add(indicator.toString(), indicator); 21 | } 22 | 23 | public override double HandleNextTick(Tick t) 24 | { 25 | double value = double.NaN; 26 | MA.HandleNextTick(t); 27 | indicator.HandleNextTick(t); 28 | 29 | if (!MA[0].Equals(double.NaN)) 30 | { 31 | double[] MAArray = MA.ToArray(); 32 | double[] indArray = indicator.ToArray(); 33 | SortedList tickHighs = new SortedList(); 34 | SortedList tickLows = new SortedList(); 35 | SortedList indHighs = new SortedList(); 36 | SortedList indLows = new SortedList(); 37 | for (int i = 2; i < MAArray.Length; i++) 38 | { 39 | //high 40 | if (MAArray[i] < MAArray[i - 1] && MAArray[i - 1] > MAArray[i - 2]) 41 | { 42 | tickHighs.Add(i - 1, MAArray[i - 1]); 43 | } 44 | if (indArray[i] < indArray[i - 1] && indArray[i - 1] > indArray[i - 2]) 45 | { 46 | indHighs.Add(i - 1, indArray[i - 1]); 47 | } 48 | 49 | //low 50 | if (MAArray[i] > MAArray[i - 1] && MAArray[i - 1] < MAArray[i - 2]) 51 | { 52 | tickLows.Add(i - 1, MAArray[i - 1]); 53 | } 54 | if (indArray[i] > indArray[i - 1] && indArray[i - 1] < indArray[i - 2]) 55 | { 56 | indLows.Add(i - 1, indArray[i - 1]); 57 | } 58 | 59 | } 60 | 61 | if (tickHighs.Count > 0 && indHighs.Count > 0 62 | && tickLows.Count > 0 && indLows.Count > 0) 63 | { 64 | LinearRegression lrTickHighs = new LinearRegression(); 65 | LinearRegression lrTickLows = new LinearRegression(); 66 | LinearRegression lrindkHighs = new LinearRegression(); 67 | LinearRegression lrindLows = new LinearRegression(); 68 | 69 | lrTickHighs.Model(tickHighs.Keys.ToArray(), tickHighs.Values.ToArray()); 70 | lrTickLows.Model(tickLows.Keys.ToArray(), tickLows.Values.ToArray()); 71 | lrindkHighs.Model(indHighs.Keys.ToArray(), indHighs.Values.ToArray()); 72 | lrindLows.Model(indLows.Keys.ToArray(), indLows.Values.ToArray()); 73 | 74 | if (lrTickHighs.X2 > 0 && lrindkHighs.X2 < 0) value = 1; 75 | else if (lrTickLows.X2 < 0 && lrindLows.X2 > 0) value = -1; 76 | else value = 0; 77 | 78 | value = lrindkHighs.Fit(indArray[0]); 79 | } 80 | } 81 | 82 | indicatorData.Enqueue(value); 83 | return value; 84 | 85 | } 86 | 87 | public override string ToString() 88 | { 89 | return "Divergence" + Period; 90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /DotNet/QuantSys/TradeEngine/MarketInterface/FXCMInterface/Listener/ResponseListener.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using fxcore2; 3 | using QuantSys.TradeEngine.MarketInterface.FXCMInterface.EventArguments; 4 | 5 | namespace QuantSys.TradeEngine.MarketInterface.FXCMInterface.Listener 6 | { 7 | 8 | public delegate void ResponseHandler(object sender, EventArgs e); 9 | 10 | public class ResponseListener : IO2GResponseListener 11 | { 12 | private readonly FXSession _connection; 13 | public event ResponseHandler ResponseReceived; 14 | 15 | 16 | public ResponseListener(FXSession connection) 17 | { 18 | _connection = connection; 19 | } 20 | 21 | 22 | public void onRequestCompleted(string s, O2GResponse response) 23 | { 24 | Console.WriteLine(s); 25 | 26 | switch (response.Type) 27 | { 28 | case O2GResponseType.CommandResponse: 29 | case O2GResponseType.CreateOrderResponse: 30 | case O2GResponseType.GetAccounts: 31 | case O2GResponseType.GetClosedTrades: 32 | case O2GResponseType.GetMessages: 33 | case O2GResponseType.GetOffers: 34 | case O2GResponseType.GetOrders: 35 | case O2GResponseType.GetSystemProperties: 36 | case O2GResponseType.GetTrades: 37 | { 38 | try 39 | { 40 | AccountInformationEventArg data = AccountInformationEventArg.ProcessData(_connection, 41 | response); 42 | 43 | } 44 | catch (Exception e) 45 | { 46 | Console.WriteLine(e); 47 | } 48 | 49 | break; 50 | } 51 | case O2GResponseType.MarketDataSnapshot: 52 | { 53 | try 54 | { 55 | MarketDataEventArg mData = MarketDataEventArg.ProcessMarketData(_connection, response); 56 | OnResponseReceived(mData); 57 | } 58 | catch (Exception e) 59 | { 60 | Console.WriteLine(e); 61 | } 62 | break; 63 | } 64 | case O2GResponseType.ResponseUnknown: 65 | case O2GResponseType.TablesUpdates: 66 | break; 67 | } 68 | } 69 | 70 | public void onRequestFailed(string s1, string s2) 71 | { 72 | Console.WriteLine(s1 + " " + s2); 73 | } 74 | 75 | public void onTablesUpdates(O2GResponse response) 76 | { 77 | //Console.WriteLine(response.ToString()); 78 | 79 | switch (response.Type) 80 | { 81 | case O2GResponseType.CommandResponse: 82 | case O2GResponseType.CreateOrderResponse: 83 | case O2GResponseType.GetAccounts: 84 | case O2GResponseType.GetClosedTrades: 85 | case O2GResponseType.GetMessages: 86 | case O2GResponseType.GetOffers: 87 | case O2GResponseType.GetOrders: 88 | case O2GResponseType.GetSystemProperties: 89 | case O2GResponseType.GetTrades: 90 | case O2GResponseType.MarketDataSnapshot: 91 | case O2GResponseType.ResponseUnknown: 92 | case O2GResponseType.TablesUpdates: 93 | break; 94 | } 95 | } 96 | 97 | 98 | protected virtual void OnResponseReceived(EventArgs e) 99 | { 100 | if (ResponseReceived != null) 101 | ResponseReceived(this, e); 102 | } 103 | 104 | } 105 | } -------------------------------------------------------------------------------- /DotNet/QuantSys/TradeEngine/MarketInterface/FXCMInterface/Functions/HistoricPriceEngine.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Threading; 4 | using fxcore2; 5 | using QuantSys.MarketData; 6 | using QuantSys.TradeEngine.MarketInterface.FXCMInterface.EventArguments; 7 | using QuantSys.TradeEngine.MarketInterface.FXCMInterface.Listener; 8 | using QuantSys.Util; 9 | 10 | namespace QuantSys.TradeEngine.MarketInterface.FXCMInterface.Functions 11 | { 12 | public class HistoricPriceEngine 13 | { 14 | 15 | private Quantum _mktData; 16 | private int _completeCounter; 17 | private bool complete; 18 | 19 | private FXSession session; 20 | private ResponseHandler mHandler; 21 | private object locker; 22 | 23 | public bool Complete { get { return complete; } } 24 | public Quantum Data { get { return _mktData; } } 25 | public Symbol Symbol { get; set; } 26 | 27 | public HistoricPriceEngine(FXSession session) 28 | { 29 | _mktData = new Quantum(); 30 | _completeCounter = 0; 31 | complete = false; 32 | mHandler = HistoricDataReceived; 33 | this.session = session; 34 | } 35 | 36 | public void Reset() 37 | { 38 | _mktData = new Quantum(); 39 | _completeCounter = 0; 40 | complete = false; 41 | } 42 | 43 | public void GetLongHistoricPrices(string symbol, string timeframe, int ticks) 44 | { 45 | _mktData = new Quantum(); 46 | Symbol = new Symbol(symbol); 47 | session.AttachHandler(mHandler); 48 | 49 | DateTime dateNow = DateTime.Now; 50 | TimeSpan time = Timeframe.StringToTimeSpan(timeframe); 51 | 52 | DateTime startDate = dateNow.AddMinutes(-ticks * Timeframe.TimeframeToMinutes(timeframe)); 53 | 54 | O2GRequestFactory factory = session.Session.getRequestFactory(); 55 | O2GTimeframeCollection timeframes = factory.Timeframes; 56 | O2GTimeframe tfo = timeframes[timeframe]; 57 | 58 | int counter = ticks; 59 | 60 | lock (locker) 61 | { 62 | while (counter > 0) 63 | { 64 | 65 | _completeCounter++; 66 | int subticks = (counter >= QSConstants.MAX_FXCM_API_TICKS) 67 | ? QSConstants.MAX_FXCM_API_TICKS 68 | : counter; 69 | O2GRequest request = factory.createMarketDataSnapshotRequestInstrument(symbol, tfo, subticks); 70 | factory.fillMarketDataSnapshotRequestTime(request, startDate, 71 | startDate.AddMinutes(2*subticks*Timeframe.TimeframeToMinutes(timeframe))); 72 | session.Session.sendRequest(request); 73 | 74 | startDate = startDate.AddMinutes(subticks*Timeframe.TimeframeToMinutes(timeframe)); 75 | counter -= (counter >= QSConstants.MAX_FXCM_API_TICKS) ? QSConstants.MAX_FXCM_API_TICKS : counter; 76 | } 77 | } 78 | 79 | int timeCounter = 0; 80 | while (!Complete || timeCounter++ < 3000) //max timeout 30 seconds 81 | { 82 | Thread.Sleep(100); 83 | } 84 | 85 | } 86 | 87 | public void HistoricDataReceived(object sender, EventArgs e) 88 | { 89 | lock (locker) 90 | { 91 | MarketDataEventArg marketData = ((MarketDataEventArg) e); 92 | _mktData.CombineWith(marketData.data); 93 | _completeCounter--; 94 | } 95 | 96 | if (_completeCounter == 0) 97 | { 98 | complete = true; 99 | session.DetachHandler(mHandler); 100 | 101 | foreach (KeyValuePair KVP in _mktData.Data) 102 | { 103 | KVP.Value.Symbol = Symbol; 104 | } 105 | } 106 | } 107 | } 108 | 109 | } 110 | -------------------------------------------------------------------------------- /DotNet/QuantSys/MarketData/Quantum.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading; 6 | using QuantSys.TradeEngine; 7 | using QuantSys.TradeEngine.MarketInterface.FXCMInterface; 8 | using QuantSys.TradeEngine.MarketInterface.FXCMInterface.Functions; 9 | using QuantSys.Util; 10 | 11 | namespace QuantSys.MarketData 12 | { 13 | 14 | public class Quantum : IEnumerable 15 | { 16 | private readonly SortedList _data; 17 | public Quantum(SortedList data) 18 | { 19 | _data = data; 20 | } 21 | 22 | public Quantum() 23 | { 24 | _data = new SortedList(); 25 | } 26 | 27 | public Tick[] ToArray() 28 | { 29 | return _data.Values.ToArray(); 30 | } 31 | public SortedList Data 32 | { 33 | get { return _data; } 34 | } 35 | 36 | public Symbol Symbol { get; set; } 37 | public Timeframe Period { get; set; } 38 | 39 | public Tick this[int index] 40 | { 41 | get { return _data.Values[index]; } 42 | } 43 | 44 | public void CombineWith(Quantum other) 45 | { 46 | foreach (KeyValuePair kvp in other.Data) 47 | { 48 | if(!_data.ContainsKey(kvp.Key)) 49 | _data.Add(kvp.Key, kvp.Value); 50 | } 51 | } 52 | 53 | public IEnumerator GetEnumerator() 54 | { 55 | return Data.Values.GetEnumerator(); 56 | } 57 | 58 | IEnumerator IEnumerable.GetEnumerator() 59 | { 60 | return GetEnumerator(); 61 | } 62 | 63 | 64 | 65 | /// 66 | /// Parses an excel file into a Quantum object. 67 | /// 68 | /// 69 | /// 70 | /// 71 | /// 72 | public static Quantum ExcelToQuantum(string filename, string symbol, int startIndex = 0) 73 | { 74 | object[,] denseMatrix; 75 | ExcelUtil.Open(@filename, out denseMatrix); 76 | var s = new Symbol(symbol); 77 | 78 | var mData = new SortedList(); 79 | 80 | for (int i = denseMatrix.GetLength(0) - startIndex; i > 1; i--) 81 | { 82 | try 83 | { 84 | DateTime dateTime = (DateTime)denseMatrix[i, 1]; 85 | 86 | var t = new Tick( 87 | 0, 88 | (double)denseMatrix[i, 6], 89 | (double)denseMatrix[i, 7], 90 | (double)denseMatrix[i, 8], 91 | (double)denseMatrix[i, 9], 92 | 0, 93 | (double)denseMatrix[i, 2], 94 | (double)denseMatrix[i, 3], 95 | (double)denseMatrix[i, 4], 96 | (double)denseMatrix[i, 5], 97 | (double)denseMatrix[i, 10], 98 | dateTime 99 | ); 100 | t.Symbol = s; 101 | mData.Add(dateTime, t); 102 | } 103 | catch (Exception e) 104 | { 105 | Console.WriteLine(e.Message); 106 | } 107 | } 108 | 109 | return (new Quantum(mData) { Symbol = s }); 110 | } 111 | 112 | public static Quantum QuantumFromLiveData(string symbol, string timeframe, int ticks) 113 | { 114 | FXSession session = new FXSession(); 115 | session.InitializeSession(); 116 | HistoricPriceEngine h = new HistoricPriceEngine(session); 117 | h.GetLongHistoricPrices(symbol, timeframe, ticks); 118 | while(!h.Complete) Thread.Sleep(100); 119 | 120 | return (h.Data); 121 | } 122 | 123 | 124 | } 125 | } -------------------------------------------------------------------------------- /DotNet/QuantSys/TradeEngine/Simulation/Account/Portfolio.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using QuantSys.MarketData; 4 | 5 | namespace QuantSys.TradeEngine.Simulation.Account 6 | { 7 | public class Portfolio 8 | { 9 | public const double STARTING_BALANCE = 10000; 10 | public const double MARGIN_REQUIREMENT = 0.2; 11 | 12 | public int NumPositions 13 | { 14 | get { return _positions.Count; } 15 | } 16 | 17 | public Position this[Symbol symbol] 18 | { 19 | get { return _positions[symbol]; } 20 | } 21 | 22 | public Dictionary Positions { get { return _positions; } } 23 | 24 | private Dictionary _positions; 25 | 26 | public Portfolio(double startingBalance = STARTING_BALANCE) 27 | { 28 | CurrentBalance = startingBalance; 29 | StartingBalance = startingBalance; 30 | CurrentMargin = startingBalance; 31 | CurrentEquity = startingBalance; 32 | _positions = new Dictionary(); 33 | } 34 | 35 | public double CurrentEquity { get; set; } 36 | public double CurrentBalance { get; set; } 37 | public double CurrentMargin { get; set; } 38 | public double StartingBalance { get; set; } 39 | 40 | 41 | public bool ExistsPositionForSymbol(Symbol s) 42 | { 43 | return _positions.ContainsKey(s); 44 | } 45 | 46 | public bool TakePosition(Symbol s, double price, Position.PositionSide side, double size, DateTime date) 47 | { 48 | //Check if we can take the position, based on margin requirement 49 | 50 | //If there's a position open for s, adjust position accordingly 51 | 52 | _positions.Add(s, new Position(s, price, size, side, date)); 53 | 54 | 55 | return true; 56 | } 57 | 58 | //Balance is update when positions are closed 59 | public double ClosePosition(Tick t, double price) 60 | { 61 | if (ExistsPositionForSymbol(t.Symbol)) 62 | { 63 | double changeInBalance = _positions[t.Symbol].ClosePosition(t, price); 64 | _positions.Remove(t.Symbol); 65 | AdjustPortfolioBalance(changeInBalance); 66 | return changeInBalance; 67 | } 68 | return 0; 69 | } 70 | 71 | public bool ReducePosition(Tick t, double size) 72 | { 73 | if (ExistsPositionForSymbol(t.Symbol)) 74 | { 75 | double changeInBalance = _positions[t.Symbol].ReducePosition(t, size); 76 | AdjustPortfolioBalance(changeInBalance); 77 | return true; 78 | } 79 | return false; 80 | } 81 | 82 | public bool IncreasePosition(Tick t, double size) 83 | { 84 | if (ExistsPositionForSymbol(t.Symbol)) 85 | { 86 | _positions[t.Symbol].IncreasePosition(t, size); 87 | return true; 88 | } 89 | return false; 90 | } 91 | 92 | private void AdjustPortfolioBalance(double change) 93 | { 94 | CurrentBalance += change; 95 | } 96 | 97 | 98 | //Portfolio Equity and Margin is adjusted on tick 99 | public void AdjustPortfolioEquityAndMargin(params Tick[] ticks) 100 | { 101 | double tempEquity = CurrentBalance; 102 | 103 | foreach (Tick t in ticks) 104 | { 105 | if (ExistsPositionForSymbol(t.Symbol)) 106 | { 107 | tempEquity += _positions[t.Symbol].Size* 108 | ((_positions[t.Symbol].Side.Equals(Position.PositionSide.Long)) 109 | ? t.BidClose - _positions[t.Symbol].PositionPrice 110 | : _positions[t.Symbol].PositionPrice - t.AskClose); 111 | } 112 | } 113 | 114 | CurrentEquity = tempEquity; 115 | 116 | //if margin falls below requirement, need to close all positions. 117 | } 118 | } 119 | } -------------------------------------------------------------------------------- /DotNet/QuantSys/MarketData/Timeframe.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace QuantSys.MarketData 4 | { 5 | public class Timeframe 6 | { 7 | public enum Period 8 | { 9 | T, 10 | m1, 11 | m5, 12 | m15, 13 | m30, 14 | H1, 15 | H2, 16 | H3, 17 | H4, 18 | H8, 19 | D1, 20 | W1, 21 | M1 22 | }; 23 | 24 | public static int TimeframeToMinutes(string timespan) 25 | { 26 | switch (timespan) 27 | { 28 | case "m1": 29 | return 1; 30 | case "m5": 31 | return 5; 32 | case "m15": 33 | return 15; 34 | case "m30": 35 | return 30; 36 | case "H1": 37 | return 60; 38 | case "H2": 39 | return 120; 40 | case "H3": 41 | return 180; 42 | case "H4": 43 | return 240; 44 | case "H6": 45 | return 360; 46 | case "H12": 47 | return 720; 48 | case "D1": 49 | return 60 * 24; 50 | case "W1": 51 | return 60 * 24 * 7; 52 | case "M1": 53 | return 60 * 24 * 30; 54 | } 55 | 56 | return 60; 57 | } 58 | 59 | 60 | public static TimeSpan StringToTimeSpan(string timespan) 61 | { 62 | TimeSpan t = new TimeSpan(); 63 | 64 | switch (timespan) 65 | { 66 | case "m1": 67 | { 68 | t = new TimeSpan(0, 1, 0); 69 | break; 70 | } 71 | case "m5": 72 | { 73 | t = new TimeSpan(0, 5, 0); 74 | break; 75 | } 76 | case "m15": 77 | { 78 | t = new TimeSpan(0, 15, 0); 79 | break; 80 | } 81 | case "m30": 82 | { 83 | t = new TimeSpan(0, 30, 0); 84 | break; 85 | } 86 | case "H1": 87 | { 88 | t = new TimeSpan(1, 0, 0); 89 | break; 90 | } 91 | case "H2": 92 | { 93 | t = new TimeSpan(2, 0, 0); 94 | break; 95 | } 96 | case "H3": 97 | { 98 | t = new TimeSpan(3, 0, 0); 99 | break; 100 | } 101 | case "H4": 102 | { 103 | t = new TimeSpan(4, 0, 0); 104 | break; 105 | } 106 | case "H6": 107 | { 108 | t = new TimeSpan(6, 0, 0); 109 | break; 110 | } 111 | case "H12": 112 | { 113 | t = new TimeSpan(12, 0, 0); 114 | break; 115 | } 116 | case "D1": 117 | { 118 | t = new TimeSpan(1, 0, 0, 0); 119 | break; 120 | } 121 | case "W1": 122 | { 123 | t = new TimeSpan(5, 1, 0); 124 | break; 125 | } 126 | case "M1": 127 | { 128 | t = new TimeSpan(25, 1, 0); 129 | break; 130 | } 131 | } 132 | 133 | return t; 134 | } 135 | public Period TimePeriod { get; set; } 136 | 137 | public Timeframe() 138 | { 139 | 140 | } 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /DotNet/QuantSys/Analytics/StatisticalModeling/PCA/PCA.cs: -------------------------------------------------------------------------------- 1 | using MathNet.Numerics.LinearAlgebra; 2 | 3 | namespace QuantSys.Analytics.StatisticalModeling.PCA 4 | { 5 | class PCA 6 | { 7 | private Matrix sourceMatrix; 8 | private Vector singularValues; 9 | 10 | private Vector eigenValues; 11 | private Matrix eigenVectors; 12 | private Matrix resultMatrix; 13 | 14 | /* 15 | /// Computes the Principal Component Analysis algorithm. 16 | public void Compute() 17 | { 18 | int rows = sourceMatrix.RowCount; 19 | int cols = sourceMatrix.ColumnCount; 20 | 21 | // Create a new matrix to work upon 22 | Matrix matrix = Matrix.Create(new double[rows,cols]); 23 | 24 | 25 | // Prepare the data, storing it in the new matrix. 26 | if (this.analysisMethod == AnalysisMethod.Correlation) 27 | { 28 | for (int i = 0; i < rows; i++) 29 | for (int j = 0; j < cols; j++) 30 | // subtract mean and divide by standard deviation (convert to Z Scores) 31 | matrix[i, j] = (sourceMatrix[i, j] - sourceMatrix.GetColumnVector(j).Mean())/ 32 | sourceMatrix.GetColumnVector(j).StandardDeviation(); 33 | } 34 | else 35 | { 36 | for (int i = 0; i < rows; i++) 37 | for (int j = 0; j < cols; j++) 38 | // Just center the data around the mean. Will have no effect if the 39 | // data is already centered (the mean will be zero). 40 | matrix[i, j] = (sourceMatrix[i, j] - sourceMatrix..GetColumnVector(j).Mean()); 41 | } 42 | 43 | 44 | 45 | // Perform the Singular Value Decomposition (SVD) of the matrix 46 | SingularValueDecomposition singularDecomposition = new SingularValueDecomposition(matrix); 47 | singularValues = singularDecomposition.SingularValues; 48 | 49 | 50 | // Eigen values are the square of the singular values 51 | for (int i = 0; i < singularValues.Length; i++) 52 | { 53 | eigenValues[i] = singularValues[i] * singularValues[i]; 54 | } 55 | 56 | 57 | // The principal components of 'Source' are the eigenvectors of Cov(Source). Thus if we 58 | // calculate the SVD of 'matrix' (which is Source standardized), the columns of matrix V 59 | // (right side of SVD) will be the principal components of Source. 60 | 61 | 62 | // The right singular vectors contains the principal components of the data matrix 63 | this.eigenVectors = singularDecomposition.RightSingularVectors; 64 | 65 | // The left singular vectors contains the scores of the principal components 66 | this.resultMatrix = singularDecomposition.LeftSingularVectors; 67 | 68 | 69 | // Calculate proportions 70 | double sum = 0; 71 | for (int i = 0; i < eigenValues.Length; i++) 72 | sum += eigenValues[i]; 73 | sum = (1.0 / sum); 74 | 75 | for (int i = 0; i < eigenValues.Length; i++) 76 | componentProportions[i] = eigenValues[i] * sum; 77 | 78 | 79 | // Calculate cumulative proportions 80 | this.componentCumulative[0] = this.componentProportions[0]; 81 | for (int i = 1; i < this.componentCumulative.Length; i++) 82 | { 83 | this.componentCumulative[i] = this.componentCumulative[i - 1] + this.componentProportions[i]; 84 | } 85 | 86 | 87 | // Creates the object-oriented structure to hold the principal components 88 | PrincipalComponent[] components = new PrincipalComponent[singularValues.Length]; 89 | for (int i = 0; i < components.Length; i++) 90 | { 91 | components[i] = new PrincipalComponent(this, i); 92 | } 93 | this.componentCollection = new PrincipalComponentCollection(components); 94 | } 95 | * 96 | * * 97 | */ 98 | } 99 | 100 | } 101 | -------------------------------------------------------------------------------- /DotNet/QuantSys/MachineLearning/NeuralNetwork/TwoStageNN.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using MathNet.Numerics.LinearAlgebra.Double; 3 | using QuantSys.Analytics; 4 | using QuantSys.Analytics.StatisticalModeling; 5 | 6 | namespace QuantSys.MachineLearning.NeuralNetwork 7 | { 8 | public class TwoStageNN 9 | { 10 | private readonly int cycles; 11 | private readonly object[,] data; 12 | private readonly int[] vectors; 13 | private readonly int window; 14 | 15 | public double RMSE; 16 | public double correlation; 17 | 18 | public TwoStageNN(int window, int cycles, object[,] data, int[] vectors) 19 | { 20 | this.window = window; 21 | this.cycles = cycles; 22 | this.data = data; 23 | this.vectors = vectors; 24 | } 25 | 26 | public void Execute() 27 | { 28 | var nnSet = new Stage1NeuralNetwork[vectors.Length]; 29 | 30 | int trainLength = 2000; 31 | int validationLength = 500; 32 | int predictLength = 500; 33 | int useLength = 3000; 34 | 35 | var totalData = new DenseMatrix(vectors.Length, useLength); 36 | var outputData = new DenseMatrix(vectors.Length, validationLength - window); 37 | 38 | /////////////////populate the actual price data we want to predict 39 | var pricingData = new double[useLength]; 40 | 41 | for (int i = 2; i < 2 + useLength; i++) 42 | { 43 | pricingData[i - 2] = (double) data[useLength + 3 - i, 5]; 44 | } 45 | 46 | 47 | double[] returnpricingData = pricingData.RawRateOfReturn(); 48 | for (int i = 0; i < returnpricingData.Length; i++) pricingData[i + 1] = returnpricingData[i]; 49 | pricingData[0] = 0; 50 | 51 | 52 | ////////////////////////training and validation//////////////////////// 53 | for (int i = 2; i < 2 + useLength; i++) 54 | { 55 | for (int j = 0; j < vectors.Length; j++) 56 | { 57 | totalData[j, i - 2] = (double) data[useLength + 3 - i, vectors[j]]; 58 | } 59 | } 60 | 61 | 62 | for (int j = 0; j < vectors.Length; j++) 63 | { 64 | double[] train = totalData.Row(j).ToArray().Take(trainLength).ToArray(); 65 | double[] validate = 66 | totalData.Row(j).ToArray().Skip(trainLength).ToArray().Take(validationLength).ToArray(); 67 | nnSet[j] = new Stage1NeuralNetwork(window, cycles, train, validate); 68 | nnSet[j].Execute(j); 69 | outputData.SetRow(j, nnSet[j].OutputData); 70 | } 71 | 72 | var s1 = new Stage2NeuralNetwork(vectors.Length, cycles, outputData, 73 | pricingData.Skip(trainLength).ToArray().Take(validationLength).ToArray().Skip(window).ToArray()); 74 | s1.Execute(); 75 | 76 | ////////////////////////////////////////////////////////////////////////// 77 | //////////////////////////////////prediction///////////////////////////// 78 | var predictedData = new DenseMatrix(vectors.Length, predictLength - window + 1); 79 | 80 | var lastPredData = new double[vectors.Length]; 81 | 82 | for (int j = 0; j < vectors.Length; j++) 83 | { 84 | double[] predictData = 85 | totalData.Row(j) 86 | .ToArray() 87 | .Skip(trainLength + validationLength) 88 | .ToArray() 89 | .Take(predictLength) 90 | .ToArray(); 91 | nnSet[j].Predict(predictData); 92 | predictedData.SetRow(j, nnSet[j].OutputData); 93 | lastPredData[j] = nnSet[j].NextPrediction; 94 | } 95 | 96 | s1.Predict(predictedData, 97 | pricingData.ToArray() 98 | .Skip(trainLength + validationLength) 99 | .ToArray() 100 | .Take(predictLength) 101 | .ToArray() 102 | .Skip(window) 103 | .ToArray()); 104 | 105 | correlation = s1.outputCorre; 106 | RMSE = s1.outputRMSE; 107 | } 108 | } 109 | } --------------------------------------------------------------------------------