79 lines
4.3 KiB
C#
79 lines
4.3 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using MarketData.Numerical;
|
|
using MarketData.MarketDataModel;
|
|
using MarketData.DataAccess;
|
|
using MarketData.Cache;
|
|
using MarketData.Utils;
|
|
|
|
namespace MarketData.Generator.Indicators
|
|
{
|
|
// ***********************************************************************************
|
|
public class OverExtendedIndicator
|
|
{
|
|
private static double marginPercent=1.50; // The default margin is 1.00. 1.50 Gives the best results in backtests from 2013->2021
|
|
private OverExtendedIndicator() // Also, regarding VioaltionThresshold below.... the best results were obtained with MarginePercent=1.5 and ViolationThresshol=1.00
|
|
{
|
|
}
|
|
// UseOverExtendedIndicator:true/false
|
|
// UseOverExtendedIndicatorDays:45
|
|
// UseOverExtendedViolationThreshhold:2 breaks >=2 this number are considered to be violations
|
|
// This Indicator determines if a price is overextended by looking at the K band of the bollinger band over the past "dayCount" days.
|
|
// If closing price breaks the K band by more than 1.00% then we consider that to be an indication that the price is overextended.
|
|
public static bool? IsOverextended(String symbol,DateTime pricingDate,int dayCount=20)
|
|
{
|
|
bool isOverExtended=false;
|
|
Prices prices=GBPriceCache.GetInstance().GetPrices(symbol,pricingDate,dayCount*4);
|
|
if(null==prices || 0==prices.Count)return null;
|
|
BollingerBands bollingerBands=BollingerBandGenerator.GenerateBollingerBands(prices,dayCount);
|
|
if(null==bollingerBands)return false;
|
|
bollingerBands=new BollingerBands(bollingerBands.Take(dayCount).ToList());
|
|
BollingerBandElement item=bollingerBands.Where(x => x.Close>x.K && (((x.Close-x.K)/x.K)*100.00)>marginPercent).FirstOrDefault();
|
|
if(null!=item)isOverExtended=true;
|
|
return isOverExtended;
|
|
}
|
|
// This method considers an overextended condition based upon an allowable number of upper band breaks
|
|
public static bool? IsOverextended(String symbol,DateTime pricingDate,int dayCount=20,int violationThreshhold=1)
|
|
{
|
|
bool isOverExtended=false;
|
|
Prices prices=GBPriceCache.GetInstance().GetPrices(symbol,pricingDate,dayCount*4);
|
|
if(null==prices||0==prices.Count) return null;
|
|
BollingerBands bollingerBands=BollingerBandGenerator.GenerateBollingerBands(prices,dayCount);
|
|
if(null==bollingerBands) return false;
|
|
bollingerBands=new BollingerBands(bollingerBands.Take(dayCount).ToList());
|
|
List<BollingerBandElement> items=bollingerBands.Where(x => x.Close>x.K&&(((x.Close-x.K)/x.K)*100.00)>marginPercent).ToList();
|
|
if(null==items)return null;
|
|
if(items.Count>violationThreshhold)isOverExtended=true;
|
|
return isOverExtended;
|
|
}
|
|
// This method considers an overextended condition based upon an allowable number of upper band breaks and user supplied marginPercent
|
|
public static bool? IsOverextended(String symbol,DateTime pricingDate,int dayCount=20,int violationThreshhold=1,double paramMarginPercent=1.00)
|
|
{
|
|
bool isOverExtended=false;
|
|
Prices prices=GBPriceCache.GetInstance().GetPrices(symbol,pricingDate,dayCount*4);
|
|
if(null==prices||0==prices.Count) return null;
|
|
BollingerBands bollingerBands=BollingerBandGenerator.GenerateBollingerBands(prices,dayCount);
|
|
if(null==bollingerBands) return false;
|
|
bollingerBands=new BollingerBands(bollingerBands.Take(dayCount).ToList());
|
|
List<BollingerBandElement> items=bollingerBands.Where(x => x.Close>x.K&&(((x.Close-x.K)/x.K)*100.00)>paramMarginPercent).ToList();
|
|
if(null==items) return null;
|
|
if(items.Count>violationThreshhold) isOverExtended=true;
|
|
return isOverExtended;
|
|
}
|
|
public static int? OverExtendedCount(String symbol,DateTime pricingDate,int dayCount=20)
|
|
{
|
|
Prices prices=GBPriceCache.GetInstance().GetPrices(symbol,pricingDate,dayCount*4);
|
|
if(null==prices||0==prices.Count) return null;
|
|
BollingerBands bollingerBands=BollingerBandGenerator.GenerateBollingerBands(prices,dayCount);
|
|
if(null==bollingerBands) return null;
|
|
bollingerBands=new BollingerBands(bollingerBands.Take(dayCount).ToList());
|
|
List<BollingerBandElement> items=bollingerBands.Where(x => x.Close>x.K).ToList();
|
|
if(null==items)return null;
|
|
return items.Count;
|
|
}
|
|
}
|
|
}
|