@@ -210,6 +210,67 @@ export class TechnicalAnalysis {
210210 const idx = this . context . idx ;
211211 return [ [ this . context . precision ( supertrend [ idx ] ) , direction [ idx ] ] ] ;
212212 }
213+
214+ crossover ( source1 , source2 ) {
215+ // Get current values
216+ const current1 = Array . isArray ( source1 ) ? source1 [ 0 ] : source1 ;
217+ const current2 = Array . isArray ( source2 ) ? source2 [ 0 ] : source2 ;
218+
219+ // Get previous values
220+ const prev1 = Array . isArray ( source1 ) ? source1 [ 1 ] : this . context . data . series [ source1 ] [ 1 ] ;
221+ const prev2 = Array . isArray ( source2 ) ? source2 [ 1 ] : this . context . data . series [ source2 ] [ 1 ] ;
222+
223+ // Check if source1 crossed above source2
224+ return prev1 < prev2 && current1 > current2 ;
225+ }
226+
227+ crossunder ( source1 , source2 ) {
228+ // Get current values
229+ const current1 = Array . isArray ( source1 ) ? source1 [ 0 ] : source1 ;
230+ const current2 = Array . isArray ( source2 ) ? source2 [ 0 ] : source2 ;
231+
232+ // Get previous values
233+ const prev1 = Array . isArray ( source1 ) ? source1 [ 1 ] : this . context . data . series [ source1 ] [ 1 ] ;
234+ const prev2 = Array . isArray ( source2 ) ? source2 [ 1 ] : this . context . data . series [ source2 ] [ 1 ] ;
235+
236+ // Check if source1 crossed below source2
237+ return prev1 > prev2 && current1 < current2 ;
238+ }
239+
240+ pivothigh ( source , _leftbars , _rightbars ) {
241+ //handle the case where source is not provided
242+ if ( _rightbars == undefined ) {
243+ _rightbars = _leftbars ;
244+ _leftbars = source ;
245+
246+ //by default source is
247+ source = this . context . data . high ;
248+ }
249+ const leftbars = Array . isArray ( _leftbars ) ? _leftbars [ 0 ] : _leftbars ;
250+ const rightbars = Array . isArray ( _rightbars ) ? _rightbars [ 0 ] : _rightbars ;
251+
252+ const result = pivothigh ( source . slice ( 0 ) . reverse ( ) , leftbars , rightbars ) ;
253+ const idx = this . context . idx ;
254+ return this . context . precision ( result [ idx ] ) ;
255+ }
256+
257+ pivotlow ( source , _leftbars , _rightbars ) {
258+ //handle the case where source is not provided
259+ if ( _rightbars == undefined ) {
260+ _rightbars = _leftbars ;
261+ _leftbars = source ;
262+
263+ //by default source is
264+ source = this . context . data . low ;
265+ }
266+
267+ const leftbars = Array . isArray ( _leftbars ) ? _leftbars [ 0 ] : _leftbars ;
268+ const rightbars = Array . isArray ( _rightbars ) ? _rightbars [ 0 ] : _rightbars ;
269+
270+ const result = pivotlow ( source . slice ( 0 ) . reverse ( ) , leftbars , rightbars ) ;
271+ const idx = this . context . idx ;
272+ return this . context . precision ( result [ idx ] ) ;
273+ }
213274}
214275
215276//Here we did not use indicatorts implementation because it uses a different smoothing method which gives slightly different results that pine script
@@ -715,4 +776,76 @@ function calculateSupertrend(high: number[], low: number[], close: number[], fac
715776 return [ supertrend , direction ] ;
716777}
717778
779+ // Pivot high identifies a local high point
780+ function pivothigh ( source : number [ ] , leftbars : number , rightbars : number ) : number [ ] {
781+ const result = new Array ( source . length ) . fill ( NaN ) ;
782+
783+ // We need at least leftbars + rightbars + 1 (for the center point) values
784+ for ( let i = leftbars + rightbars ; i < source . length ; i ++ ) {
785+ const pivot = source [ i - rightbars ] ;
786+ let isPivot = true ;
787+
788+ // Check if the pivot is higher than all bars to the left within leftbars range
789+ for ( let j = 1 ; j <= leftbars ; j ++ ) {
790+ if ( source [ i - rightbars - j ] >= pivot ) {
791+ isPivot = false ;
792+ break ;
793+ }
794+ }
795+
796+ // Check if the pivot is higher than all bars to the right within rightbars range
797+ if ( isPivot ) {
798+ for ( let j = 1 ; j <= rightbars ; j ++ ) {
799+ if ( source [ i - rightbars + j ] >= pivot ) {
800+ isPivot = false ;
801+ break ;
802+ }
803+ }
804+ }
805+
806+ // If this is a pivot point, set its value, otherwise keep NaN
807+ if ( isPivot ) {
808+ result [ i ] = pivot ;
809+ }
810+ }
811+
812+ return result ;
813+ }
814+
815+ // Pivot low identifies a local low point
816+ function pivotlow ( source : number [ ] , leftbars : number , rightbars : number ) : number [ ] {
817+ const result = new Array ( source . length ) . fill ( NaN ) ;
818+
819+ // We need at least leftbars + rightbars + 1 (for the center point) values
820+ for ( let i = leftbars + rightbars ; i < source . length ; i ++ ) {
821+ const pivot = source [ i - rightbars ] ;
822+ let isPivot = true ;
823+
824+ // Check if the pivot is lower than all bars to the left within leftbars range
825+ for ( let j = 1 ; j <= leftbars ; j ++ ) {
826+ if ( source [ i - rightbars - j ] <= pivot ) {
827+ isPivot = false ;
828+ break ;
829+ }
830+ }
831+
832+ // Check if the pivot is lower than all bars to the right within rightbars range
833+ if ( isPivot ) {
834+ for ( let j = 1 ; j <= rightbars ; j ++ ) {
835+ if ( source [ i - rightbars + j ] <= pivot ) {
836+ isPivot = false ;
837+ break ;
838+ }
839+ }
840+ }
841+
842+ // If this is a pivot point, set its value, otherwise keep NaN
843+ if ( isPivot ) {
844+ result [ i ] = pivot ;
845+ }
846+ }
847+
848+ return result ;
849+ }
850+
718851export default TechnicalAnalysis ;
0 commit comments