今日もヤバさをI/O中。

(物理的)大型エンジニアのブログです。基本的に何かが足りません。

「メッセージが少なくとも 1 回配信されること」にまつわる SQS 使う上での注意点

この記事は Willgate Advent Calendar 2018 - Qiita の 9 日目の記事です。

以前弊社のブログで、 Amazon Simple Queue Service (以下 SQS と呼ぶ) を導入した例についての記事を書きました。

tech.willgate.co.jp

当時は「メッセージが少なくとも 1 回配信されることしか保証されていない」ということがイマイチピンときていなかったため、調べながら導入・実装に当たっていました。

今回は「メッセージが少なくとも 1 回配信されることしか保証されていない」ことで、実装時に何を気をつけなければいけないか分かったことをまとめます。

保証されていることは「メッセージが少なくとも 1 回配信されること」のみ

まず前提として、SQSは「メッセージが少なくとも 1 回配信されること」しか保証されていません。そのため以下のようなことが起こります。

  • 同じメッセージを重複して取得した
  • 別のシステムからA, B, C, Dという順番でメッセージを送信したが、受信するときにはB, D, A, Cという順番で取得した。
  • SQSにメッセージが存在してるにも関わらず、空のレスポンスが返ってきた
  • 削除済みのメッセージを取得した

一つずつ見ていきましょう。

同じメッセージを重複して取得した

「少なくとも 1 回配信」ということなので、同じメッセージを複数取得することがあります。

対処法としては、「メッセージ ID を見て、重複していた時には重複を消す」といった処理の追加が挙げられます。

別のシステムからA, B, C, Dという順番でメッセージを送信したが、受信するときにはB, D, A, Cという順番で取得した

SQS にはスタンダードキューと FIFO キューというものが存在します。この現象は SQS のスタンダートキューで起きる現象です。

「キューは普通、先入先出し(FIFO)じゃないの?」というツッコミが来そうですが…残念ながら、スタンダートキューではメッセージ送信の順番は保証されていません。もし、メッセージ送信の順番を保持してほしいならば、 FIFO キューを使いましょう。

2018/12/25 現在、東京リージョンでも FIFO キューを使用することができます。 aws.amazon.com

FIFO キューを使用しないならば、パッと思いつく限りだと「メッセージに送信時間を含ませ、メッセージをキューから受け取った後に送信時間でソートする」でしょうか?

確実にできる保証はないので、出来れば FIFO キューを使う方が良いかなと思います。

SQS にメッセージが存在してるにも関わらず、空のレスポンスが返ってくる

こちらバグではなく、どうやら仕様のようです。

docs.aws.amazon.com

Amazon SQS は分散システムであるため、キューにあるメッセージが非常に少ない場合は、受信したリクエストに対して空のレスポンスを表示する場合があります。

対策としては ReceiveMessageWaitTimeSeconds を1秒以上に設定する、いわゆるロングポーリングを設定することが挙げられます。

例えば、ReceiveMessageWaitTimeSeconds を10秒に設定すると、メッセージを取得するまで最大10秒待つことになります。10秒の間にメッセージを取得できなかった時は空のレスポンスが帰ってきます。

詳しくはこちらに書いてあります。

docs.aws.amazon.com

削除済みのメッセージを取得した

こちらもバグではなく、仕様だそうです。

docs.aws.amazon.com

この場合、使用できないサーバーではメッセージのコピーが削除されず、メッセージの受信時に、そのメッセージコピーをもう一度受け取る場合があります。

どういった目的で SQS を使用するかによりますが、既にそのメッセージを使った処理が行われているか判定するロジックが必要になります。

例えば、メッセージに DB へ登録するための ID が挿入されているとします。その時は「保存先の DB を参照し、既に ID が登録されていた時にはメッセージを削除する」といった処理が必要になってきます。

まとめ

最初は SQS 特有の注意点が多くて、戸惑うことや面倒だと思うことも多いと思います。 それでも享受できるメリットの方がはるかに大きいサービスだと思いますので、是非プロダクトにてご活用ください!

ソースコードリーディングはいいぞ

