Thanks for the reply.
I will firmly admit that learning generics is tough. The documentation is slim.
And I don't know where a nice set of examples exist. That is why I am pressing
through displaying my ignorance and hoping for some help.
My apologies for the very simple sample code. I was trying to provide enough
code to convey the problem. But not so much as to bog down in unnecessary
information. I will endeavor to provide better examples and sufficient
information in the future.
You are correct I did not provide a valid constructor I did not feel it
necessary for the question. And yes I do understand that a seq is not fixed
sized. But my object is. It will never increase the size of the seq which it
contains. The fact that it is a seq is an implementation detail. I would use an
array. But I do not have sufficient information at compile time to create an
array.
I don't know that there will ever be any users of the slice operation of my
object. But I wanted to learn how to do it and code it. I believed it would be
another step to understanding generics.
And I was correct. You did provide me with enough information to make it work.
I am writing a trading app. I think Nim is a great language for such an app.
I did not start writing the app in Nim but in Smalltalk. Performance was not
the best but sufficient. Stability is what became the problem. When I had an
array of 5-100million floats and the memory was 1gb+. I was going to finish the
app and get version 1 running. But with the stability problem. I decided to go
to what I was going to write version 2 in. It will take me a little longer as I
am far and away not as familiar with static typing, static compilation and Nim
in general.
In trading you have a continual stream of time series data. Which is a set of
values containing (datetime, open, high, low, close) for the specified time
period. Then you operate on those values. A common item is a fixed sized slice
of the data from the most recent, back a specified number of periods.
Commonly this is done in a multi-dimensional array maintaining a large number
of periods of data. And on the column you need a slice of
`mydata[latestIndex - numberOfPeriods .. latestIndex]`.
I have chosen not to go that route but simply maintain only the data which
which is necessary for my specific strategy.
For your complete understanding of what I am actually doing. Not a sample. I
will provide the complete code below. Should anybody like any of the code. I
hereby release it under the MIT license.
The MovingArray below is somewhat like a FIFOQueue that is fixed in size. There
may be something out there like this or better than this. I am not an expert in
programming or algorithms. So my implementation may be naive or better
implementations exist. But I will display my ignorance. I have a lot to learn.
Thanks again.
##MovingArray
##(c) copyright 2019 Jimmie Houchin
##MIT license
type MovingArray*[T: int|float] = ref object
##MovingArray is an array type object with a fixed number of values.
##It maintains a small set of state variables which are update each push()
values*: seq[T]
size*: int
index: int
sum*: T
high*: T
low*: T
proc newMovingArray*[T: int|float](size: int, tp: typedesc[T]):
MovingArray[T] =
result = MovingArray[T](
size: size,
values: newSeq[T](size),
sum: 0,
index: size-1,
high: low(T), #guarantees first value will replace initial value
low: high(T) #guarantees first value will replace initial value
)
proc `[]`*(ma: MovingArray, index: int): int|float =
var i = ma.index + index
if i > ma.size-1:
i = i - ma.size
result = ma.values[i]
proc `[]`*[T: int|float](ma: MovingArray[T], hs: HSlice): seq[T] =
result = newSeq[float](hs.b - hs.a + 1)
var index = 0
for i in hs:
result[index] = ma[i]
index += 1
proc push*[T: int | float](ma: MovingArray, n: T): T =
if ma.index == ma.size-1:
ma.index = 0
else:
ma.index += 1
result = ma.values[ma.index]
ma.values[ma.index] = n
ma.sum = ma.sum - result + n
if ma.high < n:
ma.high = n
elif ma.high == result:
ma.high = ma.values.max()
if ma.low > n:
ma.low = n
elif ma.low == result:
ma.low = ma.values.min()
proc avg*(ma: MovingArray): float =
result = ma.sum / ma.size
Run