Posts: 12
Threads: 2
Joined: Jun 2024
Mar-21-2025, 12:22 PM
(This post was last modified: Mar-21-2025, 12:22 PM by Frankd.)
Hello,
I am trying to make complexe calculation that require a lot of data.
in c# create a loop counting from 0 to 5, consecutively e.g. 0 to 5, 1 to 5, 2 to 5, 3 to ...
This in python will return:
Output: 0 1 2 3 4 5
1 2 3 4 5
2 3 4 5
3 4 5
4 5
In python it translate in to
for i in range(5):
for j in range(i, 6):
print(j, end=' ')
print()Is there a way to test each value one by one without producing a large output? Because with 100 000 data to test at some point it will crash or reach a limit.
I can put a if statement but if it has to test 90 000 possibilities before getting to the answer it wont solve the problem.
Iideally, after the first pass it jump to the next and erasing or forgetting the last one.
I tried with this but i can say if it works or not:
MAX_NUMBER = 5
buffer = [''] * ((MAX_NUMBER + 1) * 2) # Space for numbers and spaces
for i in range(MAX_NUMBER + 1):
buffer_index = 0
for j in range(i, MAX_NUMBER + 1):
buffer[buffer_index] = str(j)
buffer_index += 1
buffer[buffer_index] = ' '
buffer_index += 1
print(''.join(buffer[:buffer_index - 1]))Any suggestions?
Thank you
Posts: 6,981
Threads: 22
Joined: Feb 2020
Mar-21-2025, 04:15 PM
(This post was last modified: Mar-21-2025, 04:16 PM by deanhystad.)
I don't understand your question. You mention "data", but all your code does is print numbers. It doesn't produce anything that could be used as "data". As no "data" is produced, I have no idea what you mean by "test each value".
Could you describe what you mean by "test each value"?
I have no idea if any of this is applicable to your problem.
def countdown_generator(max_number, start=0):
"""Generator that returns countdowns with an increasing start."""
for number in range(start, max_number + 1):
yield list(range(number, max_number + 1))
print("Use as an iterator in a for loop.")
for values in countdown_generator(5):
print(*values)
print("Use as an iterator in a for loop. Start at 2")
for values in countdown_generator(5, 2):
print(*values)
print("Wrap generator in an iterator so you can use next().")
countdown_iter = iter(countdown_generator(5, 2))
print(*next(countdown_iter))
next(countdown_iter)
print(*next(countdown_iter))
def countdown(end, start=0):
"""Return a list of int start at start and ending at end."""
return list(range(start, end + 1))
print("Using countdown.")
print(*countdown(5))
print(*countdown(5, 2))Output: Use as an iterator in a for loop.
0 1 2 3 4 5
1 2 3 4 5
2 3 4 5
3 4 5
4 5
5
Use as an iterator in a for loop. Start at 2
2 3 4 5
3 4 5
4 5
5
Wrap generator in an iterator so you can use next().
2 3 4 5
4 5
Using countdown.
0 1 2 3 4 5
2 3 4 5
Posts: 12
Threads: 2
Joined: Jun 2024
The loop is just an example.
I need to for loop a great deal of bars in a charting app.
i represent the barIndex in the chart and it goes to CurrentPrice the end of the chart. The value of barIndex CurrentPrice can be as many as 10 000 bars index if not more.
The more it loop throught data the slower the calculation and the chart software crash. Ninjatrader.com
looping from 0 to 10 000 barIndex is expensive.
This is a cma in C#
double sumC =0;
double sumC1 = 0;
double cmaIDX =0;
for (int barIndex = 0; barIndex < CurrentBar; barIndex++)
{
double closePrice = Bars.GetClose(barIndex);
double volumes = Bars.GetVolume(barIndex);
double clovol = closePrice * volumes;
sumC += clovol;
sumC1 += volumes;
cmaIDX = sumC / sumC1;
}
The idea was to create multiple cmaIDX. That explain the use of nested loop:
for i in range(5):
for j in range(i, 6):
print(j, end=' ')
print()When cmaIDX is = to a certain value it will break and return if both are =.
I hope this is a better explaination. In fact i dont need 10 000 cmaIDX, i just want to calculate each one untill it reach a match.
TY
Posts: 1,300
Threads: 151
Joined: Jul 2017
Terrible explanation!
Basically, you want to check sales volume and share price for all shares you are interested in, I believe. If the price has risen by a certain amount, sell.
You should provide more information, such as:
Bars.GetClose(barIndex)
Bars.GetVolume(barIndex)
What do they look like?
But, below is maybe something like what you want:
from random import randint
# a function to provide a closing price
def closing_price(num):
random_num = randint(10, 30)
cp = num * 2 + random_num
return cp
# a function to provide a sales volume
def sales_volume(num):
sv = randint(25,45) + num
return sv
# do the calculations
def calc(bi):
# get a random price to quit on
cmaIDX_wanted = randint(25,30)
sumC, sumC1, cmaIDX = 0, 0, 0
close_price = closing_price(bi)
volumes = sales_volume(bi)
print(f'For Bar Index {bi} closing price is {close_price}, sales volume is {volumes}.')
clovol = close_price * volumes
sumC += clovol
sumC1 += volumes
cmaIDX = sumC / sumC1
if cmaIDX >= cmaIDX_wanted:
print(f'Sell all shares of bar index {bi}! We are rich!')
return (cmaIDX, cmaIDX_wanted)
else:
print(f'Desired share price not reached for bar index {bi}. No sale today')
return (cmaIDX, cmaIDX_wanted)
# generator for large lists
# bar_index = (i for i in range(5))
# a list if it is not too big
bar_index = [i for i in range(5)]
for bi in bar_index:
print(f'Bar Index is {bi}')
result = calc(bi)
print(f'Price wanted = {result[1]}, price achieved = {result[0]}\n')The results look like this, using random numbers to simulate market fluctuations:
Output: Bar Index is 0
For Bar Index 0 closing price is 24, sales volume is 167.
Desired share price not reached for bar index 0. No sale today
Price wanted = 27, price achieved = 24.0
Bar Index is 1
For Bar Index 1 closing price is 15, sales volume is 34.
Desired share price not reached for bar index 1. No sale today
Price wanted = 27, price achieved = 15.0
Bar Index is 2
For Bar Index 2 closing price is 24, sales volume is 86.
Desired share price not reached for bar index 2. No sale today
Price wanted = 29, price achieved = 24.0
Bar Index is 3
For Bar Index 3 closing price is 32, sales volume is 208.
Sell all shares of bar index 3! We are rich!
Price wanted = 28, price achieved = 32.0
Bar Index is 4
For Bar Index 4 closing price is 19, sales volume is 236.
Desired share price not reached for bar index 4. No sale today
Price wanted = 30, price achieved = 19.0
Posts: 12
Threads: 2
Joined: Jun 2024
Mar-23-2025, 12:17 PM
(This post was last modified: Mar-23-2025, 12:17 PM by Frankd.)
I will explain again.
Like i said this is in C# the code to create a cma cumulative moving average.
double sumC =0;
double sumC1 = 0;
double cmaIDX =0;
for (int barIndex = 0; barIndex < CurrentBar; barIndex++)
{
double closePrice = Bars.GetClose(barIndex);
double volumes = Bars.GetVolume(barIndex);
double clovol = closePrice * volumes;
sumC += clovol;
sumC1 += volumes;
cmaIDX = sumC / sumC1;
}In chart it looks like this:
The cma return 2605.31. First, I want the final value of my cma to be equal to the value of CurrentBar, which is 2744.75. The loop will automatically fetch the number of bars needed to arrive at the currentbar value.
Then, as in this example, create several cma above or below the first one with an interval of .25, .50, .75 or 1 point.
The problem is that I'm limited. The more cma you create, the more the application slows down and freezes. In this example of the RMMA indicator, if we ask to create a CMA for each period, it will take 20 minutes at best to appear on the screen.
Is there a way to program the loop to avoid the creation of a multitude of cma to arrive at the answer? Obviously, I can reduce the number of cma with the interval, but we lose precision.
Thank you
Posts: 2,198
Threads: 12
Joined: May 2017
Quote:The problem is that I'm limited. The more cma you create, the more the application slows down and freezes. In this example of the RMMA indicator, if we ask to create a CMA for each period, it will take 20 minutes at best to appear on the screen.
The bigger the window, the more calculations the CPU has to do. With many data points, this can get very slow.
From where comes the data? Is it on Disk? Is it in memory? Which format?
Does your C# program use vectors to use the SIMD instructions on your CPU?
I'm not familiar with C#, but I guess this could help: https://devblogs.microsoft.com/dotnet/ha...-net-core/
With Python you get this kind of optimazation with numpy.
Posts: 6,981
Threads: 22
Joined: Feb 2020
Is this a data retrieval problem or a computation problem? Does it take a long time to get price and volume info for each period, or is it all the looping to compute the cma that causes the long waits? There are ways to speed up loops significantly. Easily making them thousands of times faster.
Posts: 12
Threads: 2
Joined: Jun 2024
I think it's a calculation problem. As in the first example with a nested loop, we end up reproducing several series of numbers in the output.
Output: 0 1 2 3 4 5 2.5
1 2 3 4 5 3
2 3 4 5 3.5
3 4 5
4 5
In my case the goal is to find the average that equals a certain value in order to find a match. In this kind of loop if the average I am looking for is 3.5 and the value of my variable is also 3.5 we get a match. In the case where I have 100,000 series or average to calculate it takes a lot of calculation for the computer even if the data is on the disk. I guess that's the reason for the slowness?
That's why I'm asking if there is a way to calculate all the series averages consecutively instead of all at once. The software only uses C# so my plan is to translate from Python to C# if someone finds a solution for me.
Posts: 6,981
Threads: 22
Joined: Feb 2020
I do not see how this:
double sumC =0;
double sumC1 = 0;
double cmaIDX =0;
for (int barIndex = 0; barIndex < CurrentBar; barIndex++)
{
double closePrice = Bars.GetClose(barIndex);
double volumes = Bars.GetVolume(barIndex);
double clovol = closePrice * volumes;
sumC += clovol;
sumC1 += volumes;
cmaIDX = sumC / sumC1;
}Relates to this:
for i in range(5):
for j in range(i, 6):
print(j, end=' ')
print()In the C# code the starting index stays at zero and the currentBar changes.
I would implement the C# code like this:
mport numpy as np
import matplotlib.pyplot as plt
# This part makes some random data to work with.
close = np.cumsum(np.random.rand(100) - 0.5)
volume = np.random.randint(1, 5, 100)
clovol = close * volume
clovol_sum = np.cumsum(clovol)
volume_sum = np.cumsum(volume)
cma = clovol_sum / volume_sum
plt.plot(clovol)
plt.plot(cma)
plt.show() It is quite fast.
But this computes the cumulative sum for clovol[0], then clovol[:1], clovol[:2] . . . clovol[:N-1] where N is the number of clovol values. If you want to work backwards, You can reverse the clovol array, compute the cumulative sum, and reverse back to the original order.
Posts: 12
Threads: 2
Joined: Jun 2024
This is a Python example of how this principle is applied in C#.
for i in range(5):
for j in range(i, 6):
print(j, end=' ')
print()or in C#
using System;
class Program
{
static void Main()
{
// Target average value
double targetAverage = 4.0;
// Loop through the rows (starting from 0 to 4)
for (int i = 0; i <= 4; i++)
{
// Initialize the sum for the average calculation
int sum = 0;
int count = 0;
// Loop to build and print the series starting from i to 5
Console.Write("Series: ");
for (int j = i; j <= 5; j++)
{
Console.Write(j + " "); // Print the current number
sum += j; // Add the number to the sum
count++; // Increment the count of numbers
}
// Calculate the average
double average = (double)sum / count;
Console.WriteLine($"| Average: {average:F2}"); // Print the average (formatted to 2 decimal places)
// Check if the average matches the target
if (average == targetAverage)
{
Console.WriteLine($"Found series with average {targetAverage} at row starting with {i}");
}
}
}
}Output: 0 1 2 3 4 5 Average: 2.50
1 2 3 4 5 Average: 3.00
2 3 4 5 Average: 3.50
3 4 5 Average: 4.00
Found series with average 4 at row starting with 3
4 5 Average: 4.50
This portion of C# code returns a weighted volume cumulative moving average.
double sumC =0;
double sumC1 = 0;
double cmaIDX =0;
for (int barIndex = 0; barIndex < CurrentBar; barIndex++)
{
double closePrice = Bars.GetClose(barIndex);
double volumes = Bars.GetVolume(barIndex);
double clovol = closePrice * volumes;
sumC += clovol;
sumC1 += volumes;
cmaIDX = sumC / sumC1;
}in order to obtain several cma for each desired period we add a nested loop as in the first example.
protected override void OnBarUpdate()
{
if (CurrentBar == 0)
{
// Target average value
double targetAverage = 4.0;
// Loop through the rows (starting from 0 to 4)
for (int i = 0; i <= 4; i++)
{
int sum = 0;
int count = 0;
// Print the series and calculate the sum and count in one loop
string seriesOutput = "Series: ";
for (int j = i; j <= 5; j++) //or for (int barIndex = i; barIndex < CurrentBar; barIndex++)
{
seriesOutput += j + " "; // Add to series output
sum += j; // Add to sum
count++; // Increment count
}
// Calculate the average
double average = (double)sum / count;
// Print the series and average
Print(seriesOutput + $"| Average: {average:F2}");
// Check if the average matches the target
if (average.ApproxCompare(targetAverage) == 0)
{
Print($"Found series with average {targetAverage} at row starting with {i}");
}
}
}do you see where I'm going with this?
To find the period that is equal to the current price you have to loop through several periods at once.
The first loop count from 1 to 4 for (int i = 0; i <= 4; i++) The second loop count all the barIndex and extract the volume and price of the serie.
for (int barIndex = i; barIndex < CurrentBar; barIndex++) This will create several series of cma, when there is a match between the cma value and current price the loop will stop.
But we're going through a lot of data, which slows down the process. Is there a loop I don't know about that allows us to test one by one without having 5 sets of output data?
|