F# Monkey

about

F#でFXのトレード検証を手軽にできるシステムを作ってみる(その3)

Summary

Oandaサーバーから取得した実際の価格に対して作成した損益算出プログラムを適用してみる

使い方

こんな感じ

module Main =

    let setting : Setting = { 
        Entry      = 138.   /// エントリーする価格
        TakeProfit = 136.   /// 利確する価格
        CutLoss    = 139.   /// 損切りする価格
        Start      = System.DateTime ( 2017,4,3,9,0,0 )    /// 対象期間の開始日時
        Last       = System.DateTime ( 2017,4,13,13,0,0 )  /// 対象期間の終了日時
    }
   
    Oanda.profitAndLoss setting

結果

1 の損失を計上しました〜

Code

最小単位で丸めるのがポイントですっ。かなりはまりました(汗)

#r @"./packages/FSharp.Data/lib/net40/FSharp.Data.dll"
open FSharp.Data

#load @"/./Users/kohei/Documents/01_F#/OANDAfs/oandafs.fsx"
open callmekohei.Oandafs

type Setting = { Entry : float ; TakeProfit : float ; CutLoss : float ; Start : System.DateTime ; Last : System.DateTime }

module Oanda =

    let profitAndLoss (setting:Setting) : unit = 

        (*
            Oanda サーバーからデーターを取得する
        *)
        
        let env   = Environment.Live
        let id    = "your id"
        let token = "your token"
        let info  = API().Init( env, id, token )
        
        let param = [  currency.GPB_JPY                     /// 対象となる通貨
                       granularity.M15                      /// 時間足
                       ("start", setting.Start |> toEET )   /// 開始時刻
                       ("end"  , setting.Last  |> toEET )   /// 終了時刻
                       includeFirst.False                   /// ヘッドは含めない
                       alignmentTimezone.Japan
                       dailyAlignment.H7   
                    ]

        let jsonFromOanda = (Rates(info).Get_History param)


        (*
            取得したデーターを損益が出しやすいように加工する
        *)

        let swapRowColumn lst =
            lst
            |> List.collect List.indexed
            |> List.groupBy fst
            |> List.map snd
            |> List.map (List.map snd)

        let pricesSet =
            JsonValue.Parse jsonFromOanda
            |> fun dt -> dt.GetProperty("candles").AsArray()
            |> Array.map ( fun (x:JsonValue) -> [x.GetProperty("highBid").AsFloat() ; x.GetProperty("lowBid").AsFloat() ])
            |> Array.toList
            |> swapRowColumn

        let highPrices = pricesSet.Item 0
        let lowPrices  = pricesSet.Item 1
        let prices     = (lowPrices,highPrices)
                         /// 高値・安値の間を最小単位で補完する
                         ||>  List.map2 ( fun a b -> [ a .. 0.001 .. b] )
                         ///  最小単位で価格を丸める( ここ重要! )
                         |>   List.map ( fun l -> l |> List.map ( fun n -> System.Math.Round( n , 3 )) )


        (*

            価格に対して自分の仕掛けが掛かっているかどうか
            また掛かっていたらどれだけ損益がでたかを調べる

        *)

        /// util function
        let pricePoint entryPrice prices =
            prices
            |> List.map ( List.tryFind ( fun n -> n = entryPrice) )
            |> List.tryFindIndex ( fun x -> Option.isSome x )

        /// entry ができるかどうか
        let entryPoint = pricePoint setting.Entry prices

        if      entryPoint.IsNone
        then    stdout.WriteLine "エントリーされませんでした"
        else
                /// entry したあとのリストをつくる
                let lst =   prices 
                            |> List.splitAt entryPoint.Value
                            |> snd

                /// tp or cl どちらかが掛かってるかを調べる
                let takeProfitPoint : option<int> = pricePoint setting.TakeProfit lst
                let cutLossPoint    : option<int> = pricePoint setting.CutLoss    lst

                let cutLoss () = 
                    let loss   = System.Math.Abs( setting.Entry - setting.CutLoss )    |> fun n -> System.Math.Round( n , 3 )
                    stdout.WriteLine( string loss   + " の損失を計上しました〜" )

                let takeProfit () =
                    let profit = System.Math.Abs( setting.TakeProfit - setting.Entry ) |> fun n -> System.Math.Round ( n , 3 )
                    stdout.WriteLine( string profit + " の利益を計上しました〜" )

                match takeProfitPoint, cutLossPoint with
                | Some t , Some c when t > c -> cutLoss    ()
                | Some _ , _                 -> takeProfit ()
                | None   , Some _            -> cutLoss    ()
                | _ -> stdout.WriteLine "まだ確定されてません"
Remove all ads