Skip to content

Commit

Permalink
Fixes #103
Browse files Browse the repository at this point in the history
  • Loading branch information
Karl Wan committed Jan 7, 2020
1 parent 084ae60 commit 8565997
Show file tree
Hide file tree
Showing 6 changed files with 241 additions and 10 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ This library is a hobby project, and would probably making breaking changes, use
* Signal capturing by rules
* Strategy backtesting by buy/sell rule

## v3.2.2 update
* Fixes CommodityChannelIndex

## v3.2 update
* Added WeightedMovingAverage, HullMovingAverage & KeltnerChannels
* Added AlphaVantage importer (thanks to @irperez)
Expand Down
27 changes: 19 additions & 8 deletions Trady.Analysis/Indicator/CommodityChannelIndex.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,30 @@ public CommodityChannelIndex(IEnumerable<TInput> inputs, Func<TInput, (decimal H

protected override decimal? ComputeByIndexImpl(IReadOnlyList<(decimal High, decimal Low, decimal Close)> mappedInputs, int index)
{
if (index < PeriodCount - 1)
var firstNonNullCciIndex = 2 * (PeriodCount - 1);

if (index < firstNonNullCciIndex)
return default;

var typicalPrices = mappedInputs
.Skip(index - PeriodCount + 1)
.Take(PeriodCount)
.Select(i => (i.High + i.Low + i.Close) / 3);
.Skip(index - firstNonNullCciIndex)
.Take(firstNonNullCciIndex + 1)
.Select(i => (i.High + i.Low + i.Close) / 3)
.ToList();

var typicalPricesSmas = Enumerable
.Range(PeriodCount - 1, PeriodCount)
.Select(i => typicalPrices.Skip(i - (PeriodCount - 1)).Take(PeriodCount).Average())
.ToList();

var deviation = Enumerable
.Range(0, PeriodCount)
.Select(i => Math.Abs(typicalPrices.ElementAt(i + PeriodCount - 1) - typicalPricesSmas.ElementAt(i)))
.ToList();

var average = typicalPrices.Average();
var meanDeviation = typicalPrices
.Select(tp => Math.Abs(tp - average)).Sum() / typicalPrices.Count();
var meanDeviation = deviation.Average();

return meanDeviation == 0 ? default : (typicalPrices.Last() - average) / (0.015m * meanDeviation);
return meanDeviation == 0 ? default : (typicalPrices.Last() - typicalPricesSmas.Last()) / (0.015m * meanDeviation);
}
}

Expand Down
4 changes: 2 additions & 2 deletions Trady.Analysis/Trady.Analysis.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<Description>Analysis module of Trady, a handy library for computing technical indicators, based on .NET Standard 2.0</Description>
<Copyright>Copyright (c) 2016-2017 Karl Wan</Copyright>
<AssemblyTitle>Trady.Analysis</AssemblyTitle>
<VersionPrefix>3.2.1</VersionPrefix>
<VersionPrefix>3.2.2</VersionPrefix>
<Authors>Karl Wan</Authors>
<TargetFramework>netstandard2.0</TargetFramework>
<AssemblyName>Trady.Analysis</AssemblyName>
Expand All @@ -27,7 +27,7 @@
<GenerateNeutralResourcesLanguageAttribute>false</GenerateNeutralResourcesLanguageAttribute>
<GenerateAssemblyVersionAttribute>false</GenerateAssemblyVersionAttribute>
<GenerateAssemblyFileVersionAttribute>false</GenerateAssemblyFileVersionAttribute>
<Version>3.2.1</Version>
<Version>3.2.2</Version>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<LangVersion>latest</LangVersion>
Expand Down
13 changes: 13 additions & 0 deletions Trady.Test/IndicatorTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,13 @@ protected async Task<IEnumerable<IOhlcv>> ImportIOhlcvDatasAsync()
//return candles;
}

protected async Task<IEnumerable<IOhlcv>> ImportCCiIOhlcvDatasAsync()
{
var csvImporter = new CsvImporter("cci_test.csv", CultureInfo.GetCultureInfo("en-US"));

return await csvImporter.ImportAsync("cci_test");
}

