Oandaのデモ口座における改悪について

1

2021年2月はじめに突然Oandaからメールがきて多くの改悪を行うということでびっくりしました。今までも一方的な変更が突然起こり辟易して来ましたが、今回の変化は大きすぎます。

【重要】デモ口座の利用期限およびオーダーブックインジケーター、APIの利用条件変更について
お客様各位 平素は、弊社のサービスをご利用いただき誠に有難うございます。 この度、デモ口座の利用期限を設けさせていただくとともに、オーダーブックインジケーター、およびAPIのご利用条件を変更させていただくことになりましたので、ご案内いたします。 はじめに、これらの判断に至った経緯は次の通りです。 デモ口座の利用期限の導入の経緯について  これまでデモ口座は期間無制限で使用可能でしたが、過去に作成されたものの、現在は未使用で放置されているデモ口座のデータが蓄積され、膨大なデータ量がサーバへの負荷となっていること、また、商用利用をはじめとして一部で、デモ口座の本来の目的以外で使用しているケースが散見され、サーバに負担をかけているためです。 オーダーブックインジケーター、APIの利用条件の変更の経緯について インジケーター、API提供の本来の目的である弊社との取引以外の目的での使用が多数見受けられ、サーバへの負担が増加しているためです。 いずれも、サーバへの負荷を高め、システム障害発生の原因となり、実際にお取引をしていらっしゃるお客様にご迷惑をおかけする原因の一つです。昨年はこのような事例が実際に発生しておりました。 このため、これらの無制限であったサービスの一部に制限をかけることで、実際にお取引されているお客様へのサービスの品質向上を目指すことこそがお客様にとっても、弊社にとっても健全であると判断し、このような決定に至りました。 何卒、ご理解のほどよろしくお願い申し上げます。 制限対象になるお客様に弊社のサービスをより理解していただくために、移行期間である2021年2月はキャンペーンとして、本番口座を保有しているお客様全員にゴールド会員資格をプレゼントさせていただきます。この機会のゴールド会員のサービスをお試しください。
デモ口座の利用期限について
本年2月1日からは、デモ口座の利用期限を当該口座開設後30日間とさせていただきます。 ただし、以下の条件を満たすお客様は継続してデモ口座をご利用いただけます。1. 本番口座ステータスがゴールド(Gold)であること。2. 本番口座のマイページから、種類ごとに1つのデモ口座を登録すること。 利用期限を経過、またはゴールド会員を失ったことによりデモ口座の利用権を失った口座はロックされます。(ログインできません。) ロックの解除にはロック後60日以内にゴールド会員のステータスに昇格(回復)後、再び本番口座のマイページより、当該デモ口座の登録を行うことでロックを解除することができます。(過去に登録していた口座に関しても再登録が必要です。) なお、60日以内にロックの解除が行われなかったデモ口座は閉鎖され、復元することはできませんのでご注意ください。
移行期間2021年2月1日より、デモ口座の利用期限を設定させていただきます。既存のデモ口座につきましては、利用期限を2021年2月28日までとさせていただきます。 ゴールド会員の方でデモ口座を継続使用される場合は2月末までにマイページより必ずご登録願います。(ご登録は2021年2月2日以降行うことができます。)

30日と言っていますが、その後、2月28日を待たずにOandaのデモ口座ではAPIも使えなくなりました。今までも一方的な変更が突然起こり辟易して来ましたが、今回の変化は大きすぎますね。。

【oandapyV20】OandaAPIでオーダブック、ポジションブックを取得する

1

この記事ではoandapyV20を使ってオーダブック、ポジションブックを取得する方法について記載します。

oandapyV20では、オーダーブックをとるためにはoandapyV20.endpoints.instrumentsのInstrumentsOrderBookというクラスで/v3/instruments/{instrument}/orderBookをGet通信で叩きます。

ポジションブックの場合は、oandapyV20.endpoints.instrumentsのInstrumentsPositionBookというクラスで/v3/instruments/{instrument}/positionBookをGet通信で叩きます。

いずれの場合もparamsで指定できるパラメータはinstrumentとtimeだけです。instrumentは必須引数ですが、timeは指定しない場合は最新が返されます。timeだUNIXTIMEを文字列型で渡します。最新を取りたい場合は、paramsは{}でいいと思います。

オーダーブックもポジションブックもほとんど同じなので、今回はオーダブックで説明したいと思います。

