unageanu-clickclient_scrap 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/ChangeLog +0 -0
- data/README +18 -0
- data/lib/clickclient_scrap.rb +273 -0
- metadata +56 -0
data/ChangeLog
ADDED
File without changes
|
data/README
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
|
2
|
+
==クリック証券Fxクライアントライブラリ
|
3
|
+
|
4
|
+
クリック証券の携帯向けサイト「モバトレ君」にアクセスし、
|
5
|
+
スクレイピングでレート情報の取得や取り引きを行うライブラリです。
|
6
|
+
|
7
|
+
===実装済みの機能
|
8
|
+
- ログイン
|
9
|
+
- ログアウト
|
10
|
+
- レート一覧の取得
|
11
|
+
|
12
|
+
===注意事項
|
13
|
+
- スクレイピングによるアクセスのため、Webサイトの仕様変更等により
|
14
|
+
突然動作しなくなる可能性があります。
|
15
|
+
|
16
|
+
===免責
|
17
|
+
- 本ライブラリの利用は自己責任でお願いします。
|
18
|
+
- ライブラリの不備・不具合等によるあらゆる損害について、作成者は責任を負いません。
|
@@ -0,0 +1,273 @@
|
|
1
|
+
begin
|
2
|
+
require 'rubygems'
|
3
|
+
rescue LoadError
|
4
|
+
end
|
5
|
+
require 'httpclient'
|
6
|
+
require 'rexml/document'
|
7
|
+
require 'date'
|
8
|
+
require 'kconv'
|
9
|
+
|
10
|
+
#
|
11
|
+
#=== クリック証券アクセスクライアント
|
12
|
+
#
|
13
|
+
#*Version*:: -
|
14
|
+
#*License*:: Ruby ライセンスに準拠
|
15
|
+
#
|
16
|
+
#クリック証券を利用するためのクライアントライブラリです。携帯向けサイトのスクレイピングにより以下の機能を提供します。
|
17
|
+
#- 外為証拠金取引(FX)取引
|
18
|
+
#
|
19
|
+
#====依存モジュール
|
20
|
+
#「{httpclient}[http://dev.ctor.org/http-access2]」を利用しています。以下のコマンドを実行してインストールしてください。
|
21
|
+
#
|
22
|
+
# gem install httpclient --source http://dev.ctor.org/download/
|
23
|
+
#
|
24
|
+
#====基本的な使い方
|
25
|
+
#
|
26
|
+
# require 'clickclient'
|
27
|
+
#
|
28
|
+
# c = ClickClient::Client.new
|
29
|
+
# # c = ClickClient::Client.new https://<プロキシホスト>:<プロキシポート> # プロキシを利用する場合
|
30
|
+
# c.fx_session( "<ユーザー名>", "<パスワード>" ) { | fx_session |
|
31
|
+
# # 通貨ペア一覧取得
|
32
|
+
# list = fx_session.list_currency_pairs
|
33
|
+
# puts list
|
34
|
+
# }
|
35
|
+
#
|
36
|
+
#====免責
|
37
|
+
#- 本ライブラリの利用は自己責任でお願いします。
|
38
|
+
#- ライブラリの不備・不具合等によるあらゆる損害について、作成者は責任を負いません。
|
39
|
+
#
|
40
|
+
module ClickClient
|
41
|
+
|
42
|
+
# クライアント
|
43
|
+
class Client
|
44
|
+
# ホスト名
|
45
|
+
DEFAULT_HOST_NAME = "https://sec-sso.click-sec.com/mf"
|
46
|
+
|
47
|
+
# 通貨ペア: 米ドル-円
|
48
|
+
USDJPY = :USDJPY
|
49
|
+
# 通貨ペア: ユーロ-円
|
50
|
+
EURJPY = :EURJPY
|
51
|
+
# 通貨ペア: イギリスポンド-円
|
52
|
+
GBPJPY = :GBPJPY
|
53
|
+
# 通貨ペア: 豪ドル-円
|
54
|
+
AUDJPY = :AUDJPY
|
55
|
+
# 通貨ペア: ニュージーランドドル-円
|
56
|
+
NZDJPY = :NZDJPY
|
57
|
+
# 通貨ペア: カナダドル-円
|
58
|
+
CADJPY = :CADJPY
|
59
|
+
# 通貨ペア: スイスフラン-円
|
60
|
+
CHFJPY = :CHFJPY
|
61
|
+
# 通貨ペア: 南アランド-円
|
62
|
+
ZARJPY = :ZARJPY
|
63
|
+
# 通貨ペア: ユーロ-米ドル
|
64
|
+
EURUSD = :EURUSD
|
65
|
+
# 通貨ペア: イギリスポンド-米ドル
|
66
|
+
GBPUSD = :GBPUSD
|
67
|
+
# 通貨ペア: 豪ドル-米ドル
|
68
|
+
AUDUSD = :AUDUSD
|
69
|
+
# 通貨ペア: ユーロ-スイスフラン
|
70
|
+
EURCHF = :EURCHF
|
71
|
+
# 通貨ペア: イギリスポンド-スイスフラン
|
72
|
+
GBPCHF = :GBPCHF
|
73
|
+
# 通貨ペア: 米ドル-スイスフラン
|
74
|
+
USDCHF = :USDCHF
|
75
|
+
|
76
|
+
# 売買区分: 買い
|
77
|
+
BUY = 0
|
78
|
+
# 売買区分: 売り
|
79
|
+
SELL = 1
|
80
|
+
|
81
|
+
# 注文タイプ: 通常
|
82
|
+
ORDER_TYPE_NORMAL = 0
|
83
|
+
# 注文タイプ: IFD
|
84
|
+
ORDER_TYPE_IFD = 1
|
85
|
+
# 注文タイプ: OCO
|
86
|
+
ORDER_TYPE_OCO = 2
|
87
|
+
# 注文タイプ: IFD-OCO
|
88
|
+
ORDER_TYPE_IFD_OCO = 3
|
89
|
+
|
90
|
+
|
91
|
+
#
|
92
|
+
#===コンストラクタ
|
93
|
+
#
|
94
|
+
#*proxy*:: プロキシホストを利用する場合、そのホスト名とパスを指定します。
|
95
|
+
# 例) https://proxyhost.com:80
|
96
|
+
#
|
97
|
+
def initialize( proxy=nil )
|
98
|
+
@client = HTTPClient.new( proxy, "Mozilla/5.0")
|
99
|
+
#@client.debug_dev=STDOUT
|
100
|
+
@client.set_cookie_store("cookie.dat")
|
101
|
+
@host_name = DEFAULT_HOST_NAME
|
102
|
+
end
|
103
|
+
|
104
|
+
#ログインし、セッションを開始します。
|
105
|
+
#-ブロックを指定した場合、引数としてセッションを指定してブロックを実行します。ブロック実行後、ログアウトします。
|
106
|
+
#-そうでない場合、セッションを返却します。この場合、ClickClient::FX::FxSession#logoutを実行しログアウトしてください。
|
107
|
+
#
|
108
|
+
#戻り値:: ClickClient::FX::CurrencyPairの配列。
|
109
|
+
#戻り値:: ClickClient::FX::CurrencyPairの配列。
|
110
|
+
def fx_session( userid, password, &block )
|
111
|
+
@client.get("#{@host_name}/" )
|
112
|
+
result = @client.post_content("#{@host_name}/sso-redirect", {
|
113
|
+
"j_username"=>userid,
|
114
|
+
"j_password"=>password,
|
115
|
+
"LoginForm"=>"ログイン".tosjis,
|
116
|
+
"s"=>"02",
|
117
|
+
"p"=>"80"
|
118
|
+
})
|
119
|
+
if result.toutf8 =~ /<META HTTP-EQUIV="REFRESH" CONTENT="0;URL=([^"]*)">/
|
120
|
+
uri = URI.parse( $1 )
|
121
|
+
base = "#{uri.scheme}://#{uri.host}:#{uri.port}"
|
122
|
+
result = @client.get_content($1)
|
123
|
+
commands = result.toutf8.scan( /<a[^>]*?href="([^"]*)"[^>]*>([^<]*)<\/a>/).inject({}) {|r,l|
|
124
|
+
r[l[1]] = "#{base}#{l[0]}"; r
|
125
|
+
}
|
126
|
+
session = FX::FxSession.new( @client, commands )
|
127
|
+
if block_given?
|
128
|
+
begin
|
129
|
+
yield session
|
130
|
+
ensure
|
131
|
+
session.logout
|
132
|
+
end
|
133
|
+
else
|
134
|
+
return session
|
135
|
+
end
|
136
|
+
else
|
137
|
+
error = result.toutf8 =~ /<font color="red">([^<]*)</ ? $1.strip : result
|
138
|
+
raise "login failed.detail=#{error}".toutf8
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
#ホスト名
|
143
|
+
attr :host_name, true
|
144
|
+
end
|
145
|
+
|
146
|
+
module FX
|
147
|
+
#=== FX取引のためのセッションクラス
|
148
|
+
#Client#fx_sessionのブロックの引数として渡されます。詳細はClient#fx_sessionを参照ください。
|
149
|
+
class FxSession
|
150
|
+
|
151
|
+
def initialize( client, commands )
|
152
|
+
@client = client
|
153
|
+
@commands = commands
|
154
|
+
end
|
155
|
+
#レート一覧を取得します。
|
156
|
+
#
|
157
|
+
#戻り値:: 通貨ペアをキーとするClickClient::FX::Rateのハッシュ。
|
158
|
+
def list_rates
|
159
|
+
result = @client.get_content( @commands["レート一覧(新規注文)"] )
|
160
|
+
@swaps = list_swaps unless @swaps
|
161
|
+
reg = />([A-Z]+\/[A-Z]+)<\/a>[^\-\.\d]*?([\d]+\.[\d]+\-[\d]+)/
|
162
|
+
return result.toutf8.scan( reg ).inject({}) {|r,l|
|
163
|
+
pair = l[0].gsub( /\//, "" ).to_sym
|
164
|
+
swap = @swaps[pair]
|
165
|
+
rate = FxSession.convert_rate l[1]
|
166
|
+
if ( rate && swap )
|
167
|
+
r[pair] = Rate.new( pair, rate[0], rate[1], swap.sell_swap, swap.buy_swap )
|
168
|
+
end
|
169
|
+
r
|
170
|
+
}
|
171
|
+
end
|
172
|
+
#12.34-35 形式の文字列をbidレート、askレートに変換する。
|
173
|
+
def self.convert_rate( str ) #:nodoc:
|
174
|
+
if str =~ /([\d]+)\.([\d]+)\-([\d]+)/
|
175
|
+
high = $1
|
176
|
+
low = $2
|
177
|
+
low2 = $3
|
178
|
+
bid = high.to_f+(low.to_f/(10**low.length))
|
179
|
+
ask_low = (low[0...low.length-low2.length] + low2).to_f
|
180
|
+
if low.to_f > ask_low
|
181
|
+
ask_low += 10**low2.length
|
182
|
+
end
|
183
|
+
ask = high.to_f+(ask_low/10**low.length)
|
184
|
+
return [bid,ask]
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
#スワップの一覧を取得します。
|
189
|
+
#
|
190
|
+
#戻り値:: 通貨ペアをキーとするClickClient::FX::Swapのハッシュ。
|
191
|
+
def list_swaps
|
192
|
+
result = @client.get_content( @commands["スワップ/証拠金一覧"] )
|
193
|
+
reg = /<dd>([A-Z]+\/[A-Z]+) <font[^>]*>売<\/font>[^\-\d]*?([\-\d]+)[^\-\d]*<font[^>]*>買<\/font>[^\-\d]*([\-\d]+)[^\-\d]*<\/dd>/
|
194
|
+
return result.toutf8.scan( reg ).inject({}) {|r,l|
|
195
|
+
pair = l[0].gsub( /\//, "" ).to_sym
|
196
|
+
r[pair] = Swap.new( pair, l[1].to_i, l[2].to_i ); r
|
197
|
+
}
|
198
|
+
end
|
199
|
+
|
200
|
+
#
|
201
|
+
#注文を行います。
|
202
|
+
#
|
203
|
+
#*currency_pair_code*:: 通貨ペアコード(必須)
|
204
|
+
#*sell_or_buy*:: 売買区分。ClickClient::FX::BUY,ClickClient::FX::SELLのいずれかを指定します。(必須)
|
205
|
+
#*unit*:: 取引数量(必須)
|
206
|
+
#*options*:: 注文のオプション。注文方法に応じて以下の情報を設定できます。
|
207
|
+
# - <b>通常注文</b> ※注文レートが設定されていれば通常取引となります。
|
208
|
+
# - <tt>:rate</tt> .. 注文レート(必須)
|
209
|
+
# - <tt>:execution_expression</tt> .. 執行条件。ClickClient::FX::EXECUTION_EXPRESSION_LIMIT_ORDER等を指定します(必須)
|
210
|
+
# - <tt>:expiration_type</tt> .. 有効期限。ClickClient::FX::EXPIRATION_TYPE_TODAY等を指定します(必須)
|
211
|
+
# - <tt>:expiration_date</tt> .. 有効期限が「日付指定(ClickClient::FX::EXPIRATION_TYPE_SPECIFIED)」の場合の有効期限をDateで指定します。(有効期限が「日付指定」の場合、必須)
|
212
|
+
#<b>戻り値</b>:: ClickClient::FX::OrderResult
|
213
|
+
#
|
214
|
+
def order ( currency_pair_code, sell_or_buy, unit, options={} )
|
215
|
+
result = @client.get_content( @commands["レート一覧(新規注文)"] )
|
216
|
+
if result.toutf8 =~ /<form[~>]?*action="([^"]*)"[~>]*>(.*?<select name="P001"[^>]*>(.*)<\/select>.*?<select name="P100"[^>]*>(.*)<\/select>.*)<\/form>)/m
|
217
|
+
action = $1
|
218
|
+
p001 = $3
|
219
|
+
p100 = $4
|
220
|
+
hidden = $2
|
221
|
+
# 通貨ペア
|
222
|
+
pairs = p001.scan( /<option value="([^"]+)">([A-Z]+\/[A-Z]+)/m ).inject({}) {|r,l|
|
223
|
+
pair = l[1].gsub( /\//, "" ).to_sym
|
224
|
+
r[pair] = l[0]; r
|
225
|
+
}
|
226
|
+
# 取り引き種別
|
227
|
+
type = p100.scan( /<option value="([^"]+)">([^\s]+)/m ).inject({}) {|r,l|
|
228
|
+
r[l[1]] = l[0]; r
|
229
|
+
}
|
230
|
+
# hidden
|
231
|
+
params = hidden.scan( /<input type="hidden" name="([^"]+)" value="([^"]+)">/m ).inject({}) {|r,l|
|
232
|
+
r[l[1]] = l[0]; r
|
233
|
+
}
|
234
|
+
end
|
235
|
+
# if ( options[:rate] != nil )
|
236
|
+
# if ( options[:stop_order_rate] != nil )
|
237
|
+
# # 逆指値レートが指定されていればOCO取引
|
238
|
+
# path = "/ws/fx/ocoChumon.do"
|
239
|
+
# body << "&srp=#{options[:rate].to_s}"
|
240
|
+
# body << "&grp=#{options[:stop_order_rate].to_s}"
|
241
|
+
# else
|
242
|
+
# # そうでなければ通常取引
|
243
|
+
# raise "options[:execution_expression] is required." if options[:execution_expression] == nil
|
244
|
+
# path = "/ws/fx/tsujoChumon.do"
|
245
|
+
# body << "&crp=#{options[:rate].to_s}"
|
246
|
+
# body << "&sjt=#{options[:execution_expression].to_s}"
|
247
|
+
# end
|
248
|
+
# raise "options[:expiration_type] is required." if options[:expiration_type] == nil
|
249
|
+
# body << "&bbt=#{sell_or_buy.to_s}"
|
250
|
+
# body << "&thn=#{unit.to_s}"
|
251
|
+
# body << "&dat=#{options[:expiration_type].to_s}"
|
252
|
+
# body << "&ykd=" << options[:expiration_date].strftime( "%Y%m%d%H" ) if options[:expiration_date] != nil
|
253
|
+
# end
|
254
|
+
# result = @client.post( @base_uri + path, body)
|
255
|
+
# doc = ClickClient.parse( result.content )
|
256
|
+
# return OrderResult.new( doc.root )
|
257
|
+
end
|
258
|
+
|
259
|
+
# ログアウトします。
|
260
|
+
def logout
|
261
|
+
@client.get_content( @commands["ログアウト"] )
|
262
|
+
end
|
263
|
+
end
|
264
|
+
|
265
|
+
#=== スワップ
|
266
|
+
Swap = Struct.new(:pair, :sell_swap, :buy_swap)
|
267
|
+
#=== レート
|
268
|
+
Rate = Struct.new(:pair, :bid_rate, :ask_rate, :sell_swap, :buy_swap )
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
272
|
+
|
273
|
+
|
metadata
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: unageanu-clickclient_scrap
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Masaya Yamauchi
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-02-13 00:00:00 -08:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description:
|
17
|
+
email: y-masaya@red.hot.co.jp
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files:
|
23
|
+
- README
|
24
|
+
files:
|
25
|
+
- README
|
26
|
+
- ChangeLog
|
27
|
+
- lib/clickclient_scrap.rb
|
28
|
+
has_rdoc: true
|
29
|
+
homepage: http://github.com/unageanu/clickclient_scrap/tree/master
|
30
|
+
post_install_message:
|
31
|
+
rdoc_options:
|
32
|
+
- --main
|
33
|
+
- README
|
34
|
+
require_paths:
|
35
|
+
- lib
|
36
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: "0"
|
41
|
+
version:
|
42
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: "0"
|
47
|
+
version:
|
48
|
+
requirements: []
|
49
|
+
|
50
|
+
rubyforge_project:
|
51
|
+
rubygems_version: 1.2.0
|
52
|
+
signing_key:
|
53
|
+
specification_version: 2
|
54
|
+
summary: click securities client library for ruby.
|
55
|
+
test_files: []
|
56
|
+
|