private void MinuteCandleByTicks() { // 설정값 var coinName = Coin.Ticker; var candleType = CandleType.Name; var candleCount = CandleCount; var feeRate = FeeRate; var tradeRate = TradeRate; var triggerRate = TriggerRate; // 해당 코인 보유금액이 있으면 매도 없으면 매수 var candles = ApiData.getCandle <List <Candle> >(coinName, candleType, candleCount); // 캔들 조회 //var currCandle = candles.First(); // 현재 캔들 //var currPrice = currCandle.Close; // 현재가 var ticker = ApiData.getTicker(coinName).FirstOrDefault(); var currPrice = (ticker != null) ? ticker.Value <double>("trade_price") : 0D; // 현재가 //var orderChance = GetOrderChance(ApiData, coinName, currPrice); // 주문 가능 정보 var orderChance = GetBalance(ApiData, coinName, currPrice, StartKRW); var krwBalance = orderChance.KRWBalance; // 보유 현금 var coinBalance = orderChance.CoinBalance; // 코인 보유금 var coinVol = orderChance.CoinVol; // 보유 코인 수량 var avgPrice = orderChance.AvgBuyPrice; // 매수 평단가 var coinBuyBalance = avgPrice * coinVol; // 코인 매수금 var minTradeKRW = Settings.Default.minTradeKRW; // 최소 거래 금액 // 분봉 N개를 기준으로 직전 시가 에서 현재 금액 등낙률을 가져온다. var prevCandle = candles[1]; // 직전 캔들 var lastCandle = candles.Last(); // 마지막 캔들 var prevPrice = prevCandle.Low; // 직전저가 var highPrice = candles.GetRange(1, candles.Count - 1).Max(x => x.High); // 최고가 var changePrice = (currPrice - prevPrice); // 변동가 var changeRate = (changePrice / currPrice) * 100; // 변동율 var candlesChange = (currPrice - highPrice); // 캔들 변동가 var candlesRate = (candlesChange / highPrice) * 100; // 캔들 변동율 var profit = coinBalance - coinBuyBalance; // 수익 //var tradeProfitRate = (avgPrice == 0) ? 0D : (profit / avgPrice) * 100; // 수익율 var targetProfit = coinBuyBalance + (coinBuyBalance * ((triggerRate / candleCount) + (feeRate * 2)) / 100); //var targetPrice = avgPrice + targetProfit; //var target = coinBuyPrice var result = null as JObject; var args = new object[] { coinName, currPrice, prevPrice, highPrice, changeRate, candlesRate, avgPrice, targetProfit }; var buyTs = DateTime.Now - LastBuyDate; var sellTs = DateTime.Now - LastSellDate; var minutes = sellTs.TotalMinutes; WriteCurrent("{0} : 현재가 {1:N0}, 직전가 {2:N0}, 시작가 {3:N0}, 직전등락폭 {4:F6}, 등락폭 {5:F6}, 평단가 {6:N0}, 목표가 {7:N0}", args); if (StartKRW < minTradeKRW && krwBalance > minTradeKRW && coinBalance < minTradeKRW) { // 거래 시작 금액 StartKRW = krwBalance; } try { if (coinBalance <= minTradeKRW && krwBalance <= minTradeKRW) { // 보유현금과 보유 코인이 최소 거래금액 보다 적으면 거래 없음 WriteLog("#### 거래 불가 : 보유현금 {0}, 코인보유금 {1}, 최소 거래 금액 {2},", krwBalance, coinBalance, minTradeKRW); } else if (krwBalance > minTradeKRW && sellTs.TotalSeconds >= CandleType.Minute * 60 / 2 && candlesRate <= -(triggerRate + (feeRate * 2)) && changeRate >= (feeRate * 2)) { // BUY // 보유현금이 최소 거래금액 보다 많음 // 수익율 초과하여 떨어지다 수수료율 2배 이상 상승 했을때 거래비율 만큼 산다. var total = ToOrderPrice(krwBalance); result = React.executeDeal(true, false, coinName, 0, 0, total); LastBuyDate = DateTime.Now; WriteLog("#### {0} BUY : 금액 {1:N0}, 수량 {2:F6}", coinName, total, total / currPrice); } else if (coinBalance > minTradeKRW && (buyTs.TotalSeconds >= CandleType.Minute * 60 * candleCount / 2 || targetProfit <= coinBalance)) { // SELL // 코인평가금 최소 거래금액 보다 많음 // 분봉 하나의 시간이 지나면 시장가에 전체 매도 // 현재가가 평단가 보다 (수익율/캔들수 + 수료율2배) 이상일때 전체 매도 var vol = coinVol; vol = Math.Truncate(vol * 100000) / 100000; result = React.executeDeal(false, false, coinName, vol, 0, 0); LastSellDate = DateTime.Now; WriteLog("#### {0} SELL : 금액 {1:N0}, 수량 {2:F6}", coinName, vol * currPrice, vol); } } catch (Exception ex) { WriteLog(ex.StackTrace); } if (result != null) { var uuid = result.Value <string>("uuid"); var coinProfit = GetOrderResult(ApiData, uuid, coinName, currPrice, StartKRW); //WriteLog("#### RESULT : {0}", result.ToString()); //var coinProfit = GetBalance(ApiData, coinName, StartKRW); //txtProfitPrice.Text = coinProfit.KrwProfit.ToString("N0"); //txtProfitRate.Text = coinProfit.KrwProfitRate.ToString("F6"); var profits = new object[] { coinName, StartKRW, coinProfit.TotalBalance, coinProfit.KrwProfit, coinProfit.KrwProfitRate }; WriteLog("#### {0} 수익 : 거래시작금액 {1:N0}, 현재평가 금액 {2:N0}, 수익금액 {3:N0}, 수익율 {4:F6}", profits); } }