Lapsa's very own thread

Posted By: Lapsa

Lapsa's very own thread - 08/17/21 13:08

I want to document my experiments somewhere.
This seems like a decent place. I like forums.
Feedback is welcome.

------------------------

Cycles

My latest obsession is cycles. Been thinking a lot about what would be good ways to utilize Hilbert's Transform Dominant Cycle.

So today wrote a small script to compare how fixed length SMA looks compared to dc_period long SMA to see if I spot anything meaningful.


Code
#include <profile.c>

function run()
{
	set(PLOTNOW);
	BarPeriod = 1;
	LookBack = 100;
	StartDate = 20210702;
	EndDate = 20210816;

	vars seriesClose = series(priceClose());

	var sma23 = SMA(seriesClose,23);
	var period = HTDcPeriod(seriesClose);

	plot("SMA 23", sma23, MAIN, RED);
	plot("ASMA", adaptiveSma, MAIN, GREEN);
}


[Linked Image]


Conclusions are kind of obvious:
- lags less when dominant cycle is shorter than fixed one
- lags more when longer

Picked length 23 cause it looked like kind of average of what dominant cycle tends to spin around.

So I thought:
"Ok... but how that visually compares to The Shapeshifter of MA`s aka KAMA"?


Code
	var kama = KAMA(seriesClose, 23);
	var veryAdaptiveKama = KAMA(seriesClose, period);
	plot("KAMA 23", kama, MAIN, SILVER);
	plot("VAKAMA", veryAdaptiveKama, MAIN, GREY);


[Linked Image]


The effect is same although SMA behaves much differently than KAMA.

So really... No huge revelations here.

Lets smash in some trade signals!!!111eleven


Code
#include <profile.c>

function run()
{
	set(PLOTNOW);
	BarPeriod = 1;
	LookBack = 100;
	StartDate = 20210702;
	EndDate = 20210816;

	vars seriesClose = series(priceClose());
	var period = HTDcPeriod(seriesClose);

	var sma22 = SMA(seriesClose,22);
	var adaptiveSma = SMA(seriesClose,period);
	var kama22 = KAMA(seriesClose, 22);
	var veryAdaptiveKama = KAMA(seriesClose, period);
	
	if (	  
	  price() > veryAdaptiveKama &&
	  veryAdaptiveKama > kama22 &&
	  veryAdaptiveKama > adaptiveSma &&
	  adaptiveSma > sma22 &&
	  rising(series(sma22))
	) {
		exitShort();
		if (ProfitOpen >= 0) enterLong();
	}
	
	if (	  
	  price() < veryAdaptiveKama &&
	  veryAdaptiveKama < kama22 &&
	  veryAdaptiveKama < adaptiveSma &&
	  adaptiveSma < sma22 &&
	  falling(series(sma22))
	) {
		exitLong();
		if (ProfitOpen >= 0) enterShort();
	}
	
	plot("SMA 22", sma22, MAIN, RED);
	plot("ASMA", adaptiveSma, MAIN, GREEN);
	plot("KAMA 22", kama22, MAIN, SILVER);
	plot("VAKAMA", veryAdaptiveKama, MAIN, GREY);	
	plot("Profit Open", ProfitOpen, NEW, RED);
	plot("HT Dc Period", period, NEW, BLACK);
}


[Linked Image]

Quote

Monte Carlo Analysis... Median AR 2509%
Win 9100$ MI 6082$ DD 810$ Capital 2774$
Trades 2485 Win 42.7% Avg +36.6p Bars 67
AR 2631% PF 1.82 SR 0.00 UI 0% R2 1.00


For such randomness - PF of 1.82 ain't total disaster.
Posted By: Lapsa

Re: Lapsa's very own thread - 08/17/21 20:10

Ehler's "Modified Simple Moving Averages"


Code
#include <profile.c>

var ModifiedSMA(var* Data, var* FractionalCoefficients)
{
	var sum=0., coefficientSum=0.;
	int i;
	int period=sizeof(FractionalCoefficients);
	
	for(i=0; i<period; i++) {
		sum += (Data[i] * FractionalCoefficients[i]);
		coefficientSum += FractionalCoefficients[i];
	}

	return sum / coefficientSum;
}

function run()
{
	set(PLOTNOW);
	BarPeriod = 1;
	LookBack = 100;
	StartDate = 20210702;
	EndDate = 20210816;

	vars seriesClose = series(priceClose());

	var sma = SMA(seriesClose, 4);
	var coefficients[] = {.5,1,1,1,.5};	
	var modifiedSMA = ModifiedSMA(seriesClose, coefficients);
	
	var weirdCoefficients[] = {.2,1,1.6,1,.2};
	var weirdSMA = ModifiedSMA(seriesClose, weirdCoefficients);
	
	var weirderCoefficients[] = {.1,1,1,1.7,.2};
	var weirderSMA = ModifiedSMA(seriesClose, weirderCoefficients);

	var shouldBeFastestCoefficients[] = {2,.2,1.2,.2,.4};
	var shouldBeFastest = ModifiedSMA(
		seriesClose, shouldBeFastestCoefficients
	);
	
	plot("SMA 4", sma, MAIN, RED);
	plot(".5 1 1 1 .5", modifiedSMA, MAIN, BLUE);
	plot(".2 1 1.6 1 .2", weirdSMA, MAIN, GREEN);
	plot(".1 1 1 1.7 .2", weirderSMA, MAIN, MAGENTA);
	plot("2 .2 1.2 .2 .4", shouldBeFastest, MAIN, CYAN);
}


[Linked Image]
Posted By: Lapsa

Re: Lapsa's very own thread - 08/17/21 20:44

EMA Ribbon

So I've been reading that book.
Yesterday it got me wondering - how exactly EMAs with varying alphas look like.


Code
#include <profile.c>

function run()
{
	set(PLOTNOW);
	BarPeriod = 1;
	LookBack = 100;
	StartDate = 20210702;
	EndDate = 20210816;

	vars closes = series(priceClose());

	var ema1 = EMA(closes,.1);
	var ema2 = EMA(closes,.2);
	var ema3 = EMA(closes,.3);
	var ema4 = EMA(closes,.4);
	var ema5 = EMA(closes,.5);
	var ema6 = EMA(closes,.6);
	var ema7 = EMA(closes,.7);
	var ema8 = EMA(closes,.8);
	var ema9 = EMA(closes,.9);
	var ema10 = EMA(closes,.15);
	
	plot(".1", ema1, MAIN, RED);
	plot(".2", ema2, MAIN, GREEN);
	plot(".3", ema3, MAIN, BLUE);
	plot(".4", ema4, MAIN, ORANGE);
	plot(".5", ema5, MAIN, BLACK);
	plot(".6", ema6, MAIN, MAGENTA);
	plot(".7", ema7, MAIN, OLIVE);
	plot(".8", ema8, MAIN, PURPLE);
	plot(".9", ema9, MAIN, LIGHTBLUE);
	plot(".15", ema10, MAIN, MAROON);
}


[Linked Image]


Looks beautiful.

Can't help but see that graph in 3D.
Reminds me of Sietches from Dune.

Ohkay... Is there an application for bunch of EMAs?

One of the most obvious "Market inefficiencies" for an algo trader to exploit is automation itself.

Got me wondering how would ribbon look like with more commonly used time periods.


Code
#include <profile.c>

function run()
{
	set(PLOTNOW);
	BarPeriod = 1;
	LookBack = 1500;
	StartDate = 20210703;
	EndDate = 20210816;

	vars closes = series(priceClose());

	var ema2 = EMA(closes,2);
	var ema5 = EMA(closes,5);
	var ema15 = EMA(closes,15);
	var ema30 = EMA(closes,30);
	var ema45 = EMA(closes,45);	
	var ema60 = EMA(closes,60);
	var ema120 = EMA(closes,120);	
	var ema180 = EMA(closes,180);
	var ema240 = EMA(closes,240);
	var ema1440 = EMA(closes,1440);	
	
	plot("2", ema2, MAIN, SILVER + TRANSP);
	plot("5", ema5, MAIN, CYAN + TRANSP);
	plot("15", ema15, MAIN, GREEN + TRANSP);
	plot("30", ema30, MAIN, MAGENTA);
	plot("45", ema45, MAIN, BLUE);
	plot("60", ema60, MAIN, DARKBLUE);
	plot("120", ema120, MAIN, PURPLE);
	plot("180", ema180, MAIN, MAROON);
	plot("240", ema240, MAIN, RED);
	plot("1440", ema1440, MAIN, BLACK);
}


[Linked Image]


Frikin sea waves!

Lets smash in some trade signals!!!111eleven


Code
#include <profile.c>

function run()
{
	set(NFA|PRELOAD|PLOTNOW);
	BarPeriod = 1;
	LookBack = 2000;
	StartDate = 20210703;
	EndDate = 20210716;
	BarMode = BR_FLAT;	
	History = "*.t6";
	Amount = 8;
	Capital = 600;
	// MaxLong = 5;
	// MaxShort = 5;
	// Stop = ATR(100) * 10;

	vars closes = series(priceClose());

	vars ema2 = series(KAMA(closes,2));
	vars ema5 = series(EMA(closes,5));
	vars ema15 = series(EMA(closes,14));
	vars ema30 = series(EMA(closes,27));
	vars ema45 = series(EMA(closes,44));	
	vars ema60 = series(EMA(closes,60));
	vars ema120 = series(EMA(closes,120));	
	vars ema180 = series(EMA(closes,181));
	vars ema240 = series(EMA(closes,235));
	vars ema1440 = series(EMA(closes,1433));	
	
	if (
		rising(ema2)
		&& rising(ema5)
		&& rising(ema15)
		&& rising(ema30)
		&& rising(ema45)
		&& rising(ema60)
		&& rising(ema120)
		&& rising(ema180)
		&& rising(ema240)
		&& rising(ema1440)
		&& ema2[0] > ema15[0]
		&& ema15[0] > ema30[0]
		&& ema30[0] > ema45[0]
		&& ema45[0] > ema60[0]
		&& ema120[0] > ema180[0]
		&& ema180[0] > ema240[0]
		&& ema240[0] < ema1440[0]		
	) enterLong(Amount);
	
	if (
		falling(ema2)
		&& falling(ema5)
		&& falling(ema15)
		&& falling(ema30)
		&& falling(ema45)
		&& falling(ema60)
		&& falling(ema120)
		&& falling(ema180)
		&& falling(ema240)
		&& falling(ema1440)
		&& ema2[0] < ema15[0]
		&& ema15[0] < ema30[0]
		&& ema30[0] < ema45[0]
		&& ema45[0] < ema60[0]
		&& ema120[0] < ema180[0]
		&& ema180[0] < ema240[0]
		&& ema240[0] > ema1440[0]
	) enterLong(Amount);
	
	if (crossUnder(ema5, ema45))
		exitShort();
	
	if (crossOver(ema5, ema45))
		exitLong();
}