//protected async Task<IEnumerable<IOhlcv>> ImportSpyAsync()
//{
// var csvImporter = new CsvImporter("spx.csv", CultureInfo.GetCultureInfo("en-US"));
Expand Down Expand Up @@ -69,6 +76,12 @@ public async Task TestCciAsync()
var candles = await ImportIOhlcvDatasAsync();
var result = candles.Cci(20)[candles.Count() - 1];
Assert.IsTrue(result.Tick.Value.IsApproximatelyEquals(8.17m));

// Fixes #103: Not getting expected CCI values
var candles2 = await ImportCCiIOhlcvDatasAsync();
var cci = candles2.Cci(14);
var result2 = cci[candles2.Count() - 1];
Assert.IsTrue(result2.Tick.Value.IsApproximatelyEquals(66.66666667m));
}

[TestMethod]
Expand Down
3 changes: 3 additions & 0 deletions Trady.Test/Trady.Test.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@
</ItemGroup>

<ItemGroup>
<None Update="cci_test.csv">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="EURUSD.csv">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
Expand Down
201 changes: 201 additions & 0 deletions Trady.Test/cci_test.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
DateTime,Open,High,Low,Close,Volume
12/1/2019 17:00,1,1,1,1,573576400
12/1/2019 18:00,1,2,1,1,168192700
12/1/2019 19:00,1,3,1,1,101786600
12/1/2019 20:00,1,4,1,1,73600000
12/1/2019 21:00,1,5,1,1,50237200
12/1/2019 22:00,1,6,1,1,37149800
12/1/2019 23:00,1,7,1,1,78063400
12/2/2019 0:00,1,8,1,1,57267900
12/2/2019 1:00,1,9,1,1,111639200
12/2/2019 2:00,1,10,1,1,41855500
12/2/2019 3:00,1,11,1,1,35230300
12/2/2019 4:00,1,12,1,1,42473400
12/2/2019 5:00,1,13,1,1,61489200
12/2/2019 6:00,1,14,1,1,26159500
12/2/2019 7:00,1,15,1,1,38034000
12/2/2019 8:00,1,16,1,1,28219600
12/2/2019 9:00,1,17,1,1,15816800
12/2/2019 10:00,1,18,1,1,17102800
12/2/2019 11:00,1,19,1,1,16855000
12/2/2019 12:00,1,20,1,1,43563800
12/2/2019 13:00,1,21,1,1,42978900
12/2/2019 14:00,1,22,1,1,30849000
12/2/2019 15:00,1,23,1,1,15553600
12/2/2019 16:00,1,24,1,1,21875300
12/2/2019 17:00,1,25,1,1,74834000
12/2/2019 18:00,1,26,1,1,24352900
12/2/2019 19:00,1,27,1,1,24858700
12/2/2019 20:00,1,28,1,1,28568000
12/2/2019 21:00,1,29,1,1,17713300
12/2/2019 22:00,1,30,1,1,19526900
12/2/2019 23:00,1,31,1,1,14122000
12/3/2019 0:00,1,32,1,1,8763600
12/3/2019 1:00,1,33,1,1,10032100
12/3/2019 2:00,1,34,1,1,10945600
12/3/2019 3:00,1,35,1,1,17785200
12/3/2019 4:00,1,36,1,1,14269500
12/3/2019 5:00,1,37,1,1,13030300
12/3/2019 6:00,1,38,1,1,11300700
12/3/2019 7:00,1,39,1,1,8108300
12/3/2019 8:00,1,40,1,1,24672100
12/3/2019 9:00,1,41,1,1,30438600
12/3/2019 10:00,1,42,1,1,16841800
12/3/2019 11:00,1,43,1,1,13685100
12/3/2019 12:00,1,44,1,1,11869100
12/3/2019 13:00,1,45,1,1,12390700
12/3/2019 14:00,1,46,1,1,11539800
12/3/2019 15:00,1,47,1,1,17230200
12/3/2019 16:00,1,48,1,1,64597400
12/3/2019 17:00,1,49,1,1,123102300
12/3/2019 18:00,1,50,1,1,29285900
12/3/2019 19:00,1,51,1,1,56179400
12/3/2019 20:00,1,52,1,1,44604400
12/3/2019 21:00,1,53,1,1,56374500
12/3/2019 22:00,1,54,1,1,80647000
12/3/2019 23:00,1,55,1,1,27778900
12/4/2019 0:00,1,56,1,1,36782900
12/4/2019 1:00,1,57,1,1,29537400
12/4/2019 2:00,1,58,1,1,15610700
12/4/2019 3:00,1,59,1,1,25794700
12/4/2019 4:00,1,60,1,1,24973100
12/4/2019 5:00,1,61,1,1,39308800
12/4/2019 6:00,1,62,1,1,47861100
12/4/2019 7:00,1,63,1,1,157565300
12/4/2019 8:00,1,64,1,1,129293400
12/4/2019 9:00,1,65,1,1,101186600
12/4/2019 10:00,1,66,1,1,70640600
12/4/2019 11:00,1,67,1,1,49892200
12/4/2019 12:00,1,68,1,1,32813700
12/4/2019 13:00,1,69,1,1,29622200
12/4/2019 14:00,1,70,1,1,20704000
12/4/2019 15:00,1,71,1,1,25417000
12/4/2019 16:00,1,72,1,1,16124700
12/4/2019 17:00,1,73,1,1,30647500
12/4/2019 18:00,1,74,1,1,58764200
12/4/2019 19:00,1,75,1,1,46622400
12/4/2019 20:00,1,76,1,1,60781800
12/4/2019 21:00,1,77,1,1,46066500
12/4/2019 22:00,1,78,1,1,36371700
12/4/2019 23:00,1,79,1,1,24797800
12/5/2019 0:00,1,80,1,1,50508200
12/5/2019 1:00,1,81,1,1,121584000
12/5/2019 2:00,1,82,1,1,65041600
12/5/2019 3:00,1,83,1,1,72819800
12/5/2019 4:00,1,84,1,1,50667600
12/5/2019 5:00,1,85,1,1,36371700
12/5/2019 6:00,1,86,1,1,24797800
12/5/2019 7:00,1,87,1,1,50508200
12/5/2019 8:00,1,88,1,1,121584000
12/5/2019 9:00,1,89,1,1,65041600
12/5/2019 10:00,1,90,1,1,72819800
12/5/2019 11:00,1,91,1,1,50667600
12/5/2019 12:00,1,92,1,1,36371700
12/5/2019 13:00,1,93,1,1,24797800
12/5/2019 14:00,1,94,1,1,50508200
12/5/2019 15:00,1,95,1,1,121584000
12/5/2019 16:00,1,96,1,1,65041600
12/5/2019 17:00,1,97,1,1,72819800
12/5/2019 18:00,1,98,1,1,50667600
12/5/2019 19:00,1,99,1,1,36371700
12/5/2019 20:00,1,100,1,1,24797800
12/5/2019 21:00,1,101,1,1,50508200
12/5/2019 22:00,1,102,1,1,121584000
12/5/2019 23:00,1,103,1,1,65041600
12/6/2019 0:00,1,104,1,1,72819800
12/6/2019 1:00,1,105,1,1,50667600
12/6/2019 2:00,1,106,1,1,36371700
12/6/2019 3:00,1,107,1,1,24797800
12/6/2019 4:00,1,108,1,1,50508200
12/6/2019 5:00,1,109,1,1,121584000
12/6/2019 6:00,1,110,1,1,65041600
12/6/2019 7:00,1,111,1,1,72819800
12/6/2019 8:00,1,112,1,1,50667600
12/6/2019 9:00,1,113,1,1,24797800
12/6/2019 10:00,1,114,1,1,50508200
12/6/2019 11:00,1,115,1,1,121584000
12/6/2019 12:00,1,116,1,1,65041600
12/6/2019 13:00,1,117,1,1,72819800
12/8/2019 17:00,1,118,1,1,50667600
12/8/2019 18:00,1,119,1,1,36371700
12/8/2019 19:00,1,120,1,1,24797800
12/8/2019 20:00,1,121,1,1,50508200
12/8/2019 21:00,1,122,1,1,121584000
12/8/2019 22:00,1,123,1,1,65041600
12/8/2019 23:00,1,124,1,1,72819800
12/9/2019 0:00,1,125,1,1,50667600
12/9/2019 1:00,1,126,1,1,36371700
12/9/2019 2:00,1,127,1,1,24797800
12/9/2019 3:00,1,128,1,1,50508200
12/9/2019 4:00,1,129,1,1,121584000
12/9/2019 5:00,1,130,1,1,65041600
12/9/2019 6:00,1,131,1,1,72819800
12/9/2019 7:00,1,132,1,1,50667600
12/9/2019 8:00,1,133,1,1,36371700
12/9/2019 9:00,1,134,1,1,24797800
12/9/2019 10:00,1,135,1,1,50508200
12/9/2019 11:00,1,136,1,1,121584000
12/9/2019 12:00,1,137,1,1,65041600
12/9/2019 13:00,1,138,1,1,72819800
12/9/2019 14:00,1,139,1,1,50667600
12/9/2019 15:00,1,140,1,1,36371700
12/9/2019 16:00,1,141,1,1,24797800
12/9/2019 17:00,1,142,1,1,50508200
12/9/2019 18:00,1,143,1,1,121584000
12/9/2019 19:00,1,144,1,1,65041600
12/9/2019 20:00,1,145,1,1,72819800
12/9/2019 21:00,1,146,1,1,50667600
12/9/2019 22:00,1,147,1,1,36371700
12/9/2019 23:00,1,148,1,1,24797800
12/10/2019 0:00,1,149,1,1,50508200
12/10/2019 1:00,1,150,1,1,121584000
12/10/2019 2:00,1,151,1,1,65041600
12/10/2019 3:00,1,152,1,1,72819800
12/10/2019 4:00,1,153,1,1,50667600
12/10/2019 5:00,1,154,1,1,36371700
12/10/2019 6:00,1,155,1,1,24797800
12/10/2019 7:00,1,156,1,1,50508200
12/10/2019 8:00,1,157,1,1,121584000
12/10/2019 9:00,1,158,1,1,65041600
12/10/2019 10:00,1,159,1,1,72819800
12/10/2019 11:00,1,160,1,1,50667600
12/10/2019 12:00,1,161,1,1,36371700
12/10/2019 13:00,1,162,1,1,24797800
12/10/2019 14:00,1,163,1,1,50508200
12/10/2019 15:00,1,164,1,1,121584000
12/10/2019 16:00,1,165,1,1,65041600
12/10/2019 17:00,1,166,1,1,72819800
12/10/2019 18:00,1,167,1,1,50667600
12/10/2019 19:00,1,168,1,1,36371700
12/10/2019 20:00,1,169,1,1,24797800
12/10/2019 21:00,1,170,1,1,50508200
12/10/2019 22:00,1,171,1,1,121584000
12/10/2019 23:00,1,172,1,1,65041600
12/11/2019 0:00,1,173,1,1,72819800
12/11/2019 1:00,1,174,1,1,50667600
12/11/2019 2:00,1,175,1,1,36371700
12/11/2019 3:00,1,176,1,1,24797800
12/11/2019 4:00,1,177,1,1,50508200
12/11/2019 5:00,1,178,1,1,121584000
12/11/2019 6:00,1,179,1,1,65041600
12/11/2019 7:00,1,180,1,1,72819800
12/11/2019 8:00,1,181,1,1,50667600
12/11/2019 9:00,1,182,1,1,36371700
12/11/2019 10:00,1,183,1,1,24797800
12/11/2019 11:00,1,184,1,1,50508200
12/11/2019 12:00,1,185,1,1,121584000
12/11/2019 13:00,1,186,1,1,65041600
12/11/2019 14:00,1,187,1,1,72819800
12/11/2019 15:00,1,188,1,1,50667600
12/11/2019 16:00,1,189,1,1,36371700
12/11/2019 17:00,1,190,1,1,24797800
12/11/2019 18:00,1,191,1,1,50508200
12/11/2019 19:00,1,192,1,1,121584000
12/11/2019 20:00,1,193,1,1,65041600
12/11/2019 21:00,1,194,1,1,72819800
12/11/2019 22:00,1,195,1,1,50667600
12/11/2019 23:00,1,196,1,1,36371700
12/12/2019 0:00,1,197,1,1,65041600
12/12/2019 1:00,1,198,1,1,72819800
12/12/2019 2:00,1,199,1,1,50667600
12/12/2019 3:00,1,200,1,1,36371700

0 comments on commit 8565997

Please sign in to comment.