Q:

Using a thread safe variable with a parallel for loop C#

This is my first time working woth a parallel for loop and I understand the basics as you can see with my code below but I'm not understanding how to make the variables inside the loop thread safe. 
I'm following the article at https://docs.microsoft.com/en-us/dotnet/standard/parallel-programming/how-to-write-a-parallel-for-loop-with-thread-local-variables
I'm currently getting constant errors for: Sequence contains no elements in my Calculations class when it is performing the calculations on the data. Am I missing something simple to make this all thread safe?
UPDATE: I added all of the relevant code for the Calculations class showing one method as an example that is returning constant Sequence contains no elements exceptions and what I have done so far to try to fix the issue (exceptions still going on)
UPDATE 2: I added the custom classes in my code which should allow it to compile now.
public static async Task Test()
    {
        Vector<double> vectorArrayBuy = null;
        Vector<double> vectorArraySell = null;
        Calculations calcTemp = null;

        try
        {
            using (financeEntities context = new financeEntities())
            {
                List<string> symbolList = new List<string>();
                symbolList = GetStockSymbols("nasdaq");

                foreach (string symbol in symbolList)
                {
                    var query = await context.DailyStockDatas.Where(i => i.Symbol == symbol && i.Market == "nasdaq").ToListAsync();
                    if (query.Count >= 200)
                    {
                        List<MultipleRegressionInfo> listMRInfo = new List<MultipleRegressionInfo>();
                        Calculations calc = new Calculations(query, j);
                        calcTemp = calc;

                        Parallel.For(0, 200, j =>
                        {
                            var targetValueBuy = calc.ListCalculationData.Select(i => i.MRTargetValueBuy).ToList();
                            var targetValueSell = calc.ListCalculationData.Select(i => i.MRTargetValueSell).ToList();
                            vectorArrayBuy = CreateVector.Dense(targetValueBuy.ToArray());
                            vectorArraySell = CreateVector.Dense(targetValueSell.ToArray());
                            var name = calc.ListCalculationData.First();
                            IEnumerable<double> value;

                            value = calc.ListCalculationData.Select(i => i.WilliamsR);
                            MultipleRegressionInfo r1 = Rn(value, vectorArrayBuy, nameof(name.WilliamsR), j, calc);
                            listMRInfo.Add(r1);
                        });

class Calculations
{
    public List<DailyStockData> Data { get; set; }
    public ConcurrentBag<CalculationData> ListCalculationData { get; set; }

    public Calculations(List<DailyStockData> dailyData, int days)
    {
        lock (thisLock)
        {
            Data = dailyData;

            // initiate the data
            ListCalculationData = new ConcurrentBag<CalculationData>();

            for (int i = 0; i < Data.Count; i++)
            {
                var currentDate = Data.ElementAt(i).Date;

                CalculationData calc = new CalculationData(currentCalcData);
                calc.WilliamsR = CalculateWilliamsR(days, currentDate);

                // add current calculator class to the list
                ListCalculationData.Add(calc);
            }
        }
    }
public double CalculateWilliamsR(int days, DateTime startingDate)
    {
        double williamsR = 0;
        double highestHigh = 0;
        double currentClose = 0;
        double lowestLow = 0;

        try
        {
            highestHigh = FindMaxOrMin(days, startingDate, MaxOrMinType.HighestHigh);
            lowestLow = FindMaxOrMin(days, startingDate, MaxOrMinType.LowestLow);
            currentClose = (double)Data.Where(i => i.Date <= startingDate).Last().Close;
            williamsR = -100 * ((highestHigh - currentClose) / (highestHigh - lowestLow));
        }
        catch (Exception ex)
        {
            williamsR = 0;
            Console.WriteLine(ex.Message);
            Console.WriteLine(ex.StackTrace);
        }

        return williamsR;
    }

    public enum MaxOrMinType
    {
        HighestHigh,
        LowestLow,
        HighestClose,
        LowestClose
    }

    public double FindMaxOrMin(int days, DateTime startingDate, MaxOrMinType type)
    {
        double maxMin = 0;

        try
        {
            lock (thisLock)
            {
                switch (type)
                {
                    // gets Sequence contains no elements exceptions at all of the below lines
                    case MaxOrMinType.HighestClose:
                        maxMin = (double)Data.Where(i => i.Date <= startingDate).Take(days).Max(i => i.Close);
                        break;
                    case MaxOrMinType.HighestHigh:
                        maxMin = (double)Data.Where(i => i.Date <= startingDate).Take(days).Max(i => i.High);
                        break;
                    case MaxOrMinType.LowestClose:
                        maxMin = (double)Data.Where(i => i.Date <= startingDate).Take(days).Min(i => i.Close);
                        break;
                    case MaxOrMinType.LowestLow:
                        maxMin = (double)Data.Where(i => i.Date <= startingDate).Take(days).Min(i => i.Low);
                        break;
                    default:
                        break;
                }
            }
        }
        catch (Exception ex)
        {
            maxMin = 0;
            Console.WriteLine(ex.Message);
            Console.WriteLine(ex.StackTrace);
        }

        return maxMin;
    }

public class DailyStockData
{
    public DailyStockData();

    public int ID { get; set; }
    public string Symbol { get; set; }
    public string Market { get; set; }
    public DateTime Date { get; set; }
    public decimal Open { get; set; }
    public decimal High { get; set; }
    public decimal Low { get; set; }
    public decimal Close { get; set; }
    public decimal AdjustedClose { get; set; }
    public long Volume { get; set; }
}

public class CalculationData
{
    public CalculationData(CalculationData calcData)
    {
        Date = calcData.Date;
        Open = calcData.Open;
        High = calcData.High;
        Low = calcData.Low;
        Close = calcData.Close;
        AdjustedClose = calcData.AdjustedClose;
        Volume = calcData.Volume;
        WilliamsR = calcData.WilliamsR;
}

    public CalculationData() { }

    public DateTime Date { get; set; }
    public double Open { get; set; }
    public double High { get; set; }
    public double Low { get; set; }
    public double Close { get; set; }
    public double AdjustedClose { get; set; }
    public double Volume { get; set; }
    public double WilliamsR { get; set; }
}

A:

Sequence contains no elements

For this problem, the issue is with taking Max of an empty set (i.e. a set with no data in it). Thus:
maxMin = (double)Data.Where(i => i.Date <= startingDate).Take(days).Max(i => i.Close);

fails. To solve this, change it to:
maxMin  = Data.Where(i => i.Date <= startingDate).Take(days)
    .OrderByDescending(z => z.Close)
    .Select(z => (double?)z.Close)
    .FirstOrDefault() ?? 0;

The OrderByDescending will ensure that the highest Close is listed first. The Select will ensure that the Close value is returned (or null if there is no entries at all). The ?? 0 will convert the null to 0 if there are no matches (change 0 to whatever value makes sense for your purposes.
For a different approach, consider https://github.com/morelinq/MoreLINQ/issues/28 .
You will need to change each of the switch statements in a similar way to solve the issue (with Close being either Close or High or Low, and with OrderByDescending being either OrderByDescending or OrderBy).
Additionally, it is odd in your original code that you were doing a Take without an earlier OrderBy, but I'll ignore that for now.

Thread safety

In terms of the thread-safety of calling listMRInfo.Add - rather than doing:
List<MultipleRegressionInfo> listMRInfo = new List<MultipleRegressionInfo>();

Parallel.For(0, 200, j =>
{
    // Code here
    listMRInfo.Add(r1);
});

consider doing:
var listMRInfo = Enumerable.Range(0, 200)
    .AsParallel()
    .Select(j =>
    {
        // Code here
        return r1;
    })
    .ToList();

This will allow you to have the same basic Parallel behaviour as For, but also allow you to have a List as the result (in a thread safe way).

