teratail header banner
teratail header banner
質問するログイン新規登録

質問編集履歴

2

コードを整理して本文も書き直しました

2020/07/28 12:23

投稿

khalipon
khalipon

スコア2

title CHANGED
File without changes
body CHANGED
@@ -1,82 +1,100 @@
1
+ 追記を繰り返すと長文になってしまうので、整理して書き直すことにします。
1
- 仮想通貨のアービトラージ(裁定取引)の機会がどのくらいあるのかチェックしたいと思っています。
2
+ GAS24時間動かしたいのでUrlFetchを使う回数を減らすためにコードは書き直しています。
2
3
 
3
- 取引所からの各コインの価格データスプレッドシートに取り入れ、それを
4
+ 仮想通貨の3通貨を使ったアビトラのチャンスを伺うために取引所のCoinEXからコインの価格を
5
+ 取ってきています。
4
6
 
7
+ アルトコイン>基軸通貨1>基軸通貨2>元のアルト と交換する場合、交換手数料を含めないとしても
8
+ コインの枚数は増減します。仮に2%減った場合は、逆の回し方をして、アルト>基軸2>基軸1>アルト
9
+ と回せば増やせると思ってます。
5
10
 
6
- 仮想通貨めぼし銘柄を、基軸通貨を間に2つ挟ん同一取引所内の3通貨に交換た場合、
11
+ CoinEX価格データはtradingviewで拾えなAPI直接取るかないので
7
- どのくらいの頻度でさやが発生するのかを調べたいのですが
8
- 例えばATOM>BTC>BCH>ATOM だとXRP>BCH>BTC>XRPといったいくつかの
12
+ dosのbatファイル位しったことがなったですが、四苦八苦しながら進めています。
9
- ルートでの増減率を調べています。
10
13
 
11
- 上記のATOM>BTC>BCHルートの場合、
14
+ ##一覧表は大まかにはできました
15
+ A列B列 >tickerデータをgetRangeでごちゃごちゃ置いてます。
12
- A1セにルート名として"ATOM-BTC-BCH"記入
16
+ C 列 >ルート名です ATOM>BTCBCH だか ATOM>BCH>BTC といった具合です。
13
- B1セルからN1まで、取引所から取得したそれぞれの通貨の価格を取得し、枚数を順番に計算
17
+ D列~R列 >計算式をいれます。
14
- O1セ最終的なATOM枚数%でみちびいたとします。99.75%だしたら0.25%減ったことになりますし
18
+ S列 >アビトラ開始前のアトが最終的に何%にったます。99.34あれば0.66%減ことになり
15
- 100.5%だしたら0.5%増えたのだします。
19
+  100.5とあれば0.5%増えた いう具合です。
20
+ U列 >判定列です。S列の値が101.5以上あった場合はメール通知したいので =IF(S6>=101.5,"送信"," ") のように
21
+  入れて、送信判定の時は送信というキーワードを表示させ、それ以外は空白にしています。送信というキーワード
22
+  がある行の、C,S列を本文としてメールを送信します。 ATOM>BTC>BCH 101.6 といった具合です。
23
+  一度に複数行が「送信」判定の場合に1回のメールにする方法があるのかもしれませんが、とりあえず
24
+  送信判定数のメールで構わないと思っています。
25
+  onEdit? とかでトリガーを指定できるのかもしれませんがやり方がよくわからないので、
26
+  トリガーの追加から、スプレッドシートを変更時をトリガーとして設定できるかなと思ってます。
27
+  (が まだ試してません。)
16
28
 