この記事は Willgate Advent Calendar 2018 - Qiita 2 日目の記事です。

皆さんソースコードリーディングしていますか?お恥ずかしながら、僕は最近読むようになりました!

実際やってみると、ソースコードリーディングによって得るものが多いことを知り、今では読書感覚でフレームワークやライブラリのソースコードを読むことも…

今回は、ソースコードリーディングによって何が得られるのかについて書きたいと思います!

結論:ソースコードリーディングはアウトプットするチャンスの塊

何故ソースコードリーディングが良いのか。それは、ソースコードリーディングがアウトプットに繋がりやすいからだと僕は思います。

僕自身、アウトプットのきっかけとなっているのがソースコードリーディングによるものが一番多いです。

チャンスその1:業務で活かせる

ライブラリやフレームワークなどのソースコードを読んでいくと、細かい挙動まで処理を把握することができます。

すると、「思わぬ挙動によってバグが発生してしまった!」なんていうことを防ぐことができます。どんどん読み進んでいけば、「あのライブラリ・フレームワークについてならこの人に聞くと良いよ」という評価を得ることもできるかも…!

特にフレームワークソースコードを読むと、徐々に「良い設計とはなんなのか?」ということも学べるので、設計の勉強にもなります。

チャンスその2:ブログ記事のネタになる

ソースコードを読んだ結果わかったことをブログに書くだけで、立派なアウトプットの 1 つとなります。

僕も Laravel の Collection メソッドについて記事を書いていますが、1 メソッドだけでもなかなかの分量になります。

参考; cocoeyes02.hatenadiary.jp

チャンスその3:OSS に参加できる

ソースコードを読み進めていくと、「あれ? 何故ここでは、こんな処理が無いのだろう?」「あれ、ここにエラーハンドリングが無いのは何故だろう?」など疑問点が出てくることがあります。それは、思想によるものだったり、単なる考慮漏れだったり…様々な理由があります。

そんな時、もちろん身近で詳しい人に聞くのもありですが、issue や pull request を立てるというのも手です!

僕自身もソースコードを読んでいて、疑問に思ったことや思ったことを何回か issue に立てています。

github.com

github.com

issue や pull request を立てると GitHub では 1 contributionとして扱われるので、commit 以外でもcontributionの草を生やしていくことができます。

最後に

今回あげたアウトプットチャンスは、あくまで一例です。他にも LT 会やセッションの登壇ネタになったり、読み進めていけば執筆のチャンス…なんていうこともあるかもしれません。

「最近アウトプットしていないなあ…」と悩んでいる人は、ぜひソースコードリーディングをお勧めします!

初めてのE2E テスト( nightmare )でハマったことと解決策

この記事は Willgate Advent Calendar 2018 - Qiita の23日目の記事です。素で忘れていたため、2日遅れの記事となってしまいました…反省ですね。

皆さんは普段から E2E テスト書いていますか? 僕は、業務で初めて nightmare を使った E2E テストを書きました。

今後 E2E テストを書く上で忘れないよう、ハマったことと解決策をいくつかピックアップして書きます!

なお、今回のE2E テストというのは Web ブラウザの E2E テストを指すものとします。

「 input type="date" で上手く日付を入力できない」

.type("input[name='date']", "2018/12/25") を入力すると… f:id:cocoeyes02:20181225180521g:plain

年が6桁まで入力され、"201812/02/05"という入力になってしまいました。

input type="date" は約 27 万年まで入力することができる

input type="date" は、約 27 万年まで入力することができます。

何故そうなるかは、こちらのサイトに詳しく書いてあります。 unarist.hatenablog.com

Date 型の最大値が約 27 万なので、約 27 万年まで入力できてしまうということですね。

max="9999-12-31" を 指定する

解決策も上記の参考サイトに書いてありました。

max="9999-12-31" を 指定することによって、年が 4 桁までしか入力できなくなり nightmare でもスムーズに入力できるようになります。

E2E テストでなくても、年を 6 桁で使用することは通常ないと思いますので max 属性の指定をお勧めします。