[Linked Image]

Quote

Monte Carlo Analysis... Median AR 2070%
Win 10650$ MI 23156$ DD 2952$ Capital 666$
Trades 532 Win 62.6% Avg +25.0p Bars 59
CAGR 163492235397780660000000000000000000.00% PF 2.41 SR 0.00 UI 0% R2 1.00
Chart...


Finetuned af.
Likes to randomly pop up Margin Calls.

Posted By: Lapsa

Re: Lapsa's very own thread - 08/18/21 10:58

Ehler's "Modified Least-Squares Quadratics"


Code
#include <profile.c>

var ModifiedSMA(var* Data, var* FractionalCoefficients)
{
	var sum=0., coefficientSum=0.;
	int i;
	int period=sizeof(FractionalCoefficients);
	
	for(i=0; i<period; i++) {
		sum += (Data[i] * FractionalCoefficients[i]);
		coefficientSum += FractionalCoefficients[i];
	}

	return sum / coefficientSum;
}

function run()
{
	set(PLOTNOW);
	BarPeriod = 1;
	LookBack = 100;
	StartDate = 20210702;
	EndDate = 20210816;

	vars seriesClose = series(priceClose());

	var sma = SMA(seriesClose, 5);
	var c1[] = {7,24,34,24,7};
	var c2[] = {1,6,12,14,12,6,1};
	var c3[] = {-1,28,78,108,118,108,78,28,-1};
	var c4[] = {-11,18,88,138,168,178,168,138,88,18,-11};

	var m1 = ModifiedSMA(seriesClose, c1);
	var m2 = ModifiedSMA(seriesClose, c2);
	var m3 = ModifiedSMA(seriesClose, c3);
	var m4 = ModifiedSMA(seriesClose, c4);

	// [7 24 34 24 7] / 96
        // [1 6 12 14 12 6 1] / 52
        // [−1 28 78 108 118 108 78 28 −1] / 544
        // [−11 18 88 138 168 178 168 138 88 18 −11] / 980
	
	plot("SMA 5", sma, MAIN, RED);
	plot("c1", m1, MAIN, BLUE);
	plot("c2", m2, MAIN, GREEN);
	plot("c3", m3, MAIN, MAGENTA);
	plot("c4", m4, MAIN, CYAN);
}


[Linked Image]
Posted By: Lapsa

Re: Lapsa's very own thread - 08/18/21 11:26

2 Pole Butterworth filter

Quote

The Butterworth filter is a type of signal processing filter designed to have a frequency response as flat as possible in the passband. It is also referred to as a maximally flat magnitude filter.

Properties of the Butterworth filter are:
- monotonic amplitude response in both passband and stopband
- Quick roll-off around the cutoff frequency, which improves with increasing order
- Considerable overshoot and ringing in step response, which worsens with increasing order
- Slightly non-linear phase response
- Group delay largely frequency-dependent



Code
#include <profile.c>

var Butterworth2Pole(var* Data, int Period)
{
	var a = exp(-1.414*PI/Period);
	var b = 2*a*cos(1.414*1.25*180/Period);
	var c2 = b;
	var c3 = -a*a;
	var c1 = 1-c2-c3;
	
	var* Filt = series(*Data,3);
	// syntax error? TODO: check what happened w/ SETSERIES
	//	SETSERIES(Data,0);
	series(Data[0],0); // is that an equivalent?
	return Filt[0] = c1*Data[0] + c2*Filt[1] + c3*Filt[2];
}

function run()
{
	set(PLOTNOW);
	BarPeriod = 1;
	LookBack = 100;
	StartDate = 20210702;
	EndDate = 20210816;

	vars seriesClose = series(priceClose());

	var sma = SMA(seriesClose, 5);
	var butt = Butterworth2Pole(seriesClose, 5);
	var butt3Pole = Butterworth(seriesClose, 5);
		
	plot("SMA 5", sma, MAIN, SILVER);
	plot("2 Pole Butt", butt, MAIN, RED);
	plot("3 Pole Butt", butt3Pole, MAIN, BLUE);
}


[Linked Image]
[Linked Image]
Posted By: Lapsa

Re: Lapsa's very own thread - 08/18/21 18:26

Ehler's Decycler Oscillator (fixed)

Quote

Trigonometric functions (Sine, Cosine etc) expect angles in degrees (0..360), while in C and in most other languages angles are in radians (0..2*PI). Log is the logarithm base e as in C.


Seemingly best use:
- set long periods
- 0 crossover for uptrend
- 0 crossunder for downtrend


Code
#include <profile.c>

var rad(var degrees) { return degrees*PI/180; }
var rcos(var degrees) {	return cos(rad(degrees)); }
var rsin(var degrees) {	return sin(rad(degrees)); }

var DecyclerOscillator(var* Close, var HPPeriod1, var HPPeriod2) // 30 60
{	
	var alpha1;
	var alpha2;
	var* hp1 = series(0,3);
	var* hp2 = series(0,3);
	
	alpha1 = 
		(rcos(.707*360/HPPeriod1)+
		rsin(.707*360/HPPeriod1)-1)
		/rcos(.707*360/HPPeriod1);

	alpha2 = 
		(rcos(.707*360/HPPeriod2)+
		rsin(.707*360/HPPeriod2)-1)/
		rcos(.707*360/HPPeriod2);
	
	hp1[0] = (1-alpha1/2)*(1-alpha1/2)*
		(Close[0]-2*Close[1]+Close[2])+
		2*(1-alpha1)*hp1[1]-(1-alpha1)*
		(1-alpha1)*hp1[2];
	
	hp2[0] = (1-alpha2/2)*(1-alpha2/2)*
		(Close[0]-2*Close[1]+Close[2])+
		2*(1-alpha2)*hp2[1]-(1-alpha2)*
		(1-alpha2)*hp2[2];
	 
	return hp2[0] - hp1[0];
}

function run()
{
	set(PLOTNOW);
	BarPeriod = 1;
	LookBack = 100;
	StartDate = 20210702;
	EndDate = 20210816;

	vars closes = series(priceClose());
	
	var osc = DecyclerOscillator(closes, 30, 60);
	var zma = ZMA(closes, 30);

	plot("ZMA", zma, MAIN, BLACK);
	plot("Decycler OSC", osc, NEW, BLACK);
}


[Linked Image]

Refactored:

Code
var DecyclerOscillator(var* Close, var HPPeriod1, var HPPeriod2) // 30 60
{
	return HighPass2(Close, HPPeriod2) - HighPass2(Close, HPPeriod1);
}

Posted By: Lapsa

Re: Lapsa's very own thread - 08/18/21 19:25

Quote

One of the amazing characteristics of a band-pass filter is that if the
center period of the filter is tuned to a static sine wave whose period is
the same as the center period of the filter, then there is absolutely no lag
in the output.
Posted By: Lapsa

Re: Lapsa's very own thread - 08/19/21 20:24

Ehler's "Adaptive Stochastic Indicator"

I'm proud and happy I pulled this one through.

Well... Sort of.

Running Tests multiple times produces different results.
Not sure why. Yay!

Something memory, variables, pointers whatnot related.
`MaxPwr` looks like potential troublemaker.

Interestingly, adaptive CCI source code has this:

Code
//Find Maximum Power Level for Normalization
MaxPwr = .991*MaxPwr[1];


Also - overall computation seems notoriously slow.
Like 3 seconds for a single day.
Something I've been doing wrong.

When it works - results look legit.

Haven't finished the book.
Not sure if this one is supposed to be equivalent of Zorro's bundled StochEhlers indicator.
They do look similar although Zorro's one got some of that buttery smoothing.

All in all - fun but unusable.

TODO:
try to identify the issue by replacing snippets with in-built stuff (e.g. center of gravity)


Code
#include <profile.c>

var rad(var degrees) { return degrees*PI/180; }
var rcos(var degrees) { return cos(rad(degrees)); }
var rsin(var degrees) { return sin(rad(degrees)); }

