自動売買プログラムを自作して株の注文を行う。

トレードステーションを使いなさいというのが解のような気もしますが、自動売買のためのプログラムを書いていきたいと思います。

紹介するプログラムはSeleniumを使ってWEB画面を操作し株の買付を行います。また自動操作中のWEB画面は邪魔なのでChromeのヘッドレス化を行います。こうすることでプログラムはバッググラウンドで動作するようになります。テスト中は画面が立ち上がるほうが便利かもしれませんが、実際に使う場合はこちらのほうが便利ですし、幾分速度も上がるでしょう。

まずSMBC日興証券のお客様ログイン画面より、支店番号、口座番号、パスワードを入力しログインします。続いてお取引タブの信用取引、新規買付画面に遷移し、銘柄コード、注文数量、注文単価を入力、制度信用と当日中をチェックして注文内容を確認を押下します。

またSeleniumを使ってスクレイピングや操作を行う上で必要な知識も紹介しておきます。

目次

環境設定

Chromeじゃない人はChromeをインストールしてください。 ChromeDriverが必要になります。ここからダウンロードして、パスの通っているところにおいてください。 あるいは

sudo apt install -y chromium-browser
wget -O /tmp/chromedriver.zip http://chromedriver.storage.googleapis.com/2.21/chromedriver_linux64.zip 
sudo unzip /tmp/chromedriver.zip chromedriver -d /usr/local/bin/
sudo chmod +x /usr/local/bin/chromedriver

Seleniumも必要です。

gem install selenium-webdriver

コード

こんな感じです。

class Smbc
  def login(siten_code, kouza_code, password )
    ua = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.116 Safari/537.36"
    caps = Selenium::WebDriver::Remote::Capabilities.chrome("chromeOptions" => {binary: '/usr/bin/google-chrome', args: ["--headless", "--disable-gpu", "--user-agent=#{ua}", "window-size=1280x800"]})
    @driver = Selenium::WebDriver.for :chrome, desired_capabilities: caps
    @driver.manage.timeouts.implicit_wait = DEFAULT_TIMEOUT
    @wait = Selenium::WebDriver::Wait.new(:timeout => 1)
    @driver.navigate.to 'https://trade.smbcnikko.co.jp/Login/0/login/ipan_web/hyoji/'
    e = @driver.find_element(:id, :padInput0)
    e.send_keys(siten_code)
    e = @driver.find_element(:id, :padInput1)
    e.send_keys(kouza_code)
    e = @driver.find_element(:id, :padInput2)
    e.send_keys(password)
    e = @driver.find_element(:css, 'p.inputBtn input')
    e.click
    e = @wait.until { @driver.find_element(:name, :menu03) }
    e.click
    @torihiki_url = @driver.current_url
    puts @torihiki_url
    a = @driver.find_elements(:css, 'div.con_mrg04_1 span.txt_01 a')
    @buy_url = a.find{|e| e.text == '新規買付' }.attribute(:href)
    @sell_url = a.find{|e| e.text == '新規売付' }.attribute(:href)
    @open_interest_url = a.find{|e| e.text ==  '建玉一覧(返済・現引・現渡)' }.attribute(:href)
  end

  def buy(hash)
    navigate_to_buy_page
    new_order(hash)
  end

  def navigate_to_buy_page
    @driver.navigate.to @buy_url
  end

  def exists?(method, selector)
    @driver.manage.timeouts.implicit_wait = 0
    a = @driver.find_elements(method, selector)
    @driver.manage.timeouts.implicit_wait = DEFAULT_TIMEOUT
    a.length > 0
  end

  def new_order(hash)
    e = @driver.find_element(:css, 'input[type="hidden"][name="shintategaku"]')
    sikin = e.attribute(:value).gsub(/,/,'').to_f
    return if sikin < hash[:volume].to_i * hash[:price].to_f
    e = @driver.find_element(:css, 'td#imeig input[type="text"]')
    e.send_keys hash[:code]
    method = :css
    selector = 'td#ihensaikigen input[type="radio"][id="seido"]'
    if exists?(method, selector)
      e = @driver.find_element(method, selector)
      e.click
    end
    e = @driver.find_element(:css, 'td#isuryo input[type="text"][name="suryo"]')
    e.send_keys hash[:volume]
    e = @driver.find_element(:css, 'td#itanka input[type="text"][name="kakaku"]')
    e.send_keys hash[:price]
    e = @driver.find_element(:css, 'td#ikikan input[type="radio"][id="tojit"]')
    e.click
    e = @driver.find_element(:css, 'input[type="image"][alt="注文内容を確認する"]')
    e.send_keys(' ')
    e = @driver.find_element(:css, 'input[type="image"][alt="注文する"]')
    e.send_keys(' ')
  end
end

利用する場合は次のようになります。

Bundler.require
agent = Smbc.new
siten = '支店コード'
kouza = '口座番号'
password = 'パスワード'
agent.login siten, kouza, password
agent.buy code: 1301, price: 4300, volume: 1000

Seleniumを使うにあたって

Seleniumのプログラミングを行うにあたって、必要となるものは次の5個くらいなものです。

  • @driver.navigate.to(url)
    • urlに遷移します
  • element = @driver.find_element(method, path)

  • elements = @driver.find_elements(method, path)
    • methodには:id, :name, :css, :xpathなどを指定します。それぞれのmethodに対してpathを指定し、要素を取得します。find_elementの場合は取得できた先頭の要素が返ってきますが、見つからない場合はエラーとなります。find_elementsは取得できた要素のすべてが返ってきます。見つからない場合は空の配列が返ってきます。Seleniumには存在確認がありませんので、find_elementsを使って存在確認を行うことができます。pathの指定方法は後述します。
  • element.send_keys(key)
    • elementにkeyを送ります。
  • element.click
    • elementをクリックします。ただし、クリックできない要素もたまにあります。そういった場合はelement.send_keys(‘ ‘)などとして、要素に対してスペースを送ってかげるとうまくいくことがあります。

以上のメソッドのみで必要な操作は行えると思います。 find_elementのpathは次のようにして調べます。

  • chromeで調べたい要素のページを開きます。

  • 入力フォームのテキストボックスなどを右クリックし検証を選択します。すると左右にウィンドウが分割され、右にhtmlが表示されるようになります。

  • 右ウィンドウのハイライトされているところをさらに右クリックし、Copy - Copy Selectorを選択します。

  • CSSのセレクタがクリップボードに取得できます。

取得できたセレクタをfind_elementのpathとして使います。この場合はmethodは:cssです。同様の方法でxpathなども取得できます。

まとめません