ドル円の最新のオーダーブックを取得するコードはこちらです。ポジションブックを見たい場合はInstrumentsPositionBookを使ってください。

# -*- coding: utf-8 -*-
import json
from oandapyV20 import API
from oandapyV20.endpoints.pricing import PricingInfo
from oandapyV20.exceptions import V20Error
import oandapyV20.endpoints.instruments as instruments
import datetime
import pandas as pd

def main():
    account_id="XXX-XXX-XXXXXXX-XXX"
    access_token = "***************************************************************"
    api = API(access_token=access_token, environment="practice")#or live

    params ={}
    r = instruments.InstrumentsOrderBook(instrument="EUR_USD",
                                         params=params)
    api.request(r)
    data = (r.response)
    print(data)

if __name__ == "__main__":
    main()

返り値の中身を詳細に見てみます。所期のデータはdata[‘orderBook’][‘buckets’]にリストで返ってきています。

#まずはなんの型が帰ってきているかきます。
(Pdb) type(data)
<class 'dict'>
(Pdb) data.keys()
dict_keys(['orderBook'])

(Pdb) type(data['orderBook'])
<class 'dict'>
(Pdb) data['orderBook'].keys()
dict_keys(['instrument', 'time', 'unixTime', 'price', 'bucketWidth', 'buckets'])

(Pdb) data['orderBook']['instrument']
'EUR_USD'
(Pdb) data['orderBook']['time']
'2020-12-07T12:00:00Z'
(Pdb) data['orderBook']['price']
'1.21131'
(Pdb) data['orderBook']['bucketWidth']
'0.00050'

(Pdb) type(data['orderBook']['buckets'])
<class 'list'>
(Pdb) len(data['orderBook']['buckets'])
5548
(Pdb) data['orderBook']['buckets'][0]
{'price': '0.00000', 'longCountPercent': '0.4861', 'shortCountPercent': '0.3107'}
(Pdb) data['orderBook']['buckets'][1000]
{'price': '1.12050', 'longCountPercent': '0.0351', 'shortCountPercent': '0.0200'}
(Pdb) data['orderBook']['buckets'][3000]
{'price': '7.59750', 'longCountPercent': '0.0000', 'shortCountPercent': '0.0150'}
(Pdb) data['orderBook']['buckets'][5000]
{'price': '107.77800', 'longCountPercent': '0.0025', 'shortCountPercent': '0.0000'}

綺麗な最終結果だけが欲しいならdata[‘orderBook’][‘buckets’]をPandasに変換します。

(Pdb) pd.DataFrame(data['orderBook']['buckets'])
                 price longCountPercent shortCountPercent
0              0.00000           0.4861            0.3107
1              0.00050           0.1428            0.0802
2              0.00100           0.2956            0.0451
3              0.00150           0.0576            0.0251
4              0.00200           0.0401            0.0225
...                ...              ...               ...
5543    34887878.00000           0.0025            0.0000
5544   100000000.00000           0.0025            0.0000
5545  1000000000.00000           0.0000            0.0050
5546  7000000000.00000           0.0000            0.0025
5547  9999999999.00000           0.0025            0.0000

[5548 rows x 3 columns]

参考文献

https://developer.oanda.com/rest-live-v20/instrument-ep/

https://developer.oanda.com/rest-live-v20/instrument-ep/

ローソクを取得したい場合はこちらをご覧ください

https://np-sys.com/hacks-with-it/oanda%e3%81%a7%e3%81%ae%e7%82%ba%e6%9b%bf%e3%83%87%e3%83%bc%e3%82%bf%e3%82%92%e5%8f%96%e5%be%97/

現在の価格をリアムタイムに欲しい場合はこちらをご覧ください

https://np-sys.com/hacks-with-it/%e3%80%90oandapyv20%e3%80%91oandaapi%e3%81%a7%e4%be%a1%e6%a0%bc%e3%82%92streaming%e9%85%8d%e4%bf%a1%e3%81%a7%e5%8f%96%e5%be%97%e3%81%99%e3%82%8b/

【oandapyV20】OandaAPIで価格をStreaming配信で取得する

1

この記事ではoandapyV20を使ってStreaming配信でリアルタイムに価格を取得する方法について記載します。