var AdaptiveStochastic(vars Close)
{
	var AvgLength = 3;
	var M;
	var N;
	var X;
	var Y;
	var alpha1;
	var* HP = series(0,3);
	var a1;
	var b1;
	var c1;
	var c2;
	var c3;
	var* Filt = series(0,3);
	var Lag;
	var count;
	var Sx;
	var Sy;
	var Sxx;
	var Syy;
	var Sxy;
	var Period;
	var Sp;
	var Spx;
	var* MaxPwr = series(0,3);
	var DominantCycle;
	
	var* Corr = series(0, 48);
	var* CosinePart = series(0, 48);
	var* SinePart = series(0, 48);
	var* SqSum = series(0, 48);
	var R[48][2];
	var Pwr[48];	
	
	//Highpass filter cyclic components whose periods are shorter than 48 bars
	alpha1 = (rcos(.707*360 / 48) + rsin(.707*360 / 48) - 1) / rcos(.707*360 / 48);
	
	HP[0] = (1 - alpha1 / 2)*(1 - alpha1 / 2)*
		(Close[0] - 2*Close[1] + Close[2]) + 
		2*(1 - alpha1)*HP[1] - 
		(1 - alpha1) * (1 - alpha1)*HP[2];
	
	
	//Smooth with a Super Smoother Filter from equation 3-3
	a1 = exp(-1.414*3.14159 / 10);
	b1 = 2*a1*rcos(1.414*180 / 10);
	c2 = b1;
	c3 = -a1*a1;
	c1 = 1 - c2 - c3;
	Filt[0] = c1*(HP[0] + HP[1]) / 2 + c2*Filt[1] + c3*Filt[2];
		
	//Pearson correlation for each value of lag
	for (Lag = 0; Lag < 48; Lag++) {		
		//Set the averaging length as M
		M = AvgLength;
		if (AvgLength == 0) M = Lag;
		Sx = 0;
		Sy = 0;
		Sxx = 0;
		Syy = 0;
		Sxy = 0;
		
		for (count = 0; count < M - 1; count++) {
			X = Filt[count];
			Y = Filt[Lag + count];
			Sx = Sx + X;
			Sy = Sy + Y;
			Sxx = Sxx + X*X;
			Sxy = Sxy + X*Y;
			Syy = Syy + Y*Y;
		}
		
		if ( (M*Sxx - Sx*Sx)*(M*Syy - Sy*Sy) > 0 ) {
			Corr[Lag] = (M*Sxy - Sx*Sy)/sqrt((M*Sxx-Sx*Sx)*(M*Syy-Sy*Sy));
		}
	}
	
	for (Period = 0; Period < 48; Period++) {
		CosinePart[Period] = 0;
		SinePart[Period] = 0;
		
		for(N = 3; N < 48; N++) {
			CosinePart[Period] = CosinePart[Period] + Corr[N]*rcos(360*N / Period);
			SinePart[Period] = SinePart[Period] + Corr[N]*rsin(360*N / Period);
		}
		SqSum[Period] = CosinePart[Period]*CosinePart[Period] +
		SinePart[Period]*SinePart[Period];
	}
	
	for (Period = 0; Period < 48; Period++) {
		R[Period][2] = R[Period][1];
		R[Period][1] = .2*SqSum[Period]*SqSum[Period] +.8*R[Period][2];
	}
	
	// Find Maximum Power Level for Normalization
	MaxPwr[0] = .995*MaxPwr[1];
	for (Period = 10; Period < 48; Period++) {
		if (R[Period][1] > MaxPwr[0]) MaxPwr[0] = R[Period][1];
	}
	
	for (Period = 3; Period < 48; Period++) {
		Pwr[Period] = R[Period][1] / MaxPwr[0];
	}
	
	//Compute the dominant cycle using the CG of the spectrum
	Spx = 0;
	Sp = 0;
	for(Period = 10; Period < 48; Period++) {
		if (Pwr[Period] >= .5) {
			Spx = Spx + Period*Pwr[Period];
			Sp = Sp + Pwr[Period];
		}
	}
	
	if (Sp != 0) DominantCycle = Spx / Sp;
	if (DominantCycle < 10) DominantCycle = 10;
	if (DominantCycle > 48) DominantCycle = 48;
	
	//Stochastic Computation starts here
	var* HighestC = series(0, 3);
	var* LowestC = series(0, 3);
	var* Stoc = series(0, 3);
	var* SmoothNum = series(0, 3);
	var* SmoothDenom = series(0, 3);
	var* AdaptiveStochastic = series(0, 3);
	
	HighestC[0] = Filt[0];
	LowestC[0] = Filt[0];
	
	for (count = 0; count < DominantCycle - 1; count++ ) {
		if (Filt[count] > HighestC[0]) HighestC[0] = Filt[count];
		if (Filt[count] < LowestC[0]) LowestC[0] = Filt[count];	
	}
	
	Stoc[0] = (Filt[0] - LowestC[0]) / (HighestC[0] - LowestC[0]);
	return AdaptiveStochastic[0] = 
		c1*(Stoc[0] + Stoc[1]) / 2 + c2*AdaptiveStochastic[1] + c3*AdaptiveStochastic[2];
}

function run()
{
	set(PLOTNOW);
	BarPeriod = 1;
	LookBack = 500;
	StartDate = 20210809;
	EndDate = 20210810;

	vars closes = series(priceClose(), 48);
	var astoch = AdaptiveStochastic(closes);
	
	var original = StochEhlers(closes, 48, 10, 48);
	
	plot("ASTOCH", astoch, NEW, RED);
        plot("Zorro`s EStoch", original, NEW, BLUE);
}


[Linked Image]
[Linked Image]
Posted By: Lapsa

Re: Lapsa's very own thread - 08/20/21 17:25

Ehler's "Even Better Sinewave"

Looks usable.



Code
#include <profile.c>

var rad(var degrees) { return degrees*PI/180; }
var rcos(var degrees) {	return cos(rad(degrees)); }
var rsin(var degrees) {	return sin(rad(degrees)); }

var EvenBetterSinewave(vars Close, var Duration)
{
	var alpha1;
	var* HP = series(1,2);
	var a1;
	var b1;
	var c1;
	var c2;
	var c3;
	var* Filt = series(1,3);
	var count;
	var Wave;
	var Pwr;
	
	// HighPass filter cyclic components whose periods are shorter than Duration input
	alpha1 = (1 - rsin(360 / Duration)) / rcos(360 / Duration);
	HP[0] = .5*(1 + alpha1)*(Close[0] - Close[1]) + alpha1*HP[1];
	
	// Smooth with a Super Smoother Filter from equation 3-3
	a1 = exp(-1.414*3.14159 / Duration);
	b1 = 2*a1*rcos(1.414*180 / Duration);
	c2 = b1;
	c3 = -a1*a1;
	c1 = 1 - c2 - c3;
	Filt[0] = c1*(HP[0] + HP[1]) / 2 + c2*Filt[1] + c3*Filt[2];
	
	// 3 Bar average of Wave amplitude and power
	Wave = (Filt[0] + Filt[1] + Filt[2]) / 3;
	Pwr = (Filt[0]*Filt[0] + Filt[1]*Filt[1] + Filt[2]*Filt[2]) / 3;
	
	// Normalize the Average Wave to Square Root of the Average Power
	return Wave / sqrt(Pwr);
}

function run()
{
	set(PLOTNOW);
	BarPeriod = 1;
	LookBack = 100;
	StartDate = 20210702;
	EndDate = 20210816;

	vars close = series(priceClose());
		
	var evenBetterSinewave = EvenBetterSinewave(close, 10);
	
	plot("EBSW", evenBetterSinewave, NEW, BLACK);
}


[Linked Image]

Refucktored version:

Code
#include <profile.c>

var EvenBetterSinewave(vars Close, var Duration)
{
	var Wave;
	var Pwr;
		
	var* HP = series(HighPass1(Close, Duration), 2);
	if (HP[0] == 0) HP[0] = 1;
	
	var* Filt = series(Smooth(HP, Duration), 3);	
	Wave = SMA(Filt, 3);
	Pwr = (Filt[0]*Filt[0] + Filt[1]*Filt[1] + Filt[2]*Filt[2]) / 3;
	
	return Wave / sqrt(Pwr);
}

function run()
{
	set(PLOTNOW);
	BarPeriod = 1;
	LookBack = 100;
	StartDate = 20210702;
	EndDate = 20210816;

	vars close = series(priceClose());
		
	var evenBetterSinewave = EvenBetterSinewave(close, 10);
	
	plot("EBSW", evenBetterSinewave, NEW, BLACK);
}


Comparison with [CC] EBSW indicator on TradingView:

[Linked Image]


Interestingly - that one allows setting HighPass length separately from SuperSmoothFilter length.

Like this:

Code
var EvenBetterSinewave(vars Close, var HPLength, SSFLength)
{
	var Wave;
	var Pwr;
		
	var* HP = series(HighPass1(Close, HPLength), 2);
	if (HP[0] == 0) HP[0] = 1;
	
	var* Filt = series(Smooth(HP, SSFLength), 3);	
	Wave = SMA(Filt, 3);
	Pwr = (Filt[0]*Filt[0] + Filt[1]*Filt[1] + Filt[2]*Filt[2]) / 3;
	
	return Wave / sqrt(Pwr);
}


Lets smash in some trade signals!!!111eleven


Code
#include <profile.c>

var EvenBetterSinewave(vars Close, var Duration)
{
	var Wave;
	var Pwr;
		
	var* HP = series(HighPass1(Close, Duration), 2);
	if (HP[0] == 0) HP[0] = 1;
	
	var* Filt = series(Smooth(HP, Duration), 3);	
	Wave = SMA(Filt, 3);
	Pwr = (Filt[0]*Filt[0] + Filt[1]*Filt[1] + Filt[2]*Filt[2]) / 3;
	
	return Wave / sqrt(Pwr);
}

function run()
{
	set(PLOTNOW|PARAMETERS);
	BarPeriod = 1;
	LookBack = 250;
	StartDate = 20210702;
	EndDate = 20210816;

	vars close = series(priceClose());

	var* ebsw = series(EvenBetterSinewave(close, 225));
	
	if (crossOver(ebsw, -.99)) enterLong();	
	if (crossUnder(ebsw, .99)) enterShort();

	plot("EBSW", ebsw, NEW, BLACK);
}


[Linked Image]

Quote

Monte Carlo Analysis... Median AR 805%
Win 732$ MI 489$ DD 144$ Capital 448$
Trades 245 Win 38.8% Avg +29.9p Bars 181
AR 1311% PF 1.44 SR 0.00 UI 0% R2 1.00


Gotta fit that curve!
Posted By: Lapsa

Re: Lapsa's very own thread - 08/21/21 13:46

Ehler's "Band-Pass Filter"


Code
#include <profile.c>

var rad(var degrees) { return degrees*PI/180; }
var rcos(var degrees) {	return cos(rad(degrees)); }
var rsin(var degrees) {	return sin(rad(degrees)); }

var BPSignal;
var BPTrigger;

var BandPassFilter(var* Close, var Period, var Bandwidth)
{
	var alpha2;
	var* HP = series(0, 3);
	var gamma1;
	var alpha1;
	var beta1;
	var* BP = series(0, 3);
	var* Peak = series(0, 2);
	var* Signal = series(0, 2);
	var* Trigger = series(0, 2);
	
	alpha2 = (
		rcos(.25*Bandwidth*360 / Period) + 
		rsin(.25*Bandwidth*360 / Period) - 1
	  )  / rcos(.25*Bandwidth*360 / Period);

	HP[0] = (1 + alpha2 / 2)*(Close[0] - Close[1]) + 
		(1- alpha2)*HP[1];
		
	beta1 = rcos(360 / Period);
	
	gamma1 = 1 / rcos(360*Bandwidth / Period);
	alpha1 = gamma1 - sqrt(gamma1*gamma1 - 1);
	
	BP[0] = .5*(1 - alpha1)*(HP[0] - HP[2]) + 
		beta1*(1 + alpha1)*BP[1] - alpha1*BP[2];

	Peak[0] = .991*Peak[1];
	
	if (abs(BP[0]) > Peak[0]) Peak[0] = abs(BP[0]);
	
	if (Peak[0] != 0) Signal[0] = BP[0] / Peak[0];
	
	alpha2 = (rcos(1.5*Bandwidth*360 / Period) + 
		rsin(1.5*Bandwidth*360 / Period) - 1) / 
		rcos(1.5*Bandwidth*360 / Period);

	Trigger[0] = 
		(1 + alpha2 / 2)*(Signal[0] - Signal[1]) +
		(1- alpha2)*Trigger[1];
		
	BPSignal = Signal[0];
	BPTrigger = Trigger[0];
}

