フィボナッチを使ったポジション計算

<img width="375" alt="S__35250192.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/476477/d62c96a9-1023-9906-ee6b-c9c20c3606bd.jpeg">

# フィボナッチを使ったトレード用 計算ツール

FXでトレードする際の利確・損切ライン、利益・損失額の計算ができる簡単なプログラムを作ってみました。
この作成の目的は動作するものを作ることだけではなく、オブジェクト指向な書き方に挑戦することが目的です。


##　見た目
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/476477/91e8195b-35d4-3fe3-008a-7377eeac0bb4.png)


##　コード内容
####フォーム

```c#:Form1.cs
namespace Fibonacci_Form
{
    public partial class Form1 : Form
    {
        private IntPtr HHook;

        #region フォーム初期化
        public Form1()
        {
            InitializeComponent();
        }
        #endregion

        #region 横線描画
        // 画面中央に引く横線を作成するメソッド
        private void Form1_Paint(object sender, PaintEventArgs e)
        {
            // グラフィックオブジェクトの作成
            Graphics g = this.CreateGraphics();

            // Penを作成
            Pen grayPen = new Pen(Color.Gray, 2);

            // lineの始点と終点を設定
            Point start_point = new Point(25, 250);
            Point end_point = new Point(480, 250);

            // lineを描画
            g.DrawLine(grayPen, start_point, end_point);

            // Penを解放する
            grayPen.Dispose();

            // Graphicsを解放する
            g.Dispose();
        }
        #endregion

        #region 買ボタン押下
        // 買ボタン押下時
        private void Buy_btn_Click(object sender, EventArgs e)
        {

            try
            {
                Property p = new Property();

                // ロット数
                p.Lot = int.Parse(lot_text.Text);
                // 通貨数
                p.Tsuka = int.Parse(tsuka_combo.Text);
                // 0%座標
                p.Zero = double.Parse(zero_text.Text);
                // 100%座標
                p.Hundred = double.Parse(hundred_text.Text);
                // エントリーポイント
                p.Entry = entry_combo.Text;


                // 結果を入れるリスト
                List<string> sList = new List<string>();
                Calc c = new Calc();
                sList = c.CalcAskResult(p.Lot, p.Tsuka, p.Zero, p.Hundred, p.Entry);

                // 結果を表示
                lost_num.Text = sList[0];
                win_num.Text = sList[1];
                loss_amount.Text = "-" + sList[2] + " 円";
                profit_amount.Text = sList[3] + " 円";

            } catch
            {
                SetHook(this);
                MessageBox.Show("値を正しく入力してください",
                                "エラー",
                                MessageBoxButtons.OK,
                                MessageBoxIcon.Error);

                lost_num.Text = null;
                win_num.Text = null;
                loss_amount.Text = null;
                profit_amount.Text = null;
            }
        }
        #endregion

        #region 売ボタン押下
        #endregion

        #region メッセージボックスを中央に表示するための処理(外部引用)
        #endregion
    }
}
```
####　気を付けたこと
* フォームから取って来た値を変数に入れるのではなく、プロパティを使用する
* 誤った値が入った場合・0%と100%が逆の状態の場合はエラーを表示する
* タブ順を指定した
* イベントが呼ばれた時に必要な処理、もしくはフォームに出力すること以外はここでは行わないようにする

####　プロパティ

```c#:Property.cs
namespace Fibonacci_Form
{
    public class Property
    {
        // 自動実装プロパティ
        public int Lot { get; set; }
        public int Tsuka { get; set; }
        public double Zero { get; set; }
        public double Hundred { get; set; }
        public String Entry { get; set; }

    }
}
```
####　気を付けたこと
* プロパティの存在の理解…

####　計算メソッド