「window.confirm() が表示されない」

js で window.confirm() によるダイアログの確認はよく使用されているかと思いますが、nightmare のテスト中では window.confirm() が表示されません。

デフォルトで表示できないようになっている

Nightmare の Readme に、こんな一文が書いてあります。

Nightmare disables window.confirm from popping up by default, (略)

github.com

そもそもデフォルトでは、表示できないようになっているんですね。

デフォルトというからには、どこか設定を変えれば表示されるのでしょうか?(残念ながら、僕は見つけることができませんでした)

window.confirm() の処理を書き換える js ファイルを読み込む

今回の場合は .inject() を使用して、window.confirm() のダイアログで OK を押したように振る舞うメソッドを用意しました。以下は使用例です。

// hoge.js
clickSubmit = () => {
    var url = 'https://hoge.com/huga/create';
    $('.piyo-form').attr('action', url);
    $('.piyo-form').submit();
}
// (略)
.inject('js', 'hoge.js')
.click('.submit-btn') 
.evaluate(() => {
    clickSubmit();
    return true;
})
// (略)

.inject() を使うと、テスト中限定で css や js ファイルを読み込むことができます。

今回は window.confirm() の話でしたが、window.alert() や window.prompt() でも同じ方法で対処することができます。

E2E テストで悩んでいることを、E2E テストツール単体で全て解決する必要はない

今回対処した方法は、max 属性の設定だったり、メソッドの追加だったり…。

nightmare を使った tips というよりは、Web ブラウザでの E2E テスト全般の tips というような感じになったと感じます。

今後も E2E テストで悩むことがあったら、nightmare を使った解決策だけに限らず、広い視野で解決策を探りたいと思います。

Eloquent ORM vs Query Builder (+ DB Facade )

Laravel で データ取得の方法と述べると、Eloquent ORM と Query Builder (+ DB Facade )の2つが上げられると思います。

今回は、二つのメリットとデメリットを見比べつつ、どういう状況で使えば良いのかを書きます。

Eloquent ORM

Eloquent ORMは、Laravel が提供している O/R マッパです。

ActiveRecord ライクにデータの取得ができます。

メリット

O/R マッパ のメリットを享受できる

  • SQL という別の言語を、アプリケーション( Laravel )に介入せず済む
  • テーブル同士の関係性を定義できる
  • 再利用性や拡張性が高い

など...

今回は、O/R マッパについて述べるわけではないので、詳しくは書きません。

色々柔軟に設定できる

何ができるかは、ドキュメントを読めば一目瞭然です。

Eloquent:利用の開始 5.7 Laravel

  • 独自のグローバルスコープ適応による、独自メソッド実装
  • 特定のイベントをフックにした処理の実行(いわゆるObserverパターン)

拡張性に優れた機能を、有していると言えます

デメリット

O/R マッパ のデメリットを享受する

  • SQL が書けなくても、データ取得ができる
  • ぱっと見、どういうクエリを発行しているのかわからない
  • Eloquent O/R マッパは ActiveRecord パターンで実装されているので、ActiveRecord パターンを覚える必要がある

など...

こちらも、O/R マッパについて述べるわけではないので、詳しくは書きません。

ですが、「ぱっと見、どういうクエリを発行しているのかわからない」は、次のデメリットで関連して触れることになります。

特定のメソッドを使うと、サブクエリを使って実行する

例えば has や whereHas では、exists を使ったサブクエリを実行します。

参考: qiita.com

当然ながら、サブクエリを実行するわけなので、クエリの実行時間が長いことになります。中には join 句を使えばサブクエリにしなくて良いような内容も、サブクエリで実行します。

このデメリットは、O/R マッパのデメリットで挙げた「ぱっと見、どういうクエリを発行しているのかわからない」が躊躇に現れていると思います。

どういう時に使えば良いか

  • パフォーマンスよりも安全性を取りたい
  • 確実に、リレーションに沿ったデータ取得をしたい
  • 特定の状況下での条件付けや、処理の実行を実装したい

Query Builder (+ DB Facade )

Laravel が提供しているクエリを生成するためのメソッド群。