function run()
{
	set(PLOTNOW);
	BarPeriod = 1;
	LookBack = 100;
	StartDate = 20210702;
	EndDate = 20210816;

	vars closes = series(priceClose());
	BandPassFilter(closes, 20, .3);
	
	plot("Signal", BPSignal, NEW, BLACK);
	plot("Trigger", BPTrigger, END, RED);
}


[Linked Image]

Lets smash in some trade signals!!!111eleven

Code
#include <profile.c>

var rad(var degrees) { return degrees*PI/180; }
var rcos(var degrees) {	return cos(rad(degrees)); }
var rsin(var degrees) {	return sin(rad(degrees)); }

var BPSignal;
var BPTrigger;

var BandPassFilter(var* Close, var Period, var Bandwidth)
{
	var alpha2;
	var* HP = series(0, 3);
	var gamma1;
	var alpha1;
	var beta1;
	var* BP = series(0, 3);
	var* Peak = series(0, 2);
	var* Signal = series(0, 2);
	var* Trigger = series(0, 2);
	
	alpha2 = (
			rcos(.25*Bandwidth*360 / Period) + 
			rsin(.25*Bandwidth*360 / Period) - 1
		) / rcos(.25*Bandwidth*360 / Period);

	HP[0] = (1 + alpha2 / 2)*(Close[0] - Close[1]) + 
		(1- alpha2)*HP[1];
		
	beta1 = rcos(360 / Period);
	
	gamma1 = 1 / rcos(360*Bandwidth / Period);
	alpha1 = gamma1 - sqrt(gamma1*gamma1 - 1);
	
	BP[0] = .5*(1 - alpha1)*(HP[0] - HP[2]) + 
		beta1*(1 + alpha1)*BP[1] - alpha1*BP[2];

	Peak[0] = .991*Peak[1];
	
	if (abs(BP[0]) > Peak[0]) Peak[0] = abs(BP[0]);
	
	if (Peak[0] != 0) Signal[0] = BP[0] / Peak[0];
	
	alpha2 = (rcos(1.5*Bandwidth*360 / Period) + 
		rsin(1.5*Bandwidth*360 / Period) - 1) / 
		rcos(1.5*Bandwidth*360 / Period);

	Trigger[0] = 
		(1 + alpha2 / 2)*(Signal[0] - Signal[1]) +
		(1- alpha2)*Trigger[1];
		
	BPSignal = Signal[0];
	BPTrigger = Trigger[0];
}

function run()
{
	set(PLOTNOW);
	BarPeriod = 1;
	LookBack = 300;
	StartDate = 20210810;
	EndDate = 20210816;
	//Capital = 500;

	vars closes = series(priceClose());
	BandPassFilter(closes, 23, .05821);
	
	var* signalSeries = series(BPSignal);
	var* triggerSeries = series(BPTrigger);	

	MaxLong = 1;
	MaxShort = 1;
	
	if (
		BPTrigger < BPSignal
		//&& BPSignal > -0.3
	) {
		if (ProfitOpen >= 0) enterLong();
		else exitShort();
	}
	if (
		BPTrigger > BPSignal
		//&& BPSignal < 0.3
	) {
		if (ProfitOpen >= 0)	enterShort();
		else exitLong();
	}
	
	plot("Signal", BPSignal, NEW, BLACK);
	plot("Trigger", BPTrigger, END, RED);
}


[Linked Image]

Quote

Monte Carlo Analysis... Median AR 4054%
Win 318$ MI 1481$ DD 134$ Capital 409$
Trades 424 Win 50.9% Avg +7.5p Bars 13
AR 4350% PF 1.22 SR 0.00 UI 0% R2 1.00


High signal count.

Only Period of 23 works seemingly well in combination with that weird bandwidth of .05821.

Fails to perform month before.

Posted By: Lapsa

Re: Lapsa's very own thread - 08/21/21 14:58

Ehler's "Dominant Cycle Measured by Zero Crossings of the Band-Pass Filter"

Not 100% sure I got it right. Might be, might be not.

Looks believable.


Code

var rad(var degrees) { return degrees*PI/180; }
var rcos(var degrees) {	return cos(rad(degrees)); }
var rsin(var degrees) {	return sin(rad(degrees)); }

var DCBandPass(var* Close, var Period, var Bandwidth)
{
	var alpha2;
	var* HP = series(0, 3);
	var gamma1;
	var alpha1;
	var beta1;
	var* BP = series(0, 3);
	var* Peak = series(0, 2);
	var* Real = series(0, 3);
	var* counter = series(0, 2);
	var* DC = series(0, 2);
	
	alpha2 = (
			rcos(.25*Bandwidth*360 / Period) + 
			rsin(.25*Bandwidth*360 / Period) - 1
		) / rcos(.25*Bandwidth*360 / Period);

	HP[0] = (1 + alpha2 / 2)*(Close[0] - Close[1]) + 
		(1- alpha2)*HP[1];
		
	beta1 = rcos(360 / Period);
	
	gamma1 = 1 / rcos(360*Bandwidth / Period);
	alpha1 = gamma1 - sqrt(gamma1*gamma1 - 1);
	
	BP[0] = .5*(1 - alpha1)*(HP[0] - HP[2]) + 
		beta1*(1 + alpha1)*BP[1] - alpha1*BP[2];

	Peak[0] = .991*Peak[1];
	
	if (abs(BP[0]) > Peak[0]) Peak[0] = abs(BP[0]);
	
	if (Peak[0] != 0) Real[0] = BP[0] / Peak[0];
	
	DC[0] = DC[1];
	if (DC[0] < 6) DC[0] = 6;
	counter[0] = counter[1] + 1;
	
	if (crossOver(Real, 0) || crossUnder(Real, 0)) {
		DC[0] = 2*counter[0];					
		if (2*counter[0] > 1.25*DC[1]) {

			DC[0] = 1.25*DC[1];
		}
		if (2*counter[0] < .8*DC[1]) {
			DC[0] = .8*DC[1];
		}
		counter[0] = 0;
	}
	
	return DC[0];
}


function run()
{
	set(PLOTNOW);
	BarPeriod = 1;
	LookBack = 300;
	StartDate = 20210810;
	EndDate = 20210816;

	vars closes = series(priceClose());

	var dc = DCBandPass(closes, 20, .7);
	var ht_dc = HTDcPeriod(closes);
	
	var sma = SMA(closes, dc);
	var ht_sma = SMA(closes, ht_dc);
	
	plot("BPDC SMA", sma, MAIN, RED);
	plot("HTDC SMA", ht_sma, MAIN, BLACK);
	
	plot("BP DC", dc, NEW, RED);
	plot("HT DC", ht_dc, END, BLACK);
}

[Linked Image]
Posted By: Lapsa

Re: Lapsa's very own thread - 08/23/21 03:32

I like this one:


Code
#include <profile.c>

var rad(var degrees) { return degrees*PI/180; }
var rcos(var degrees) {	return cos(rad(degrees)); }
var rsin(var degrees) {	return sin(rad(degrees)); }

var DecyclerOscillator(var* Close, var HPPeriod1, var HPPeriod2)
{
	return HighPass2(Close, HPPeriod2) - HighPass2(Close, HPPeriod1);
}

var EvenBetterSinewave(vars Close, var HPLength, SSFLength)
{
	var Wave;
	var Pwr;
		
	var* HP = series(HighPass1(Close, HPLength), 2);
	if (HP[0] == 0) HP[0] = 1;
	
	var* Filt = series(Smooth(HP, SSFLength), 3);	
	Wave = SMA(Filt, 3);
	Pwr = (Filt[0]*Filt[0] + Filt[1]*Filt[1] + Filt[2]*Filt[2]) / 3;
	
	return Wave / sqrt(Pwr);
}

function run()
{
	set(PLOTNOW|PARAMETERS|PRELOAD);
	BarPeriod = 1;
	LookBack = 2000;
	StartDate = 20210701;
	EndDate = 20210816;

	Capital = 2000;
	Lots = 1;
	LotAmount = 5;
	Amount = 0;
	MaxLong = 5;
	MaxShort = 5;
	
	vars closes = series(priceClose());
	var close = closes[0];
	
	//var* smooth = series(Smooth(closes, 8));
	//var zma = ZMA(closes, 9);
	//var szma = ZMA(smooth, 6);
	
	//var osc = DecyclerOscillator(closes, 5, 9);
	//var ebsw = EvenBetterSinewave(closes, 4, 8);
	
	var ebsw = EvenBetterSinewave(closes, 4, 7);
	var stoch = StochEhlers(closes, 22, 152, 11);
	var* stochS = series(stoch);
	
	if (
		ebsw > .02
		&& stoch < .8
		&& rising(stochS)
	) enterLong();
	
	if (
		ebsw < -.91
		&& stoch > .2
		&& falling(stochS)
	) enterShort();

	//if (osc < 0) exitLong();	
	//if (osc > 0) exitShort();	
		
	
	// plot("ZMA", zma, MAIN, DARKBLUE);
	// plot("SZMA", szma, MAIN, CYAN);
	
	
	//if (osc > 0) osc = .5; else osc = -.5;
	
	plot("EBSW", ebsw, NEW, CYAN);
	plot("Stoch", stoch, NEW, MAGENTA);
	
	//plot("Decycler", osc, NEW, ORANGE);
	
	
	// plot("EBSW", ebsw, NEW, BLACK);	
}


Quote

Monte Carlo Analysis... Median AR 381%
Win 1800$ MI 1213$ DD 1573$ Capital 2504$
Trades 3236 Win 47.3% Avg +5.6p Bars 60
CAGR 17866.37% PF 1.12 SR 0.00 UI 0% R2 1.00


[Linked Image]



Simple setup.
Plenty of room for improvements.
High signal count.
Almost manageable drawdown.
Scalable.
Fast feedback.
Reasonably consistent.
Magical numbers ain't that magical.
Posted By: Lapsa

Re: Lapsa's very own thread - 08/24/21 00:22

Quote

If the commission is a percentage of the trade value, enter the negative percent value, f.i. -0.25 for 0.25%.
The commission is then automatically calculated from the percentage using the formula Commission = -Percent/100 * Price / LotAmount * PIPCost / PIP.
Posted By: Lapsa

Re: Lapsa's very own thread - 08/25/21 23:04

44 HP & 120 SSF on EBSW.

22 HP sort of workable.

I have given up on lower periods.

Unsure about upper bound.
Perhaps something at days & weeks scale.

Ain't interested - screws up feedback cycle too much.