Streaming配信は非常に便利であるものの、最大で250msごとのデータしか提供されませんので急激な値動きまで把握できるわけではない事に注意が必要です。公式では「1秒間に4回のウィンドウを作成し、それぞれのウィンドウの最後で有効な値を返す」という記載があります。詳細は記載されていないものの、250ms程度のデータであること、アカウントごとにデータを生成するので、すべての人に同じデータが配信されるわけではない事に留意が必要です。

ストリーミング配信は/v3/accounts/{accountID}/pricing/streamにGet通信でアクセスする事で提供されます。

oandapyV20を使った基本のコードはこちらです(ドル円の価格を取得)。

# -*- coding: utf-8 -*-
import json
from oandapyV20 import API
from oandapyV20.endpoints.pricing import PricingInfo
from oandapyV20.exceptions import V20Error
import oandapyV20.endpoints.pricing as pricing
import oandapyV20.endpoints.instruments as instruments
import datetime
import pandas

def main():
    account_id="XXX-XXX-XXXXXXX-XXX"
    access_token = "******************************************************************"
    api = API(access_token=access_token, environment="practice")#or live

    params ={
            "instruments": "USD_JPY,EUR_JPY"
            }
    r = pricing.PricingStream(accountID=account_id, params=params)
    rv = api.request(r)
    maxrecs = 100
    for ticks in rv:
        print(json.dumps(ticks, indent=4),",")
        if maxrecs == 0:
            r.terminate("maxrecs records received")

if __name__ == "__main__":
    main()

これを実行すると、価格のリアルタイムデータが取得でします。ticksという変数にはこのような値が入ります。

{
    "type": "PRICE",
    "time": "2020-12-04T21:59:55.602697089Z",
    "bids": [
        {
            "price": "104.185",
            "liquidity": 250000
        }
    ],
    "asks": [
        {
            "price": "104.191",
            "liquidity": 250000
        }
    ],
    "closeoutBid": "104.177",
    "closeoutAsk": "104.199",
    "status": "non-tradeable",
    "tradeable": false,
    "instrument": "USD_JPY"
} ,

基本的には通貨ペア(Instruments)しかカスタマイズしないと思います。通貨ペアを変更したいときはparamsの値を変えてください。2つ以上のペアを同時にデータ取得したいときは、paramsにそれぞれのペアをカンマで区切って指定すればOKです。例えば、2つを指定したいときはこのように指定します。

    params ={
            "instruments": "USD_JPY,EUR_JPY"
            }

そうすると下記のデータが返ってきます。

{
    "type": "PRICE",
    "time": "2020-12-04T21:59:53.324563034Z",
    "bids": [
        {
            "price": "126.254",
            "liquidity": 250000
        }
    ],
    "asks": [
        {
            "price": "126.320",
            "liquidity": 250000
        }
    ],
    "closeoutBid": "126.238",
    "closeoutAsk": "126.336",
    "status": "non-tradeable",
    "tradeable": false,
    "instrument": "EUR_JPY"
} ,
{
    "type": "PRICE",
    "time": "2020-12-04T21:59:55.602697089Z",
    "bids": [
        {
            "price": "104.185",
            "liquidity": 250000
        }
    ],
    "asks": [
        {
            "price": "104.191",
            "liquidity": 250000
        }
    ],
    "closeoutBid": "104.177",
    "closeoutAsk": "104.199",
    "status": "non-tradeable",
    "tradeable": false,
    "instrument": "USD_JPY"
} ,
{
    "type": "HEARTBEAT",
    "time": "2020-12-06T11:28:32.333476447Z"
} ,

リアルタイムでデータが取得できるのはとても便利です。

通貨ペアの指定について

円関連

“USD_JPY”,’EUR_JPY’,’GBP_JPY’,’AUD_JPY’,’NZD_JPY’,’CAD_JPY’,’CHF_JPY’,

ドル関連

“EUR_USD”,’GBP_USD’,’AUD_USD’,’NZD_USD’,’USD_CAD’,’USD_CHF’,’USD_CNH’,

ユーロ関連

‘EUR_GBP’,’EUR_AUD’,’EUR_NZD’,’EUR_CHF’,’GBP_AUD’

参考文献

https://developer.oanda.com/rest-live-v20/pricing-ep/

https://developer.oanda.com/rest-live-v20/pricing-ep/

ローソクチャートを取得したいときはこちらの記事をご覧ください。

https://np-sys.com/hacks-with-it/oanda%e3%81%a7%e3%81%ae%e7%82%ba%e6%9b%bf%e3%83%87%e3%83%bc%e3%82%bf%e3%82%92%e5%8f%96%e5%be%97/

