I've been trying to build a recursive function to replace the following n deep nested loop algorithm, the depth will change based on the length of the combination anywhere for 2 to n (most likely less than 20)
Edit: removed confusing code
I have searched this site and found Converting nested loop and More nested loop conversions but I can't seam to tweak them to output what I need.
or I could just be looking at it wrong and not needing a recursive function at all.
trying to do this in C#, thanks for any help.
Edit: hope this explains things a bit more.
What I’m trying to do is find the best combination of options and amounts to give me maximum return without going over budget.
So I have a cut down list of options that meets my requirements, then I want to feed them into this program/script to get the best combination with highset return, I also need to reduce my risk by buying more than one option normally 3-10
So below is my full code so far fixed at a depth of 3:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Combinations
{
class Program
{
static void Main(string[] args)
{
Stopwatch stopwatch = new Stopwatch();
List<option> options = new List<option> {
new option("A", 6.50, 0.18, 25000, 3),
new option("B", 23.00, 0.59, 25000, 3),
new option("C", 27.50, 0.60, 25000, 3),
new option("D", 21.00, 0.40, 25000, 3),
new option("E", 16.00, 0.30, 25000, 3),
new option("F", 7.00, 0.13, 25000, 3),
new option("G", 22.50, 0.38, 25000, 3),
new option("H", 27.00, 0.45, 25000, 3),
new option("I", 13.00, 0.20, 25000, 3),
new option("J", 20.50, 0.30, 25000, 3),
new option("K", 17.50, 0.25, 25000, 3),
new option("L", 10.50, 0.15, 25000, 3),
new option("M", 29.00, 0.41, 25000, 3),
new option("N", 26.50, 0.37, 25000, 3),
new option("P", 15.50, 0.21, 25000, 3),
new option("Q", 16.00, 0.20, 25000, 3),
new option("R", 10.00, 0.12, 25000, 3),
new option("S", 25.00, 0.30, 25000, 3),
new option("T", 27.00, 0.32, 25000, 3),
new option("U", 22.00, 0.25, 25000, 3),
new option("V", 26.50, 0.30, 25000, 3),
new option("W", 27.00, 0.30, 25000, 3),
new option("X", 14.50, 0.16, 25000, 3),
new option("Y", 28.50, 0.31, 25000, 3),
new option("Z", 28.50, 0.30, 25000, 3)
};
stopwatch.Start();
IEnumerable<List<option>> combinations = GetCombination(options, 3);
stopwatch.Stop();
Console.WriteLine("Combinations - Time elapsed: {0}", stopwatch.Elapsed);
stopwatch.Start();
bestFit(combinations);
stopwatch.Stop();
Console.WriteLine("Best Fit - Time elapsed: {0}", stopwatch.Elapsed);
Console.ReadKey();
}
static IEnumerable<List<option>> GetCombination(List<option> list, int _size)
{
double count = Math.Pow(2, list.Count);
List<option> combination = new List<option>();
int size = 0;
for (int i = 1; i <= count - 1; i++)
{
for (int j = 0; j < list.Count; j++)
{
if (((i >> j) & 1) == 1)
{
combination.Add(list[j]);
size++;
}
}
if (size == _size)
{
yield return combination;
}
combination.Clear();
size = 0;
}
}
static void bestFit(IEnumerable<List<option>> combinations)
{
double max = 0d;
double results = 0d;
double total = 0d;
string output = "";
string tmpOutput = "";
int y0 = 0;
int y1 = 1;
int yn = 2;
foreach (var combination in combinations)
{
option A1 = combination[y0];
for (int x1 = A1.lower; x1 < A1.upper; x1++)
{
option A2 = combination[y1];
for (int x2 = A2.lower; x2 < A2.upper; x2++)
{
option An = combination[yn];
for (int xn = An.lower; xn < An.upper; xn++)
{
int[] counts = { x1, x2, xn };
int i = 0;
foreach (option objOption in combination)
{
results += objOption.bid * 100 * counts[i] / objOption.cash;
total += (objOption.strike - objOption.bid) * 100 * counts[i];
tmpOutput += objOption.symbol + " STO " + counts[i].ToString() + " @ $" + objOption.strike + ", ";
i++;
}
if (results > max && total < A1.cash)
{
output = tmpOutput.Remove(tmpOutput.Length - 2) + " for a gain of " + results*100 + "% using a total of $" + total;
max = results;
}
results = 0d;
total = 0d;
tmpOutput = "";
}
}
}
}
Console.WriteLine(output);
}
}
class option
{
public string symbol { get; set; }
public double strike { get; set; }
public double bid { get; set; }
public double cash { get; set; }
public int lower;
public int upper;
public option(string _symbol, double _strike, double _bid, double _cash, int _trades)
{
this.symbol = _symbol;
this.strike = _strike;
this.bid = _bid;
this.cash = _cash;
double tradeCash = _cash / _trades;
this.lower = (int)((0.25 * tradeCash) / ((_strike - _bid) * 100));
this.upper = (int)((1.25 * tradeCash) / ((_strike - _bid) * 100));
}
}
}
This should give an output of:
Combinations - Time elapsed: 00:00:00.0002575
A STO 15 @ $6.5, B STO 3 @ $23, D STO 4 @ $21 for a gain of 2.428% using a total of $24443
Best Fit - Time elapsed: 00:00:11.9196411
hope this help to clear things up.