2

私が取り組んでいるこの小さなコードには実用的なアプリケーションがあるとは思いませんが、非同期に頭を悩ませようとしていて、少し苦労しているようです。Yahoo から過去の株価データを取得し、すべてのデータを 1 つの csv ファイルに保存してから、一括コピーを使用して SQL Server に読み込みたいとします。データを SQL Server にロードすることについてはあまり心配していませんが、データを新しい csv ファイルに書き込む方法が気になります。非同期で実行できますか/実行する必要がありますか?

私が知る限り、履歴データを取得するときにストリームの一部としてティッカーを取得する方法がないため、ストリームを取得して、各項目の先頭にティッカーを追加した新しいリストにマッピングしています。テストを実行すると、ティッカーのないレコードと、複数のティッカー ("MSFT, YHOO" など) を持つレコードが得られることがあります。

それで、私の質問は、問題を引き起こさずにこのデータを単一のcsvファイルにダンプするにはどうすればよいですか? 次に、データを分割すると、空のテール アイテムが得られます。それを落とすための最良の方法は何ですか?

私が言ったように、これが実用的なアプリケーションを持っているかどうかはわかりませんが、私は学ぼうとしているので、私の無知を許していただければ幸いです. 助けてくれてありがとう、本当に感謝しています。ここに私が持っているものがあります:

open System
open System.IO
open System.Web
open System.Net

let fromDate = new DateTime(2013, 1, 1)

let getTickers = 
    "MSFT" :: "YHOO" :: []

let getData (ticker : string) = 
    async {
        let url = System.String.Format("http://ichart.finance.yahoo.com/table.csv?s={0}&g=d&ignore=.csv&a={1}&b={2}&c={3}", ticker, fromDate.Month - 1, fromDate.Day, fromDate.Year)

        Console.WriteLine(url)

        let req = WebRequest.Create(url)
        let! rsp = req.AsyncGetResponse()
        use stream = rsp.GetResponseStream()
        use reader = new StreamReader(stream)

        let lines = 
            reader.ReadToEnd().Split('\n')
            |> Seq.skip 1 // skip header
            |> Seq.map (fun line-> (String.Format("{0}, {1}", ticker, line.ToString())))

        Seq.iter (fun x->printfn "%s" (x.ToString())) lines
        ()
    }

let z = 
    getTickers 
    |> List.map getData
    |> Async.Parallel
    |> Async.RunSynchronously
4

1 に答える 1

2

IMO、これはやり過ぎですが、うまくいけば、あなたが知りたいことを示しています。

open System
open System.IO
open System.Net

let tickers = 
  [ 
    "MSFT"
    "YHOO"
  ]

let getData (writer: TextWriter) ticker =
  async {
    let url = sprintf "http://ichart.finance.yahoo.com/table.csv?s=%s&g=d&ignore=.csv" ticker
    let req = WebRequest.Create(url)
    let! resp = req.GetResponseAsync() |> Async.AwaitTask
    use stream = resp.GetResponseStream()
    use reader = new StreamReader(stream)
    let! lines = reader.ReadToEndAsync() |> Async.AwaitTask
    let lines = 
      lines.Split('\n')
        |> Seq.skip 1
        |> Seq.filter ((<>) "") //skip empty lines
    for line in lines do
      do! writer.WriteLineAsync(String.Format("{0}, {1}", ticker, line)).ContinueWith(ignore) |> Async.AwaitTask
  }

let writeAllToFile path =
  use writer = new StreamWriter(path=path)
  tickers
    |> Seq.map (getData writer)
    |> Async.Parallel
    |> Async.RunSynchronously
    |> ignore

writeAllToFile @"C:\quotes.csv"
于 2013-01-10T16:25:42.167 に答える