2012年11月8日木曜日

RubyでExcelを操作するサンプル

FXのシステムトレードのブログを運用している。

不労所得を確保セヨ!!シストレ24戦記
http://sysken.blogspot.jp/

FX会社から提供される取引報告のExcelファイルから、HTMLの表組みを手作業で行なっていたのだが、件数が多いと時間がかかる。

そこで、下記の記事を参考にして、RubyでExcelファイルから値を抜き出してHTMLに変換するプログラムを作成してみた。

VBA より便利で手軽 Excel 操作スクリプト言語「Ruby」へのお誘い (前編)
http://jp.rubyist.net/magazine/?0027-ExcellentRuby

Excelで値を取り出してしまえば、後は通常のRubyのプログラムと同様に値を扱えば良い。

数字をカンマ区切りにするのは、下記の記事を参考にさせていただいた。

Re: 金額カンマ編集について
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-list/37580

以下、作成したソースコード。
# encoding: CP932
require 'win32ole'

# ストラテジー別の最終取り引き回数(手動で変更)
RIKIWIKITAVYFX_USDJPY_LAST = 173
PMINVESTCAPITAL_EURGBP_LAST = 95
DBSWING_EURUSD_LAST = 28
T_Follow_EURUSD_LAST = 10

# 表組み用HTML
TABLE_HEADER = '<table border="1" bordercolor="#888" cellspacing="0" style="border-collapse: collapse; border-color: rgb(136, 136, 136); border-width: 1px;"><tbody>' + "\n"
TABLE_FOOTER = '</tbody></table>' + "\n"
FIRST_TAG = '<tr><td style="width: 150px;">'
SECOND_TAG = '</td><td style="text-align: right; width: 100px;"><b><span style="color: blue;">'
THIRD_TAG = '</span></b></td><td style="text-align: right; width: 100px;"><b><span style="color: blue;">'
FOURTH_TAG = '</span></b></td></tr>' + "\n"

# ExcelファイルのOpen
app = WIN32OLE.new('Excel.Application')
book = app.Workbooks.Open(app.GetOpenFilename)

# Excelファイルからのデータ抽出
rowIndex = 0
rikiwikitavyfxUSDJPYrowArray = Array.new
pminvestcapitalEURGBProwArray = Array.new
dbswingEURUSDrowArray = Array.new
tfollowEURUSDrowArray = Array.new

for row in book.ActiveSheet.UsedRange.Rows do
  if rowIndex > 0
    colIndex = 0
    colText = ""
    colArray = Array.new
    colArray << ''
    for cell in row.Columns do
      if colIndex == 2 || colIndex == 4 || colIndex.between?(10,12)
        colArray << cell.Value
      end
      colIndex += 1
    end
    if colArray[1] == "RikiTikiTavi FX" && colArray[2] == "USDJPY"
      rikiwikitavyfxUSDJPYrowArray << colArray 
    elsif colArray[1] == "Pminvestcapital" && colArray[2] == "EURGBP"
      pminvestcapitalEURGBProwArray << colArray 
    elsif colArray[1] == "DBSwing" && colArray[2] == "EURUSD"
      dbswingEURUSDrowArray << colArray 
    elsif colArray[1] == "T Follow" && colArray[2] == "EURUSD"
      tfollowEURUSDrowArray << colArray 
    end
  end
  rowIndex += 1 
end

# HTML表組み用関数
def createTable(rowArray, serial, labelSerial)
  
  sumPips = 0
  sumMoney = 0

  table = "<b>" + labelSerial.to_s + ". "
  table += rowArray[0][1] + ":"
  table += rowArray[0][2].slice(0, 3) + "/" + rowArray[0][2].slice(3, 3)
  table += "</b><br />\n"
  table += "<br />\n"
  table += "<br />\n"
  table += "<br />\n"
  table += TABLE_HEADER
  rowArray.reverse!
  for row in rowArray do
    table += FIRST_TAG
    table += serial.to_s + "回目の取り引き"
    if row[4] < 0
      table += SECOND_TAG.sub("blue", "red")
    else
      table += SECOND_TAG
    end
    table += row[4].to_s.reverse.gsub( /(\d{3})(?=\d)/, '\1,' ).reverse + "pips"
    if row[5] < 0
      table += THIRD_TAG.sub("blue", "red")
    else
      table += THIRD_TAG
    end
    table += row[5].round.to_s.reverse.gsub( /(\d{3})(?=\d)/, '\1,' ).reverse + "円"
    table += FOURTH_TAG
    serial += 1
    sumPips += row[4] * 10
    sumMoney += row[5]
  end
  table += FIRST_TAG
  table += "合 計"
  if sumPips < 0
    table += SECOND_TAG.sub("blue", "red")
  else
    table += SECOND_TAG
  end
  table += (sumPips / 10).to_s.reverse.gsub( /(\d{3})(?=\d)/, '\1,' ).reverse + "pips"
  if sumMoney < 0
    table += THIRD_TAG.sub("blue", "red")
  else
    table += THIRD_TAG
  end
  table += sumMoney.round.to_s.reverse.gsub( /(\d{3})(?=\d)/, '\1,' ).reverse + "円"
  table += FOURTH_TAG
  table += TABLE_FOOTER
  table += "<br />\n"
  table += "<br />\n"
  table += "<br />\n"
  return table
end

# ストラテジー別HTML作成
labelSerial = 1
outputFile = ''

if dbswingEURUSDrowArray.size > 0
  outputFile += createTable(dbswingEURUSDrowArray, DBSWING_EURUSD_LAST, labelSerial) 
  labelSerial += 1
end

if tfollowEURUSDrowArray.size > 0
  outputFile += createTable(tfollowEURUSDrowArray, T_Follow_EURUSD_LAST, labelSerial) 
  labelSerial += 1
end

if pminvestcapitalEURGBProwArray.size > 0
  outputFile += createTable(pminvestcapitalEURGBProwArray, PMINVESTCAPITAL_EURGBP_LAST, labelSerial) 
  labelSerial += 1
end

if rikiwikitavyfxUSDJPYrowArray.size > 0
  outputFile += createTable(rikiwikitavyfxUSDJPYrowArray, RIKIWIKITAVYFX_USDJPY_LAST, labelSerial) 
  labelSerial += 1
end

# HTMLファイルの書き出し
outputHTMLFile = "<html><body>\n" 
outputHTMLFile += outputFile 
outputHTMLFile += "</body></html>\n"

open("シストレ24成績.html", "w") {|f| f.write outputFile}

book.close(false)
app.quit

0 件のコメント:

コメントを投稿