【oandapyV20】OandaAPIでローソクを取得

1

この記事ではoandapyV20を使ってローソクチャートを取得する方法について記載します。ローソクの長さ、取得データの種類、取得期間の指定方法なども含めて記載します。

oandapyV20では、PricingInfoというクラスで/v3/instruments/{instrument}/candlesをGet通信で叩いています。

ドル円のローソクチャートを取得基本のコードはこちらです。

# -*- coding: utf-8 -*-
import json
from oandapyV20 import API
from oandapyV20.endpoints.pricing import PricingInfo
from oandapyV20.exceptions import V20Error
import oandapyV20.endpoints.instruments as instruments
import datetime
import pandas

def main():
    account_id="XXX-XXX-XXXXXXX-XXX"
    access_token = "***************************************************************"
    api = API(access_token=access_token, environment="practice")#or live

    params = {"instruments": "USD_JPY"}
    pricing_info = PricingInfo(accountID=account_id, params=params)


    r = instruments.InstrumentsCandles(instrument="USD_JPY",
                                    params={
                                        "granularity": "S15", # ロウソク足の種類を選択
                                        "alignmentTimezone": "Japan", # タイムゾーン
                                        #"from":datetime.datetime.now()
                                    }
    )
    data = api.request(r)
    for candle in r.response["candles"]:
        print(candle)

if __name__ == "__main__":
    main()

データの返り値であるcandleの変数には下記の値が入ります

(Pdb) candle
{'complete': True, 'volume': 117597, 'time': '2020-11-05T08:00:00.000000000Z', 'mid': {'o': '104.314', 'h': '104.388', 'l': '103.360', 'c': '103.424'}}

ローソク足の長さを指定する

上記ではローソクの長さを15秒に指定しますが、最短で5秒、最大で1ヶ月まで変更できます。oandapyV20では、InstrumentsCandlesをインスタンス化する際のparamという変数で様々な取得条件を指定しますが、ローソク足の長さはgranularityというキーで指定します。これに対応する値は文字列型で下記で指定します。

    r = instruments.InstrumentsCandles(instrument="USD_JPY",
                                    params={
                                        "granularity": "S15", # ロウソク足の種類を選択
                                        "alignmentTimezone": "Japan", # タイムゾーン
                                        #"from":datetime.datetime.now()
                                    }
    )
引数間隔
S55秒間
S1010秒間
S1515秒間
S3030秒間
M11分間
M22分間
M33分間
M44分間
M55分間
M1010分間
M1515分間
M3030分間
H11時間
H22時間
H33時間
H44時間
H66時間
H88時間
H1212時間
D1日
W1週間
M1ヶ月

総データ取得期間の指定

総データ取得期間を指定する際は、同様にparamという辞書の中で指定します。この中でfromとtoというキーで時間を「文字列型」のUNIXTIMEで指定します。

r = instruments.InstrumentsCandles(
                        instrument="USD_JPY",
                        params={
                            "granularity": "D",
                            "alignmentTimezone": "Japan",
                            "from":str((datetime.datetime.now()-datetime.timedelta(days=30)).timestamp()),
                            "to":str((datetime.datetime.now()-datetime.timedelta(days=25)).timestamp())
                            }
                        )

キャンドルの本数の指定

データの期間を指定する代わりに、キャンドルの本数で総データ取得期間を指定することもできます。デフォルトは500本となります。キャンドルの本数で帰って来るデータの量を指定したい場合はcount引数を整数で指定します。なお、期間をfrom,toで指定した場合こちらは使用できません。countの最大は5000本です。

r = instruments.InstrumentsCandles(
instrument="USD_JPY",
params={
"granularity": "D",
"alignmentTimezone": "Japan",
"count":100}
)

ローソクの価格種を指定する

ask,bid,middleのいずれのローソクを取得するかについてはparamsでpriceキーで指定できます。“M” はmidpoint candles、 “B” はbid candles)、 “A” はask candlesとのことで、デフォルトは”M”となります。

midの場合

(Pdb) candle
{'complete': True, 'volume': 117597, 'time': '2020-11-05T08:00:00.000000000Z', 'mid': {'o': '104.314', 'h': '104.388', 'l': '103.360', 'c': '103.424'}}

bidの場合

(Pdb) candle
{'complete': True, 'volume': 117597, 'time': '2020-11-05T08:00:00.000000000Z', 'bid': {'o': '104.308', 'h': '104.382', 'l': '103.354', 'c': '103.418'}}

