Subscribed unsubscribe Subscribe Subscribe

F# Monkey

about

grep 色情報はいらない〜 はまった〜

Summary

grepで文字列を取り出す時

色情報がついてて

sedしにくかった

Environment

$ sw_vers 
ProductName:    Mac OS X
ProductVersion: 10.12.4
BuildVersion:   16E195


$ uname -v
Darwin Kernel Version 16.5.0:
Fri Mar  3 16:52:33 PST 2017;
root:xnu-3789.51.2~3/RELEASE_X86_64

こんな感じ

cat ./abc.txt | grep -e '#r'
^[[01;31m^[[K#r^[[m^[[K @"./packages/FSharp.Control.Reactive/lib/net45/FSharp.Control.Reactive.dll"
^[[01;31m^[[K#r^[[m^[[K @"./packages/FSharp.Compiler.Service/lib/net45/FSharp.Compiler.Service.dll"
^[[01;31m^[[K#r^[[m^[[K @"./packages/Newtonsoft.Json/lib/net45/Newtonsoft.Json.dll"
^[[01;31m^[[K#r^[[m^[[K @"./packages/FsPickler/lib/net45/FsPickler.dll"
^[[01;31m^[[K#r^[[m^[[K @"./packages/FsPickler.Json/lib/net45/FsPickler.Json.dll"
^[[01;31m^[[K#r^[[m^[[K @"./packages/Suave/lib/net40/Suave.dll"

対策〜

cat ./abc.txt | grep --color=never -e '#r'
#r @"./packages/FSharp.Control.Reactive/lib/net45/FSharp.Control.Reactive.dll"
#r @"./packages/FSharp.Compiler.Service/lib/net45/FSharp.Compiler.Service.dll"
#r @"./packages/Newtonsoft.Json/lib/net45/Newtonsoft.Json.dll"
#r @"./packages/FsPickler/lib/net45/FsPickler.dll"
#r @"./packages/FsPickler.Json/lib/net45/FsPickler.Json.dll"
#r @"./packages/Suave/lib/net40/Suave.dll"
Remove all ads

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

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

adacolaさんに教えてもらったよ〜

Summary

前回の続き

アクティブパターンを使うとif/then/elseが綺麗になるよ、みたいな

code

module FX20170410 =

    /// とりあえず価格はこんな感じでつくってみる
    let highPrices = [99. .. -1. .. 92.]
    let lowPrices  = [97. .. -1. .. 90.]
    let dayprices  = List.map2 ( fun a b -> [a .. 0.001 .. b] ) lowPrices highPrices 

    /// entry ,tp, cl に対しての情報
    type Info = { Entry : float ; TakeProfit : float ; CutLoss : float }

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

    let info : Info = { Entry = 99. ; TakeProfit = 95. ; CutLoss = 100. }

    /// entry ができるかどうか
    let entryPoint : option<int> = pricePoint info.Entry dayprices

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

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

            let cutLoss () = 
                let loss   = System.Math.Abs( info.Entry - info.CutLoss )
                stdout.WriteLine( string loss   + " の損失を計上しました〜" )

            let takeProfit () =
                let profit = System.Math.Abs( info.TakeProfit - info.Entry )
                stdout.WriteLine( string profit + " の利益を計上しました〜" )

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

結果

4 の利益を計上しました〜

感想

ここをチェック〜

yukitosさん、bleisさん、adacolaさん。ありがとうございます!

gitter.im

Remove all ads

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

Summary

手軽にトレーディングアイディアを試せるシステムをつくってみる!

Motivation

FXトレードの幅がひろがるんじゃないかと・・(もっともっとお金ほしい〜)

今回の骨子

とりあえず下記2つをやってみました

ある価格にたいして

1 entry できる場所があるかどうか
2 takeprofit or cutloss の場所があるかどうか

Code

こんな感じ

module FX20170410 =
    

    /// とりあえず価格はこんな感じでつくってみる
    let lowPrices  = [97. .. 104.]
    let highPrices = [99. .. 106.]
    let dayprices  = List.map2 ( fun a b -> [a .. 0.001 .. b] ) lowPrices highPrices 
    
    /// entry ,tp, cl に対しての情報
    type Info = { Entry : float ; TakeProfit : float ; CutLoss : float }
    
    /// util function
    let pricePoint entryPrice prices =
        prices
        |> List.map ( List.tryFind ( fun n -> n = entryPrice) )
        |> List.tryFindIndex ( fun x -> Option.isSome x )


    /// ---------------------------------------------------------------------


    /// エントリーは100, 利確は105, 損切りは95とする
    let info : Info = { Entry = 100. ; TakeProfit = 105. ; CutLoss = 95. }

    /// entry ができるかどうか
    let entryPoint : option<int> = pricePoint info.Entry dayprices

    if entryPoint.IsSome then
        /// entry したあとのリストをつくる
        let lst =   dayprices 
                    |> List.splitAt entryPoint.Value
                    |> snd
        
        /// tp or cl どちらかが掛かってるかを調べる
        let takeProfitPoint : option<int> = pricePoint info.TakeProfit dayprices
        let cutLossPoint    : option<int> = pricePoint info.CutLoss dayprices

        if  takeProfitPoint.IsSome && cutLossPoint.IsSome then
            stdout.WriteLine "*****"
        elif  takeProfitPoint.IsSome then
            let profit = info.TakeProfit - info.Entry
            stdout.WriteLine( string profit + " の利益を獲得しました〜" )
        elif  cutLossPoint.IsSome then
            stdout.WriteLine "*****"
        else
            stdout.WriteLine "*****"
    else
        stdout.WriteLine "エントリーされませんでした"

結果

5 の利益を獲得しました〜

*** time : 0.139117 s ***

感想

まだまだ何もわかってないのでちょっとずつ作っていきたいです!

Remove all ads

OANDA API からデーター取得のメモ

最新のローソク足を取得

1時間足のローソク足を2本取得する

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

let env   = Environment.Live
let id    = "**********"
let token = "**********"
let info  = API().Init( env, id, token )

let param = [   currency.GPB_JPY         /// 対象となる通貨
                granularity.H1           /// 時間足
                ("count","2")            /// 取得したいローソク足の本数
                 
                /// ここはおまじない
                alignmentTimezone.Japan  /// タイムゾーンはJST
                dailyAlignment.H7        /// ヘッドを調整
            ]

Rates(info).Get_History param |> printfn "%s"

結果

{
    "instrument" : "GBP_JPY",
    "granularity" : "H1",
    "candles" : [
        {
            "time" : "2017-04-07T19:00:00.000000Z",
            "openBid" : 137.583,
            "openAsk" : 137.612,
            "highBid" : 137.723,
            "highAsk" : 137.753,
            "lowBid" : 137.512,
            "lowAsk" : 137.539,
            "closeBid" : 137.571,
            "closeAsk" : 137.598,
            "volume" : 8103,
            "complete" : true
        },
        {
            "time" : "2017-04-07T20:00:00.000000Z",
            "openBid" : 137.57,
            "openAsk" : 137.598,
            "highBid" : 137.622,
            "highAsk" : 137.655,
            "lowBid" : 137.327,
            "lowAsk" : 137.378,
            "closeBid" : 137.372,
            "closeAsk" : 137.448,
            "volume" : 6087,
            "complete" : true
        }
    ]
}

期間を指定してローソク足を取得

期間:2017/4/3 9時から12時までローソク足3本取得する

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

let env   = Environment.Live
let id    = "********"
let token = "********"
let info  = API().Init( env, id, token )

let startDate = System.DateTime( 2017,4,3,9,0,0)  |> toEET /// 日本の時刻をヨーロッパの時刻に変換する
let endDate   = System.DateTime( 2017,4,3,13,0,0) |> toEET /// 日本の時刻をヨーロッパの時刻に変換する

let param = [  currency.GPB_JPY     /// 対象となる通貨
               granularity.H1       /// 時間足
               ("start",startDate)  /// 開始時刻
               ("end"  , endDate )  /// 終了時刻
               includeFirst.False   /// ヘッドは含めない
               
               /// おまじない
               alignmentTimezone.Japan
               dailyAlignment.H7   
            ]

Rates(info).Get_History param |> printfn "%s"

結果

{
    "instrument" : "GBP_JPY",
    "granularity" : "H1",
    "candles" : [
        {
            "time" : "2017-04-03T03:00:00.000000Z",
            "openBid" : 139.66,
            "openAsk" : 139.689,
            "highBid" : 139.717,
            "highAsk" : 139.754,
            "lowBid" : 139.516,
            "lowAsk" : 139.546,
            "closeBid" : 139.553,
            "closeAsk" : 139.583,
            "volume" : 4431,
            "complete" : true
        },
        {
            "time" : "2017-04-03T04:00:00.000000Z",
            "openBid" : 139.547,
            "openAsk" : 139.577,
            "highBid" : 139.686,
            "highAsk" : 139.717,
            "lowBid" : 139.544,
            "lowAsk" : 139.575,
            "closeBid" : 139.625,
            "closeAsk" : 139.656,
            "volume" : 4323,
            "complete" : true
        },
        {
            "time" : "2017-04-03T05:00:00.000000Z",
            "openBid" : 139.625,
            "openAsk" : 139.655,
            "highBid" : 139.89,
            "highAsk" : 139.922,
            "lowBid" : 139.623,
            "lowAsk" : 139.654,
            "closeBid" : 139.724,
            "closeAsk" : 139.758,
            "volume" : 5534,
            "complete" : true
        }
    ]
}
Remove all ads

.NETの時間表記のちょっとしたメモ

f:id:callmekohei00:20170409234100p:plain

Summary

.netの時間表記のちょっとしたメモ

code

こんな感じ

open System

/// このパソコンのタイムゾーンの確認
System.TimeZoneInfo.Local.Id |> printfn "%A" /// "Asia/Tokyo"


/// このパソコンに入ってるタイムゾーンの確認
System.TimeZoneInfo.GetSystemTimeZones()
|> Seq.iter ( fun n -> stdout.WriteLine n )

/// Africa/Abidjan
/// Africa/Accra
/// Africa/Addis_Ababa
/// ....




/// 日付をRFC3339形式にする関数
let toRFC3339 dt =
    System.Xml.XmlConvert.ToString( dt, System.Xml.XmlDateTimeSerializationMode.Utc )


/// RFC3339形式を普通の日付形式にする関数
let toDate rfc3339 =
    System.DateTime.Parse(rfc3339)





/// (JST)2017年4月9日11時という時刻
let JST = DateTime( 2017,4,9,11,0,0 )

JST |> stdout.WriteLine              /// 4/9/2017 11:00:00 AM
JST |> toRFC3339 |> stdout.WriteLine /// 2017-04-09T11:00:00Z


/// Convert UTC ( JST = UTC + 9 )
let UTC = JST |> System.TimeZoneInfo.ConvertTimeToUtc

UTC |> stdout.WriteLine              /// 4/9/2017 2:00:00 AM
UTC |> toRFC3339 |> stdout.WriteLine /// 2017-04-09T02:00:00Z


/// Convert EET ( EET = UTC + 3 summer, UTC + 2 winter )
let easternZone = TimeZoneInfo.FindSystemTimeZoneById("Europe/Rome")
let EET         = System.TimeZoneInfo.ConvertTime( JST ,easternZone )

EET |> stdout.WriteLine              /// 4/9/2017 4:00:00 AM
EET |> toRFC3339 |> stdout.WriteLine /// 2017-04-09T04:00:00Z
Remove all ads

5分でNeovimでF#を書く方法

f:id:callmekohei00:20170404114941p:plain

Summary

5分でNeovimF#Hello Worldしてみる〜

Environment

$ sw_vers
ProductName:    Mac OS X
ProductVersion: 10.12.3
BuildVersion:   16D32

Prepare

terminalを立ち上げる

Finder を立ち上げて

/Applications/Utilities/Terminal.app をダブルクリック

Homebrew をインストール

$ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

monoをインストール

$ brew install mono

Neovimをインストール

$ brew install neovim

Python3をインストール

$ brew install python3
$ pip3 install --upgrade pip3 setuptools
$ sudo -H pip3 install --upgrade -I neovim

Setting

Neovimの設定( init.vim をつくる )

// create nvim folder and init.vim file
$ mkdir .config/nvim
$ vim   .config/nvim/init.vim

init.vimは、たとえばこんな感じ

"----------------------------------------------------------
" Plugin manager ( Shougo/dein.vim )
"----------------------------------------------------------

let s:dein_dir = $HOME . '/.config/nvim/dein'
let s:toml     = $HOME . '/.config/nvim/dein.toml'

let s:dein_repo_dir = s:dein_dir . '/repos/github.com/Shougo/dein.vim'

if !isdirectory(s:dein_repo_dir)
  execute '!git clone https://github.com/Shougo/dein.vim' s:dein_repo_dir
endif

    execute 'set runtimepath+=' . s:dein_repo_dir

if dein#load_state(s:dein_dir)
    call dein#begin(s:dein_dir)
    call dein#load_toml(s:toml, {'lazy': 0})
    call dein#end()
    call dein#save_state()
endif

if dein#check_install()
    call dein#install()
endif

filetype plugin indent on
syntax   enable


"----------------------------------------------------------
" Neovim's Python provider
"----------------------------------------------------------
let g:python_host_prog  = '/usr/local/bin/python'
let g:python3_host_prog = '/usr/local/bin/python3'

"----------------------------------------------------------
" General
"----------------------------------------------------------
" Tab
set shiftwidth=4            "vimが自動でインデントを行った際、設定する空白数
set tabstop=4               "<TAB>を含むファイルを開いた際、<TAB>を何文字の空白に変換するかを設定
set softtabstop=4           "キーボードで<TAB>を入力した際、<TAB>を何文字の空白に変換するかを設定
set expandtab               "タブ文字を空白に設定する。shofttabstopとセットで使用すると便利

" Clipbord
set clipboard+=unnamedplus  " use clipboard ( see : help clipboard )

set nowrap
set number
set noswapfile

"----------------------------------------------------------
" Seek
"----------------------------------------------------------
set wrapscan
set ignorecase
set smartcase
nnoremap <silent> <C-l> :nohlsearch<CR>

"----------------------------------------------------------
" Appearance
"----------------------------------------------------------
colorscheme birds-of-paradise

" English menu display
source $VIMRUNTIME/delmenu.vim
set    langmenu=none
source $VIMRUNTIME/menu.vim

if has("multi_lang")
    language en_gb
endif

"----------------------------------------------------------
" Char code
"----------------------------------------------------------
set encoding=utf-8
set fileencodings=utf-8,iso-2022-jp,euc-jp,sjis

"----------------------------------------------------------
" Key binding
"----------------------------------------------------------
inoremap <S-Tab> <BS>

" hjkl in insert mode
" see : https://github.com/neovim/neovim/wiki/FAQ#my-ctrl-h-mapping-doesnt-work
inoremap <C-h> <Left>
inoremap <C-j> <Down>
inoremap <C-k> <Up>
inoremap <C-l> <Right>

pluginの設定 ( dein.toml をつくる )

// create dein folder and dein.toml file
$ mkdir .config/nvim/dein
$ vim   .config/nvim/dein.toml

dein.tomlは、たとえばこんな感じ

#----------------------------------------------------------
# Shougo ware
#----------------------------------------------------------

[[plugins]]
repo = 'Shougo/dein.vim'

[[plugins]]
repo = 'Shougo/denite.nvim'

[[plugins]]
repo = 'Shougo/deoplete.nvim'
hook_add = '''
    let g:deoplete#enable_at_startup = 1
    let g:deoplete#max_list = 1000
    set previewheight=5
'''

[[plugins]]
repo = 'callmekohei/deoplete-fsharp'

#----------------------------------------------------------
# Color scheme
#----------------------------------------------------------

[[plugins]]
repo = 'ronny/birds-of-paradise.vim'

[[plugins]]
repo = 'cespare/vim-toml'


#----------------------------------------------------------
# Quickrun
#----------------------------------------------------------

[[plugins]]
repo = 'thinca/vim-quickrun'
hook_add = '''
    set splitright
    let g:quickrun_config = {
    \
    \     '_' : {
    \           'hook/output_encode/enable'       : 1
    \         , 'hook/output_encode/encoding'     : 'utf-8'
    \         , 'hook/time/enable'                : 1
    \         , 'hook/time/format'                : "\n*** time : %g s ***"
    \         , 'hook/time/dest'                  : ''
    \         , "outputter/buffer/split"          : 'vertical'
    \         , 'outputter/buffer/close_on_empty' : 1
    \     }
    \     , 'fsharp': {
    \           'exec'   :  [ 'fio %s:p:r.fsx' ]
    \         , 'command':  'fio'
    \     }
    \ }

    au FileType qf nnoremap <silent><buffer>q :quit<CR>
'''

F#を手軽に実行できるようにする ( fio コマンドをつくる )

$ vim fio

fioの中身

urlencoded_str=$(curl -s -w '%{url_effective}\n' --data-urlencode $1 -G '')
urlencoded_str=${urlencoded_str:2}
curl -s 'localhost:8080/evalScript/'${urlencoded_str}

fio コマンドをbinに移動

$ chmod 777 fio
$ sudo mv fio /usr/local/bin

F#を実行してみる!

$ nvim abc.fsx

F#のコード

"hello" |> stdout.Write

escをおして:Quickrunと入力しリターン

// 右側に表示される
hello

感想

5分では無理か・・・ (^_^;

Remove all ads

(ポエム)テキストエディタとビール

f:id:callmekohei00:20170329115027p:plain

あれもこれもと言うけどさ
大人の事情だと言うけどさ
そうじゃないんだ


頭がいいとか悪いとか
賢しいとか要領がとか
そうじゃないんだ


泥臭く泥臭く
まっさらなエディタの上に
コードを書いて実行をして


自分がしたいことを
表現してみせるんだ
テキストエディタで


人も景色も変わるけど
今日も元気だ
ビールがうまい
Remove all ads

F# on RX

f:id:callmekohei00:20170325142408p:plain

Prepare01 ( Library )

source https://www.nuget.org/api/v2

nuget FSharp.Control.Reactive
nuget system.reactive

Prepare02 ( required )

F#のコードにRxライブラリを取り込むのはこんな感じ

#r @"./packages/System.Reactive.Core/lib/net46/System.Reactive.Core.dll"
#r @"./packages/System.Reactive.Linq/lib/net46/System.Reactive.Linq.dll"
#r @"./packages/System.Reactive.Interfaces/lib/net45/System.Reactive.Interfaces.dll"
#r @"./packages/System.Reactive.PlatformServices/lib/net46/System.Reactive.PlatformServices.dll"
#r @"./packages/FSharp.Control.Reactive/lib/net45/FSharp.Control.Reactive.dll"

open System                  // System.EventArgs, System.Timers.ElapsedEventArgs
open System.Reactive.Linq    // IGroupedObservable
open FSharp.Control.Reactive // Observable methods

Rx overview

Rxの勘所〜

IObservable<'T> とは string とか List とかと同じタイプの一種

IObservable<string><string> とは IObservable の中身が string ということ

"Hello" という string を IObservable<string> にするには Observable.single "hello world"

Intro

Rxとはこんな感じ〜

// プリント関数
let oStdout ( obs:IObservable<'T> ) = 
    obs
    /// 全てのIObservableに対しての操作が終わったら`-----`を印字する
    |> Observable.finallyDo( fun _ -> stdout.WriteLine("-------------") )
    /// IObservableを印字する
    |> Observable.subscribe( fun x -> stdout.WriteLine(x) )


Observable.single "hello world"
|> oStdout

Observable.single "hello world"
|> Observable.map ( fun s -> s.ToUpper() )
|> oStdout

Observable.single "hello world"
|> Observable.concat ( Observable.single "callmekohei" )
|> oStdout

結果

hello world
-------------
HELLO WORLD
-------------
hello world
callmekohei
-------------

Event with Rx

IEvent<_>IObservable<_>と同じ感覚でオーケー

// イベントをインスタンス化
let e = Event<_>()

// イベントを実体化する
e.Publish
// イベントハンドラを登録する
// イベントハンドラとはイベントを実行するときに行う操作のこと
|> Observable.add( fun (e:string) -> stdout.WriteLine(e) )

// イベントを実行する
e.Trigger("hello world")

結果

hello world


IEvent<ElapsedEventHandler,ElapsedEventArgs>IObservable<_>と同じ感覚でオーケー

/// file name is timer.fsx
open System.Timers

// イベントをインスタンス化
let timer = new Timer(1000.)

/// イベントを実体化
timer.Elapsed
/// イベントハンドラを登録
|> Observable.add (fun (e:ElapsedEventArgs) -> printfn "%A"( e.SignalTime ))

// イベントを実行(1000msごとにイベントを実行する)
timer.Start()

stdout.WriteLine("please enter key...")

/// dispose method call
stdin.ReadLine()
stdout.WriteLine("dispose method call.")

/// イベントを破棄する(メモリクリアする)<--- これ重要!
timer.Disposed

結果

$ fsharpi timer.fsx 
please enter key...
3/25/2017 1:41:42 PM
3/25/2017 1:41:43 PM
3/25/2017 1:41:44 PM
3/25/2017 1:41:45 PM
3/25/2017 1:41:46 PM

dispose method call.

Observable methods

いろいろなメソッド〜

//----------------------------------------------------------------------------
// single, toObservable and generate
//

"hello world"
|> Observable.single
|> oStdout
/// hello world

["hello world"]
|> Observable.toObservable
|> oStdout
/// hello world

Observable.generate 0 (fun i -> i < 3) ( fun i -> i + 1 ) ( fun i -> i * i )
|> oStdout
/// 0
/// 1
/// 4


//----------------------------------------------------------------------------
// apply, defer
//

["hello world"]
|> Observable.toObservable
|> Observable.apply ( Observable.toObservable ( [fun s -> s.ToUpper()] ) )
|> oStdout
/// HELLO WORLD

fun _ -> Observable.single "hello world"
|> Observable.defer
|> oStdout
/// hello world


//----------------------------------------------------------------------------
// map, collect, flatmap and filter
//

"hello world"
|> Observable.single
|> Observable.map ( fun s -> s.ToUpper() )
|> oStdout
/// HELLO WORLD

["hello world"]
|> Observable.toObservable
|> Observable.thenMap ( fun s -> s.ToUpper() )
|> fun x -> [x]
|> Observable.joinWhen
|> oStdout
/// HELLO WORLD

["hello";"world"]
|> Observable.collect (fun s -> Observable.single ( s.ToUpper() ) )
|> oStdout
/// HELLO
/// WORLD

["hello";"world"]
|> Observable.toObservable
|> Observable.flatmap (fun s -> Observable.single ( s.ToUpper() ) )
|> oStdout
/// HELLO
/// WORLD

["hello";"world"]
|> Observable.toObservable
|> Observable.filter (fun s -> s = "hello" )
|> oStdout
/// hello


//----------------------------------------------------------------------------
// concat 
//

Observable.single "hello"
|> Observable.concat ( Observable.single "world" )
|> oStdout
// hello
// world


//----------------------------------------------------------------------------
// iter, finallyDo 
//

["hello";"world"]
|> Observable.toObservable
|> Observable.iter ( fun _ -> stdout.WriteLine("---------") )
|> oStdout
/// ---------
/// hello
/// ---------
/// world


["hello";"world"]
|> Observable.toObservable
|> Observable.finallyDo ( fun _ -> stdout.WriteLine("---------") )
|> oStdout
/// hello
/// world
/// ---------


//----------------------------------------------------------------------------
// reduce and fold 
//

["hello";"world"]
|> Observable.toObservable
|> Observable.reduce ( fun a b -> a + " " + b )
|> oStdout
/// hello world

["hello";"world"]
|> Observable.toObservable
|> Observable.fold ( fun acc s -> acc + " " + s |> fun s -> s.TrimStart(' ') ) ""
|> oStdout
/// hello world


//----------------------------------------------------------------------------
// zip
//

(Observable.single "hello", Observable.single "world")
||> Observable.zip
|>  oStdout
/// (hello, world)



//----------------------------------------------------------------------------
// repeatCount
//

["I";"want";"to";"eat";"icecream"]
|> Observable.toObservable
|> Observable.repeatCount 2
|> Observable.subscribe( fun (obs:IObservable<string>) ->
    obs |> Observable.subscribe( fun obs' -> stdout.WriteLine(obs') ) |> ignore
    () )

/// I
/// want
/// I
/// to
/// want
/// eat
/// to
/// icecream
/// eat
/// icecream


//----------------------------------------------------------------------------
// groupBy
//

["hello";"world";"callmekohei"]
|> Observable.toObservable
|> Observable.groupBy ( fun s -> s.Length < 6 )
|> Observable.subscribe ( fun (g:IGroupedObservable<bool,string>) -> stdout.WriteLine( string(g.Key) , g |> oStdout))
/// True
/// hello
/// world
/// False
/// callmekohei


//----------------------------------------------------------------------------
// others
//

["hello";"world"]
|> Observable.toObservable
|> Observable.head
|> oStdout
/// hello

["hello";"world"]
|> Observable.toObservable
|> Observable.first
|> oStdout
/// hello

["hello";"world"]
|> Observable.toObservable
|> Observable.last
|> oStdout
/// world

["hello";"world"]
|> Observable.toObservable
|> Observable.elementAt 1
|> oStdout
/// world

["hello";"world"]
|> Observable.toObservable
|> Observable.contains "hello"
|> oStdout
/// True

["hello";"world"]
|> Observable.toObservable
|> Observable.exists ( fun s -> s = "hello" )
|> oStdout
/// True

["hello";"world"]
|> Observable.toObservable
|> Observable.count 
|> oStdout
/// 2

["hello";"world";"hello";"world"]
|> Observable.toObservable
|> Observable.distinct 
|> oStdout
/// hello
/// world

Observable.range 1 10 
|> Observable.skip 3
|> Observable.take 3
|> oStdout
// 4
// 5
// 6

Observable.range 1 10
|> Observable.skipWhile( fun i -> i < 5 )
|> Observable.takeWhile( fun i -> i < 10 )
|> oStdout
// 5
// 6
// 7
// 8
// 9

Observable.range 1 10
|> Observable.maxOf
|> oStdout
/// 10


Observable.range 1 10
|> Observable.all ( fun n -> n % 2 = 0 )
|> oStdout
// False

Observable.empty 
|> Observable.any 
|> oStdout
// False


//----------------------------------------------------------------------------
// error raise
//

Observable.throw ( exn "エラーだよ" )
|> oStdout
/// エラーだよ

Observable methods ( async )

いろいろなメソッド〜 その2( async )




    
  
Remove all ads

F#言語を使ってロト6を当ててみる!(予測編)

f:id:callmekohei00:20170319155858p:plain

Summary

データーベースSqliteに保存されてる当選番号をもとに予測する

まずは・・・

スロットという考え方

たとえば 01 09 11 24 29 42 という当選番号は下記のように考えます

スロット1  01
スロット2  09
スロット3  11
スロット4  24
スロット5  29
スロット6  42

ゾーンという考え方

ロト61から43までの数字を3つに区分します

ゾーン1  01 - 15
ゾーン2  16 - 30
ゾーン3  31 - 43

予測の方法

ランダムリストの作成

過去の当選番号をスロットごとにリスト化します

スロット毎に数字をランダムに選びます

スロット1で`10`を選んだらスロット2は`11`以上の数字をランダムに選びます

ランダムリストの選別

ゾーンをランダムに作成します(たとえば`2 1 3`)

先ほど作成したランダムリストから、先ほど作成したゾーンに適合するもののみフィルターします

5個のランダムリストを選びます

あたるかどうか

わかりませんwww

一応コード

こんな感じ

module Main =
    open Util
    
    /// (STEP1) 各スロットごとの数字をリストにまとめる

    let cq = new ConcurrentQueue<int list>()
            
    let s = @"SELECT * FROM loto6"

    let f2 = fun (r:SQLiteDataReader) -> 
        [2..7]
        |> List.map( fun n -> r.GetInt32(n) )
        |> fun l -> cq.Enqueue l
        |> ignore
    
    let data =    
        let db = SQ3( sqlite_connection )
        db.sqlite_open
        db.sqlite_select s f2 
        cq.ToArray() |> Array.toList |> swapRowColumn

    
    /// (STEP2) 各ゾーンの個数にもとづいて予測する
    
    let idea04 (loto:Loto) (n:int) =

        let zone = createZone loto

        Seq.initInfinite (fun _ -> createAscendantRandomList data )
        |> Seq.filter (fun l -> toZone loto l = zone )
        |> Seq.distinct
        |> Seq.take n

    idea04 loto6 5
    |> Seq.fold ( fun acc l -> prettyPrint " " l + "\n" + acc ) ""
    |> stdout.WriteLine


コードはこちらから〜

当たるも八卦当たらぬも八卦 · GitHub



Good Luck!

Remove all ads

F#言語を使ってロト6を当ててみる!(データーベース登録編)

f:id:callmekohei00:20170319150912p:plain

Summary

取得した当選番号をデーターベースSqliteに保存する

First Step

FSharp.Data, System.Data.SQLitenugetします

osxの人はここを参考にlibSQLite.Interop.dylibも用意します

F#からSQLiteをつかってみる を一読してF#からSqliteに対しての操作をつかんでください

Second Step

データーベースファイルをあらかじめ作成します

テーブル名をloto6とします

/// loto.sqlite3という名前のデーターベースファイルを作成
$ sqlite3 loto.sqlite3

/// カラムをid, date, n1~n6 として作成
/// id は key とします ( key は重複ができない値です )
sqlite> create table loto6 ( id int primary key, date text , n1 int, n2 int, n3 int, n4 int, n5 int, n6 int );

/// 作業を終了します
sqlite> .exit

Third Step

次のような感じで当選情報をデーターベースに登録します

webの当選情報の当選回数とデーターベースの`id`を比較します

不足してる当選情報のsqlを作成します

データーベースに登録します

当選情報とidの比較

最新のidをデーターベースから取得します

sqliteのメソッドは返り値を返さないのでConcurrentQueueを使って返り値を取得します

/// 最新のid をデーターベースから取得する関数
let lastID_sqlite (db:SQ3) : int =

    let cq = new ConcurrentQueue<_>()

    let str = @"SELECT id FROM loto6"

    let f = fun (r:SQLiteDataReader) -> 
        cq.Enqueue ( r.GetInt32(0) ) |> ignore

    db.sqlite_open
    db.sqlite_select str f
    db.sqlite_close 

    cq.ToArray()
    |> fun arr ->
        if Array.isEmpty arr
        then 0
        else Array.max arr

sqlの作成

/// みずほ銀行のホームページから取得した当選情報
["1157"; "2017/03/16"; "05"; "17"; "20"; "28"; "39"; "42"]

/// ↓↓↓↓↓↓↓

/// データーベースに登録するための文字列(sql)
"INSERT INTO loto6 ( id, date, n1, n2, n3, n4, n5, n6 ) VALUES ('1157','2017/03/16','05','17','20','28','39','42')"

sqlを作成する関数

/// データーベースに登録するための当選情報の文字列を作成する関数 
let atariList atariData : string list =
    let str = @"INSERT INTO loto6 ( id, date, n1, n2, n3, n4, n5, n6 ) VALUES ("
    atariData
    |> List.map( fun l -> l |> List.fold ( fun acc s -> acc + "," + "'" + s + "'" |> fun s -> s.TrimStart(',') ) "" )
    |> List.map( fun s -> str + s + ")" )

データーベースへの登録

データーベースに登録する関数

/// データーベースに当選番号情報を登録する関数
let register (db:SQ3) atariStringsList : unit =
    db.sqlite_open
    atariStringsList |> List.iter ( fun s -> db.sqlite_insert s )
    db.sqlite_close

Code

今回書いたコードはこちら〜

みずほ銀行のホームページから取得したロト6の当選番号情報をデーターベースに登録するスクリプト · GitHub

参考

www.dbonline.jp

qiita.com

Remove all ads

F#言語を使ってロト6を当ててみる!(当選番号取得編)

f:id:callmekohei00:20170319095445p:plain

Summary

みずほ銀行のホームページから過去の当選番号を取得する

First Step

まずFSharp.Datanugetします

Second Step

こんな感じでデーター取得します

/// FSharp.Data.dll にパスをとおします
#r @"./packages/FSharp.Data/lib/net40/FSharp.Data.dll"
open FSharp.Data

/// 当選番号の書いてあるホームページアドレス
let url = @"http://www.mizuhobank.co.jp/takarakuji/loto/loto6/index.html"
/// 当選番号が書いてある css selector
let css = @"table.typeTK > tbody > tr > td.alnCenter.extension > strong"

/// HTMLを取得します 文字コードは utf-8 にしときます(文字化け対策)
Http.RequestString( url , responseEncodingOverride = "utf-8")

/// HTMLをF#で扱えるようにパース(構文解析)します
|> HtmlDocument.Parse

/// 当選番号が書いてある行を取り出します
|> fun doc -> doc.CssSelect( css )

/// 当選番号をとりだします
|> List.map ( fun n -> n.InnerText() )

/// ボーナス数字も含めた7つのくくりでリストをつくります
|> List.chunkBySize 7

/// ボーナス数字をカットします
|> List.map ( List.truncate 6 )

/// 表示します
|> List.iter( fun l -> printfn "%A" l )

結果

["05"; "17"; "20"; "28"; "39"; "42"]
["03"; "06"; "19"; "31"; "35"; "40"]
["14"; "19"; "22"; "23"; "28"; "43"]
["08"; "12"; "30"; "36"; "41"; "42"]
["04"; "15"; "20"; "24"; "26"; "30"]

Advance

先ほど作ったコードを使いやすくします

こんな感じで使えるようにします

#load @"./mizuho.fsx"
open mizuho.Mizuho

Atari loto6_head |> printfn "%A"

結果

[["1157"; "2017/03/16"; "05"; "17"; "20"; "28"; "39"; "42"];
 ["1156"; "2017/03/13"; "03"; "06"; "19"; "31"; "35"; "40"];
 ["1155"; "2017/03/09"; "14"; "19"; "22"; "23"; "28"; "43"];
 ["1154"; "2017/03/06"; "08"; "12"; "30"; "36"; "41"; "42"];
 ["1153"; "2017/03/02"; "04"; "15"; "20"; "24"; "26"; "30"]]


mizuho.fsxのコードはこちら〜

みずほ銀行のホームページから当選番号を取得するスクリプト · GitHub

mizuho.fsx のちょっとした解説

ちかいうちに書きます・・・

Remove all ads

F#言語を使ってロト6を当ててみる!(心構え編)




LOTO6


Summary

ロト6を当てておいしいお寿司たべたいですっ

というか以前に書いた、R言語を使ってロト6を当ててみる! でロト6を予測するのはcallmekohei的には不可能と思ってたり、、、

でもでもでも、ロト6当てたいのです

というわけで懲りもせずに今度はF#というプログラミング言語を使って予想してみたいとおもいまふ〜

こんな感じで

その1:みずほ銀行のホームページから過去の当選番号を取得する

その2:取得した当選番号をデーターベースSqliteに保存する

その3:データーベースSqliteに保存されてる当選番号をもとに予測する

こんな人にオススメ〜

F#に興味ある人

F#を使ったwebスクレイピングに興味ある人

F#Sqliteを使いたい人

ロト6でおすし食べたい人

コードなど

ここにすべて置いてますっ

github.com

Remove all ads

友達がいないのでパソコンにこんにちはと言ってもらうようにしたった

f:id:callmekohei00:20170318074536p:plain

Summary

callmekoheiと自分の名前を打ち込んだら、こんにちは callmekoheiと返事してもらえるプログラムを作ったった

Motivation

と、友達がいないから・・・(泣

Code

ほとんどが定型コード。コピペでオーケー(^_^)/

/// インタラクティブ・コンソール・アプリの定型パターン
module InteractiveConsole =

    type PrinterAgent() =
        let inbox = MailboxProcessor.Start( fun inbox ->
            let rec loop () = async {
                let! (msg: Choice<string,AsyncReplyChannel<unit>>) = inbox.Receive()
                match msg with
                | Choice1Of2 (s: string) ->
                    System.Console.WriteLine s
                    return! loop ()
                | Choice2Of2 ch ->
                    ch.Reply ()
                }
            loop ()
        )

        member x.WriteLine(s) = inbox.Post (Choice1Of2 s)
        member x.Quit()       = inbox.PostAndReply(fun ch -> Choice2Of2 ch)

    let agent = new PrinterAgent()

    let rec main f str =
        match str with
        | "exit" | "quit" -> agent.Quit()
        | _      -> 
            agent.WriteLine( f str )
            main f ( stdin.ReadLine() )

module ABC =
    
    /// ここに自分のつくったコードを書く!
    let hello (s:string) :string =
        "hello! " + s

    [<EntryPointAttribute>]
    let entry argv =
        try
            InteractiveConsole.main hello ""
            0
        with e ->
            stdout.WriteLine( e.Message )
            0

実行のしかた

// 上のコードをコピペ
$ vim abc.fsx

// コンパイル
$ fsharpc abc.fsx

// 実行
$ mono abc.exe

// 自分の名前を入力する
callmekohei
hello! callmekohei // 返事が返ってくる!

// プログラムを終了する
quit
Remove all ads

(F#) async のメモ

Async<'T>に関してのちょっとしたメモ

0. Prepare

async{...} とすると Async<'T>になる

.

let!とかdo!とかのbang!Asyncをはぎとる。つまりAsync<’T>’Tに、Async<Async<’T>>Async<’T>`になる。

1. RunSynchronously and Start

async blockをバックグラウンドで実行させるかどうかのメソッド .

バックグラウンドで実行させない

// always hello world

async{
    stdout.WriteLine("hello")
}|> Async.RunSynchronously

stdout.WriteLine("world")

バックグラウンドで実行させる

// hello world or world hello or world

async{
    stdout.WriteLine("hello")
}|> Async.Start

stdout.WriteLine("world")

2. Parallel

実行順序は保証されない

// hello world or world hello
let hello1 = async { stdout.WriteLine("hello") }
let world1 = async { stdout.WriteLine("world") }

[hello1;world1]
|> Async.Parallel
|> Async.RunSynchronously

実行順序は保証されないがリストの場所は保証される

// ["hello";"world"]
let hello2 = async { return "hello" }
let world2 = async { return "world" }

[hello2;world2]
|> Async.Parallel
|> Async.RunSynchronously
|> printfn "%A"

3. Order in async block

async blockの中は上から下に実行される

// hello world

let hello = async { do stdout.WriteLine("hello") }
let world = async { do stdout.WriteLine("world") }

async {
    do! hello
    do! world
} |> Async.RunSynchronously

4. Wait async (StartChild)

StartChildを使うことでasync blockの中でAsync<'T>をバックグラウンド処理できるようになる

let wakeUp = async {
    do! Async.Sleep(1500)
    do stdout.WriteLine("Wake up!")
}

let goodMorning = async { stdout.WriteLine("goodMorning") }
let iamSleep    = async { stdout.WriteLine("zzz...") }

async { 
    let! (iamWakeUp:Async<unit>) = Async.StartChild( wakeUp, 100 )
    try
        do! iamWakeUp
    with :? exn ->
        do! iamSleep 
} |> Async.RunSynchronously
// world hello
let hello = async {
    do! Async.Sleep(100)
    do stdout.WriteLine("hello") }

let world = async { do stdout.WriteLine("world") }

async {
    let! child = hello |> Async.StartChild
    do! world
    do! child
} |> Async.RunSynchronously

.

Taskを使った例 .

AwaitIAsyncResultを使うことで待機させることができる

.

無期限に待つ例

let apple  = async { return 100 }
let banana = async { return 70  }
let cherry = async { return 350 }
let sum = [ apple; banana; cherry ]

let eating = async { do stdout.WriteLine("Taste good!") }

async {
    let! (withinMoney:bool) = Async.AwaitIAsyncResult( sum |> Async.Parallel |> Async.StartAsTask)
    do!  eating
} |> Async.RunSynchronously

タイムアウトを指定した例

let wakeUp = async {
    do! Async.Sleep(1500)
    return stdout.WriteLineAsync("Wake up!")
}

let goodMorning = async { stdout.WriteLine("goodMorning") }
let iamSleep = async { stdout.WriteLine("zzz...") }

async {
    let! (wakeUpWithinTime:bool) = Async.AwaitIAsyncResult( wakeUp |> Async.StartAsTask ,100 )
    if    wakeUpWithinTime
    then  do! goodMorning
    else  do! iamSleep
} |> Async.RunSynchronously

5. Exception and Cancel

let green  = fun _ ->  stdout.WriteLine("green") 
let yellow = fun _ ->  stdout.WriteLine("yellow") 
let red    = fun _ ->  stdout.WriteLine("red") 

// 通常の動作
let signalGreen = async { do () }
Async.StartWithContinuations ( signalGreen, green, yellow, red )

// エラー処理
let signalYellow:Async<obj> = async {
    return raise <| new System.Exception()
}
Async.StartWithContinuations ( signalYellow, green, yellow, red )

// キャンセル処理
let signalRed (tokenSource:System.Threading.CancellationTokenSource)  = async {
    do! Async.Sleep(1000)
}

let tokenSource = new System.Threading.CancellationTokenSource()
Async.StartWithContinuations ( signalRed tokenSource , green, yellow, red , tokenSource.Token )
tokenSource.Cancel()
Remove all ads