SQL ライクにクエリを書くことができる( Query Builder )他、SQL をそのまま書いて実行する( DB Facade )こともできます。

メリット

Eloquent と比べて高速

join 句を使ったクエリを書けば、Eloquent でサブクエリを使って取得している処理よりも早くなります。

また、以下 URL では、同じ実行結果でも、Eloquent O/R マッパ に比べて Query Builder (+ DB Facade )の方が早いことを主張しています。

参考:https://www.youtube.com/watch?v=3TJfR1Ta4GU

どういうクエリを実行しているのかはわかりやすい

SQL 文と書き方に大きな差はないので、なんのクエリが発行されているかは非常にわかりやすいです。

SQL を書けさえすれば学習コストは低い

どんなメソッドがあるかは覚える必要があるものの、それ以外に必要なことは、SQL 文を書けることだけです。

デメリット

自力で考慮しなければいけない点がある

  • テーブル同士の結合は自身で行う必要があるため、リレーションを正しく把握して反映する必要がある
  • 論理削除の条件は、自分で条件指定する
  • そもそも SQL 文で間違った書き方を書いてはいけない

など...

これらを正しく考慮できていないと、意図しないデータを取得してしまう場合があります。

また、個人開発ではなくチームによる開発であれば、レビュアーが上記の点を考慮してコードレビューしなければなりません。

どういう時に使えば良いか

  • 複雑な条件や大量のデータを扱うので、パフォーマンスを求めたい(検索画面、一覧画面とか)
  • 複雑な条件のクエリを、発行したい

allメソッド Collectionメソッドソースコードリーディング100本ノック1本目

メソッド概要

コレクション 5.8 (翻訳中)Laravel

allメソッドはコレクションの裏の配列表現を返します。

<?php

collect([1, 2, 3])->all();

// [1, 2, 3]

裏の配列表現なんて仰々しい事を言っていますが、単純にコレクションの中身を配列で返すだけのメソッドです。

ソースコードリーディング

allメソッド

では早速、ソースコードリーディングをやって行きましょう。

<?php

/**
 * Get all of the items in the collection.
 *
 * @return array
 */
public function all()
{
    return $this->items;
}

items プロパティの値を取得する。以上。第3部完ッ!!

…これだけだと切なすぎるので、items プロパティに何の値が代入されているのか construct を見ましょう。

Collection の construct

<?php

/**
 * Create a new collection.
 *
 * @param  mixed  $items
 * @return void
 */
public function __construct($items = [])
{
    $this->items = $this->getArrayableItems($items);
}

$items を引数にして、getArrayableItems メソッドを呼び出しています。

とりあえず getArrayableItems メソッドの中身を覗きましょう。

getArrayableItemsメソッド

<?php

/**
 * Results array of items from Collection or Arrayable.
 *
 * @param  mixed  $items
 * @return array
 */
protected function getArrayableItems($items)
{
    if (is_array($items)) {
        return $items;
    } elseif ($items instanceof self) {
        return $items->all();
    } elseif ($items instanceof Arrayable) {
        return $items->toArray();
    } elseif ($items instanceof Jsonable) {
        return json_decode($items->toJson(), true);
    } elseif ($items instanceof JsonSerializable) {
        return $items->jsonSerialize();
    } elseif ($items instanceof Traversable) {
        return iterator_to_array($items);
    }

    return (array) $items;
}

CollectionArrayable から配列を作成するメソッドのようです。 条件式が複数あるので、一つずつ何をしているのか処理を追っていきましょう。

条件式:is_array($items)

<?php

if (is_array($items)) {
    return $items;
}

$items が配列だったら、そのまま $items を返します。 配列なら、わざわざ変換する必要はありませんからね。

条件式:$items instanceof self

<?php

} elseif ($items instanceof self) {
    return $items->all();
}

$itemsインスタンスself ( Collection ) だったら、all メソッドを実行しその返り値を返します。

ここで、ちょっとした例を出してみます。

<?php