17
- UrlFetchは1回の実行で13回程に抑え、分ベースのタイマーで1分ごとにトリガーさせようと思います。
18
-
19
- ここまでは出来たのですが、O列である一定以上の数値、たとえば101%以上になった時
20
- にアラートのメールを送信するようにしたいのですがどのようにすればよいのかわかりません。
21
-
22
- たとえばO1が101%に、A1のルート名 "ATOM-BTC-BCH" 、そしてO1の値 "101%" をメールの本文として、メールのタイトルは
23
- ”価格アラト”とし送信したいです。
29
+ ##tickerデタを取っくるコード
24
-
25
- コード.gsなのですが
30
+ ```
26
31
  function myFunction(){
27
- SpreadsheetApp.getActiveSpreadsheet().getRange("C1").setValue( JSON.parse(UrlFetchApp.fetch("https://api.coinex.com/v1/market/ticker?market=ATOMBTC")) ["data"]["ticker"]["last"]);
32
+ var ss = SpreadsheetApp.getActiveSpreadsheet();
28
- SpreadsheetApp.getActiveSpreadsheet().getRange("G1").setValue( JSON.parse(UrlFetchApp.fetch("https://api.coinex.com/v1/market/ticker?market=BCHBTC")) ["data"]["ticker"]["last"]);
33
+ var response = UrlFetchApp.fetch("https://api.coinex.com/v1/market/ticker/all");
29
- SpreadsheetApp.getActiveSpreadsheet().getRange("K1").setValue( JSON.parse(UrlFetchApp.fetch("https://api.coinex.com/v1/market/ticker?market=ATOMBCH")) ["data"]["ticker"]["last"]);
30
- SpreadsheetApp.getActiveSpreadsheet().getRange("C2").setValue( JSON.parse(UrlFetchApp.fetch("https://api.coinex.com/v1/market/ticker?market=XRPBTC")) ["data"]["ticker"]["last"]);
34
+ var ATOMBTC = JSON.parse(response)["data"]["ticker"]["ATOMBTC"]
35
+ ss.getRange("A9").setValue(ATOMBTC["buy"]);
36
+ ss.getRange("A10").setValue(ATOMBTC["sell"]);
31
- SpreadsheetApp.getActiveSpreadsheet().getRange("K2").setValue( JSON.parse(UrlFetchApp.fetch("https://api.coinex.com/v1/market/ticker?market=XRPBCH")) ["data"]["ticker"]["last"]);
37
+ var ATOMBCH = JSON.parse(response)["data"]["ticker"]["ATOMBCH"]
38
+ ss.getRange("A11").setValue(ATOMBCH["buy"]);
39
+ ss.getRange("A12").setValue(ATOMBCH["sell"]);
32
40
  }
33
- の下に付け加えるように、
41
+ ```
34
- function sendNotification() {
42
+ こんな感じで調べたい通貨ペアの買値と売値をA,B列に置いてます。
35
- }
43
+ 3行目のUrlFetchAppで5000文字以上のデータを一度に取ってきています。
44
+ データを一度に取ってからそのresponseを個別にパースしていいのかな?と思ったらできるみたいなので
36
- た形で記述しいくのでしょうか?
45
+ これで進めようってます。
37
46
 
47
+ このmyFunctionは分ベースのトリガーで動かしたいので1日に1440回起動することになります。
48
+ ということは1日20000回の縛りに収めるために、5秒ことにループさせてもいいのかなと思います
49
+ (が その場合さやが開いてる間、5秒ごとにメールが来てしまいます)
38
- こちらを見ると>> https://teratail.com/questions/155111#_=_
50
+ ループさせる場合にSpreadsheetApp.flush();を使うのは前回こちらで教えてもらったので
51
+ こうなるのかなと思います。
52
+ ```
39
- function onEdit(e) {
53
+ function myFunction(){
54
+ var i = 1 ;
55
+ while(i <= 13) {
56
+ var ss = SpreadsheetApp.getActiveSpreadsheet();
57
+ var response = UrlFetchApp.fetch("https://api.coinex.com/v1/market/ticker/all");
58
+ var ATOMBTC = JSON.parse(response)["data"]["ticker"]["ATOMBTC"]
59
+ ss.getRange("A9").setValue(ATOMBTC["buy"]);
60
+ ss.getRange("A10").setValue(ATOMBTC["sell"]);
61
+ var ATOMBCH = JSON.parse(response)["data"]["ticker"]["ATOMBCH"]
62
+ ss.getRange("A11").setValue(ATOMBCH["buy"]);
63
+ ss.getRange("A12").setValue(ATOMBCH["sell"]);
64
+ SpreadsheetApp.flush()
65
+ Utilities.sleep(5000)
66
+ i++
67
+ }
68
+
40
69
  }
41
- となっており、それが理にかなっているような気もしています。
42
-
43
- どなたかアドバイスよろしくお願いいたします。_(._.)_
44
-
45
-
46
- 追記です
70
+ ```
47
- あれらいろいろ参考にしがら試してます。
71
+ ##なんうまく行かない送信部分
48
-
49
- P1に "=IF(O1>=100.5,"送信","false")" と入れて、O列の値が0.5%以上のさやが開く時に
50
- 「送信」判定を入れるするようにしました。
51
-
52
- その上で下記のコードを入れ、送信 という文字の入った行のA、Oの値をメール本文として
72
+ 送信というキーワードを含む行のCS列を本文にいれたメールを送信する部分です。
53
- 送信するようにしました。
73
+ ```
54
-
55
74
  function sendmail() {
56
- var ss = SpreadsheetApp.getActive().getSheetByName('シート1');
75
+ var ss = SpreadsheetApp.getActive().getSheetByName('シート1');
57
- var lastRow = ss.getLastRow();
76
+ var lastRow = ss.getLastRow();
58
- var address = 'aaa@bbb.com';
77
+ var address = 'kkk@gggl.com';
59
- var options = {name: 'アビトラアラート'};
78
+ var options = {name: 'アビトラアラート'};
60
-
79
+ var MailText = rangeC +" "+ rangeS;
80
+ var subject = "GASからの送信";
61
- for(var i=2; i<=lastRow; i++){
81
+ for(var i=2; i<=lastRow; i++)
82
+ {
62
- if (ss.getRange(i, 16).getValue() == "送信"){
83
+ if (ss.getRange(i, 21).getValue() == "送信")
84
+ {
63
- var rangeA = ss.getRange('A' + i).getValue();
85
+ var rangeC = ss.getRange('C' + i).getValue();
64
- var rangeO = ss.getRange('O' + i).getValue();
86
+ var rangeS = ss.getRange('S' + i).getValue();
65
- }
87
+ }
66
-
67
- var MailText = rangeA +" "+ rangeO;
68
- var subject = "GASよりメール送信";
88
+ }
69
- GmailApp.sendEmail(address, subject, MailText,options );
70
89
 
90
+ GmailApp.sendEmail(address, subject, MailText,options );
71
- }
91
+ }
72
- }
92
+ ```
73
93
 
