2

私はF#を数か月に1回程度使用していますが、その間にすべてを忘れているようですので、無知なことをお許しください。以下の私のコードは、Yahooからデータを取得しています。それは私がしなければならないことを表す良い例です。返される最初の行には列見出しがあります。データ(リストの末尾)を取得してデータベースに挿入する必要があります。返された列見出しに基づいて挿入ステートメントを生成する最良の方法は何ですか(列見出しはデータベースの列名と一致します)?

以下の例では、dataWithHeaders。[0] 「Date、Open、High、Low、Close、Volume、AdjClose」が含まれます。その文字列を取り、見出しの周りに角かっこを入れてインサートを作成する必要がありますか?次に、insertDataで値をパラメーターとして追加しますか?よりエレガントな解決策はありますか?

let url = System.String.Format("http://ichart.finance.yahoo.com/table.csv?s={0}&g=d&ignore=.csv", "FB")

let splitLineIntoArray (line : string) = 
    line.Split(",".ToCharArray())

let insertData (data : string[]) =
    // insert data
    ()

let client = new WebClient()
let dataWithHeaders = 
    client.DownloadString(url).Split(Environment.NewLine.ToCharArray())

let data =
    dataWithHeaders
    |> Array.toList
    |> List.tail
    |> List.map(splitLineIntoArray)
    |> List.iter insertData
4

2 に答える 2

8

データをSQLServerにロードする場合は、この優れたCSVリーダー(無料)とSqlBulkCopyクラスを使用できます。シンプルで効率的です。

let loadStockPrices ticker =
  use client = new WebClient()
  let url = sprintf "http://ichart.finance.yahoo.com/table.csv?s=%s&g=d&ignore=.csv" ticker
  use stringReader = new StringReader(client.DownloadString(url))
  use csvReader = new CsvReader(stringReader, hasHeaders=true)
  use con = new SqlConnection("<connection_string>")
  con.Open()
  use bulkCopy = new SqlBulkCopy(con, DestinationTableName="<destination_table>")
  bulkCopy.WriteToServer(csvReader)

宛先テーブルには、受信データ(OHLCなど)と同じ列が必要です。

于 2012-07-26T20:18:16.843 に答える
4

編集:タイププロバイダーは良い方法かもしれませんが、SqlBulkCopyはdefです。そのシンプルさで知られています。

挿入用のプロバイダーコードを入力します:http: //msdn.microsoft.com/en-us/library/hh361033(v = vs.110) .aspx#BKMK_UpdateDB

type dbSchema = SqlDataConnection<"Data Source=MYSERVER\INSTANCE;Initial Catalog=MyDatabase;Integrated Security=SSPI;">
let db = dbSchema.GetDataContext()

// Enable the logging of database activity to the console.
db.DataContext.Log <- System.Console.Out

let newRecord = new dbSchema.ServiceTypes.Table1(Id = 100,
                                                 TestData1 = 35, 
                                                 TestData2 = 2.0,
                                                 Name = "Testing123")
let newValues =
    [ for i in [1 .. 10] ->
          new dbSchema.ServiceTypes.Table3(Id = 700 + i,
                                           Name = "Testing" + i.ToString(),
                                           Data = i) ]
// Insert the new data into the database.
db.Table1.InsertOnSubmit(newRecord)
db.Table3.InsertAllOnSubmit(newValues)
try
    db.DataContext.SubmitChanges()
    printfn "Successfully inserted new rows."
with
   | exn -> printfn "Exception:\n%s" exn.Message

私は似たようなことをしました。実際、Luca BologneseがF#でプレゼンテーションを行うのを見ながら書いたこのコード。これは実際にyahooのフィードをスクレイプし、標準開発者を返します。株価の変動。

ここに完全なプロジェクト:https ://github.com/djohnsonm/Stock-Ticker-App

open System.Net
open System.IO

let internal loadPrices ticker = async {
let url = @"http://ichart.finance.yahoo.com/table.csv?s=" + ticker + "&d=6&e=22&f=2011&g=d&a=2&b=13&c=1986&ignore=.csv"
let req = WebRequest.Create(url)
let resp = req.GetResponse()
let stream = resp.GetResponseStream()
let reader = new StreamReader(stream)
let csv = reader.ReadToEnd()
let prices = 
    csv.Split([|'\n'|])
    |> Seq.skip 1
    |> Seq.map (fun line -> line.Split([|','|]))
    |> Seq.filter(fun values -> values |> Seq.length = 7)
    |> Seq.map(fun values ->
        System.DateTime.Parse(values.[0]),
        float values.[6])
return prices}

type StockAnalyzer (lprices, days) =
    let prices =
        lprices
        |> Seq.map snd
        |> Seq.take days
    static member GetAnalyzers (tickers, days) =
        tickers
        |> Seq.map loadPrices
        |> Async.Parallel
        |> Async.RunSynchronously
        |> Seq.map (fun prices -> new StockAnalyzer(prices, days))
    member s.Return =
        let lastPrice = prices |> Seq.nth 0
        let startPrice = prices |> Seq.nth(days-1)
        lastPrice / startPrice - 1.
    member s.StdDev =
        let logRets =
            prices
            |> Seq.pairwise
            |> Seq.map (fun (x,y) -> log(x/y))
        let mean = logRets |> Seq.average
        let sqr x = x * x
        let var = logRets |> Seq.averageBy (fun r -> sqr (r-mean))
        sqrt var
于 2012-07-26T20:06:25.970 に答える