通貨を指定する

これはinstrument引数で指定します。通貨のペアを/ではなく_でつないで指定します。

例えば,よく使うものを列挙すると

ペアコード
ドル円USD_JPY
ドルユーロEUR_USD
ユーロ円EUR_JPY

https://www.oanda.jp/course/currencypair

参考文献

https://oanda-api-v20.readthedocs.io/en/latest/endpoints/instruments/instrumentlist.html

https://developer.oanda.com/rest-live-v20/instrument-ep/

リアルタイムでデータを取得したい場合はこちらの記事をご覧ください。

https://np-sys.com/hacks-with-it/%e3%80%90oandapyv20%e3%80%91oandaapi%e3%81%a7%e4%be%a1%e6%a0%bc%e3%82%92streaming%e9%85%8d%e4%bf%a1%e3%81%a7%e5%8f%96%e5%be%97%e3%81%99%e3%82%8b/

Adsenseの住所確認の日数と手順について

1

Google Adsenseでは、収益が1000円程度を超えると住所確認のために郵送でPINコードが発送されます。振り込み準備に向けて、これに印字された6桁の番号をAdsenseのHPで入力し、住所が正しいことを認証伝えておく必要があります。記載された通りに実施するとうまくいきませんので、この方法について解説します。

Adsenseからメールが届きます

収益が一定を超えると、Adsenseからメールが届きます。

Screenshot
AdSense でお知らせいただいたお支払い先住所宛に、個人識別番号(PIN)を記載したハガキを 11月 18, 2020 付で発送いたしました。
ハガキが届きましたら、このメールにある [住所を確認する] をクリックし、AdSense のホーム画面で PIN をご入力ください。あるいは AdSense アカウントにログインして、ホーム画面で直接、同じ手順を行っていただくこともできます。
重要: この PIN による住所確認が最初の郵送日から 4 か月以内に行われなかった場合、広告配信が停止されますのでご注意ください。

4ヶ月以内に行わないと広告停止されると書いてありますが、葉書が到着するまでに結構時間がかかるので不安になります。日本では結構時間がかかるようで心配は入りません。私は2つのサイトで実施したことがありますがそれぞれ3週間弱かかりました。直近のサイトについては、11月18日発送で自宅に届いたのは12月4日でした。18日かかったことになります。

PINの入力方法

葉書の通りにやってもうまくいきません。葉書では歯車のアカウントからPINを送信してくださいと書いてありますが、アカウント の画面にはPINのことなど書いておりませんPCでAdsenseにログインして、トップページから辿る必要があります。

Screenshot

赤丸で囲ったところから入力するようにしてください。

PythonとAngularの組み合わせが最強な理由

1

クロスプラットフォームは生産性が高い

 なにかをサービスインしようとしたとき、Androidだけ、iOSだけ、あるいはWebだけというのは片手落ちです。だからといってAndroid用にKotlinで開発し、iOS用にSwiftで開発し、そしてWeb用にも別個に開発など現実的ではありません。

 すでに大成功しているソフトならもちろんありですが、現実はうまくいくか保証のないまま開発し、なるべく多くのユーザーに使ってもらいながら成功につなげていきたいと考えると思います。だからこそ、クロスプラットフォームであることは特に個人や小規模の開発チームにとって必須のツールとなると考えています。

ここでは、フロントエンドとしてAngular,バックエンドとしてPythonという組み合わせがメリットの大きな組み合わせであることを解説します。

どこのプラットフォームを抑えるか

すぐに思いつくプラットフォームとしては、デスクトップ、スマホアプリ、Webです。

  • デスクトップアプリ
    Linuxは置いておいてもMacとWindowsがあります
  • スマホアプリ
    AndroidとiOSがあります
  • Web
    これはユーザーに非常に簡単にアクセスできるプラットフォームとして外すことはできないです

ユーザーは各プラットフォームに分散していますが、個人的にはWebとスマホアプリを抑えればほとんどカバーできると考えており、デスクトップアプリの優先度は低いと思っています。したがって、クロスプラットフォームの環境はUnity,Xamarin,Cordova,Ionic,React,Capacitorなどがあると思いますが、Ionic,React,CordovaなどのWeb系の技術が選択肢として残ります。

さらにそのなかでどのフレームワークが強いかをこちらの記事で考えたのですが、私の意見ではAngularが断然オススメです。