P.s. Tether printer goes brrrrrrrrr
Posted By: Lapsa

Re: Lapsa's very own thread - 08/26/21 23:44

Incremental strategy development per month.
Posted By: Lapsa

Re: Lapsa's very own thread - 09/02/21 09:51

Quote

the angle is a mostly useless parameter, although held in high esteem by Gann believers.


^_^
Posted By: AndrewAMD

Re: Lapsa's very own thread - 09/02/21 13:40

Read this, especially "Gann Magic":
https://financial-hacker.com/seventeen-popular-trade-strategies-that-i-dont-really-understand/

William Gallacher had a few words to say about Gann in Winner Take All as well.
Posted By: Lapsa

Re: Lapsa's very own thread - 09/02/21 19:29

Already enjoyed that article. Sharing similar sentiment.

`Winner takes all` seems like a good read.
Have seen that title before.

Thanks.
Posted By: Lapsa

Re: Lapsa's very own thread - 09/04/21 01:08

Think I've given up on thoroughly understanding what Sharpe ratio means, how it's affected and why should I care.

Quote

Sharpe Ratio = (r_x — R_f)/stdDev(r_x)


aka big numbers good, small numbers bad

That's about it.
Posted By: Lapsa

Re: Lapsa's very own thread - 09/04/21 01:28

Perceptron experiments were fun although not quite the direction I would like to take.

I don't find:

Quote

Sig[0]*723 - Sig[1]*123 - Sig[2]*542 > your_mom


meaningful.

It's justified, even useful - but not particularly meaningful.

For me - such loss of clarity is unacceptable.

Similarly - I find Deep Learning repulsive.

Someday, maybe, likely I will change my mind. Who knows...
Posted By: Lapsa

Re: Lapsa's very own thread - 09/04/21 09:08

Just a reminder that winning trades is possible.


[Linked Image]

[Linked Image]

I wonder how will it land.

[Linked Image]

Hmm... That's quite a bump ignored.

[Linked Image]

As Ben Finegold would say: "Frankly ridiculous!"

[Linked Image]
Posted By: Lapsa

Re: Lapsa's very own thread - 09/07/21 00:48

Day4 - still in profits.
Posted By: Lapsa

Re: Lapsa's very own thread - 09/07/21 09:39

Some more green numbers.


[Linked Image]


Can't say it's optimal.
Quite a spike ignored.

But hey - it's fully automatic!
Posted By: Lapsa

Re: Lapsa's very own thread - 09/07/21 23:03

Autocorrelation Periodogram Dominant Cycle

I think I fixed bugs. At least most of them.


Spikes looks suspicious.

And I still don't understand what's that MaxPwr decay line is supposed to do.
Perhaps some odd EasyLanguage behavior?

I mean - decay doesn't get applied. MaxPwr will always get initialized as zero.

Some room for refactoring: Correlation, EMA, AGC should be able to replace some lines.

Still a bit sluggish but might be actually usable.

Seems to be more accurate than calculating dominant period via Hilbert transform (assuming that it works correctly).
Combined with BandPass, some curve fitting and decreased smoothing - it seems like a reasonable strategy foundation.

Code
#include <profile.c>

var rad(var degrees) { return degrees*PI/180; }
var rcos(var degrees) { return cos(rad(degrees)); }
var rsin(var degrees) { return sin(rad(degrees)); }

var AutocorrelationPeriodogramCycle(vars Close)
{
	var AvgLength = 3;
	var M;
	var N;
	var X;
	var Y;
	var* HP = series(0, 3);
	var* Filt = series(0, 48);
	var Lag;
	var count;
	var Sx;
	var Sy;
	var Sxx;
	var Syy;
	var Sxy;
	var Period;
	var Sp;
	var Spx;
	var* MaxPwr = series(0,2);
	var DominantCycle;

	var Corr[48];
	var CosinePart[48];
	var SinePart[48];
	var SqSum[48];
	var R[48][2];
	var Pwr[48];

	// Highpass filter cyclic components whose periods are shorter than 48 bars
	HP = series(HighPass2(Close, 48), 3);
	
	//Smooth with a Super Smoother Filter from equation 3-3	
	//Filt = series(Smooth(HP, 10), 50); // original
	Filt = series(Smooth(HP, 8), 50);

	//Pearson correlation for each value of lag
	for (Lag = 0; Lag < 48; Lag++) {		
		//Set the averaging length as M
		M = AvgLength;
		if (AvgLength == 0) M = Lag;
		Sx = 0;
		Sy = 0;
		Sxx = 0;
		Syy = 0;
		Sxy = 0;
		
		for (count = 0; count < M - 1; count++) {
			X = Filt[count];
			Y = Filt[Lag + count];
			Sx = Sx + X;
			Sy = Sy + Y;
			Sxx = Sxx + X*X;
			Sxy = Sxy + X*Y;
			Syy = Syy + Y*Y;
		}
		
		if ( (M*Sxx - Sx*Sx)*(M*Syy - Sy*Sy) > 0 ) {
			Corr[Lag] = (M*Sxy - Sx*Sy)/sqrt((M*Sxx-Sx*Sx)*(M*Syy-Sy*Sy));
		}
	}
	
	for (Period = 10; Period < 48; Period++) {
		CosinePart[Period] = 0;
		SinePart[Period] = 0;
		
		for(N = 3; N < 48; N++) {
			CosinePart[Period] = CosinePart[Period] +	Corr[N]*rcos(370*N / Period);
			SinePart[Period] = SinePart[Period] + Corr[N]*rsin(370*N / Period);
		}
		SqSum[Period] = CosinePart[Period]*CosinePart[Period] +
		SinePart[Period]*SinePart[Period];
	}
	
	for (Period = 10; Period < 48; Period++) {
		R[Period][2] = R[Period][1];
		R[Period][1] = .2*SqSum[Period]*SqSum[Period] +.8*R[Period][2];
	}	
	
	// Find Maximum Power Level for Normalization
	MaxPwr[0] = .995*MaxPwr[0]; // huh? wtf?!
	for (Period = 10; Period < 48; Period++) {
		if (R[Period][1] > MaxPwr[0]) MaxPwr[0] = R[Period][1];
	}
	
	for (Period = 3; Period < 48; Period++) {
		Pwr[Period] = R[Period][1] / MaxPwr[0];
	}
	
	//Compute the dominant cycle using the CG of the spectrum
	Spx = 0;
	Sp = 0;
	for(Period = 10; Period < 48; Period++) {
		if (Pwr[Period] >= .5) {
			Spx = Spx + Period*Pwr[Period];
			Sp = Sp + Pwr[Period];
		}
	}
	
	if (Sp != 0) DominantCycle = Spx / Sp;
	if (DominantCycle < 10) DominantCycle = 10;
	if (DominantCycle > 48) DominantCycle = 48;
	
	return DominantCycle;
}

function run()
{
	set(PLOTNOW);
	BarPeriod = 1;
	LookBack = 100;
	StartDate = 20210815;
	EndDate = 20210825;

	vars Close = series(priceClose());
	var dc = AutocorrelationPeriodogramCycle(Close);
	var ht_dc = DominantPeriod(Close, 25);
	
	var* bp = series(BandPass(Close, dc*2, .0542)); // TEH BIG PLAYZ
	// var* bp_ht = series(BandPass(Close, ht_dc, .06));
	
	// if (valley(bp)) enterLong();
	// if (peak(bp)) enterShort();
	
	if (crossOver(bp, 0)) enterLong();
	if (crossUnder(bp, 0)) enterShort();
	
	plot("BP", bp, NEW, MAGENTA);
	// plot("BP HT", bp_ht, END, CYAN);
	plot("DC", dc, NEW, RED);
	plot("HT DC", ht_dc, END, BLUE);
}


[Linked Image]

Quote

Monte Carlo Analysis... Median AR 435%
Win 0.23$ MI 0.69$ DD 0.15$ Capital 1.61$
Trades 394 Win 47.5% Avg +5.8p Bars 28
AR 512% PF 1.12 SR 0.00 UI 0% R2 1.00


^ 10 days



no moar spikey:


Code
	for (Period = 10; Period < 48; Period++) {
		R[Period][2] = R[Period][1];
		// original
		// R[Period][1] = .2*SqSum[Period]*SqSum[Period] +.8*R[Period][2];
		
		// https://quantstrattrader.com/2017/02/15/ehlerss-autocorrelation-periodogram/
		// R[period, ] <- EMA(sqSum[period, ] ^ 2, ratio = 0.2)
		
		// Lapsa`s adaptation
		R[Period][1] = EMA(pow(SqSum[Period], 2), .2);
	}


Code

var rad(var degrees) { return degrees*PI/180; }
var rcos(var degrees) {	return cos(rad(degrees)); }
var rsin(var degrees) {	return sin(rad(degrees)); }