// IN: $items = new Collection([1])
$this->items = $this->getArrayableItems(new Collection([1]));
$this->items = new Collection([1])->all();
$this->items = $this->getArrayableItems([1]);
$this->items = [1];


// IN: $items = new Collection(new Collection([1]))
$this->items = $this->getArrayableItems(new Collection(new Collection([1])));
$this->items = new Collection(new Collection([1]))->all();
$this->items = $this->getArrayableItems(new Collection([1]));
$this->items = new Collection([1])->all();
$this->items = $this->getArrayableItems([1]);
$this->items = [1];

つまり、2次元の Collection でも3次元の Collection でも、1次元の Collection にしてくれます。以下が実際に実行した結果です。

<?php

dd(new Collection(new Collection([1])));
Collection {#450 ▼
  #items: array:1 [▼
    0 => 1
  ]
}

dd(new Collection(new Collection(new Collection([1]))));
Collection {#450 ▼
  #items: array:1 [▼
    0 => 1
  ]
}

条件式:$items instanceof Arrayable

<?php

} elseif ($items instanceof Arrayable) {
    return $items->toArray();
} 

$itemsインスタンスArrayable だったら、toArray メソッドを実行しその返り値を返します。

Arrayable

Arrayable は、Laravel が提供している interface です。

<?php

namespace Illuminate\Contracts\Support;

interface Arrayable
{
    /**
     * Get the instance as an array.
     *
     * @return array
     */
    public function toArray();
}

toArray メソッドのみが定義されています。

別クラスに Arrayableimplements した上で、変換処理を記述した toArray メソッドを実装する、という使い方でしょうか。

配列じゃない別クラスでも toArray メソッドを使うことで、配列へ変換できるようにするため用意されている interface のようですね。

条件式:$items instanceof Jsonable

<?php

} elseif ($items instanceof Jsonable) {
    return json_decode($items->toJson(), true);
}

$itemsインスタンスJsonable だったら、json_decode 関数を実行しその返り値を返します。

json_decode 関数の第二引数が true なので、$items は配列にデコードされます。

Jsonable

jsonable は、 Laravel が提供している interface です。

<?php

namespace Illuminate\Contracts\Support;

interface Jsonable
{
    /**
     * Convert the object to its JSON representation.
     *
     * @param  int  $options
     * @return string
     */
    public function toJson($options = 0);
}

toJson メソッドのみが定義されています。

こちらも別クラスに Jsonableimplements した上で、変換処理を記述した toJson メソッドを実装する、という使い方でしょうか。

json 形式じゃない別クラスでも toJson メソッドを使うことで、json 形式へ変換できるようにするため用意されている interface のようですね。

Arrayable とちょっとだけ似ている気がします。

条件式:$items instanceof JsonSerializable

<?php

} elseif ($items instanceof JsonSerializable) {
    return $items->jsonSerialize();
}

$itemsインスタンスJsonSerializable だったら、jsonSerialize メソッドを実行しその返り値を返します。

JsonSerializable

JsonSerializablephp が提供している interface です。 ( PHP: JsonSerializable - Manual )

<?php

/**
 * Objects implementing JsonSerializable
 * can customize their JSON representation when encoded with
 * <b>json_encode</b>.
 * @link http://php.net/manual/en/class.jsonserializable.php
 */
interface JsonSerializable  {

    /**
    * Specify data which should be serialized to JSON
    * @link http://php.net/manual/en/jsonserializable.jsonserialize.php
    * @return mixed data which can be serialized by <b>json_encode</b>,
    * which is a value of any type other than a resource.
    * @since 5.4.0
    */
    public function jsonSerialize ();

}

jsonSerialize 関数のみが定義されています。( PHP: JsonSerializable::jsonSerialize - Manual )

別クラスに JsonSerializableimplements した上で、 jsonSerialize 関数を定義し、配列への変換処理を記述する。

使い方自体は ArrayableJsonable と一緒のようですね。

条件式:$items instanceof Traversable

<?php

} elseif ($items instanceof Traversable) {
    return iterator_to_array($items);
}

$itemsインスタンスTraversable だったら、iterator_to_array 関数を実行しその返り値を返します。