https://np-sys.com/general/%e5%80%8b%e4%ba%ba%e3%83%bb%e5%b0%91%e4%ba%ba%e6%95%b0%e3%81%ae%e3%82%b7%e3%82%b9%e3%83%86%e3%83%a0%e9%96%8b%e7%99%ba%e3%81%ab%e3%81%afangular%e3%81%8c%e3%82%aa%e3%82%b9%e3%82%b9%e3%83%a1/

バックエンドはどうするか

Angularでフロントエンドを書くとするとバックエンドはどうすればいいでしょうか。TypeScriptが使えるのでnode.jsで書くのはもちろんいいと思います。PHPエンジニアもいると思います。

 ただ、わたしはバックエンドはPythonが好きです。もともとPythonがもっとも馴染みのある言語ということがありますが、バックエンドというのはデータ処理が少なからずあると思うのです。例えばAIを搭載したアプリケーションを開発する場合を考えた時、AIはほぼPython一択です。そうでなくても多くのデータ処理を実行する可能性は多いにあるため、node.jsでもなくPHPでもなく、バックエンドはPythonが汎用性が高いと考えます。Pythonで書いておけばカバー範囲が広いと思っており、バックエンドはPythonで作成したAPIで担当させておいて、AngularからそのAPIを叩いてデータ処理を行うというイメージです。

