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

Reply via email to