var AutocorrelationPeriodogramCycle(var* Close)
{
	var AvgLength = 3;
	var M;
	var N;
	var X;
	var Y;
	var* HP = series(0, 3);
	var* Filt = series(0, 48);
	var Lag;
	var count;
	var Sx;
	var Sy;
	var Sxx;
	var Syy;
	var Sxy;
	var Period;
	var Sp;
	var Spx;
	var* MaxPwr = series(0,2);
	var DominantCycle;

	var Corr[48];
	var CosinePart[48];
	var SinePart[48];
	var SqSum[48];
	var R[48][2];
	var Pwr[48];

	// Highpass filter cyclic components whose periods are shorter than 48 bars
	HP = series(HighPass2(Close, 48), 3);
	
	//Smooth with a Super Smoother Filter from equation 3-3	
	//Filt = series(Smooth(HP, 10), 50);
	Filt = series(Smooth(HP, 10), 50);

	//Pearson correlation for each value of lag
	for (Lag = 0; Lag < 48; Lag++) {		
		//Set the averaging length as M
		if (AvgLength == 0) M = Lag;
		else M = AvgLength;
		
		Sx = 0;
		Sy = 0;
		Sxx = 0;
		Syy = 0;
		Sxy = 0;
		
		for (count = 0; count < M - 1; count++) {
			X = Filt[count];
			Y = Filt[Lag + count];
			Sx = Sx + X;
			Sy = Sy + Y;
			Sxx = Sxx + X*X;
			Sxy = Sxy + X*Y;
			Syy = Syy + Y*Y;
		}
		
		if ( (M*Sxx - Sx*Sx)*(M*Syy - Sy*Sy) > 0 ) {
			Corr[Lag] = (M*Sxy - Sx*Sy)/sqrt((M*Sxx-Sx*Sx)*(M*Syy-Sy*Sy));
		}
	}
	
	for (Period = 10; Period < 48; Period++) {
		CosinePart[Period] = 0;
		SinePart[Period] = 0;
		
		for(N = 3; N < 48; N++) {
			CosinePart[Period] = CosinePart[Period] +	Corr[N]*rcos(370*N / Period);
			SinePart[Period] = SinePart[Period] + Corr[N]*rsin(370*N / Period);
		}
		SqSum[Period] = CosinePart[Period]*CosinePart[Period] +
		SinePart[Period]*SinePart[Period];
	}
	
	for (Period = 10; Period < 48; Period++) {
		R[Period][2] = R[Period][1];
		// original
		// R[Period][1] = .2*SqSum[Period]*SqSum[Period] +.8*R[Period][2];
		
		// https://quantstrattrader.com/2017/02/15/ehlerss-autocorrelation-periodogram/
		// R[period, ] <- EMA(sqSum[period, ] ^ 2, ratio = 0.2)
		
		// Lapsa`s adaptation
		R[Period][1] = EMA(pow(SqSum[Period], 2), .2);
	}
	
	// Find Maximum Power Level for Normalization
	
	MaxPwr[0] = .995*MaxPwr[0]; // huh? wtf?!
	for (Period = 10; Period < 48; Period++) {
		if (R[Period][1] > MaxPwr[0]) MaxPwr[0] = R[Period][1];
	}
	
	for (Period = 3; Period < 48; Period++) {
		Pwr[Period] = R[Period][1] / MaxPwr[0];
	}
	
	//Compute the dominant cycle using the CG of the spectrum
	Spx = 0;
	Sp = 0;
	for(Period = 10; Period < 48; Period++) {
		if (Pwr[Period] >= .5) {
			Spx = Spx + Period*Pwr[Period];
			Sp = Sp + Pwr[Period];
		}
	}
	
	if (Sp != 0) DominantCycle = Spx / Sp;
	if (DominantCycle < 10) DominantCycle = 10;
	if (DominantCycle > 48) DominantCycle = 48;
	
	return DominantCycle;
}


[Linked Image]

Failed to use Correlation function successfully.
I mean - I can pinpoint what should be replaced yet failing to do that cause of LiteC and my stupidity.
Posted By: Lapsa

Re: Lapsa's very own thread - 09/09/21 11:12

((38 * 45) * 1440) * 90 = 221616000

Lots of looping even for Lite C.
Posted By: Lapsa

Re: Lapsa's very own thread - 09/09/21 22:45

Well... This is actually kind of impressive.

Autocorrelation periodogram approach calculated dominant cycle long bandpass filtering <----- try reading that to someone

With some slight tinkering (e.g. removed smoothing, adjusted peak decay & whatnot).


[Linked Image]

Quote

Monte Carlo Analysis... Median AR 3932%
Win 0.73$ MI 22.12$ DD 0.24$ Capital 6.58$
Trades 166 Win 51.2% Avg +8.7p Bars 8
AR 4036% PF 1.37 SR 0.00 UI 0% R2 1.00


166 trades on a single (!) day with 1.37 PF (fees included)

[Linked Image]


Think I won't take a look how miserably it fails on other days.
Too much hopelessness already.
Posted By: Lapsa

Re: Lapsa's very own thread - 09/09/21 22:55

^ 3 Trades, Win 100%, Avg 558.2p, PF 10.00 on 45 BarPeriod

grin
Posted By: Lapsa

Re: Lapsa's very own thread - 09/14/21 11:49

For the memes - played around with idea of adapting Ichimoku Cloud.

Think there's some tangible benefit floating Kijun a bit.
Maaaaaaaaybe Tenkan too.

This is what happens when you mess with Senkou and Displacement bit too much:


[Linked Image]


Japanese cloud becomes a crack addict.

Anyhow... As much as I like Ichimoku system esthetically, just as much I find it useless.

Also - annoyed that I couldn't find a way to alter cloud color.
Also - it's unclear how to figure out "future" cloud.
Posted By: Lapsa

Re: Lapsa's very own thread - 09/14/21 19:57

hmm... might be up to something

Quote

Monte Carlo Analysis... Median AR 2319%
Win 0.99$ MI 2.60$ DD 0.16$ Capital 1.64$
Trades 44 Win 70.5% Avg +224.6p Bars 377
AR 1901% PF 3.71 SR 0.00 UI 0% R2 1.00


^ 12 days period

----

PF 1.30 since May 1st


[Linked Image]


----

PF 1.50 since May 1st

Not much room left for improvements.
Trying to land 1.70 (failed)
Posted By: Lapsa

Re: Lapsa's very own thread - 09/16/21 19:18

current run


[Linked Image]


boringly good so far

more interested how it behaves when things go wrong
Posted By: Lapsa

Re: Lapsa's very own thread - 09/18/21 18:18

some turbulence

didn't take profit but to be fair - I would have kept it open too

did expect a dump

[Linked Image]

so far so good
Posted By: Lapsa

Re: Lapsa's very own thread - 09/20/21 06:59

and the wish has been granted. back to square #1

[Linked Image]
Posted By: Lapsa

Re: Lapsa's very own thread - 09/20/21 23:07

hurrr durrr evergrande
Posted By: Lapsa

Re: Lapsa's very own thread - 09/21/21 20:53

Found an equivalent of Ehler's Pearson correlation calculation to Zorro's in built Correlation.

Mental model is still quite muddy but as it seems - this may be kind of huge.

If Ehler is wrong (or my translation thereof) - this might trim whole bar of lag.

