# Cycle Swing Indicator # Adaptive Ultra-Smooth Momentum Indicator Popular technical indicators often react too slowly to changes and deliver shaky signal lines. If they are smoothed, the lag becomes greater and greater, rendering the signals useless for real-time analysis. When the lag is eliminated and the smoothed, clear reversal points are restored, new options for technical analysis arise. The Cycle-Swing Indicator is fast, clear and smooth. You get better timing, greater accuracy, and better signals. Many systems include momentum as an indicator. Until now, however, momentum signals have been extremely jittery, resulting in whipsaw trades. In contrast, the adaptive cycle swing generates an ultra-smooth swing without adding lag to the original signal. The Cycle Swing Indicator "CSI" provides an optimized "momentum" oscillator based on the current dominant cycle by considering the dominant cycle swing instead of the raw source momentum. Offering the following improvements: - Smoothness - Zero delay - Sharpness at turning points - Robust and adaptable to market conditions - Accurate deviation detection The following common problems with standard indicators are solved by this indicator: First, normal indicators introduce a lot of false signals due to their noisy signal line. Second, to compensate for the noise, one would normally try to add some smoothing. But this only results in adding more delay to the indicator, which makes it almost useless. Third, standard indicators require a length adjustment to derive reliable signals. However, you never know how to set the right length. All three problems described above are solved by the developed adaptive cyclic algorithm. [![Screenshot_csi.jpg](https://docs.cycle.tools/uploads/images/gallery/2020-12/scaled-1680-/screenshot-csi.jpg)](https://docs.cycle.tools/uploads/images/gallery/2020-12/screenshot-csi.jpg) # Source Code This chapter provides access to source code library for the Cycle Swing Indicator for TradeStation, NinjaTrader, MetaTrader and TradingView. Requires a valid account and login. # MetaTrader MQ4 - CSI ```C# //+------------------------------------------------------------------+ //| WTT_CycleSwing.mq4 | //| Copyright 2014- 2017, WhenToTrade | //| https://www.whentotrade.com | //| Book reference: https://www.amazon.com/dp/1974658244 | //| License: Attribution 4.0 International (CC BY 4.0) | //+------------------------------------------------------------------+ #property copyright "Copyright 2014-2017, WhenToTrade" #property link "https://www.whentotrade.com" #property description "WhenToTrade Cycle Swing Indicator (CSI)" #property description "The CSI is an ultra smooth momentum indicator based on dominant cycles acceleration" #property description "See book reference: 'Decoding The Hidden Market Rhyhtm - Part 1'" #property version "1.00" #property strict #property indicator_separate_window #property indicator_buffers 2 #property indicator_plots 2 //--- plot CSI #property indicator_label1 "CSI" #property indicator_type1 DRAW_LINE #property indicator_color1 clrRed #property indicator_style1 STYLE_SOLID #property indicator_width1 1 //--- indicator buffers double CSIBuffer[]; double sourceValues[50]; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- indicator buffers mapping SetIndexBuffer(0,CSIBuffer); //name and label //MQL4: //IndicatorShortName("WTT CSI"); //MQL5: IndicatorSetString(INDICATOR_SHORTNAME,"WTT CSI"); //MQL4: // SetIndexLabel(0,"CSI"); //MQL5: PlotIndexSetString(0,PLOT_LABEL,"CSI"); //Set the starting point of CSI //MQL4: //SetIndexDrawBegin(0,250); //MQL5: PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,250); return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ int OnCalculate(const int rates_total, const int prev_calculated, const datetime &time[], const double &open[], const double &high[], const double &low[], const double &close[], const long &tick_volume[], const long &volume[], const int &spread[]) { if(rates_total<=200) return(0); //--- start variable for calculation of bars int start_index=prev_calculated; //--- work at the last bar if the indicator values have already been calculated at the previous tick if(prev_calculated>0) start_index--; //--- define indexing direction in arrays bool as_series_closes=ArrayGetAsSeries(close); bool as_series_buffer=ArrayGetAsSeries(CSIBuffer); //--- replace indexing direction with direct one if necessary if(as_series_closes) ArraySetAsSeries(close,false); if(as_series_buffer) ArraySetAsSeries(CSIBuffer,false); //--- calculate indicator values for(int i=start_index;i