74
- ろが、該当からのメールが2,3ずつ送信されてしうようです。
94
+ れを実すると、本文とタイトルが「undefined undefined」のメールがだけ来ます。
75
- 2通だったり3通だったり不規則なですが、実際はもっと多数送信処理
95
+ GmailApp.sendEmail前の } 1つ後ろに持ってくると同じメールが8つ程来てから
76
- 始めているのでサーバーがすぐに停止処理してるのかもしれせん
96
+ Exception: 1 日にサービス email を実行した回数(行 17、ファイル「コード」) というエラー
97
+ になりました。
77
98
 
99
+ さっきまでは、本文にC列S列が入ったメールが複数ずつ来てたのですが今回はundefinedです。
78
- 何回かテストするけで、GASからは Exception: 1 日にサービス email を実行した回数が多すぎます。行 15、ファイル「コード」
100
+ んだんわからなくなってきました(24時間sendEmailが使えなくなりました~
79
- のエラーが来てしまいます。
80
-
81
- 何が原因なのでしょうか、、、、?
82
- どなたかよろしくお願いいたします。

1

O列の値をP列にて判定し、判定されたキーワードを含む行のA列とO列の値をメール本文に書き入れることには成功しましたが、、、

2020/07/28 12:23

投稿

khalipon
khalipon

スコア2

title CHANGED
File without changes
body CHANGED
@@ -40,4 +40,43 @@
40
40
  }
41
41
  となっており、それが理にかなっているような気もしています。
42
42
 
43
- どなたかアドバイスよろしくお願いいたします。_(._.)_
43
+ どなたかアドバイスよろしくお願いいたします。_(._.)_
44
+
45
+
46
+ 追記です
47
+ あれからいろいろ参考にしながら試しています。
48
+
49
+ P1に "=IF(O1>=100.5,"送信","false")" と入れて、O列の値が0.5%以上のさやが開く時に
50
+ 「送信」判定を入れるするようにしました。
51
+
52
+ その上で下記のコードを入れ、送信 という文字の入った行のA列、O列の値をメール本文として
53
+ 送信するようにしました。
54
+
55
+ function sendmail() {
56
+ var ss = SpreadsheetApp.getActive().getSheetByName('シート1');
57
+ var lastRow = ss.getLastRow();
58
+ var address = 'aaa@bbb.com';
59
+ var options = {name: 'アビトラアラート'};
60
+
61
+ for(var i=2; i<=lastRow; i++){
62
+ if (ss.getRange(i, 16).getValue() == "送信"){
63
+ var rangeA = ss.getRange('A' + i).getValue();
64
+ var rangeO = ss.getRange('O' + i).getValue();
65
+ }
66
+
67
+ var MailText = rangeA +" "+ rangeO;
68
+ var subject = "GASよりメール送信";
69
+ GmailApp.sendEmail(address, subject, MailText,options );
70
+
71
+ }
72
+ }
73
+
74
+ ところが、該当行からのメールが2,3通ずつ送信されてしまうようです。
75
+ 2通だったり3通だったり不規則なのですが、実際はもっと多数の送信処理を
76
+ 始めているのでサーバーがすぐに停止処理してるのかもしれません。
77
+
78
+ 何回かテストするだけで、GASからは Exception: 1 日にサービス email を実行した回数が多すぎます。(行 15、ファイル「コード」)
79
+ のエラーが来てしまいます。
80
+
81
+ 何が原因なのでしょうか、、、、?
82
+ どなたかよろしくお願いいたします。