Code
for (count = 0; count < M - 1; count++) {


It's unclear to me why original script has `count < M - 1` instead of just `count < M`.



Code
#include <profile.c>

var Corr(var* Close)
{
	var AvgLength = 0;
	var M;
	var X;
	var Y;
	var Lag;
	var count;
	var Sx;
	var Sy;
	var Sxx;
	var Syy;
	var Sxy;

	var Corr[48];

	var* HP = series(HighPass2(Close, 48), 50);
	var* Filt = series(Smooth(HP, 10), 50);

	//Pearson correlation for each value of lag
	for (Lag = 0; Lag < 48; Lag++) {		
		//Set the averaging length as M
		M = AvgLength;
		if (AvgLength == 0) M = Lag;
		Sx = 0;
		Sy = 0;
		Sxx = 0;
		Syy = 0;
		Sxy = 0;
		
		for (count = 0; count < M; count++) {
			X = Filt[count];
			Y = Filt[Lag + count];
			Sx = Sx + X;
			Sy = Sy + Y;
			Sxx = Sxx + X*X;
			Sxy = Sxy + X*Y;
			Syy = Syy + Y*Y;
		}
		
		if ( (M*Sxx - Sx*Sx)*(M*Syy - Sy*Sy) > 0 ) {
			Corr[Lag] = (M*Sxy - Sx*Sy)/sqrt((M*Sxx-Sx*Sx)*(M*Syy-Sy*Sy));
		}

	}
	return Corr[3];
}
function run()
{
	set(NFA|PLOTNOW);
	StartDate = 20210903;
	EndDate = 20210903;
	Outlier = 0;
	BarPeriod = 1;
	LookBack = 100;
	BarMode = BR_FLAT;

	Verbose = 2;
	
	var* Close = series(priceClose());

	var* x = series(Corr(Close));
	
	var* HP = series(HighPass2(Close, 48), 50);
	var* Filt = series(Smooth(HP, 10), 50);
	
	var y = Correlation(Filt, Filt+3, 3);

	plot("x", x, NEW, RED);
	plot("y", y, END, BLUE);
}


[Linked Image]



Feeling too dumb to figure it out.
Posted By: Lapsa

Re: Lapsa's very own thread - 09/22/21 00:28

Please, stay above the water.

I'm not even asking gazillion profits.

Quote

Monte Carlo Analysis... Median AR 436%
Win 32.16$ MI 6.80$ DD 5.22$ Capital 22.59$
Trades 319 Win 55.8% Avg +144.0p Bars 648
AR 361% PF 1.84 SR 0.00 UI 0% R2 1.00


------------

yeah but no...319 trades only...
curve fitting too stronk
Posted By: Lapsa

Re: Lapsa's very own thread - 09/24/21 09:52

[Linked Image]

for a change - I'm on a right side
Posted By: Lapsa

Re: Lapsa's very own thread - 09/26/21 21:08

newest strategy name: "usyk"

has to be a winner
Posted By: Lapsa

Re: Lapsa's very own thread - 09/27/21 21:38

smooth price close on 6 periods

pull out 3 period long RSIS out of it

do nothing unless rsis[0] != rsis[1]

boom! 172% -> 453%

makes no sense whatsoever
Posted By: AndrewAMD

Re: Lapsa's very own thread - 09/27/21 23:28

Originally Posted by Lapsa
makes no sense whatsoever
Usually a red flag.
Posted By: Lapsa

Re: Lapsa's very own thread - 09/28/21 06:37

Originally Posted by AndrewAMD
Originally Posted by Lapsa
makes no sense whatsoever
Usually a red flag.


yes and no

I mean - what such mechanism does is sort of understandable

it helps to follow trend

x3 difference it makes is what I find... err... quite peculiar

and it's not like there's 10 lucky trades.
think it was like 3k trades over 5 month period or something
Posted By: Lapsa

Re: Lapsa's very own thread - 09/28/21 23:07

got an old Toshiba laptop with an Arch Linux running on top of it

took awhile but I've managed to run Zorro via Wine on it successfully

fails to play those lovely sound notifications though

https://freesound.org/people/andrewweathers/sounds/25423/
https://freesound.org/people/dpren/sounds/248143/
https://freesound.org/people/phatcorns/sounds/250104/

---------------

weirdly requires manual creation of Cache folder

and sadly - eventually stops working in an hour or so

but it did open and close a (successful!) trade
Posted By: Lapsa

Re: Lapsa's very own thread - 09/29/21 01:39

with all-in compounding $5k

Quote

Monte Carlo Analysis... Median AR 233%
Win 47545$ MI 12061$ DD 9470$ Capital 7335$
Trades 1791 Win 60.1% Avg +19.8p Bars 88
CAGR 128676.60% PF 1.23 SR 0.00 UI 0% R2 1.00


sometimes worth taking a look at those cute numbers
Posted By: Lapsa

Re: Lapsa's very own thread - 10/01/21 00:25

some probably quite useless thoughts...

when it comes to crypto, I think the best strategy is to work on really short periods of time

what I mean is - most of the indicators should be very short sighted

like 3m, 5m, 9m even 2m. perhaps some high pass filtering on 20m, 30m

1. spam confirmations. as indicators are shortsighted - they are likely to align.
indicator combinations yield much more precise control over entries / exits

2. use something trend following like Ehler's even better sinewave to avoid whipsaws.
alternatively - some form of "throttling". like RSIS trick I described.
falling MMI on (!) 4m also qualifies

3. rely on trailing stops and do set a (quite loose) stop loss

4. favor priceClose() over price(). do test both though.
some indicators tend to be more strategic than tactical by their intrinsic nature

5. occasionally - some roofing, filtering, windowing, smoothing can be a game changer

6. favor steadily raising equity curve over flat one with spikes during black swans.
do make sure algo would have survived those in past

7. any change affects everything. rules can become obsolete, hindering, improvable.
parameter optimization can be helpful but it can also lead you astray
Posted By: Lapsa

Re: Lapsa's very own thread - 10/01/21 00:29

in other news:

did notice that Zorro via Wine suddenly shows up (surprisingly high) Sharpe Ratio on test runs

not sure what's up with that

always damn zero on Win10
Posted By: Lapsa

Re: Lapsa's very own thread - 10/17/21 10:58

still around, tuning my indicator soup, slowly scaling up

zero to hero porn:

[Linked Image]
Posted By: Lapsa

Re: Lapsa's very own thread - 10/18/21 21:09

day in profits
Posted By: Lapsa

Re: Lapsa's very own thread - 10/21/21 06:01

day in losses
Posted By: Lapsa

Re: Lapsa's very own thread - 10/21/21 14:52

upgraded to Zorro v2.42

Sharpe Ratio is alive!!!111 woohoooooo!
Posted By: Lapsa

Re: Lapsa's very own thread - 10/22/21 15:35

I wonder why backtest differs from actual trades.

Zorro just skipped 2 trades in last couple hours.

Makes whole thing sort of useless.
Posted By: Grant

Re: Lapsa's very own thread - 10/22/21 19:10

Are you still running Zorro in a Wine environment? This could be a problem.
So far, I only noticed some visual issues (like minimizing and then maximizing the Zorro window results in an unreadable screen and the current performance gets replaced by the bar counter when not being in a trade in test mode)

I would suggest to create a trade log with relevant variable values & broker calls (i.e. brokerCommand calls).
Posted By: Lapsa

Re: Lapsa's very own thread - 10/22/21 19:52

@Grant

Nope... Specifically installed Win7 on laptop.

Currently seems to be running fine.

Need to collect more data indeed.
Posted By: Lapsa

Re: Lapsa's very own thread - 10/22/21 20:02

This is what I'm running live (scaled up).

I do expect it to at least break even.

Quote

Lots=10;
StartDate = 20210501;
EndDate = 20211231;


Quote

Test: foxer MATICUSDT 2021
Monte Carlo Analysis... Median AR 825%
Win 103$ MI 18.03$ DD 4.44$ Capital 22.82$
Trades 2135 Win 59.6% Avg +48.5p Bars 102
AR 949% PF 1.50 SR 7.76 UI 1% R2 0.00


And I sort of like this bit:

Quote

divergence != 8


It's possible to enable hedge mode on Binance.
Although unsure if I want to.
Posted By: Lapsa

Re: Lapsa's very own thread - 10/23/21 09:06

Guess I panicked too fast.

Whole thing is sensitive to starting point.

Max trades 1, reliance on trailing stops, perhaps some internet lags.

Whole thing is kind of bound to differ.

I guess it syncs up eventually? Will keep an eye.

Anyhow... Here's actual trade results:

[Linked Image]

That 6 in a row looks sweet.

Here's backtest:

[Linked Image]

Still doing cent trades...
Could pour in, but first - want an actual success not just paper trades and backtests.
Posted By: Grant

Re: Lapsa's very own thread - 10/23/21 17:34

This is interesting to observe. It just shows how hard it is to simulate trades in a realistic way, esp in an intraday scenario.
Not a knock on Zorro, because this is a true challenge that all platforms are dealing with.
Posted By: Lapsa

Re: Lapsa's very own thread - 10/23/21 18:31

broke 1k % barrier

Quote

Test: foxer MATICUSDT 2021
Monte Carlo Analysis... Median AR 909%
Win 109$ MI 18.95$ DD 4.12$ Capital 22.01$
Trades 2144 Win 59.6% Avg +50.9p Bars 102
AR 1033% PF 1.53 SR 8.16 UI 1% R2 0.00


day likely to end in profits
Posted By: Lapsa

Re: Lapsa's very own thread - 10/24/21 08:43

I mean - if it would consistently pull out days like these:

[Linked Image]

could afford to buy a house in couple months
Posted By: Lapsa

Re: Lapsa's very own thread - 10/24/21 18:06

more squeezing

Quote

foxer compiling................
Test: foxer MATICUSDT 2021
Monte Carlo Analysis... Median AR 1049%
Win 122$ MI 20.93$ DD 4.12$ Capital 21.97$
Trades 2127 Win 59.6% Avg +57.1p Bars 105
AR 1143% PF 1.61 SR 9.02 UI 1% R2 0.00
Posted By: Lapsa

Re: Lapsa's very own thread - 10/26/21 07:39

scaled up, took losses

what's the point of such PF if it's unstable

anyhow... got some revelations

algo gonna get some major reconstructions
Posted By: Lapsa

Re: Lapsa's very own thread - 10/27/21 20:54

did attempt to reconstruct. found some new observations

equity curve looked worse - can't argue with data.
ended up improving existing one

broke even from weekend losses and got into new ones cause of own mistake.
there's a disaster waiting if you try to trade close to margin

still learning...
Posted By: Lapsa

Re: Lapsa's very own thread - 10/28/21 01:35

Quote

Test: foxer MATICUSDT 2021
Monte Carlo Analysis... Median AR 1130%
Win 133$ MI 22.45$ DD 4.12$ Capital 21.88$
Trades 2084 Win 60.3% Avg +63.7p Bars 109
AR 1232% PF 1.68 SR 9.68 UI 1% R2 0.00



with silly `Lots = max(50, Balance);`

Quote

Test: foxer MATICUSDT 2021
Monte Carlo Analysis... Median AR 124%
Win 1515868$ MI 256543$ DD 378716$ Capital 2856496$
Trades 2084 Win 60.3% Avg +63.7p Bars 109
AR 108% PF 1.19 SR 2.65 UI 7% R2 0.58

Posted By: Lapsa

Re: Lapsa's very own thread - 10/29/21 07:50

[Linked Image]
Posted By: Lapsa

Re: Lapsa's very own thread - 10/29/21 10:00

Falling MMI 4

Quote

Thus, when we know that MMI is rising, we assume that the market is becoming more efficient,
more random, more cyclic, more reversing or whatever, but in any case bad for trend trading.

However when MMI is falling, chances are good that the next beginning trend will last longer than normal.

jcl


Figured I should visualize this falling MMI 4 trick I've been using.

And it sort of works just as I imagined - as a smart throttler.

A means to recognize start of the trend and follow it.


Code
function run() 
{
	set(LOGFILE|PLOTNOW);
	BarPeriod = 60;
        MaxBars = 200;
	asset(""); // dummy asset
	ColorUp = ColorDn = 0; // don't plot a price curve
	vars Sine = series(genSine(60,30));
	var mmi = MMI(Sine, 4);
	plot("Sine",Sine[0]-0.5,MAIN,BLUE);
	plot("MMI 4", mmi, NEW, RED);
	plot("MMI Falling", falling(series(mmi)), NEW, GREEN);
}


[Linked Image]

On 2 bars it (logically) refuses to speak.
On 3 bars it skips.
On 5+ bars it lags.

I mean - indicator itself is definitely useful on longer periods.
It's just not how I've built my algo.

Here's numbehs to show crucial role this single rule is playing:

Quote

Trades 4069 Win 59.8% Avg +6.7p Bars 59
AR 117% PF 1.08 SR 1.90 UI 10% R2 0.00

Trades 2096 Win 60.2% Avg +62.8p Bars 109
AR 1217% PF 1.66 SR 9.53 UI 1% R2 0.00
Posted By: Lapsa

Re: Lapsa's very own thread - 10/29/21 12:11

I hate trailing stops, I really do

so deceiving

I mean - I'm pulling my hair fine tuning entries yet somehow such simple mechanic as trailing stop is supposed to be helpful
Posted By: Lapsa

Re: Lapsa's very own thread - 10/30/21 07:40

squeezing squeezing!

Quote

Monte Carlo Analysis... Median AR 1255%
Win 146$ MI 24.36$ DD 4.12$ Capital 21.81$
Trades 2074 Win 60.7% Avg +70.3p Bars 111
AR 1340% PF 1.75 SR 10.38 UI 1% R2 0.00


broken milestones:
- 1300%
- PF 1.7
- SR 10
Posted By: Lapsa

Re: Lapsa's very own thread - 11/01/21 17:08

need to figure out how to compound it correctly
Posted By: Lapsa

Re: Lapsa's very own thread - 11/03/21 04:27

losses only

to the point I'm willing to drop the ball

burn it all down or reborn like a phoenix!
Posted By: Lapsa

Re: Lapsa's very own thread - 11/03/21 19:26

[Linked Image]

oh well... it's not that bad
Posted By: Lapsa

Re: Lapsa's very own thread - 11/06/21 12:11

Code
setf(PlotMode,PL_ALL+PL_FINE+PL_ALLTRADES+PL_BENCHMARK);
Posted By: Lapsa

Re: Lapsa's very own thread - 11/06/21 19:07

Quote

Test: foxer SOLUSDT 2021
Monte Carlo Analysis... Median AR 529%
Win 65.80$ MI 11.25$ DD 5.57$ Capital 25.51$
Trades 1413 Win 62.1% Avg +32.8p Bars 181
AR 529% PF 1.57 SR 6.95 UI 2% R2 0.77


won't trade this one yet - numbahs unsatisfying

but I do have in mind adding another asset/s
Posted By: Lapsa

Re: Lapsa's very own thread - 11/09/21 07:07

Quote

Monte Carlo Analysis... Median AR 784%
Win 128$ MI 21.94$ DD 9.02$ Capital 34.09$
Trades 1747 Win 63.2% Avg +73.5p Bars 146
AR 772% PF 1.80 SR 8.35 UI 1% R2 0.00


breaking PF 1.80

Sharpe unhappy cause I took off stop losses while tweaking
Posted By: Lapsa

Re: Lapsa's very own thread - 11/10/21 22:30

Quote

Channeling and Elliott Waves

Channeling an impulse wave can frequently help predict the approximate ending locations of various waves.


wtf o_0

anyhow - algo doing bit badly. an ugly, prolonged drawdown

tweaked a bit, slightly lowered the bet

lo and behold - half way there to breaking even with a single trade

[Linked Image]

bugcoin doing funny moves
Posted By: Lapsa

Re: Lapsa's very own thread - 11/11/21 06:58

this is beautiful

I love Wednesdays

[Linked Image]

should finally do something about those pesky weekends

sort of bummer knowing they almost always red

------

1-2 weeks
scale up if breaks even / in profits

------

backtests makes zero sense

[Linked Image]

what the hell is going on?
Posted By: Lapsa

Re: Lapsa's very own thread - 11/15/21 21:05

yet to see a good use for windowing

I guess my approach just isn't compatible
Posted By: MegaTanker

Re: Lapsa's very own thread - 11/20/21 20:18

What's the deal with these insane backtests? 1000+% annual return, but it sounds like the live results don't live up to this, if I read that correctly?
Posted By: Grant

Re: Lapsa's very own thread - 11/20/21 22:43

I think that's the issue with cryptocurrencies. Their extreme volatility makes it pretty much impossible to create reliable backtests.
Posted By: Lapsa

Re: Lapsa's very own thread - 11/20/21 23:15

Originally Posted by MegaTanker
What's the deal with these insane backtests? 1000+% annual return, but it sounds like the live results don't live up to this, if I read that correctly?


Well... That's the thing with backtests. Past doesn't repeat itself.

Green backtest is just a small step to trade effectively.
Markets aren't simple - there's a lot of stuff going on.

Trading fully automatically while basing decisions purely on TA (with no access to volume) is quite ambitious.

About 600% from those ~1200% are from May crypto crash which is a black swan and doesn't repeat monthly.
I do think it's important to include ability to surf such waves.

Out of those 600% - I would say 50% to 200% *might be* sort of actually realistic.

One issue with measuring performance is that I'm constantly tinkering with it.
However - I do believe in such approach. If you keep bashing squares into circled holes - eventually they become circles.
Backtest shows PF1.7 (on a flat bet) but I see PF0.9, maybe PF1.2

October was in slight profits. But there were like at least 10 iterations of algo updates (starting from about AR 300%).
And mostly on fixed $10 trades.
November is red so far.
Markets retesting all time highs, stuck in indecisiveness. Probably not for long.

Quote

from $5k

Monte Carlo Analysis... Median AR 83%
Win 555327679$ MI 83282622$ DD 278602844$ Capital 1614994560$
Trades 2087 Win 59.7% Avg +70.8p Bars 121
AR 62% PF 1.18 SR 2.09 UI 7% R2 0.45


Even if history did repeat - soon enough it wouldn't.
Pulling out 5% of total market cap can't go unnoticed.

But you never know unless you live trade.
Posted By: Lapsa

Re: Lapsa's very own thread - 11/20/21 23:19

Also - it's important to understand that 0% -> 10% is not the same as 1000% -> 1010% on a simulated compounding system.

Those numbers get ridiculous really fast.
Posted By: MegaTanker

Re: Lapsa's very own thread - 11/21/21 07:09

Originally Posted by Lapsa

One issue with measuring performance is that I'm constantly tinkering with it.
However - I do believe in such approach. If you keep bashing squares into circled holes - eventually they become circles.
Backtest shows PF1.7 (on a flat bet) but I see PF0.9, maybe PF1.2


I don't know what your strategies and workflow look like but "tinkering" here sounds a lot like overfitting, doesn't it? If you're adjusting parameters or adding new mechanisms that increase the AR in the backtest, you can introduce all sorts of biases into it even with OOS testing.

Originally Posted by Lapsa


About 600% from those ~1200% are from May crypto crash which is a black swan and doesn't repeat monthly.
I do think it's important to include ability to surf such waves.


You have to be confident that your strategy wins this black swan event not by chance though. I've also played around with the MATIC coin some time and the backtests were often defined by that burst of volatility in may. But if there are 2-3 trades happening that capture these insane price jumps, I just don't know how I can know if that is random luck or if the script can actually be on the right side of these reliably. And since I'm pessimistic, I rather exclude those times from the backtest personally. Though I also don't include any mechanism in the scripts so far that specifically react to these moments.
Posted By: Lapsa

Re: Lapsa's very own thread - 11/21/21 09:43

Originally Posted by MegaTanker

I don't know what your strategies and workflow look like but "tinkering" here sounds a lot like overfitting, doesn't it?
If you're adjusting parameters or adding new mechanisms that increase the AR in the backtest, you can introduce all sorts of biases into it even with OOS testing.


Yes and no.

I mean - I would gladly have PF0 algo that somehow magically is vastly profitable.
Question is - how do you know?

How do you determine this mythical boundary at which improvements suddenly becomes overfitting?

5 successes out of 10 are much less meaningful than 500 out of 1000.
One of my rules is to strive for relatively high trade count (>2000).

I have removed couple weird rules despite losing %.
I still have some of them.

Trade and see. Adapt. Think deeply about every rule you adjust.
It's not random.

You can enter a long, see a dip and think - it's over.
Or you can see it as a temporary sweep, wait a bit longer and be in profits.

Originally Posted by MegaTanker

You have to be confident that your strategy wins this black swan event not by chance though. I've also played around with the MATIC coin some time and the backtests were often defined by that burst of volatility in may. But if there are 2-3 trades happening that capture these insane price jumps, I just don't know how I can know if that is random luck or if the script can actually be on the right side of these reliably. And since I'm pessimistic, I rather exclude those times from the backtest personally. Though I also don't include any mechanism in the scripts so far that specifically react to these moments.


[Linked Image]

I am reasonably confident. It's not just 2-3 trades. There's like hundred in May.
Would say - it's actually algo's strong suit to handle such times.

Marked other bursts of volatility.
Either it rides it or gets stopped out and stays relatively flat.

Originally Posted by MegaTanker

I rather exclude those times from the backtest personally


Mentally - I do that.
Practically - I would rather have them just to keep some sort of assurance whole thing won't go bankrupt in seconds.

Keeping such ability seemingly hinders algo, removes a lot of room during "normal times".
But on grand scale of things - I think it actually rises the bar and increases adaptivity.

Originally Posted by MegaTanker

or adding new mechanisms


It's important to think about synergy.

I try to build it from "you don't want to flip here" standpoint instead of "this is the time you trade".

Instead of SMA 50-200 cross or perhaps valley/peak like rule - I favor rise & fall.
It's careful filtering instead of catching glaringly obvious tells (in fact - I might include such layer in future).

When you build it such way - rules seem to indicate same thing yet do that differently.
Once you get to combinations of rules - they start to cover up each others weaknesses.

If we take that same SMA 50-200 cross and combine it with (imo shitty) UO - there's a good chance you can change it to 49-199 cross.
Posted By: MegaTanker

Re: Lapsa's very own thread - 11/22/21 10:25

Well, I think we have very different styles to be sure grin

Like, if your strategy actually works the way it appears in the backtest, then you will be filthy rich quickly. But if it doesn't, if you don't know to what extent it is biased/fitted, if you don't know to what extent it represents reality, I wouldn't use it at all to judge my strategy.
Posted By: Lapsa

Re: Lapsa's very own thread - 11/22/21 18:43

@MegaTanker

I don't think it works just as good as in backtest.

But the past is reality.

If your algo captures every movement in complete asset's history - there is no better bet.
Unless you are talking to time travelers.

Sure - some rules that worked in past might hinder in future.
Which is why I'm pro-tinkering.

I find it similar to software development - if your code is scary to touch, contradictory to your feelings, you want to bash it more until it isn't.

Every bias, every fitting is an improvement at particular point in time.
Trick is to align them so they don't interfere.

Speaking of ridiculous numbers - those are rookie numbers.

Once wrote a script that iterates backwards in time, captures everything in generated code.
Theoretically speaking - you can get to gazillion in couple days starting from couple bucks.
Slightly less as I didn't include fees that time but you get the idea.

Can't align those rules.
Posted By: Lapsa

Re: Lapsa's very own thread - 11/22/21 18:57

Quote
price(int offset) : var

Returns the mean price of the selected asset, by averaging all price ticks of the given bar or time frame (TWAP, time-weighted average price).


I suspect this is the main reason live differs from backtest.
Got no ticks.

Perhaps can be fixed by using MedPrice() but I'm unsure if that's desirable.
Posted By: Lapsa

Re: Lapsa's very own thread - 11/22/21 19:58

[Linked Image]

oh my... that's a new one
Posted By: Lapsa

Re: Lapsa's very own thread - 11/29/21 00:32

@MegaTanker

Here's an example of "my workflow" and tinkering.

Algo has a nasty draw down on November.
(or perhaps - more accurate picture of an actual performance)

Anyhow...

Copied algo into a new file, called it foxer_black_friday.c
Placed start date 2 weeks ago.
Killed all rules I found vaguely superficial.
Tweaked all rules till I reached ~1.5k% (from red abyss of -300% something).

And then - carefully incorporated only the best parts back into original.

2 week period retest went down to "only" +50%.

[Linked Image]
[Linked Image]

In ROFLcopter numbehs:

Quote

May 1st, $180 start =>

Test: foxer MATICUSDT 2021
Monte Carlo Analysis... Median AR 96%
Win 6169001$ MI 886650$ DD 2514043$ Capital 14074158$
Trades 2345 Win 60.7% Avg +62.4p Bars 114
AR 76% PF 1.15 SR 2.03 UI 6% R2 0.68
Posted By: Lapsa

Re: Lapsa's very own thread - 11/29/21 00:56

Why MATIC?

As it's futures algo trading - I don't really care much about the underlying asset.

But... There are some considerations.

First and foremost - the fees!

.5% movement in BTC will show up as 2% movement in MATIC

Given fees on Binance are percentage based - you end up wasting less.

Second - the nature of asset.

MATIC is pretty much a tech lubricant with a promise of providing less transaction fees for Ethereum.
(haven't even read up on details)

That causes an entanglement. I find it unlikely for MATIC to "moon" or dump completely unless it follows ETH.

I believe this intrinsic entanglement also causes pattern repetition. Some sort of similar swings around ETH.

It's not a glaringly obvious pump & dump scam scheme.
It's not completely hype based (well... sort of. whole crypto thing can be seen as such).

And that pretty much sums it up.
© 2021 lite-C Forums