Traversable

Traversablephp が提供している interface です。( PHP: Traversable - Manual )

<?php

/**
 * @link https://wiki.php.net/rfc/iterable
 */
interface iterable {}

/**
 * Interface to detect if a class is traversable using &foreach;.
 * @link http://php.net/manual/en/class.traversable.php
 */
interface Traversable extends iterable {
}

iterable を継承していることと( PHP: rfc:iterable )、コメントの内容から foreach で繰り返し可能なクラスに実装するようです。

抽象 interface なので Traversable 単体では動きません。ですので、Traversable を継承している Iterator もしくは IteratorAggregate に、foreach をした時の細かい挙動を実装する必要があります。

その上で、iterator_to_array を使って配列へと変換していきます。( PHP: iterator_to_array - Manual )

<?php

/**
 * Copy the iterator into an array
 * @link http://php.net/manual/en/function.iterator-to-array.php
 * @param Traversable $iterator <p>
 * The iterator being copied.
 * </p>
 * @param bool $use_keys [optional] <p>
 * Whether to use the iterator element keys as index.
 * </p>
 * @return array An array containing the elements of the iterator.
 * @since 5.1.0
 */
function iterator_to_array ($iterator, $use_keys = true) {}

条件式:上記に当てはまらないとき

<?php

return (array) $items;

上記に当てはまらなかった時は、配列に漢のキャストをします。

最後に

と言うわけで、Collection メソッドソースコードリーディング100本ノック1本目が終わりました!

all メソッドの内容だけでは寂しいと深掘っていったら、Laravel どころか php の内部実装まで触れてしまいました。

次は avgaverage メソッドです!

マサカリや「ここちげえぞ!!!」と言う怒りのコメントまで、お待ちしております!

Collectionメソッドソースコードリーディング100本ノック、始めます

久々の記事になります。最後に書いたのはお正月…実に10ヶ月ぶりの記事になります。 突然ですが、本日よりLaravel5.6 Collection メソッドソースコードリーディング100本ノックを始めます!

要は Collection メソッドのソースコードリーディングです

まず、僕が指し示している Collection というのは、Laravel が提供している配列のラッパークラスです。

コレクション 5.6 Laravel

Laravel を使った Web 開発をする時には、ほぼ確実と言っても良いぐらい使用されます。そして、その Collection で使用できるメソッドが…

f:id:cocoeyes02:20181111203606p:plain

数えてみるとわかるのですが、100個存在します。

そこでこの Collection メソッド100個全てのソースコードリーディングを、野球の100本ノックの如くこなすことにしました!

何故そんな事をするんだい

今回の Collection メソッドソースコードリーディング100本ノックを決行した理由は2つあります。

Larave のソースコードを読んだことがないから

一つは、Laravel のソースコードリーディングをしたことがなかったためです。

フレームワークを使用しているの中で、時にフレームワークがどんな処理をしているのか調べなければいけない時があります。

理由はバグ調査のためだったり、ドキュメントに書いていない仕様を知るためだったり…

僕は、2018年になってから、会社のプロダクトで Laravel を触り始めました。なので、がっつり Laravel のソースコードを読んで理解を深めよう! と考えたわけです。

ブログ記事を全然書けていないから

もう一つは、単純にブログ記事を全然書けていないからです。

エンジニアとして生きていくからには、アウトプットをすることが重要です。しかし、僕はここ10ヶ月ブログを投稿していません。

理由は忙しかったり…というのもありますが、一番の理由は「大したネタがない」です。

大したネタがなくても、アウトプットはして行くべきなのですが…どうもブログ記事にしたいネタが見つかりませんでした。

そこで、「ソースコードリーディングのついでに、ブログも書いちゃえばいいんじゃね?」と思い、ブログを書くことにしました!

1メソッド1記事書くつもりですので、これで100記事分のネタができたわけです。ブログが書けるよ! やったねたえちゃん!

Laravel 5.6、理解を深めていこう

今回の前提条件として、Laravel のバージョンは5.6で確認して行きたいと思います。

