/// <summary> /// 自動トレード開始 /// </summary> public void Start() { var lastCheck = DateTime.MinValue; //営業時間まで待機 while (!IsOpenMarket()) { Thread.Sleep(1000); } while (IsOpenMarket()) { //10分毎(分が10の倍数)まで待機 while (DateTime.Now.Minute % 10 != 0 || (DateTime.Now - lastCheck).TotalSeconds < 60 * 10 * 1.5) { Thread.Sleep(1000); } //保持しているポジション一覧を取得 var tradeList = Rest.GetTradeList(AccId); //覚えのないID -> orderListに追加 var idList = tradeList.Where(item => !orderList.Select(tuple => tuple.Item1).Contains(item.id)).Select(item => item.id).ToList(); idList.ForEach(item => { orderList.Add(Tuple.Create(item, DateTime.Now.AddMinutes(SELLTERM))); }); //売るタイミングでポジションが残ってるなら決済 foreach (var order in orderList.Where(data => data.Item2 <= DateTime.Now)) { //IDで照合 var pos = tradeList.Where(item => item.id == order.Item1).FirstOrDefault(); if (pos != null) { //反対売買を行う Order(pos.units, pos.side == "buy" ? "sell" : "buy"); } } //データ取得,テクニカル指標生成 var candles = new List <Candle>(); //最新の足の取得には数秒ずれるため do { candles = GetCandle(); } while ((DateTime.Now - candles.Last().time).TotalSeconds > 60 * 10 * 1.5); var lastDate = MakeIndex(candles); foreach (var str in strategy) { var selectSQL = $"SELECT COUNT(AsOfDate) FROM IndexData_10m_2017 WHERE AsOfDate = '{lastDate.ToString("yyyy-MM-dd HH:mm:ss")}' AND {str.Key}"; if (DB.ExecuteScalar(selectSQL, 0) != 0) { //marginを元にユニット数を設定 var units = 0; var detail = Rest.GetAccountDetails(AccId); var used = detail.marginUsed; var denom = detail.balance + detail.unrealizedPl; var nowMargin = detail.MarginLiquidationRate; var margin = nowMargin; var nowPrice = candles.Last().closeMid; while (margin < nowMargin + MAX_MARGIN_PERTRADE && margin < MAX_MARGIN) { units += UNIT; margin = (used + nowPrice * units) * LEVERAGE * 0.5 / (denom); } //注文 if (units > 0) { var id = Order(units, str.Value); //orderListに追加 orderList.Add(Tuple.Create(id, lastDate.AddMinutes(SELLTERM))); } } } lastCheck = lastDate; } }