Skip to content

Instantly share code, notes, and snippets.

@shout-poor
Last active June 11, 2023 13:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save shout-poor/e3b6ac1cddd69208e6cd006d9803fe2e to your computer and use it in GitHub Desktop.
Save shout-poor/e3b6ac1cddd69208e6cd006d9803fe2e to your computer and use it in GitHub Desktop.
Gnucash で日本株情報を Stooq.com から取得する Perlモジュール
#!/usr/bin/perl -w
# Copyright (C) 2022 by Kazuyuki Ono <shout@noisyspot.jp>
#
# Permission to use, copy, modify, and/or distribute this software for any purpose
# with or without fee is hereby granted.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
# FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
# OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
# TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
# THIS SOFTWARE.
#
# 使い方:
# - cpan で Finance::Quote と Switch をインストールする (以下ドキュメント参照)
# - https://wiki.gnucash.org/wiki/Online_Quotes#Finance::Quote
# - Date::Simple のインストールで失敗する場合は環境変数 LC_TIME=C を設定してインストールする
#
# - ライブラリインストール先を確認する
# $ perl -e '$,=":"; print @INC;'
#
# - Finance::Quote がインストールされたディレクトリを探し、当ファイル `Stooq.pm` を Finance/Quote 以下にコピーする
#
# - 環境変数 FQ_LOAD_QUOTELET に "Stooq" を設定し、Gnucash を起動する。
#
# - 証券エディター で、「記号/略号」 (symbol) に、Stooq.com での Stock symbol を設定する。
# 日本株であれば、「証券コード + ".JP"」とする。( 例えば "7203.JP" )
# 加えて、「オンライン相場表を取得」にチェックを入れ、タイプは「未知」を選択し、ドロップダウンで 「stooq」を選択する。
#
# - 価格データベースで「相場表を取得」を押して価格が更新されたら成功
#
# ※これとは別に、Gnucash は通貨レートを Alpha Vantage API から取得する仕様になっており、
# Alpha Vantage の API キーを取得して環境変数 ALPHAVANTAGE_API_KEY に設定しておく必要があります。
# Alpha Vantage については以下を参照
# https://www.alphavantage.co/
#
# 現状できないこと・テストしていないこと:
# - 日本株しかテストしていません
# - 指数や投資信託の情報は取得できません
#
package Finance::Quote::Stooq;
require 5.018;
use strict;
use Switch;
use LWP::UserAgent;
use HTTP::Request::Common;
use utf8;
our $VERSION = '0.10'; # VERSION
our @labels = qw/date isodate method price success currency errormsg/;
sub labels {
return ( sharenet => \@labels );
}
sub methods {
return ( stooq => \&stooq );
}
sub stooq {
my $quoter = shift;
my @symbols = @_;
my $ua = $quoter->user_agent();
my %info;
foreach my $symbol (@symbols) {
eval {
my $url = "https://stooq.com/q/d/l/?s=$symbol";
my $reply = $ua->get($url);
if (!$reply->is_success) {
$info{$symbol, 'success'} = 0;
$info{$symbol, 'method'} = 'stooq';
$info{$symbol, 'errormsg'} = 'HTTP failure ' . $reply->message;
next;
}
my @lines = split /\n/, $reply->content;
my $line = pop @lines;
chomp $line;
# Record format
# date,open,high,low,last,volume
my ($date, $open, $high, $low, $price, $volume) = split /,/, $line;
$info{$symbol, 'success'} = 1;
$info{$symbol, 'price'} = $price;
$info{$symbol, 'method'} = 'stooq';
$info{$symbol, 'currency'} = 'JPY';
if ($date =~ /(\d+)\-(\d+)\-(\d+)/) {
$quoter->store_date(\%info, $symbol, {year => $1, month => $2, day => $3});
}
};
if ($@) {
my $error = "Search failed: $@";
$info{$symbol, 'success'} = 0;
$info{$symbol, 'errormsg'} = trim($error);
}
}
### info : %info
return wantarray() ? %info : \%info;
}
sub _currency {
my $symbol = shift;
my ($code, $loc) = split /\./, $symbol;
my $cur;
switch (lc $loc) {
case 'jp' {$cur = 'JPY'}
case 'us' {$cur = 'USD'}
case 'de' {$cur = 'EUR'}
case 'uk' {$cur = 'GBP'}
case 'hk' {$cur = 'HKD'}
case 'hu' {$cur = 'HUF'}
else {$cur = 'USD'}
}
return $cur;
}
1;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment