(*
Instructions on using this program : 
Enter the parameters below .   The first two parameters are self descriptive .   
' 
                  EstimatedPercentSaturation' tells the program how far out it should go in the simulation .   Do NOT enter values at above 100, the program will run forever . 
' 
              PercentGaussianError' tells the program how much error to introduce at each data point .   The percent given by here will represent 1 standard deviation in a Gaussian distribution around the value of the data point .   While this leads to a violation of one of the fundamental assumptions of nonlinear regression, the effect is minor . 
'IterationsForErrorEvaluation' controls the number of times that the program should run with the combination of parameters you've entered.  On each iteration, the program compares the back-calculated Kd to the actual starting Kd to achieve an absolute value error estimate.
The program assumes that the units used for [Protein] and Kd are IDENTICAL .   Therefore if you estimate ~10uM Kd but have 0.5mM protein, adjust one of the numbers so that the units match .   Once you' ve entered your parameters, press [SHIFT]-[ENTER] to run the program .   
Output will consists of a representative plot of the simulated binding titration with and without Gaussian error introduced.  Three numbers follow :   the first is the error in Kd calculated over the number of iterations specified, while the second and third are the overall average values obtained for fitting Qo and Qmax. This is followed by a representative set of fitting diagnostics from a single iteration of the nonlinear fit .   This includes standard error, confidence intervals, etc .   The final number displayed is the number of times the calculation failed. *)

YourEstimatedKd =  .02;
YourProteinConcentration = 
        1;
EstimatedPercentSaturation = 
        95;
PercentGaussianError = 
        5;
IterationsForErrorEvaluation = 10;



<< 
      Statistics`ContinuousDistributions`; << Statistics`NonlinearFit`; 
    y = Array[#1^#2  &, {500, 2}]; nonrandomy = Array[#1^#2  &, {500, 2}]; 
    i = 1; Pt = YourProteinConcentration; Kd = YourEstimatedKd; Qo = 1000; 
    Qmax = 2000; jprev = 1000;  jz = 0; qotot = 0; qmtot = 0; 
    Off[NonlinearRegress]; 
    Off[FindMinimum::fqnum];
While[
        jprev/Qmax  < ( EstimatedPercentSaturation/100), 
        jprev = Qo + (Qmax - 
                  Qo)*(((Pt + jz + Kd - (Sqrt[(((Pt + jz + Kd))^2) - 4*Pt*jz]))/(2*Pt))); jz++];
jholder = 
      jz;  i = 1; errsum = 0; errcount = 1; errfailures = 0;  
    errtot  = 
      IterationsForErrorEvaluation;
While[
        errcount  ≤  errtot, 
Qo = 1000; 
        Qmax = 2000; j = jholder; jinc = j/Length[y]; jz = 0; i = 1; 
        While[i ≤  Length[y], 
          f = Qo + (Qmax - 
                    Qo)*(((Pt + jz + Kd - (Sqrt[(((Pt + jz + Kd))^2) - 4*Pt*jz]))/(2*Pt))); 
          z = Random[NormalDistribution[f, ((f*PercentGaussianError)/100)]]; 
          jz = jz + jinc;  y[[i, 1]] = jz; y[[i, 2]] = z; 
          nonrandomy[[i, 1]] = jz; 
          nonrandomy[[i, 2]] = f; 
i++]; Qo =. ; 
        ErrorInCalc =. ; 
aa = 
          Check[NonlinearRegress[y, 
              Qo + (Qmaxa - 
                      Qo)*((Pt + Ato + Kdo - (Sqrt[(((Pt + Ato + Kdo))^2) - 4*Pt*Ato]))/(2*Pt)), {Ato} , {{Kdo, Kd}, {Qmaxa, 2500}, {Qo, 500}} ], 
            ErrorInCalc, NonlinearRegress::fitfail]; 
If[
          aa == ErrorInCalc,  errfailures++;]; 
        ab = BestFitParameters /.  aa ; 
        errsum  +=  
          100*(Sqrt[(((((Kdo /. ab [[1]]) - Kd))^2)/(Kd^2))]); 
        qotot += Qo /. ab [[3]]; 
        qmtot += Qmaxa /. 
            ab [[2]]; 
errcount++];
errtot = 
        errtot - errfailures;
If[errtot  == 0, 
          Print[aa], 
ListPlot[nonrandomy]; ListPlot[y]; 
          Print[errpct  =  (errsum/errtot)]; Print[a = qotot/errtot]; 
          Print[a = qmtot/errtot]; Print[aa]; Print[errfailures];];

.