[MAD] PID
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © djmad

//@version=5
indicator('[MAD] PID',overlay = false)

 // PID Constants
string matype = input.string('SMA',title = 'MA-Type', options=['SMA','EMA','WMA','VWMA','External'],group='MA Settings')
int length = input.int(20,'MA Length',group='MA Settings')
float kP = input.float(0.2,'PID - kP (Proportional)',step=0.05,group='PID Settings')
float kI = input.float(0.1,'PID - kI (Incremental) ',step=0.05,group='PID Settings')//0.01 
float kIc = input.float(20,'PID - kIc (Inc. recentering speed)',group='PID Settings') //recentering of integral
float kD = input.float(0.3,'PID - kD (Differenctial)',step=0.05,group='PID Settings')//0.1
float exponent = input.float(1, 'exponent of oszillator' ,step = 0.05, group='Scaling and Finals')
int smoother1= input.int(3, 'smoother of oszillator' ,step = 1, group='Scaling and Finals')
float exponent_accel = input.float(1, 'exponent of acceleration' ,step = 0.05, group='Scaling and Finals')

bool onclose = input(false,'on close?')
float inputModule                   =   input(title='External Indicator Signal', defval=close)

smaCalc(simple string _type, series float _source, simple int _length) =>
    float result = 
      switch _type
        'SMA' => ta.sma(_source, _length)
        'EMA' => ta.ema(_source, _length)
        'WMA' => ta.wma(_source, _length)
        'VWMA' => ta.vwma(_source, _length)

        'External' => inputModule






update(float setpoint,float processValue) =>
    var float error = na
    float output = 0.0
    var float prevProcessValue = na
    var float integral = 0.0
    var float derivative = 0.0

    error := setpoint - processValue
    integral := integral + nz(error) - integral/kIc
    derivative := processValue - processValue[1]

    output := kP * error + kI * integral + kD * derivative
    output

macalc = smaCalc(_type = matype, _source = close, _length = length)


precalc = ta.ema(math.sign(update(macalc,close))*math.pow(math.abs(update(macalc,close)),exponent),smoother1)



result = onclose?close-precalc:-precalc

calc_accel = math.sign(ta.change(result,1))*math.pow(math.abs(ta.change(result,1)),exponent_accel)

mycolor = (result>result[1] and result > 0) ?color.green:(result<result[1]  and result < 0) ?color.red:color.yellow

plot(result,'INPUT/CLOSE PID',color=mycolor)
plot(calc_accel,'Acceleration of PID')
hline(not onclose?0:na)

barcolor(mycolor)