組み合わせるとどうなるか

 AngularをIonicで使用すると、見た目は完全にNativeになります。Nativeに比べると挙動が遅いということですが(https://developer.medley.jp/entry/2017/11/24/120000)、現在のスマートフォンの性能なら描写の多いゲームなどを除いてまったく問題ならないと思います。したがって、Ionicで開発しておけば、ひとつのプロジェクトをつくるだけでAndroid,Web,iOSのプラットフォームに高いクオリティでビルドできます。そしてバックエンドはPythonで受ける。これによって高い生産性と拡張性を備えたシステムが開発ができると考えているため、これが個人の開発や小規模でも開発を実施する場合私の考える最強の組みわせです。

榊原昌彦さんのコメント

とても共感したので、こちらの著者である榊原昌彦さんの冒頭の挨拶を引用させていただきます。

大きく変わったWebの価値Web技術で作ることができるプロダクトの選択肢は大きく増えました。Web Native開発フレームワークの「Ionic Framework」を使えば、Mobile Native,と同じようなUIとUXをユーザに提供することができます。クロスプラットフォームライブラリ「Capacitor」を利用すれば、Webアプリを「App Store」(iPhone/iPad) や「Google Play」(Android)で配信することができます。Google Chromeをはじめとしたインターネットブラウザも大きく進化しました。モバイルアプリ同等のUX(ユーザ体験)を提供することを目指して、今までモバイルアプリでしか実現できなかったプッシュ通知やオフラインでの表示、高精度GPSといった機能をWebで提供できます。また、「Electron」というWebアプリをデスクトップアプリにすることができるフレームワークが利用されるシーンも増えています。今では、WebアプリのプラットフォームはWebだけではなくなり、1つのプロダクトをiOS、Android、デスクトップへと、ハイブリッドに展開できるようになっています。Webとモバイルの境目がなくなりつつある多くのWebサイト、Webアプリではモバイルデバイスからのアクセス数が増え続けており、モバイルファースト(モバイルデバイスを利用するユーザを優先した設計)が当たり前になりつつあります。ユーザが、「ホーム画面に追加」という機能を使えば、Webをモバイルアプリのように利用できます。Webアプリとモバイルアプリの違いは、アプリストアからインストールするか、ブラウザからアクセスするかの違いになりつつあります。その中で、ハイブリッドに展開する大きなメリットは「そこにユーザがいるから」です。皆さんが作ろうとしているアプリのユーザは、Webブラウザをよく使いますか? Androidユーザが多いですか? もしかすると、App Storeでアプリを探すような人かもしれません。Webとモバイルの境目がなくなりつつある今だからこそ、プラットフォームに依存しない形であなたのアイデアを実現できることは大きな武器になります。

個人的にはこれにPythonを加えると最強だと考えています。

最後に

写真から文字情報を抽出して爆速でレポートや記事を作成するアプリを作成しています。無料なのでよかったらどうぞ。フロントエンドはIonicでCapacitorを使って開発し、バックエンドはGCPのApp EngineをPythonで書いてます。

iOS => https://apps.apple.com/app/id1497498494
Android => https://play.google.com/store/apps/details?id=com.rainbowsv2.ocr

Cloud functionsからFirestoreのStorageにアクセスして、VisionAIをつかう

1

Cloud functionsからFirestoreのStorageにアクセスして、VisionAIをつかうにあたってかなり苦労したので、ポイントをまとめておく。

1。Cloud functionにサードパーティのPythonのライブラリを使う場合、requrements.txtを書く必要がある。

2。Firebaseのデータにアクセスする場合、firebaseのプロジェクトの歯車マークから、Python用の設定ファイル(json)をダウンロードし、Cloud FUnctionsにソースコードで登録する必要がある。

import firebase_admin
from firebase_admin import credentials
from firebase_admin import storage
cred = credentials.Certificate(“ダウンロードしたファイル”)
firebase_admin.initialize_app(cred, {
‘storageBucket’: ‘ストレージなら、そのばけえと’
})

2.5 Storageからデータを取得して、一度PILの形式にする

source_blob_name = “ふあいるに名前”
blob = bucket.get_blob(source_blob_name)
img_file = io.BytesIO()
blob.download_to_file(img_file)
img = Image.open(img_file)

3。Vision AIに渡すデータは、base64の必要がある。
output = io.BytesIO()
img.save(output, format=’PNG’)
image3 = output.getvalue()

image_g = types.Image(content=image3)

response = vision_client.document_text_detection(image=image_g)
labels = response.full_text_annotation

4。VisionAIを使うためには、VisionAIのAPIを有効にしておく必要がある。ローカルで動かす場合は、それをダウンロードしてパスに設定する必要がある。

https://cloud.google.com/vision/docs?_ga=2.249257607.-1213108839.1578707642

5。cloud functionsをデプロイするのはgcloudを使った方がやりやすかった。なので、gcloudもインストールする必要がある。

使ったgcloudのコメント

https://qiita.com/masaaania/items/7a83c5e44e351b4a3a2c

gcloud functions deploy myfunc2 –trigger-http –runtime=python37
gcloud config configurations list
gcloud projects list
gcloud config set project projectname

GoogleCloudFunctionsのデプロイ方法

Console

Consoleのインラインエディタから直接書き込む方法、ローカルのzipファイルをConsoleからアップロードする方法、ローカルのファイルをgcloudコマンドでアップロードする方法の3つがある。最初はお試しでバージョン管理もできないの。2番目は理由不明で失敗する。なので3番目が一番いい。

手順としては、gcloudコマンドを使う際、現在のプロジェクトが正しいことを確認

https://qiita.com/masaaania/items/7a83c5e44e351b4a3a2c

次に、アップロードしたいファイルがある場所へ移動し、そこでterminalを開く

gcloud functions deploy myfunc2 –trigger-http –runtime=python37

以前はこれでいけたが、いまはこっちらのほうがいい

gcloud functions deploy Gcloudのファンクシィン –entry-point Pythonプログラムの関数の名前 –runtime python37 –trigger-http –allow-unauthenticated

https://cloud.google.com/functions/docs/deploying/filesystem?hl=ja

wiredxdisplayを入れたらadbコマンドが使えなくなった

1

結論を知れば当然なのだろうけどかなりはまった。

スマホをセカンドディスプレイにできるソフトがあるときいてインストールした。wiredxdisplayというもの。かなり便利だった。
https://www.splashtop.com/wiredxdisplay
 

しかし、それを使って気分よく開発したプロジェクトをadbコマンドでインストールしようとするとエラーがでる。当初は、wiredxdisplayをいれたことの影響など考えていなかったから全く原因がわからず苦労した。

パス周りを確認すると、どうもadbの実行ファイルが2つあるということしか考えられず、adbの実行ファイルがどこにあるかしらみつぶしに調べるために

find . -name ‘adb’ 2> /dev/null

で調べてみると、

./Users/hoge/Library/Android/sdk/ndk/20.0.5594570/python-packages/adb

./Applications/Splashtop XDisplay.app/Contents/MacOS/adb

と出てきた。あぁ、そうか、スマホをセカンドディスプレイとして使用するのにadb使ってるわな、と納得し、一件落着。。バージョンおなじなら両立するのにな。。

と思ってこの記事を書いた後、試してみたら両立した!

wiredxdisplayのadbファイルのある

/Applications/Splashtop XDisplay.app/Contents/MacOS

にいって、

cp /Users/hoge/Library/Android/sdk/platform-tools/adb ./adb

でAndroidstudioのadbをコピーしたら、両立して使えるように。いや、たいへんだった。

CordovaがiOSで使えなくなる!?AppleがUIWebView をなくすことについて

1

2019年8月ごろから、cordovaで作成したアプリをアップロード すると不吉なメールが届きます.

ITMS-90809:廃止されたAPIの使用-AppleはUIWebView APIを使用するアプリの提出を受け付けなくなります。詳細については、https://developer.apple.com/documentation/uikit/uiwebviewを参照してください。

ITMS-90809: Deprecated API Usage – Apple will stop accepting submissions of apps that use UIWebView APIs . See https://developer.apple.com/documentation/uikit/uiwebview for more information.

先日(2020年2月)にこのアプリをiOSに出したときもこのメッセージを受け取ってしまいました。
2020年3月の情報によるとUIwebviewを使ったアプリの受付は、


新規アプリ受付→2020年4月まで
既存のアプリ更新→2020年12月まで

とのことです。

詳しく公式のサイトを見ると、「class UIWebView : UIView」という宣言がだめなようです。なので今後はWKWebViewをつかうことになります。WKWebViewはUIWebViewの問題を解決するためにAppleが作ったWebViewです。UIWebViewよりクラッシュ率が低く、高速で、加えてセキュリティも高くなっているのでセキュリティを重視するAppleとしては他社に先駆けてWKWebViewへ移行するわけです。おそらく近いうちにGoogleも追随するのではないかと考えます。

Cordovaのコミュニティが対策を進めてくれているようですので、簡単にまとめます。

こちらはCordovaを管理してくれているMatt Netkowさんのページ。こちらに最新の情報が記載されています。さて、あらためてこの件についてなんといっているかについて。

Update 01/15/2020: On December 23rd, 2019, Apple clarified plans for UIWebView: “The App Store will no longer accept new apps using UIWebView as of April 2020 and app updates using UIWebView as of December 2020.” Please follow the instructions below to either update to a newer version of Cordova or migrate to Capacitor.

更新01/15/2020:2019年12月23日、AppleはUIWebViewの計画を明確にしました:「App Storeは、2020年4月の時点でUIWebViewを使用する新しいアプリおよび2020年12月の時点でUIWebViewを使用するアプリの更新を受け付けなくなります。」以下の指示に従って、Cordovaの新しいバージョンに更新するか、Capacitorに移行してください。

だいぶ前に周知してくれていたようです。結論としては、Capacitorに移行するか、新しいCordovaにアップデートすればよいようです。CordovaがコンパイルのときにUIWebviewを使わないようにCordova5.1.0から行うようです。

以前はIonicなどのはなしも記載されていたようで下記のような表をまとめたりしたのですが、

Cordova草分けであり、もっともメジャーなプロジェクト
IonicCordovaにangularを組み込むことで、UIの作業性を改善したものです。Cordovaという大きな円を書くと、Ionicはそのなかにあるイメージ。
CapaciterIonicのコンセプトをより推し進めた次世代のプロジェクト。将来的にはCordovaの次世代を担うとされていて、Ionicのメンバーもそう言っている。とはいえまだ出たばかりで洗練されてないところがある。でも使える。

最新のCapacitorを選ぶもよし、一方でCordova5.1.0にすればいいということで安心しました。Capacitorを使う方法は別に調べる人は調べると思うので、今回は最後にCordovaでなんとかしたい人向けに上記Webページの該当部分を訳して置いておきます。

WKWebViewプラグインがインストールされていることを確認してください:公式のApacheまたはIonicのいずれか。すべてのIonicスターターアプリには、cordova-plugin-ionic-webviewが自動的に含まれます。
<preference name = "WKWebViewOnly" value = "true" />をconfig.xmlファイルに追加します。
各Cordovaプラグインを最新バージョンに更新します(これらも警告をトリガーできます)。いっそのこと-不要になったら削除してください!
cordova prepare iosを実行して、変更を適用します。

わたしが作ったアプリはこちらです。写真からテキストを抽出するOCRソフトです。よかったらインストールしてみてください。

https://play.google.com/store/apps/details?id=com.rainbowsv2.ocr

無料の動画の上下切り抜き方法

1

こんな簡単なことなのに手間取った。

Avidemuxでできた。言葉は、クロップ、クロッピングというらしい