| 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);
}
}
}