Overall Statistics |
Total Trades 0 Average Win 0% Average Loss 0% Compounding Annual Return 0% Drawdown 0% Expectancy 0 Net Profit 0% Sharpe Ratio 0 Probabilistic Sharpe Ratio 0% Loss Rate 0% Win Rate 0% Profit-Loss Ratio 0 Alpha 0 Beta 0 Annual Standard Deviation 0 Annual Variance 0 Information Ratio 0.805 Tracking Error 0.969 Treynor Ratio 0 Total Fees $0.00 |
using MathNet.Numerics.Statistics; using System.Linq; namespace QuantConnect.Algorithm.CSharp { public class ValueArea_AMT : QCAlgorithm { Resolution resolution = Resolution.Second; decimal ticks = 0.25m; decimal POC = 0m; decimal VAHigh = 0m; decimal VALow = 0m; public override void Initialize() { SetStartDate(2020, 3, 1); //Set Start Date //SetEndDate(2020, 2, 7); SetCash(100000); //Set Strategy Cash // Store symbol objects in List manually for now Symbol spy = AddEquity("SPY", Resolution.Minute).Symbol; // Schedule calculate value area once per day Schedule.On(DateRules.EveryDay(), TimeRules.At(9, 0), () => { // History call stuck in some infinite loop on the 5th and 6th... // Get the last trading day's worth of bars @ minute resolution var bars = History<TradeBar>(spy, 450, Resolution.Minute); var VA = ValueArea(bars); POC = VA.Item1; VAHigh = VA.Item2; VALow = VA.Item3; Debug("POC " + POC + " VAHigh " + VAHigh + " VALow " + VALow); }); } public override void OnData(Slice data) { // Do something } public Tuple<decimal,decimal,decimal> ValueArea(IEnumerable<TradeBar> history) { // Define minimum price interval (ticks) int interval = 2; IDictionary<decimal,decimal> intervalpricevol = new Dictionary<decimal,decimal>(); // empty dict // Strip out close and volume from history, zip into a collection List<decimal> volumes = history.Select(x => x.Volume).ToList(); List<decimal> closes = history.Select(x => x.Close).ToList(); var pricevol = volumes .Zip(closes, (key, value) => new { key, value }) .ToLookup(x => x.key, x => x.value); decimal _hiclose = closes.Max(); decimal _loclose = closes.Min(); decimal _indprice = _hiclose; //index slice for iterating through dict, from hi to lo // Turn pricevol ticks into a collection of intervals while (_indprice >= (_loclose - ticks)) { decimal _tickvol = 0m; // count er for volumes // loop through and find valid values foreach(var pair in pricevol) { foreach (decimal value in pair) // Get total volume of prices in range if (value <= _indprice && value > (_indprice - ticks)) { _tickvol += pair.Key; } } // add new vol/price pair to dict if vol not zero if (_tickvol != 0) { intervalpricevol.Add(new KeyValuePair<decimal, decimal>(_tickvol, _indprice)); } // re-index _indprice to one tick below _indprice -= ticks; } //Debug("volume check " + (volumes.Sum() - intervalpricevol.Keys.Sum())); // Calculate POC POC = intervalpricevol[ intervalpricevol.Keys.Max() ]; // counter for prices above and below POC VAHigh = POC; VALow = POC; // counter for total, above and below volume decimal _volumecounter = 0m; decimal _prevabovevolume = 0m; decimal _prevbelowvolume = 0m; // Get total volume and * 0.70 to get Value Area threshold volume decimal _70_percent_lvl = volumes.Sum() * 0.7m; // loop through dictionary while volume counter < _70_percent_lvl while (_volumecounter < _70_percent_lvl) { // counters for total areas decimal _abovevolume = 0m; decimal _belowvolume = 0m; // Iterate over entire dict to find volumes VALow< prices < VAHigh foreach(KeyValuePair<decimal,decimal> pair in intervalpricevol) { // if volume of prices that trade above POC > below, add that slice to value area and v.v. if (pair.Value > POC && pair.Value <= (VAHigh + ticks * interval) ) { _abovevolume += pair.Key; } if (pair.Value < POC && pair.Value >= (VALow - ticks * interval)) { _belowvolume += pair.Key; } } // Compare slices and add the slice with greater volume to Value Area if ((_abovevolume - _prevabovevolume) >= (_belowvolume - _prevbelowvolume)) { VAHigh += ticks * interval; _volumecounter += (_abovevolume - _prevabovevolume); _prevabovevolume = _abovevolume; } else { VALow -= ticks * interval; _volumecounter += (_belowvolume - _prevbelowvolume); _prevbelowvolume = _belowvolume; } } return Tuple.Create(POC,VAHigh, VALow); } } }