```c#:Calc.cs
namespace Fibonacci_Form
{
    public class Calc
    {
        #region 買い計算
        // 損切ライン・利確ライン・損失・利益を計算(買いポジションなので0%をlow、100%をhighとする)
        public List<string> CalcAskResult(int lot, int tsuka, double low, double high, string entry)
        {
            List<string> sList = new List<string>();
            ListMake lm = new ListMake();

            // 0%と100%の大小が逆の場合、空のリストを返す
            if (high <= low)
            {
                return sList;
            }

            double lose_line;
            double win_line;
            double loss;
            double profit;
            double entry_point;

            // 取引金額を計算
            int amount = lot * tsuka;

            if (entry == "100%")
            {
                // 損切ラインを計算
                lose_line = Math.Round((low + (high - low) * 0.764) * 1000) / 1000;
                // 利確ラインを計算
                win_line = Math.Round((low + (high - low) * 1.618) * 1000) / 1000;
                // 損失を計算
                loss = Math.Round(amount * (high - lose_line));
                // 利益を計算
                profit = Math.Round(amount * (win_line - high));

                // ListAdd
                sList = lm.ListAdd(lose_line.ToString(), win_line.ToString(), loss.ToString(), profit.ToString());
            }
            else if (entry == "161.8%")
            {
                // エントリーポイントを計算
                entry_point = Math.Round((low + (high - low) * 1.618) * 1000) / 1000;

                // 損切ラインは100%ラインなので、high

                // 利確ラインを計算
                win_line = Math.Round((low + (high - low) * 2.618) * 1000) / 1000;
                // 損失を計算
                loss = Math.Round(amount * (entry_point - high));
                // 利益を計算
                profit = Math.Round(amount * (win_line - entry_point));

                // ListAdd
                sList = lm.ListAdd(high.ToString(), win_line.ToString(), loss.ToString(), profit.ToString());
            }
            else if (entry == "261.8%")
            {
                // エントリーポイントを計算
                entry_point = Math.Round((low + (high - low) * 2.618) * 1000) / 1000;

                // 損切ラインを計算
                lose_line = Math.Round((low + (high - low) * 1.618) * 1000) / 1000;
                // 利確ラインを計算
                win_line = Math.Round((low + (high - low) * 4.236) * 1000) / 1000;
                // 損失を計算
                loss = Math.Round(amount * (entry_point - lose_line));
                // 利益を計算
                profit = Math.Round(amount * (win_line - entry_point));

                // ListAdd
                sList = lm.ListAdd(lose_line.ToString(), win_line.ToString(), loss.ToString(), profit.ToString());
            }

            return sList;
        }
        #endregion

        #region 売り計算
        #endregion
    }
}
```
####　気を付けたこと
* 最初は計算だけでなくリストに追加するところまで書いていたが、ここはあくまで計算だけをするメソッドだと思い、計算結果をリストに追加するメソッドを別に作り、呼ぶようにした
* 計算結果を正しく出すのに苦労した

####　リスト作成

```c#:ListMake.cs
namespace Fibonacci_Form
{
    public class ListMake
    {
        public List<string> ListAdd(string a, string b, string c, string d)
        {
            List<string> sList = new List<string>();

            sList.Add(a);
            sList.Add(b);
            sList.Add(c);
            sList.Add(d);

            return sList;
        }
    }
}
```

####　エラー
最後に、不正な動作があった場合の動作
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/476477/380dcae4-c425-14a3-bab2-b53dc10ccbd5.png)
(画面中央にメッセージを出せたのは、外部からコードを丸々引用したため)
　　　　　　　　　　　　　　　↓
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/476477/1f1e6474-802d-1bd7-c6ba-dc81fdc99b0e.png)
下に表示されていた計算結果がクリアされます。


##　今後の計画
自分の取引結果を登録して、履歴を検索して表示できたり、エクセルに出力できるようなシステムを作ろうかと考えています。
データベースとのやり取りや、エクセルが絡むので、まだ書いたことの無いコードを学べると思っています。
また、今回作成したものよりはかなり多いコードの量になると思われるので、ちゃんと内容を切り分けてオブジェクト指向的なコーディングをする勉強になるのかなと思っています。


以上です。