というわけで、100本ノック1本目の all メソッドについて、書いていこうと思います!

仮想通貨でお財布を厚くしたい!-3本勝負と開発中の仮装通貨バーチャルトレードサービス-

新年明けましておめでとうございます!久々の更新になります。

今回は今まで株もFXもやったことがない僕が仮想通貨でお財布を厚くできるのか?ということについて書きます!

去年の10月ごろから口座を開いて入金し出したので、今日に至るまでに起きたことを3本勝負形式で追っていきたいと思います!

ROUND1

まず結果から申しますと、初めての仮想通貨投資チャレンジはほぼ利益ゼロ(ちょっとマイナス)ぐらいで終わりました。

我ながらこれはひどい・・・

今まで株もFXもやったことなく、手探りでやった結果がこれです。振り返ってみると・・・

  • 他の仮想通貨が上がる上がるという買い煽りに負けてしまった。
  • 急に暴落し始めたのに対して深く考えず慌てて利確した。
  • 販売所(今回はコインチェック)でJPYや他の仮想通貨から仮想通貨を買うとき、まあまあ無視できない手数料が発生しているのに気にしていなかった。
  • etc...

色々と反省事項がありましたが、とりあえず「むやみに他の仮想通貨に変えない」「ブレない心を持つ」という意志を持ってROUND2に臨みました!

ROUND2

今度はBCHがどんどん上がっていく様子を見せていたのでBCHに4万円ほど注ぎ込みました。

今度はブレないぞ!利確もせず上がるまで待つんだ!

そう思った矢先に起きたチャートがこれです。

ファッ!?うーん…(死亡)

さながらデットコースタージェットコースターのように上昇、急降下していきました。

このあとある程度は価格が元に戻ったものの、最終的に1割ほどマイナスでBCHを売ることになりました。敗北した理由は間違いなく「チャートの上昇具合しか見てなかった」ことです。

この件でトラウマを植えつけられてしまったのか1ヶ月半ほど仮想通貨を買いませんでした。かなしい。。。

番外編

やはり慣れていないものに手を出すのがマズかったんだ・・・と肩を落としていた思っていた頃の話です。仲間内で「仮想通貨バーチャルトレードができるゲームを作ったらバズるのでは?」という話題が上がりました。

何それ面白そう!!と思い、開発メンバーとして参加することになりました!

現在パブリックβテスト中でございますので、興味がある方は是非触っていただき、気になる点や要望などをフィードバックしていただければと思っています!

coin-step.com

とはいえ開発メンバーとして参加する際、「そんなサービスがあったら損せずに投資の学びを得られたではないかファ〜〜〜wwww」

というやつあたりのような気持ちがあったのも事実ですw

だからこそ最初の僕のように「株もFXもやったことないけど仮想通貨には興味あるな〜」という人に仮想通貨投資の練習ができるような場を提供したいと考えております!

どうぞよろしくお願いします!

ROUND3

ROUND3ではチャートだけでなく、その仮想通貨のイベント(ハードフォークや企業連携など)に着目して購入するという方針にしました。

ちょうどこの時はXRPが「coinbase上場」と「リップル、大企業2社と提携」という材料があったためXRPを買いました!

途中でちょくちょく買い足したりして15万ほど入金した状態になっていますが結果は・・・

祝!初めて利益がプラスに!

一時は+13,4万ぐらいになっていたので3回目の投資にしてやっと成功したと言えるでしょう!

読売新聞一面に「国内メガバンク地方銀行で銀行間送金としてXRPを扱う。インターネット銀行や地銀など数行は再来月から運用開始する」という旨の記事が出たことによる急騰が利益をもたらしたようです。

買った時に予測していたイベントとは違う理由で利益が出てしまいましたがまあいいでしょう!(coinbase上場に至っては否定されてしまいましたし)

というわけで今まで株もFXもやったことがない僕でも利益を出すことができましたが、僕が買ったXRPのポテンシャルや今後のイベントを見ている限りまだまだ上がると思っています!

なので、もう少しこのまま握り続けて様子を見たいと思います!

僕の仮想通貨ライフはこれからだ!