Home > front end >  Golang Equivalent of Python's `pd.to_datetime()`
Golang Equivalent of Python's `pd.to_datetime()`

Time:11-20

I'm new to Go, and looking to create my own algo trading strategy backtesting library, an area I'm well experienced in with Python, to help learn the language.

I have a 5 minute OHLCV SPY5min.csv dataset, the head of which looks like this:

dataset

I use this code to read in the dataset from the file, converting everything to a list of lists of values:

package main

import (
    "encoding/csv"
    "log"
    "os"
    "fmt"
)

func ReadCsvFile(filePath string) [][]string {
    f, err := os.Open(filePath)
    if err != nil {
        log.Fatal("Unable to read input file " filePath, err)
    }
    defer f.Close()

    csvReader := csv.NewReader(f)
    records, err := csvReader.ReadAll()
    if err != nil {
        log.Fatal("Unable to parse file as CSV for " filePath, err)
    }

    return records
}

func main() {
    records := ReadCsvFile("./SPY5min.csv")
    fmt.Println(records)
}

importedDataset

This returns a list of lists of string values. Cool. Now what I want to do is replicate a Pandas Dataframe like object, or perhaps separate each "column" into their own separate arrays/slices if that's easier, not sure yet.

Once that's done, I need a way to convert the strings of datetimes to actual datetime objects that I can run comparisons and loc's on. Can someone point me in the right direction?

My naive approach (pseudo) would be to:

  1. Declare 6 array variables (datetime, open, high, low, close, volume) of len(records) in size
  2. Iterate over the records list of lists
  3. Insert each value into the current i of their respective arrays
  4. Once iteration is done, mass convert the values in the datetime array to values of datetime objects?

Wondering if this is really the best way of doing this, or if there's a faster way than O(n) iteration?

CodePudding user response:

You asked, "Once that's done, I need a way to convert the strings of datetimes to actual datetime objects ...". I recently answered a similar question here: https://stackoverflow.com/a/74491722/5739452

Your timestamp looks like this: "2022-11-08 4:00". The time package contains parsing and other manipulation functions. The key detail is knowing the conventions for the layout parser format. Each element of a time is recognized as a specific number. The year is 2006, the month is 11 etc.

So, for your purpose something like this should work:

package main

import (
    "fmt"
    "time"
)

func main() {
    t := "2022-11-08 4:00"
    const layout = "2006-01-02 15:04"
    x, err := time.Parse(layout, t)
    fmt.Println(x, err)
}

CodePudding user response:

You could use a method based approach, like this:

package trading

import (
   "encoding/csv"
   "io"
   "strconv"
   "time"
)

type record []string

func records(r io.Reader) ([]record, error) {
   var recs []record
   raw := csv.NewReader(r)
   for {
      rec, err := raw.Read()
      if err == io.EOF {
         return recs, nil
      } else if err != nil {
         return nil, err
      }
      recs = append(recs, rec)
   }
}

func (r record) time() (time.Time, error) {
   return time.Parse("2006-01-02 15:04", r[0])
}

func (r record) open() (float64, error) {
   return strconv.ParseFloat(r[1], 64)
}
  •  Tags:  
  • go
  • Related