Пример #1
0
 public void RegisterUndo (string desc, React.Root root)
 {
     if (!(history.Count > 0 && history.Last ().json == json)) {
         history.Add (new ReactableEditorOperation () { desc = desc, json = React.JsonSerializer.Encode(root)});
         future.Clear ();
     }
 }
Пример #2
0
        private void PostInit()
        {
            var accessKey = Program.Accesskey;
            var secretEky = Program.Secretkey;

            ApiData = new ApiData(accessKey, secretEky);
            React   = new React(accessKey, secretEky);

            cmbAlgorithm.DataSource    = new BindingSource(BotSetting.AlgorithmList, null);
            cmbAlgorithm.ValueMember   = "Id";
            cmbAlgorithm.DisplayMember = "Name";
            cmbAlgorithm.SelectedValue = Settings.Default.algorithm;

            cmbCandle.DataSource    = new BindingSource(BotSetting.CandleTypes, null);
            cmbCandle.ValueMember   = "Minute";
            cmbCandle.DisplayMember = "Name";
            cmbCandle.SelectedValue = Settings.Default.candleType;

            cmbCoin.DataSource    = new BindingSource(BotSetting.CoinList, null);
            cmbCoin.ValueMember   = "Ticker";
            cmbCoin.DisplayMember = "CoinName";
            cmbCoin.SelectedValue = Settings.Default.coin;
        }
        public void RemoveAnAnsweredCommentRemovesItsReactions()
        {
            Comment comment = NullNormalized <Comment>(c =>
            {
                c.Content   = "I think that you are a sick person second";
                c.AccountId = Manu.Id;
                c.Article   = ArticleZero;
            });

            Comment commented = Wrapper.Comment.CommentArticle(comment);

            React reacted = Wrapper.React.React(NullNormalized <React>(r =>
            {
                r.Comment  = commented;
                r.Account  = JeanLucEmmanuel;
                r.Reaction = new ReactionType {
                    TypeId = SAD
                };
            }));

            Comment reply = NullNormalized <Comment>(c =>
            {
                c.Content   = "Hum pardon, What do you mean ? ... second also";
                c.AccountId = JeanLucEmmanuel.Id;
                c.Answer    = commented;
            });

            Comment answere = Wrapper.Comment.AnswerComment(reply);

            Comment copy = Wrapper.Comment.RemoveComment(commented);

            Comment removed    = GetCommentLike(copy);
            React   unexistant = Wrapper.React.GetReact(commented, JeanLucEmmanuel);

            Assert.AreEqual(removed.VisibilityId, REMOVED);
            Assert.IsNull(unexistant);
        }
        private void PostInit()
        {
            var accessKey = Program.Accesskey;
            var secretEky = Program.Secretkey;

            ApiData = new ApiData(accessKey, secretEky);
            React   = new React(accessKey, secretEky);

            AlgorithmList  = BotSetting.AlgorithmList;
            CandleTypeList = BotSetting.CandleTypeList;
            CoinList       = BotSetting.CoinList;

            Algorithm  = AlgorithmList.Where(x => x.Id == Settings.Default.algorithm).FirstOrDefault();
            CandleType = BotSetting.CandleTypeList.Where(x => x.Minute == Settings.Default.candleType).FirstOrDefault();
            Coin       = BotSetting.CoinList.Where(x => x.Ticker.Equals(Settings.Default.coin)).FirstOrDefault();


            algorithmBindingSource.DataSource  = AlgorithmList;
            candleTypeBindingSource.DataSource = CandleTypeList;
            coinBindingSource.DataSource       = CoinList;

            //cmbAlgorithm.DataSource = new BindingSource(BotSetting.AlgorithmList, null);
            //cmbAlgorithm.ValueMember = "Id";
            //cmbAlgorithm.DisplayMember = "Name";
            //cmbAlgorithm.SelectedValue = Settings.Default.algorithm;

            //cmbCandle.DataSource = new BindingSource(BotSetting.CandleTypeList, null);
            //cmbCandle.ValueMember = "Minute";
            //cmbCandle.DisplayMember = "Name";
            //cmbCandle.SelectedValue = Settings.Default.candleType;

            //cmbCoin.DataSource = new BindingSource(BotSetting.CoinList, null);
            //cmbCoin.ValueMember = "Ticker";
            //cmbCoin.DisplayMember = "CoinName";
            //cmbCoin.SelectedValue = Settings.Default.coin;
        }
Пример #5
0
        public void Like(int id, React obj)
        {
            var idea = ds1.Ideas.Include("Reacts").SingleOrDefault(e => id == e.IdeaId);

            obj.IdeasId = id;
            obj.like    = false;
            obj.dislike = false;

            AddReact(obj);

            foreach (var item in idea.Reacts)
            {
                if (obj.user == item.user)
                {
                    if (item.like == false)
                    {
                        idea.Like   += 1;
                        item.dislike = true;
                        item.like    = true;
                    }
                }
            }
            ds1.SaveChanges();
        }
Пример #6
0
    // Update is called once per frame
    void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            //Vector3 point = new Vector3(camera.pixelWidth/2, camera.pixelHeight/2, 0f);
            Vector3 point = Input.mousePosition;
            Ray     ray   = camera.ScreenPointToRay(point);

            RaycastHit hit;

            if (Physics.Raycast(ray, out hit))
            {
                Debug.Log("Hit: " + hit.collider.gameObject.name);

                GameObject hitTarget = hit.collider.gameObject;
                React      target    = hitTarget.GetComponent <React>();

                if (target != null)
                {
                    target.objectHit();
                }
            }
        }
    }
        private void MinuteCandleByTicks()
        {
            // 설정값
            var coinName    = Coin.Ticker;
            var candleType  = CandleType.Name;
            var candleCount = CandleCount;
            var feeRate     = FeeRate;
            var tradeRate   = OrderRate;
            var triggerRate = TriggerRate;

            // 캔들 갯수 많큼 캔들 가져오기
            var candles          = ApiData.getCandle <List <Candle> >(coinName, candleType, candleCount * 2); // 캔들 조회 (2배로 여유롭게)
            var currPrice        = candles.First().Close;                                                     // 현재가
            var prevPrice        = candles[1].Close;                                                          // 직전종가
            var highPrice        = candles.GetRange(1, candleCount - 1).Max(x => x.High);                     // 최고가
            var downPrice        = highPrice * (triggerRate + (feeRate * 2)) / 100;                           // 하락가
            var triggerDownPrice = highPrice - downPrice;                                                     // 매수 하락 촉발가
            var downRate         = Math.Min(0D, (currPrice - highPrice) * 100 / highPrice);                   // 하락율
            var upPrice          = prevPrice * ((triggerRate / candleCount) + (feeRate * 2)) / 100;           // 반등가
            var triggerUpPrice   = prevPrice + upPrice;                                                       // 매수 반등 촉발가
            var upRate           = Math.Max(0D, (currPrice - prevPrice) * 100 / prevPrice);                   // 반등 상승율
            var downUpRate       = upRate == 0 ? 0D : (-downRate / upRate);                                   // 반등율

            // 보유현금 및 주문 정보
            var orderChance    = ApiData.getOrdersChance(coinName);                                 // 주문 가능 정보
            var bid            = orderChance["bid_account"];
            var ask            = orderChance["ask_account"];
            var krwBalance     = bid.Value <double>("balance");                                     // 보유 현금
            var coinVol        = ask.Value <double?>("balance") ?? 0D;                              // 보유 코인 수량
            var avgPrice       = ask.Value <double?>("avg_buy_price") ?? 0D;                        // 매수 평단가
            var buyLock        = bid.Value <double?>("locked") ?? 0D;                               // 매수 대기 금액
            var sellLock       = ask.Value <double?>("locked") ?? 0D;                               // 매도 대기 금액
            var coinBuyBalance = avgPrice * coinVol;                                                // 코인 매수금
            var coinBalance    = currPrice * coinVol;                                               // 코인 평가금
            var totalBalance   = krwBalance + coinBalance;                                          // 현재 자산
            var minTradeKRW    = Settings.Default.minTradeKRW;                                      // 최소 거래 금액

            avgPrice = avgPrice < minTradeKRW ? currPrice : avgPrice;

            // 거래 쿨다운 타임
            var buyTs           = (DateTime.Now - LastSellDate).TotalSeconds;                       // 마지막 매도 이후 경과 시간 (초)
            var buyCoolDownSec  = CandleType.Minute * 60;                                           // 매수 쿨다운 시간 (초)
            var buyCountDownSec = buyCoolDownSec - buyTs;                                           // 매수 쿨다운 시간 (초)

            var sellTs           = (DateTime.Now - LastBuyDate).TotalSeconds;                       // 마지막 매수 이후 경과 시간 (초)
            var sellCoolDownSec  = (CandleType.Minute + (1 / candleCount)) * 60;                    // 매도 쿨다운 시간 (초)
            var sellCountDownSec = sellCoolDownSec - sellTs;                                        // 매도 까지 남은 시간 (초)

            var targetRate      = ((triggerRate / (candleCount - 1)) + (feeRate * 2)) / 100;        // 목표 수익율
            var targetSellPrice = avgPrice + (avgPrice * targetRate);                               // 매도 목표가

            var args = new object[] {
                DateTime.Now,
                coinName,
                currPrice,
                prevPrice,
                highPrice,
                downRate,
                upRate,
                avgPrice,
                StartKRW,
                totalBalance,
                triggerDownPrice,
                triggerUpPrice,
                targetSellPrice,
                sellCountDownSec,
                buyCountDownSec,
            };

            string format = "[{0:T}] {1} : 현재가 {2:N0}, 직전가 {3:N0}, 최고가 {4:N0}, 하락율 {5:F4}, 반등율 {6:F4}, 평단가 {7:N0}";

            format += (sellCountDownSec > 0) ? ", 매수 까지 {13:N0}(초)" : "";
            format += (buyCountDownSec > 0) ? ", 매도 까지 {14:N0}(초)" : "";
            format += "\r\n[{0:T}] {1} : 시작자산 {8:N0}, 현재자산 {9:N0} 매수 하락 촉발가 {10:N0}, 매수 반등 촉발가 {11:N0}, 매도 목표가 {12:N0}, 매수 목표가 {12:N0}";
            WriteCurrent(format, args);
            var now   = DateTime.Now;
            var line1 = $"[{now:T}] {coinName}";

            line1 += $" : 현재가 {currPrice:N0}, 직전가 {prevPrice:N0}, 최고가 {highPrice:N0}";
            line1 += $", 하락율 {downRate:F4}, 반등율 {upRate:F4}, 평단가 {avgPrice:N0}";
            line1 += (sellCountDownSec > 0) ? $", 매수 까지 {sellCountDownSec:N0}(초)" : "";
            line1 += (buyCountDownSec > 0) ? $", 매도 까지 {buyCountDownSec:N0}(초)" : "";
            var line2 = $"[{now:T}] {coinName}";

            line2 += $" : 시작자산 {StartKRW:N0}, 현재자산 {totalBalance:N0}";
            line2 += $", 매수 하락 촉발가 {triggerDownPrice:N0}, 매수 반등 촉발가 {triggerUpPrice:N0}, 매도 목표가 {targetSellPrice:N0}";

            WriteCurrent("{0}\r\n{1}", line1, line2);
            log.Debug(orderChance.ToString(Formatting.Indented));

            if (StartKRW < minTradeKRW && krwBalance > minTradeKRW && coinBalance < minTradeKRW)
            {
                // 거래 시작 금액
                StartKRW = krwBalance;
            }

            txtKRWBalance.Text  = krwBalance.ToString("N0");
            txtCoinBalance.Text = coinBalance.ToString("N0");
            txtBalance.Text     = totalBalance.ToString("N0");
            txtStartKRW.Text    = StartKRW.ToString("N0");

            try
            {
                var orderResult = null as JObject;
                var order       = null as JObject;
                var uuid        = "";
                var side        = "";
                var state       = "";

                if (coinBalance <= minTradeKRW && krwBalance <= minTradeKRW)
                {
                    // 보유현금과 보유 코인이 최소 거래금액 보다 적으면 거래 없음
                    WriteLog("#### 거래 불가(금액 부족) : 보유현금 {0}, 코인보유금 {1}, 매도 대기 금액 {2}, 매수 대기 금액 {3}, 최소 거래 금액 {4}", krwBalance, coinBalance, buyLock, sellLock, minTradeKRW);
                    return;
                }

                if (sellCountDownSec > 0 && buyCountDownSec > 0)
                {
                    // 거래 쿨타임 일때
                    WriteLog("#### 거래 불가(쿨타임) : 매수 까지 남은 시간(초) {0}, 매수 까지 남은 시간(초) {1}, 마지막 매수 {2:T}, 마지막 매도 {3:T}", buyCountDownSec, sellCountDownSec, LastSellDate, LastBuyDate);
                    return;
                }

                if (IsWaiting)
                {
                    // 거래 대기 중일때
                    uuid  = LastOrderResult.Value <string>("uuid");
                    side  = LastOrderResult.Value <string>("side");
                    state = LastOrderResult.Value <string>("state");
                    WriteLog("#### 거래 불가(거래 대기중) : side {0}, state {1}, uuid {2}", side, state, uuid);
                    return;
                }

                if (krwBalance > minTradeKRW &&                                                                     // 보유 현금이 최소거래 금액 보다 클때
                    currPrice <= Math.Truncate(triggerDownPrice) && currPrice >= Math.Truncate(triggerUpPrice) &&   // 현재가가 촉발 금액 사이에서 반등하고
                    downUpRate <= candleCount * 2)                                                                  // 반등율이 캔들갯수의 2배수가 넘지 않아야 함
                {
                    // BUY
                    var total       = ToOrderPrice(krwBalance);
                    var avgBuyPrice = currPrice;
                    orderResult = React.executeDeal(true, false, coinName, 0, 0, total);
                    LastBuyDate = DateTime.Now;
                    WriteLog("#### BUY : {0}", orderResult.ToString(Formatting.Indented));
                }
                else if (coinBalance > minTradeKRW &&                                                               // 코인 보유금이 최소거래 금액 보다 클때
                         currPrice >= Math.Truncate(targetSellPrice))                                               // 현재가가 목표 매수 금액보다 클때
                {
                    // SELL
                    var vol = coinVol;
                    vol          = Math.Truncate(vol * 100000) / 100000;
                    orderResult  = React.executeDeal(false, false, coinName, vol, 0, 0);
                    LastSellDate = DateTime.Now;
                    WriteLog("#### SELL : {0}", orderResult.ToString(Formatting.Indented));
                }

                if (orderResult != null)
                {
                    IsWaiting       = true;
                    LastOrderResult = orderResult;
                    uuid            = orderResult.Value <string>("uuid");
                    side            = orderResult.Value <string>("side");
                    state           = orderResult.Value <string>("state");

                    System.Threading.Thread.Sleep(1500);
                    order = ApiData.checkOrder(uuid);

                    if (order != null)
                    {
                        IsWaiting = false;
                        WriteLog("#### TRADE RESULT : {0}", order.ToString(Formatting.Indented));

                        var orderState  = order.Value <string>("state");
                        var orderPrice  = order.Value <double?>("price") ?? 0D;
                        var orderVolume = order.Value <double?>("volume") ?? 0D;
                        var tradeCount  = order.Value <double>("trade_count");
                        var trades      = order["trades"] as JArray;
                        var tradePrice  = trades[0].Value <double?>("price") ?? 0D;
                        var tradeVolume = trades[0].Value <double?>("volume") ?? 0D;
                        var tradeFunds  = trades[0].Value <double?>("funds") ?? 0D;

                        if ("done".Equals(orderState))
                        {
                            if ("bid".Equals(side))
                            {
                                // BUY
                                WriteLog("#### {0} BUY : 매수금 {1:N0} : 매수 평단가 {2:N0} : 수량 {3:F6}", coinName, tradeFunds, tradePrice, tradeVolume);
                            }
                            else if ("ask".Equals(side))
                            {
                                // SELL
                                WriteLog("#### {0} SELL : 매도금 {1:N0} : 매도 평단가 {2:N0} : 수량 {3:F6}", coinName, tradeFunds, tradePrice, tradeVolume);
                            }

                            // 수익
                            var balance = GetBalance(coinName);
                            krwBalance   = balance.KRWBalance;
                            coinBalance  = currPrice * balance.CoinVol;
                            totalBalance = krwBalance + coinBalance;
                            var profit     = totalBalance - StartKRW;
                            var profitRate = (StartKRW == 0) ? 0D : profit / StartKRW * 100;

                            txtKRWBalance.Text  = krwBalance.ToString("N0");
                            txtCoinBalance.Text = coinBalance.ToString("N0");
                            txtBalance.Text     = totalBalance.ToString("N0");
                            txtProfitPrice.Text = profit.ToString("N0");
                            txtProfitRate.Text  = profitRate.ToString("F4");

                            args = new object[] { coinName, StartKRW, totalBalance, profit, profitRate, krwBalance, coinBalance };
                            WriteLog("#### {0} 수익 : 거래시작금액 {1:N0}, 현재평가 금액 {2:N0}, 수익금액 {3:N0}, 수익율 {4:F6}, 보유현금 {5:N0}, 코인 평가 {6:N0}", args);
                        }
                    }
                    else
                    {
                        WriteLog("#### 거래 결과를 가져올수 없습니다.");
                    }
                }
            }
            catch (Exception ex)
            {
                WriteLog(ex.StackTrace);
            }
        }
        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 orderChance = GetOrderChance(ApiData, coinName, currPrice);                          // 주문 가능 정보
            var coinPrice   = orderChance.CoinBalance;                                               // 코인 보유금
            var krwBalance  = orderChance.KRWBalance;                                                // 보유 현금
            var coinVol     = orderChance.CoinVol;                                                   // 보유 코인 수량
            var avgPrice    = orderChance.AvgBuyPrice;                                               // 매수 평단가
            var minTradeKRW = Settings.Default.minTradeKRW;                                          // 최소 거래 금액

            // 분봉 N개를 기준으로 직전 시가 에서 현재 금액 등낙률을 가져온다.
            var prevCandle = candles[1];                                              // 직전 캔들
            var lastCandle = candles.Last();                                          // 마지막 캔들
            var prevPrice  = prevCandle.Close;                                        // 직전종가

            prevPrice = prevCandle.Low;                                               // 직전 저가 대입
            var startPrice = lastCandle.Open;                                         // 마지막 캔들 시작가
            var highPrice  = candles.GetRange(1, candles.Count - 1).Max(x => x.High); // 최고가

            startPrice = Math.Max(startPrice, highPrice);                             // 캔들 최고가 대입
            var change          = (currPrice - prevPrice);                            // 변동가
            var currentRate     = (change / currPrice) * 100;                         // 등락율
            var candlesChange   = (currPrice - startPrice);                           // 캔들 변동가
            var candlesRate     = (candlesChange / startPrice) * 100;                 // 캔들 등락율
            var profit          = (currPrice - avgPrice);                             // 수익
            var tradeProfitRate = (profit / avgPrice) * 100;                          // 수익율
            var result          = null as JObject;
            var args            = new object[] { coinName, currPrice, prevPrice, startPrice, currentRate, candlesRate };

            WriteLog("{0} : 현재가 {1:N0}, 직전가 {2:N0}, 시작가 {3:N0}, 직전등락폭 {4:F6}, 등락폭 {5:F6}", args);

            if (StartKRW < minTradeKRW && krwBalance > minTradeKRW && coinPrice < minTradeKRW)
            {
                // 거래 시작 금액
                StartKRW = krwBalance;
            }

            try
            {
                if (coinPrice <= minTradeKRW && krwBalance <= minTradeKRW)
                {
                    // 보유현금과 보유 코인이 최소 거래금액 보다 적으면 거래 없음
                    WriteLog("#### 거래 불가 : 보유현금 {0}, 코인보유금 {1}, 최소 거래 금액 {2},", krwBalance, coinPrice, minTradeKRW);
                }
                else if (krwBalance > minTradeKRW &&
                         candlesRate <= -(triggerRate + (feeRate * 2)) &&
                         currentRate >= (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 (coinPrice > minTradeKRW &&
                         (tradeProfitRate <= -(triggerRate - (feeRate * 2)) || tradeProfitRate >= triggerRate + (feeRate * 2)))
                {
                    // SELL
                    // 코인평가금 최소 거래금액 보다 많음
                    // 현재가가 평단가 보다 (수익율 - 수료율 * 2) 이하일때 전체 매도
                    // 현재가가 평단가 보다 (수익율 + 수료율 * 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 chance        = GetOrderChance(ApiData, coinName, currPrice);
                var totalKrw      = chance.KRWBalance + chance.CoinBalance;
                var krwProfit     = totalKrw - StartKRW;
                var krwProfitRate = krwProfit / StartKRW * 100;
                var profits       = new object[] { coinName, StartKRW, totalKrw, krwProfit, krwProfitRate };

                txtProfitPrice.Text = krwProfit.ToString("N0");
                txtProfitRate.Text  = krwProfitRate.ToString("F6");
                WriteLog("#### RESULT : {0}", result.ToString());
                WriteLog("#### {0} 수익 : 거래시작금액 {1:N0}, 현재평가 금액 {2:N0}, 수익금액 {3:N0}, 수익율 {4:F6}", profits);
            }
        }
Пример #9
0
        protected override Control CreateControl()
        {
            var changed = Changed.Adapt <float, AnySignalEditor> (this);

            return(FoldableContainer.WithLabel(Name, true, HAlign.Left,
                                               InputSignalControl("Source", Source),
                                               InputSignalControl("Warp", Warp),
                                               Container.LabelAndControl("Scale: ",
                                                                         new NumericEdit(Scale, false, 0.1f,
                                                                                         React.By((float s) => Scale = s).And(changed)), true)));
        }
        //private void MinuteCandleByTicks()
        //{
        //    // 설정값
        //    var coinName = Coin.Ticker;
        //    var candleType = CandleType.Name;
        //    var candleMinute = CandleType.Minute;
        //    var candleCount = CandleCount;
        //    var feeRate = FeeRate;
        //    var tradeRate = OrderRate;
        //    var triggerRate = TriggerRate;

        //    // 캔들 갯수 많큼 캔들 가져오기
        //    var candles = ApiData.getCandle<List<Candle>>(coinName, candleType, candleCount * 2);   // 캔들 조회 (2배로 여유롭게)
        //    var currPrice = candles.First().Close;                                                  // 현재가
        //    var prevPrice = candles[1].Low;                                                         // 직전저가
        //    var highPrice = candles.GetRange(1, candleCount - 1).Max(x => x.High);                  // 최고가
        //    var downPrice = highPrice * (triggerRate + (feeRate * (candleCount - 1))) / 100;        // 하락가
        //    var triggerDownPrice = highPrice - downPrice;                                           // 매수 하락 촉발가
        //    var downRate = Math.Min(0D, (currPrice - highPrice) * 100 / highPrice);                 // 하락율
        //    var upPrice = prevPrice * (feeRate * (candleCount - 1)) / 100;                          // 반등가
        //    var triggerUpPrice = prevPrice + upPrice;                                               // 매수 반등 촉발가
        //    var upRate = (currPrice - prevPrice) * 100 / prevPrice;                                 // 반등 상승율
        //    var downUpRate = upRate <= 0 && downRate <= 0 ? 0D : (-downRate / upRate);              // 반등율

        //    // 보유현금 및 주문 정보
        //    var orderChance = ApiData.getOrdersChance(coinName);                                    // 주문 가능 정보
        //    var bid = orderChance["bid_account"];
        //    var ask = orderChance["ask_account"];
        //    var krwBalance = bid.Value<double>("balance");                                          // 보유 현금
        //    var coinVol = ask.Value<double?>("balance") ?? 0D;                                      // 보유 코인 수량
        //    var avgPrice = ask.Value<double?>("avg_buy_price") ?? 0D;                               // 매수 평단가
        //    var buyLock = bid.Value<double?>("locked") ?? 0D;                                       // 매수 대기 금액
        //    var sellLock = ask.Value<double?>("locked") ?? 0D;                                      // 매도 대기 금액
        //    var coinBuyBalance = avgPrice * coinVol;                                                // 코인 매수금
        //    var coinBalance = currPrice * coinVol;                                                  // 코인 평가금
        //    var totalBalance = krwBalance + coinBalance;                                            // 현재 자산
        //    var minTradeKRW = Settings.Default.minTradeKRW;                                         // 최소 거래 금액

        //    // 거래 쿨다운 타임
        //    var buyTs = (DateTime.Now - LastSellDate).TotalSeconds;                                 // 마지막 매도 이후 경과 시간 (초)
        //    var buyCoolDownSec = CandleType.Minute * 60 * (candleCount - 2) / (candleCount - 1);      // 매수 쿨다운 시간 (초)
        //    var buyRemainCoolDownSec = buyCoolDownSec - buyTs;                                      // 매수 쿨다운 시간 (초)

        //    var sellTs = (DateTime.Now - LastBuyDate).TotalSeconds;                                 // 마지막 매수 이후 경과 시간 (초)
        //    var sellCoolDownSec = (CandleType.Minute + (1 / candleCount)) * 60;                       // 매도 쿨다운 시간 (초)
        //    var sellRemainCoolDownSec = sellCoolDownSec - sellTs;                                   // 매도 까지 남은 시간 (초)
        //    var targetRate = ((triggerRate / 2) + (feeRate * 2)) / 100;                             // 목표 수익율
        //    var targetSellPrice = Math.Round(avgPrice * (1 + targetRate) / 10) * 10;                // 매도 목표가

        //    var now = DateTime.Now;
        //    var line1 = $"[{now:T}] {coinName}";
        //    line1 += $" : 현재/직전/최고 {currPrice:N0}/{prevPrice:N0}/{highPrice:N0}";
        //    line1 += $", 하락율/반등율 {downRate:F2}/{upRate:F2}, 평단가 {avgPrice:N0}";
        //    line1 += (sellRemainCoolDownSec > 0) ? $", 매수쿨 {sellRemainCoolDownSec:N0}(초)" : "";
        //    line1 += (buyRemainCoolDownSec > 0) ? $", 매도쿨 {buyRemainCoolDownSec:N0}(초)" : "";
        //    var line2 = $"[{now:T}] {coinName}";
        //    line2 += $" : 시작자산 {StartKRW:N0}, 현재자산 {totalBalance:N0}";
        //    line2 += $", 매수 하락 촉발가 {triggerDownPrice:N0}, 매수 반등 촉발가 {triggerUpPrice:N0}, 매도 목표가 {targetSellPrice:N0}";

        //    WriteCurrent("{0}\r\n{1}", line1, line2);
        //    //WriteLog("orderChance {0}", orderChance.ToString(Formatting.Indented));

        //    if (StartKRW < minTradeKRW && krwBalance > minTradeKRW && coinBalance < minTradeKRW)
        //    {
        //        // 거래 시작 금액
        //        StartKRW = krwBalance;
        //    }

        //    txtKRWBalance.Text = krwBalance.ToString("N0");
        //    txtCoinBalance.Text = coinBalance.ToString("N0");
        //    txtBalance.Text = totalBalance.ToString("N0");
        //    txtStartKRW.Text = StartKRW.ToString("N0");

        //    try
        //    {
        //        var orderResult = null as JObject;
        //        var order = null as JObject;
        //        var uuid = "";
        //        var side = "";
        //        var state = "";

        //        if (coinBalance <= minTradeKRW && krwBalance <= minTradeKRW)
        //        {
        //            // 보유현금과 보유 코인이 최소 거래금액 보다 적으면 거래 없음
        //            WriteLog("#### 거래 불가(금액 부족) : 보유현금 {0}, 코인보유금 {1}, 매도 대기 금액 {2}, 매수 대기 금액 {3}, 최소 거래 금액 {4}", krwBalance, coinBalance, buyLock, sellLock, minTradeKRW);
        //            return;
        //        }

        //        if (IsWaiting)
        //        {
        //            // 거래 대기 중일때
        //            uuid = LastOrderResult.Value<string>("uuid");
        //            side = LastOrderResult.Value<string>("side");
        //            state = LastOrderResult.Value<string>("state");
        //            WriteLog("#### 거래 불가(거래 대기중) : side {0}, state {1}, uuid {2}", side, state, uuid);
        //            return;
        //        }

        //        if (krwBalance > minTradeKRW                                                                        // 보유 현금이 최소거래 금액 보다 클때
        //            && buyRemainCoolDownSec <= 0                                                                    // 매도 유예시간이 지났을때
        //            && currPrice <= Math.Truncate(triggerDownPrice) && currPrice >= Math.Truncate(triggerUpPrice)   // 현재가가 촉발 금액 사이에서 반등하고
        //            && downUpRate <= candleCount * 2)                                                               // 반등율이 캔들갯수의 2배수가 넘지 않아야 함
        //        {
        //            // BUY
        //            var total = ToOrderPrice(krwBalance);
        //            var avgBuyPrice = currPrice;
        //            orderResult = React.executeDeal(true, false, coinName, 0, 0, total);
        //            LastBuyDate = DateTime.Now;
        //            WriteLog("#### BUY : {0}", orderResult.ToString(Formatting.Indented));

        //        }
        //        else if (coinBalance > minTradeKRW                                                                  // 코인 보유금이 최소거래 금액 보다 클때
        //            && (sellRemainCoolDownSec <= 0 || currPrice >= Math.Truncate(targetSellPrice)))                 // 매수 유예시간이 지나거나 현재가가 목표 매수 금액보다 클때
        //        {
        //            // SELL
        //            var vol = coinVol;
        //            vol = Math.Truncate(vol * 100000) / 100000;
        //            orderResult = React.executeDeal(false, false, coinName, vol, 0, 0);
        //            LastSellDate = DateTime.Now;
        //            WriteLog("#### SELL : {0}", orderResult.ToString(Formatting.Indented));
        //        }

        //        if (orderResult != null)
        //        {
        //            IsWaiting = true;
        //            LastOrderResult = orderResult;
        //            uuid = orderResult.Value<string>("uuid");
        //            side = orderResult.Value<string>("side");
        //            state = orderResult.Value<string>("state");

        //            System.Threading.Thread.Sleep(1500);

        //            order = ApiData.checkOrder(uuid);

        //            if (order != null)
        //            {
        //                IsWaiting = false;
        //                WriteLog("#### TRADE RESULT : {0}", order.ToString(Formatting.Indented));

        //                var orderState = order.Value<string>("state");
        //                var orderPrice = order.Value<double?>("price") ?? 0D;
        //                var orderVolume = order.Value<double?>("volume") ?? 0D;
        //                var tradeCount = order.Value<double>("trade_count");
        //                var trades = order["trades"] as JArray;
        //                var tradePrice = trades[0].Value<double?>("price") ?? 0D;
        //                var tradeVolume = trades[0].Value<double?>("volume") ?? 0D;
        //                var tradeFunds = trades[0].Value<double?>("funds") ?? 0D;

        //                if ("done".Equals(orderState))
        //                {
        //                    if ("bid".Equals(side))
        //                    {
        //                        // BUY
        //                        WriteLog("#### {0} BUY : 매수금 {1:N0} : 매수 평단가 {2:N0} : 수량 {3:F6}", coinName, tradeFunds, tradePrice, tradeVolume);

        //                    }
        //                    else if ("ask".Equals(side))
        //                    {
        //                        // SELL
        //                        WriteLog("#### {0} SELL : 매도금 {1:N0} : 매도 평단가 {2:N0} : 수량 {3:F6}", coinName, tradeFunds, tradePrice, tradeVolume);
        //                    }

        //                    // 수익
        //                    var balance = GetBalance(coinName);
        //                    krwBalance = balance.KRWBalance;
        //                    coinBalance = currPrice * balance.CoinVol;
        //                    totalBalance = krwBalance + coinBalance;
        //                    var profit = totalBalance - StartKRW;
        //                    var profitRate = (StartKRW == 0) ? 0D : profit / StartKRW * 100;

        //                    txtKRWBalance.Text = krwBalance.ToString("N0");
        //                    txtCoinBalance.Text = coinBalance.ToString("N0");
        //                    txtBalance.Text = totalBalance.ToString("N0");
        //                    txtProfitPrice.Text = profit.ToString("N0");
        //                    txtProfitRate.Text = profitRate.ToString("F4");

        //                    var args = new object[] { coinName, StartKRW, totalBalance, profit, profitRate, krwBalance, coinBalance };
        //                    WriteLog("#### {0} 수익 : 거래시작금액 {1:N0}, 현재평가 금액 {2:N0}, 수익금액 {3:N0}, 수익율 {4:F6}, 보유현금 {5:N0}, 코인 평가 {6:N0}", args);
        //                }
        //            }
        //            else
        //            {
        //                WriteLog("#### 거래 결과를 가져올수 없습니다.");
        //            }
        //        }

        //    }
        //    catch (Exception ex)
        //    {
        //        WriteLog(ex.StackTrace);
        //    }
        //}


        private async Task MinuteCandleByTicksAsync()
        {
            // 설정값
            var coinName     = Coin.Ticker;
            var candleType   = CandleType.Name;
            var candleMinute = CandleType.Minute;
            var candleCount  = CandleCount;
            var feeRate      = FeeRate;
            var tradeRate    = OrderRate;
            var triggerRate  = TriggerRate;

            // 캔들 갯수 많큼 캔들 가져오기
            var candles          = ApiData.getCandle <List <Candle> >(coinName, candleType, candleCount * 2); // 캔들 조회 (2배로 여유롭게)
            var currPrice        = candles.First().Close;                                                     // 현재가
            var prevPrice        = candles[1].Low;                                                            // 직전저가
            var highPrice        = candles.GetRange(1, candleCount - 1).Max(x => x.High);                     // 최고가
            var downPrice        = highPrice * (triggerRate + (feeRate * (candleCount - 1))) / 100;           // 하락가
            var triggerDownPrice = highPrice - downPrice;                                                     // 매수 하락 촉발가
            var downRate         = Math.Min(0D, (currPrice - highPrice) * 100 / highPrice);                   // 하락율
            var upPrice          = prevPrice * (feeRate * (candleCount - 1)) / 100;                           // 반등가
            var triggerUpPrice   = prevPrice + upPrice;                                                       // 매수 반등 촉발가
            var upRate           = (currPrice - prevPrice) * 100 / prevPrice;                                 // 반등 상승율
            var downUpRate       = upRate <= 0 && downRate <= 0 ? 0D : (-downRate / upRate);                  // 반등율

            // 보유현금 및 주문 정보
            var orderChance    = ApiData.getOrdersChance(coinName);                                 // 주문 가능 정보
            var bid            = orderChance["bid_account"];
            var ask            = orderChance["ask_account"];
            var krwBalance     = bid.Value <double>("balance");                                     // 보유 현금
            var coinVol        = ask.Value <double?>("balance") ?? 0D;                              // 보유 코인 수량
            var avgPrice       = ask.Value <double?>("avg_buy_price") ?? 0D;                        // 매수 평단가
            var buyLock        = bid.Value <double?>("locked") ?? 0D;                               // 매수 대기 금액
            var sellLock       = ask.Value <double?>("locked") ?? 0D;                               // 매도 대기 금액
            var coinBuyBalance = avgPrice * coinVol;                                                // 코인 매수금
            var coinBalance    = currPrice * coinVol;                                               // 코인 평가금
            var totalBalance   = krwBalance + coinBalance;                                          // 현재 자산
            var minTradeKRW    = Settings.Default.minTradeKRW;                                      // 최소 거래 금액
            var fee            = currPrice * feeRate / 100;                                         // 거래 수수료
            var sellFee        = coinBalance * feeRate / 100;                                       // 매도 총 수수료
            var buyFee         = totalBalance * feeRate / 100;                                      // 매수 총 수수료
            var buyUnitPrice   = GetOrderUnitPrice(krwBalance);                                     // 매수 주문 가격 단위
            var sellUnitPrice  = GetOrderUnitPrice(coinBalance);                                    // 매도 주문 가격 단위
            //var orderUintPrice = GetOrderUnitPrice(currPrice);                                      // 캔들 가격 단위

            // 거래 쿨다운 타임
            var buyTs                = (DateTime.Now - LastSellDate).TotalSeconds;                     // 마지막 매도 이후 경과 시간 (초)
            var buyCoolDownSec       = CandleType.Minute * 60 * (candleCount - 2) / (candleCount - 1); // 매수 쿨다운 시간 (초)
            var buyRemainCoolDownSec = buyCoolDownSec - buyTs;                                         // 매수 쿨다운 시간 (초)

            var sellTs                = (DateTime.Now - LastBuyDate).TotalSeconds;                     // 마지막 매수 이후 경과 시간 (초)
            var sellCoolDownSec       = (CandleType.Minute + (1 / candleCount)) * 60;                  // 매도 쿨다운 시간 (초)
            var sellRemainCoolDownSec = sellCoolDownSec - sellTs;                                      // 매도 까지 남은 시간 (초)
            var targetRate            = ((triggerRate / 2) + (feeRate * 2)) / 100;                     // 목표 수익율
            var targetSellPrice       = Math.Round(avgPrice * (1 + targetRate) / 10) * 10;             // 매도 목표가

            var now   = DateTime.Now;
            var line1 = $"[{now:T}] {coinName}";

            line1 += $" : 현재/직전/최고 {currPrice:N0}/{prevPrice:N0}/{highPrice:N0}";
            line1 += $", 하락율/반등율 {downRate:F2}/{upRate:F2}, 평단가 {avgPrice:N0}";
            line1 += (sellRemainCoolDownSec > 0) ? $", 매수쿨 {sellRemainCoolDownSec:N0}(초)" : "";
            line1 += (buyRemainCoolDownSec > 0) ? $", 매도쿨 {buyRemainCoolDownSec:N0}(초)" : "";
            var line2 = $"[{now:T}] {coinName}";

            line2 += $" : 시작자산 {StartKRW:N0}, 현재자산 {totalBalance:N0}";
            line2 += $", 매수촉발가(하락/반등) {triggerDownPrice:N0} / {triggerUpPrice:N0}, 매도 목표가 {targetSellPrice:N0}, 매수 수수료 {totalBalance * feeRate / 100:F2}";

            WriteCurrent("{0}\r\n{1}", line1, line2);
            //WriteLog("orderChance {0}", orderChance.ToString(Formatting.Indented));

            if (StartKRW < minTradeKRW && krwBalance > minTradeKRW && coinBalance < minTradeKRW)
            {
                // 거래 시작 금액
                StartKRW = krwBalance;
            }

            if (InvokeRequired)
            {
                BeginInvoke(new Action(() =>
                {
                    txtKRWBalance.Text  = krwBalance.ToString("N0");
                    txtCoinBalance.Text = coinBalance.ToString("N0");
                    txtBalance.Text     = totalBalance.ToString("N0");
                    txtStartKRW.Text    = StartKRW.ToString("N0");
                }));
            }
            else
            {
                txtKRWBalance.Text  = krwBalance.ToString("N0");
                txtCoinBalance.Text = coinBalance.ToString("N0");
                txtBalance.Text     = totalBalance.ToString("N0");
                txtStartKRW.Text    = StartKRW.ToString("N0");
            }

            try
            {
                var orderResult = null as JObject;
                var order       = null as JObject;
                var uuid        = "";
                var side        = "";
                var state       = "";

                if (coinBalance <= minTradeKRW && krwBalance <= minTradeKRW)
                {
                    // 보유현금과 보유 코인이 최소 거래금액 보다 적으면 거래 없음
                    WriteLog("#### 거래 불가(금액 부족) : 보유현금 {0}, 코인보유금 {1}, 매도 대기 금액 {2}, 매수 대기 금액 {3}, 최소 거래 금액 {4}", krwBalance, coinBalance, buyLock, sellLock, minTradeKRW);
                    return;
                }

                if (IsWaiting)
                {
                    // 거래 대기 중일때
                    uuid  = LastOrderResult.Value <string>("uuid");
                    side  = LastOrderResult.Value <string>("side");
                    state = LastOrderResult.Value <string>("state");
                    WriteLog("#### 거래 불가(거래 대기중) : side {0}, state {1}, uuid {2}", side, state, uuid);
                    return;
                }

                if (krwBalance > minTradeKRW &&                                                                     // 보유 현금이 최소거래 금액 보다 클때
                    buyRemainCoolDownSec <= 0 &&                                                                    // 매도 유예시간이 지났을때
                    currPrice <= Math.Truncate(triggerDownPrice) && currPrice >= Math.Truncate(triggerUpPrice) &&   // 현재가가 촉발 금액 사이에서 반등하고
                    downUpRate <= candleCount * 2)                                                                  // 반등율이 캔들갯수의 2배수가 넘지 않아야 함
                {
                    // BUY
                    var unitPrice   = GetOrderUnitPrice(currPrice);
                    var total       = Math.Truncate(coinBalance / unitPrice) * unitPrice;
                    var avgBuyPrice = currPrice;
                    orderResult = React.executeDeal(true, false, coinName, 0, 0, total);
                    IsWaiting   = true;
                    LastBuyDate = DateTime.Now;
                    WriteLog("#### BUY : {0}", orderResult.ToString(Formatting.Indented));

                    var buyUUID        = orderResult.Value <string>("uuid");
                    var buyOrderResult = await GetBuyMarketResultAsync(buyUUID);

                    // SELL
                    if (buyOrderResult != null)
                    {
                        var buyPrice        = buyOrderResult.Value <double>("price");
                        var targetBuyPrice  = GetOrderUnitPrice(buyPrice + Math.Max((buyPrice * 0.5 / 100) + (fee * 2), 10));
                        var buyVol          = buyOrderResult.Value <double>("executed_volume");
                        var sellOrderResult = await GetSellOrderResultAsync(coinName, targetBuyPrice, buyVol);

                        IsWaiting   = false;
                        LastBuyDate = DateTime.Now;
                        WriteLog("#### SELL : {0}", sellOrderResult.ToString(Formatting.Indented));
                    }
                }
                //else if (coinBalance > minTradeKRW                                                                  // 코인 보유금이 최소거래 금액 보다 클때
                //    && (sellRemainCoolDownSec <= 0 || currPrice >= Math.Truncate(targetSellPrice)))                 // 매수 유예시간이 지나거나 현재가가 목표 매수 금액보다 클때
                //{
                //    // SELL
                //    var vol = coinVol;
                //    vol = Math.Truncate(vol * 100000) / 100000;
                //    orderResult = React.executeDeal(false, false, coinName, vol, 0, 0);
                //    LastSellDate = DateTime.Now;
                //    WriteLog("#### SELL : {0}", orderResult.ToString(Formatting.Indented));
                //}

                if (orderResult != null)
                {
                    IsWaiting       = true;
                    LastOrderResult = orderResult;
                    uuid            = orderResult.Value <string>("uuid");
                    side            = orderResult.Value <string>("side");
                    state           = orderResult.Value <string>("state");

                    await Task.Delay(1500);

                    order = ApiData.checkOrder(uuid);

                    if (order != null)
                    {
                        IsWaiting = false;
                        WriteLog("#### CHECK ORDER RESULT : {0}", order.ToString(Formatting.Indented));

                        var orderState  = order.Value <string>("state");
                        var orderPrice  = order.Value <double?>("price") ?? 0D;
                        var orderVolume = order.Value <double?>("volume") ?? 0D;
                        var tradeCount  = order.Value <double>("trade_count");
                        var trades      = order["trades"] as JArray;
                        var tradePrice  = 0D;
                        var tradeVolume = 0D;
                        var tradeFunds  = 0D;

                        if (trades != null && trades.Count > 0)
                        {
                            tradePrice  = trades[0].Value <double?>("price") ?? 0D;
                            tradeVolume = trades[0].Value <double?>("volume") ?? 0D;
                            tradeFunds  = trades[0].Value <double?>("funds") ?? 0D;
                        }

                        if ("done".Equals(orderState))
                        {
                            if ("bid".Equals(side))
                            {
                                // BUY
                                WriteLog("#### {0} BUY : 매수금 {1:N0} : 매수 평단가 {2:N0} : 수량 {3:F6}", coinName, tradeFunds, tradePrice, tradeVolume);
                            }
                            else if ("ask".Equals(side))
                            {
                                // SELL
                                WriteLog("#### {0} SELL : 매도금 {1:N0} : 매도 평단가 {2:N0} : 수량 {3:F6}", coinName, tradeFunds, tradePrice, tradeVolume);
                            }

                            // 수익
                            var balance = GetBalance(coinName);
                            krwBalance   = balance.KRWBalance;
                            coinBalance  = currPrice * balance.CoinVol;
                            totalBalance = krwBalance + coinBalance;
                            var profit     = totalBalance - StartKRW;
                            var profitRate = (StartKRW == 0) ? 0D : profit / StartKRW * 100;

                            if (InvokeRequired)
                            {
                                BeginInvoke(new Action(() =>
                                {
                                    txtKRWBalance.Text  = krwBalance.ToString("N0");
                                    txtCoinBalance.Text = coinBalance.ToString("N0");
                                    txtBalance.Text     = totalBalance.ToString("N0");
                                    txtProfitPrice.Text = profit.ToString("N0");
                                    txtProfitRate.Text  = profitRate.ToString("F4");
                                }));
                            }
                            else
                            {
                                txtKRWBalance.Text  = krwBalance.ToString("N0");
                                txtCoinBalance.Text = coinBalance.ToString("N0");
                                txtBalance.Text     = totalBalance.ToString("N0");
                                txtProfitPrice.Text = profit.ToString("N0");
                                txtProfitRate.Text  = profitRate.ToString("F4");
                            }

                            var args = new object[] { coinName, StartKRW, totalBalance, profit, profitRate, krwBalance, coinBalance };
                            WriteLog("#### {0} 수익 : 거래시작금액 {1:N0}, 현재평가 금액 {2:N0}, 수익금액 {3:N0}, 수익율 {4:F6}, 보유현금 {5:N0}, 코인 평가 {6:N0}", args);
                        }
                    }
                    else
                    {
                        WriteLog("#### 거래 결과를 가져올수 없습니다.");
                    }
                }
            }
            catch (Exception ex)
            {
                WriteLog(ex.StackTrace);
            }
        }
Пример #11
0
        public PersonViewModel(PeopleViewModel peopleViewModel)
        {
            if (peopleViewModel == null)
            {
                throw new ArgumentNullException("peopleViewModel");
            }

            this.PeopleViewModel = peopleViewModel;

            React.To(() => this.Age - PeopleViewModel.AverageAge)
            .Select(diff =>
            {
                if (diff > 0)
                {
                    return("above average");
                }
                else if (diff == 0)
                {
                    return("exact average");
                }
                else
                {
                    return("below average");
                }
            })
            .SetAndNotify(() => ComparedToAverageAge);

            //TODO: SetAndNotify usually has no equality check on the new value.
            //Put such logic in SetAndNotify itself.
            React.To(() => this.Age - PeopleViewModel.AverageAge)
            .Select(diff =>
            {
                if (diff > 0)
                {
                    return(new RotateTransform(-90.0));
                }
                else if (diff == 0)
                {
                    return(new RotateTransform(0.0));
                }
                else
                {
                    return(new RotateTransform(90.0));
                }
            })
            .SetAndNotify(() => ArrowIndicatorRotation);

            React.To(() => this.Age - PeopleViewModel.AverageAge)
            .Select(diff =>
            {
                if (diff > 0)
                {
                    return(Brushes.Green);
                }
                else if (diff == 0)
                {
                    return(Brushes.Blue);
                }
                else
                {
                    return(Brushes.Red);
                }
            })
            .SetAndNotify(() => ArrowIndicatorColor);
        }
        private void MinuteCandleByTicks()
        {
            // 설정값
            var coinName    = Coin.Ticker;
            var candleType  = CandleType.Name;
            var ticks       = CandleCount;
            var triggerRate = Rate;
            var feeRate     = FeeRate;
            var tradeRate   = TradeRate;
            var profitRate  = ProfitRate;

            // 해당 코인 보유금액이 있으면 매도 없으면 매수
            var candles     = ApiData.getCandle <List <Candle> >(coinName, candleType, CandleCount); // 캔들 조회
            var currCandle  = candles.First();                                                       // 현재 캔들
            var currPrice   = currCandle.Close;                                                      // 현재가
            var orderChance = GetOrderChance(ApiData, coinName, currPrice);                          // 주문 가능 정보
            var coinPrice   = orderChance.CoinBalance * currPrice;                                   // 코인 보유금
            var krwBalance  = orderChance.KRWBalance;                                                // 보유 현금
            var coinVol     = orderChance.CoinVol;                                                   // 보유 코인 수량
            var avgPrice    = orderChance.AvgBuyPrice;                                               // 매수 평단가
            var minTradeKRW = Settings.Default.minTradeKRW;                                          // 최소 거래 금액

            // 분봉 N개를 기준으로 이전 시가 에서 현재 금액 등낙률을 가져온다.
            var prevCandle      = candles[1];                                               // 직전 캔들
            var lastCandle      = candles.Last();                                           // 마지막 캔들
            var prevPrice       = prevCandle.Close;                                         // 직전종가
            var startPrice      = lastCandle.Open;                                          // 마지막 캔들 시작가
            var change          = (currPrice - prevPrice);                                  // 변동가
            var currentRate     = (change / currPrice) * 100;                               // 등락율
            var downChange      = (startPrice - currPrice);                                 // 상승전 변동가
            var downRate        = (downChange / startPrice) * 100;                          // 상승전 하락율
            var profit          = (currPrice - avgPrice);                                   // 수익
            var tradeProfitRate = (profit / avgPrice) * 100;                                // 수익율
            var result          = null as JObject;
            var args            = new object[] { coinName, currPrice, prevPrice, startPrice, currentRate, downRate };

            WriteLog("{0} : 현재가 {1:N0}, 이전가 {2:N0}, 시작가 {3:N0}, 직전등락폭 {4:F6}, 하락폭 {5:F6}", args);

            try
            {
                if (coinPrice <= minTradeKRW && krwBalance <= minTradeKRW)
                {
                    // 보유현금과 보유 코인이 최소 거래금액 보다 적으면 거래 없음
                    WriteLog("#### 거래 불가 : 보유현금 {0}, 코인보유금 {1}, 최소 거래 금액 {2},", krwBalance, coinPrice, minTradeKRW);
                }
                else if (krwBalance > minTradeKRW &&
                         downRate >= profitRate + (feeRate * 2) &&
                         currentRate >= (feeRate * 2))
                {
                    // BUY
                    // 보유현금이 최소 거래금액 보다 많음
                    // 수익율 초과하여 떨어지다 수수료율 2배 이상 상승 했을때 거래비율 만큼 산다.
                    var total = Math.Truncate(krwBalance * 1000) / 1000;
                    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 (krwBalance > minTradeKRW &&
                         (tradeProfitRate <= profitRate - (feeRate * 2) || tradeProfitRate >= profitRate + (feeRate * 2)))
                {
                    // SELL
                    // 코인평가금 최소 거래금액 보다 많음
                    // 현재가가 평단가 보다 (수익율 - 수료율 * 2) 이하일때 전체 매도
                    // 현재가가 평단가 보다 (수익율 + 수료율 * 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)
            {
                GetOrderChance(ApiData, coinName, currPrice);
                WriteLog("#### RESULT : {0}", result.ToString());
            }
        }
        private void MinuteCandleByTicks()
        {
            // 분봉 N개를 기준으로 이전 시가 에서 현재 금액 등낙률을 가져온다.
            // 촉발 등낙률 초과하여 떨어지다 수수료율 2배 이상 상승 했을때 거래비율 만큼 산다.
            // 매수 이후 (1% - 수수료율) 이상 떨어지면 전체 손절
            // 매수 이후 (1% + 수수료율) 이상 오르면 전체 익절
            var coinName    = Coin.Ticker;
            var candleType  = CandleType.Name;
            var ticks       = CandleCount;
            var triggerRate = Rate;
            var fee         = Fee;
            var tradeRate   = TradeRate;
            var profit      = Profit;
            var candles     = ApiData.getCandle <List <Candle> >(coinName, candleType, 20);
            var prevCandle  = candles[0];               // 현재 캔들
            var currCandle  = candles[1];               // 직전 캔들
            var currPrice   = currCandle.Close;         // 현재가
            var prevPrice   = prevCandle.Close;         // 직전종가

            //var algIdx = cmbAlgorithm.SelectedIndex;
            //var idx = (algIdx > 0) ? algIdx : Convert.ToInt32(txtMinute.Text);
            //var candleType = BotSetting.CandleTypes[idx];
            var orderChance = GetOrderChance(ApiData, CoinName, currPrice);
            //var ask = orderChance["ask_account"];
            //var bid = orderChance["bid_account"];
            var krwBalance = orderChance.KRWBalance;                            // 보유 현금
            var coinVol    = orderChance.CoinVol;                               // 보유 코인 수량
            var avgPrice   = orderChance.AvgBuyPrice;                           // 매수 평단가
            var coinPrice  = orderChance.CoinBalance;                           // 보유 코인 금액

            //var upRatio = (currPrice - avgPrice) / currPrice * 100;     // 평단 대비 상승폭 (%)
            //var downRatio = (currPrice - prevPrice) / currPrice * 100;  // 현재가 대비 하락폭 (%)
            var ratio     = (currPrice - prevPrice) / currPrice * 100;      // 등락폭 (%)
            var tradeRate = Convert.ToDouble(txtTradeRate.Text) / 100D;     // 거래 비중 (%)
            var result    = null as JObject;                                // 거래 결과

            //txtKRW.Text = krwBalance.ToString("N0");
            //txtCoinBalance.Text = coinPrice.ToString("N0");

            Debug.WriteLine("이전가: {0:N0}, 현재가 {1:N0}, ratio : {2:F4}%", prevPrice, currPrice, ratio);
            WriteLog("이전가: {0:N0}, 현재가 {1:N0}, ratio : {2:F4}%", prevPrice, currPrice, ratio);

            try
            {
                if (avgPrice + (2 * (avgPrice * Rate / 100)) <= currPrice && coinPrice >= 5000)
                {
                    // 현재가가 평단가보다 등락폭 2배 이상 올랐을때 전량 매도
                    var vol = coinVol;
                    vol = Math.Truncate(vol * 100000) / 100000;
                    Debug.WriteLine("#### {2} ALL SELL : 금액 {0:N0}, 수량 {1:F6}", vol * currPrice, vol, CoinName);
                    WriteLog("#### {2} ALL SELL : 금액 {0:N0}, 수량 {1:F6}", vol * currPrice, vol, CoinName);
                    result       = React.executeDeal(false, false, CoinName, vol, 0, 0);
                    LastSellDate = DateTime.Now;
                }
                else if (ratio >= Rate && coinPrice >= 5000 && ((DateTime.Now - LastSellDate).TotalMinutes >= idx || ratio >= Rate * 1.5))
                {
                    // 올랐을때 코인 금액 절반 팔기
                    var vol = (coinPrice * tradeRate) > 5000 ? coinVol * tradeRate : coinVol;
                    vol = Math.Truncate(vol * 100000) / 100000;
                    Debug.WriteLine("#### {2} SELL : 금액 {0:N0}, 수량 {1:F6}", vol * currPrice, vol, CoinName);
                    WriteLog("#### {2} SELL : 금액 {0:N0}, 수량 {1:F6}", vol * currPrice, vol, CoinName);
                    result       = React.executeDeal(false, false, CoinName, vol, 0, 0);
                    LastSellDate = DateTime.Now;
                }
                else if (ratio <= -(Rate * 1.2) && krwBalance > 5000 && (DateTime.Now - LastBuyDate).TotalMinutes >= idx)
                {
                    // 1.2배 내렸을때 보유 현금 절반으로 코인 사기
                    var total = (krwBalance * tradeRate) > 5000 ? krwBalance * tradeRate : krwBalance;
                    total = Math.Truncate(total * 1000) / 1000;
                    Debug.WriteLine("#### {2} BUY : 금액 {0:N0}, 수량 {1:F6}", total, total / currPrice, CoinName);
                    WriteLog("#### {2} BUY : 금액 {0:N0}, 수량 {1:F6}", total, total / currPrice, CoinName);
                    result      = React.executeDeal(true, false, CoinName, 0, 0, total);
                    LastBuyDate = DateTime.Now;
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex);
                WriteLog(ex.StackTrace);
            }

            orderChance = GetOrderChance(ApiData, CoinName, currPrice);

            if (result != null)
            {
                Debug.WriteLine("#### RESULT : {0}", result.ToString());
                WriteLog("#### RESULT : {0}", result.ToString());
            }
        }
Пример #14
0
 public static void RemoveBreakePoint(React.BaseNode beakePoint)
 {
     s_breakePoints.Remove(beakePoint);
 }
Пример #15
0
 public static void ToggleBreakePoint(React.BaseNode breakePoint)
 {
     if (s_breakePoints.Contains(breakePoint))
     {
         if (s_breakepointHit == breakePoint)
         {
             s_breakepointHit = null;
         }
         s_breakePoints.Remove(breakePoint);
     }
     else
     {
         s_breakePoints.Add(breakePoint);
     }
 }
Пример #16
0
 public static void CheckBreakePoint(React.BaseNode breakePoint)
 {
     if (breakePoint.ownerReactor!=null && breakePoint.ownerReactor.isInDebug && s_breakePoints.Contains(breakePoint))
     {
         Selection.activeTransform = breakePoint.ownerReactor.transform;
         Debug.Break();
         s_breakepointHit = breakePoint;
     }
 }
Пример #17
0
 public static void AddBreakePoint(React.BaseNode beakePoint)
 {
     s_breakePoints.Add(beakePoint);
 }
Пример #18
0
        protected override Control CreateControl()
        {
            var changed  = Changed.Adapt <int, AnySignalEditor> (this);
            var changedf = Changed.Adapt <float, AnySignalEditor> (this);

            return(FoldableContainer.WithLabel(Name, true, HAlign.Left,
                                               Container.LabelAndControl("Type: ",
                                                                         new Picker((int)NoiseKind,
                                                                                    React.By((int i) => NoiseKind = (WorleyNoiseKind)i).And(changed),
                                                                                    Enum.GetNames(typeof(WorleyNoiseKind))), true),
                                               Container.LabelAndControl("Seed: ",
                                                                         new NumericEdit(Seed, true, 1,
                                                                                         React.By((float i) => Seed = (int)i).And(changedf)), true),
                                               Container.LabelAndControl("CP Type: ",
                                                                         new Picker((int)ControlPoints,
                                                                                    React.By((int i) => ControlPoints = (ControlPointKind)i).And(changed),
                                                                                    Enum.GetNames(typeof(ControlPointKind))), true),
                                               Container.LabelAndControl("CP Count: ",
                                                                         new NumericEdit(ControlPointCount, true, 1,
                                                                                         React.By((float i) => ControlPointCount = (int)i).And(changedf).Filter(i => i > 2)), true),
                                               Container.LabelAndControl("Distance: ",
                                                                         new Picker((int)DistanceKind,
                                                                                    React.By((int i) => DistanceKind = (DistanceKind)i).And(changed),
                                                                                    Enum.GetNames(typeof(DistanceKind))), true),
                                               Container.LabelAndControl("Jitter: ",
                                                                         new NumericEdit(Jitter, false, 0.1f,
                                                                                         React.By((float x) => Jitter = x).And(changedf)), true),
                                               Container.LabelAndControl("Periodic: ",
                                                                         new Picker(Periodic ? 1 : 0,
                                                                                    React.By((int i) => Periodic = i != 0).And(changed),
                                                                                    "No", "Yes"), true)));
        }
Пример #19
0
 public string ReactOnPost(React react)
 {
     return(postRepository.ReactOnPost(react));
 }
Пример #20
0
        private SceneGraph CreateSceneGraph()
        {
            var sceneGraph = new SceneGraph();

            _dirLight = new DirectionalLight(sceneGraph,
                                             intensity: new Vec3(1f),
                                             direction: new Vec3(0.7f, 1f, -0.7f),
                                             maxShadowDepth: 200f);

            _camera = new Camera(sceneGraph,
                                 position: new Vec3(0f, 10f, 10f),
                                 target: new Vec3(0f, 10f, -1f),
                                 upDirection: new Vec3(0f, 1f, 0f),
                                 frustum: new ViewingFrustum(FrustumKind.Perspective, 1f, 1f, -1f, -400f),
                                 aspectRatio: 1f);

            sceneGraph.GlobalLighting = new GlobalLighting()
            {
                AmbientLightIntensity = new Vec3(0.1f),
                MaxIntensity          = 1f,
                GammaCorrection       = 1.8f,
            };

            _terrainScene = new Terrain.Scene(sceneGraph);
            var fighterGeometry = new FighterGeometry <EntityVertex, PathNode> ();

            _fighter = new Mesh <EntityVertex> (sceneGraph, fighterGeometry.Fighter.RotateY(0f).Compact())
                       .OffsetOrientAndScale(new Vec3(0f, 15f, -10f), new Vec3(0f, 0f, 0f), new Vec3(1f));

            _infoWindow = new ControlPanel <TexturedVertex> (sceneGraph,
                                                             Container.Vertical(true, false,
                                                                                Label.Static("Options", FontStyle.Bold),
                                                                                new ListView(React.Ignore <IVisualizable> (),
                                                                                             new Visualizable(() => Visual.Label(string.Format("FPS: {0}", _fps))),
                                                                                             new Visualizable(() => Visual.Label(
                                                                                                                  string.Format("Mouse: {0}", new Vec2i(Mouse.X, Mouse.Y)))))),
                                                             new Vec2i(180, 64), false);
            sceneGraph.Root.Add(_dirLight, _camera, _terrainScene.Root, _fighter,
                                _infoWindow.Offset(new Vec3(-0.95f, 0.95f, 0f)));
            return(sceneGraph);
        }
Пример #21
0
 public static Reaction <Mat4> UpdatePerspectiveMatrix()
 {
     return(React.By <Mat4> (matrix => _skybox.perspectiveMatrix &= matrix)
            .Program(_skyboxShader));
 }
Пример #22
0
 // GET: React
 public int UpdateReact(React react)
 {
     return(reactService.UpdateReact(react.VideoId, react.UserId));
 }
Пример #23
0
        /// <summary>
        /// 首页博文
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public ActionResult WrapArtList(int id)
        {
            int pageIndex = Request["pageIndex"] == null ? 1 : int.Parse(Request["pageIndex"]);
            int pageSize  = Request["pageSize"] == null ? 8 : int.Parse(Request["pageSize"]);

            List <Article> articleList = new List <Article>();
            int            totalCount  = 0;

            var whereExp = PredicateBuilder.True <Article>();

            if (id == 0)//取所有博文,对应首页<Home/Index/0>
            {
                whereExp.And(p => p.Status == 1);
                articleList = _articleService.GetPagedListBy(pageIndex, pageSize, whereExp, p => p.SubTime, true, out totalCount);
            }
            else
            {
                whereExp.And(p => p.Status == 1 && p.CategoryId == id);
                articleList = _articleService.GetPagedListBy(pageIndex, pageSize, whereExp, p => p.SubTime, true, out totalCount);
            }

            List <ArticleViewModel> articleViewList = new List <ArticleViewModel>();

            foreach (var item in articleList)
            {
                //获取博文类别名
                string categoryName = item.Category.Name;
                //获取关键词
                string[]      keywords = null;
                List <string> keyList  = new List <string>();
                if (!string.IsNullOrEmpty(item.Keywords))
                {
                    keywords = item.Keywords.Split(' ');
                    foreach (var word in keywords)
                    {
                        if (!string.IsNullOrEmpty(word))
                        {
                            keyList.Add(word);
                        }
                    }
                }
                //取前5个非空关键词
                keywords = keyList.Take(5).ToArray();
                //获取评论数
                int commentCount = _commentService.GetListBy(p => p.CmtArtId == item.Id && p.Status == 1).Count();

                //构造视图模型
                ArticleViewModel articleViewModel = new ArticleViewModel {
                    Id           = item.Id,
                    Title        = item.Title,
                    SubTime      = item.SubTime.ToShortDateString(),
                    CategoryName = categoryName,
                    ViewCount    = item.ViewCount,
                    CommentCount = commentCount,
                    Digg         = item.Digg,
                    Contents     = StringUtil.Truncate(item.ContentsRaw, 600),
                    Keywords     = keywords
                };
                articleViewList.Add(articleViewModel);
            }

            //构造分页html
            string pagerNavString = PagerHelper.GerneratePagerString(pageIndex, pageSize, totalCount);
            React  data           = new React
            {
                code      = 0,
                data      = articleViewList,
                msg       = "success",
                gotoUrl   = HttpContext.Request.Url.AbsolutePath,
                pagedHtml = pagerNavString
            };

            return(Json(data, JsonRequestBehavior.AllowGet));
        }
Пример #24
0
 public static Reaction <Mat4> UpdatePerspectiveMatrix()
 {
     return(React.By <Mat4> (matrix => _terrain.transforms.perspectiveMatrix &= matrix)
            .Program(_terrainShader));
 }
        private void Timer_Tick(object sender, EventArgs e)
        {
            var KRWAccount = ApiData.getAsset().Where(x => "KRW".Equals(x.Value <string>("currency"))).First();

            Thread.Sleep(100);
            var krwBalance = KRWAccount.Value <double>("balance");                                           // 보유 현금
            var candles    = ApiData.getCandle <List <Candle> >(CoinName, CandleType, CandleCount);

            Thread.Sleep(100);
            var prevCandle = candles[1];
            var currCandle = candles[0];
            var currPrice  = currCandle.Close;
            var prevPrice  = prevCandle.Close;

            var orderChance = ApiData.getOrdersChance(CoinName);

            Thread.Sleep(100);
            var ask      = orderChance["ask_account"];
            var coinVol  = ask.Value <double>("balance");                                                  // 보유 코인 수량
            var avgPrice = (coinVol * currPrice < 5000) ? currPrice : ask.Value <double>("avg_buy_price"); // 매수 평단가

            var coinPrice = avgPrice * coinVol;                                                            // 보유 코인 금액
            var upRatio   = (currPrice - avgPrice) / currPrice * 100;                                      // 평단 대비 상승폭 (%)
            var downRatio = (currPrice - prevPrice) / currPrice * 100;                                     // 현재가 대비 하락폭 (%)
            var result    = null as JObject;                                                               // 거래 결과

            Debug.WriteLine("upRatio : {0}, downRatio {1}", upRatio, downRatio);
            WriteLog("upRatio : {0}, downRatio {1}", upRatio, downRatio);

            try
            {
                if (upRatio >= TriggerRatio && coinPrice > 5000)
                {
                    // 올랐을때 코인 금액 절반 팔기
                    var vol = (coinPrice / 2) > 5000 ? coinVol / 2 : coinVol;
                    vol = Math.Truncate(vol * 100000) / 100000;
                    Debug.WriteLine("#### {2} SELL : 금액 {0}, 수량 {1}", vol * currPrice, vol, CoinName);
                    WriteLog("#### {2} SELL : 금액 {0}, 수량 {1}", vol * currPrice, vol, CoinName);
                    result = React.executeDeal(false, false, CoinName, vol, 0, 0);
                }
                else if (downRatio <= -(TriggerRatio) && krwBalance > 5000)
                {
                    // 내렸을때 보유 현금 절반으로 코인 사기
                    var total = (krwBalance / 2) > 5000 ? krwBalance / 2 : krwBalance;
                    total = Math.Truncate(total * 1000) / 1000;
                    Debug.WriteLine("#### {2} BUY : 금액 {0}, 수량 {1}", total, total / currPrice, CoinName);
                    WriteLog("#### {2} BUY : 금액 {0}, 수량 {1}", total, total / currPrice, CoinName);
                    result = React.executeDeal(true, false, CoinName, 0, 0, total);
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex);
            }

            if (result != null)
            {
                Debug.WriteLine("#### RESULT : {0}", result.ToString());
                WriteLog("#### RESULT : {0}", result.ToString());
            }
        }
Пример #26
0
 public Trader(string access_key, string secret_key, List <string> coinList)
 {
     InitializeComponent();
     this.react    = new React(access_key, secret_key);
     this.coinList = new List <string>(coinList);
 }
Пример #27
0
        public IHttpActionResult UpdateReact(React React)
        {
            var reactions = _context.PostReactions.ToList();
            int found     = 0;

            foreach (var reaction in reactions)
            {
                if (reaction.clientId == React.clientId && reaction.postId == React.postId && React.reactType == "Like")
                {
                    reaction.Reaction = 1;
                    found++;
                    _context.SaveChanges();
                }
                else if (reaction.clientId == React.clientId && reaction.postId == React.postId && React.reactType == "RemoveLike")
                {
                    reaction.Reaction = 0;
                    found++;
                    _context.SaveChanges();
                }
                else if (reaction.clientId == React.clientId && reaction.postId == React.postId && React.reactType == "DisLike")
                {
                    reaction.Reaction = 2;
                    found++;
                    _context.SaveChanges();
                }
                else if (reaction.clientId == React.clientId && reaction.postId == React.postId && React.reactType == "RemoveDislike")
                {
                    reaction.Reaction = 0;
                    found++;
                    _context.SaveChanges();
                }
            }

            if (found == 0 && React.reactType == "Like")
            {
                var reaction = new PostReaction
                {
                    clientId = React.clientId,
                    postId   = React.postId,
                    Reaction = 1
                };
                _context.PostReactions.Add(reaction);
                _context.SaveChanges();
                found++;
            }

            if (found == 0 && React.reactType == "DisLike")
            {
                var reaction = new PostReaction
                {
                    clientId = React.clientId,
                    postId   = React.postId,
                    Reaction = 2
                };
                _context.PostReactions.Add(reaction);
                _context.SaveChanges();
                found++;
            }


            var reacts = _context.PostReactions.Where(c => c.postId == React.postId).ToList();
            int like   = 0;
            int dlike  = 0;

            foreach (var re in reacts)
            {
                if (re.Reaction == 1)
                {
                    like++;
                }
                if (re.Reaction == 2)
                {
                    dlike++;
                }
            }
            var numOfReactionVM = new ViewModels.NumberOfReactions
            {
                Likes    = like,
                disLikes = dlike
            };

            return(Ok(numOfReactionVM));
            //return Ok();
        }
        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 * 2); // 캔들 조회 (2배로 여유롭게)
            var currPrice = candles.First().Close;                                                     // 현재가

            // 보유현금 및 주문 정보
            var orderChance    = ApiData.getOrdersChance(coinName);                                 // 주문 가능 정보
            var bid            = orderChance["bid_account"];
            var ask            = orderChance["ask_account"];
            var krwBalance     = bid.Value <double>("balance");                                     // 보유 현금
            var coinVol        = ask.Value <double>("balance");                                     // 보유 코인 수량
            var avgPrice       = ask.Value <double>("avg_buy_price");                               // 매수 평단가
            var bidLock        = bid.Value <double>("locked");                                      // 매수 대기 금액
            var coinBuyBalance = avgPrice * coinVol;                                                // 코인 매수금
            var coinBalance    = currPrice * coinVol;                                               // 코인 평가금
            var minTradeKRW    = Settings.Default.minTradeKRW;                                      // 최소 거래 금액

            // 분봉 N개를 기준으로 직전 시가 에서 현재 금액 등낙률을 가져온다.
            //var prevCandle = candles[1];                                                          // 직전 캔들
            //var lastCandle = candles.Last();                                                      // 마지막 캔들
            var prevPrice        = candles[1].Close;                                                // 직전종가
            var highPrice        = candles.GetRange(1, candleCount - 1).Max(x => x.High);           // 최고가
            var downPrice        = highPrice * (triggerRate + (feeRate * 2)) / 100;                 // 하락가
            var triggerDownPrice = highPrice - downPrice;                                           // 매수 하락 촉발가
            var downRate         = Math.Min(0D, (currPrice - highPrice) * 100 / highPrice);         // 하락율
            var upPrice          = prevPrice * ((triggerRate / candleCount) + (feeRate * 2)) / 100; // 반등가
            var triggerUpPrice   = prevPrice + upPrice;                                             // 매수 반등 촉발가
            var upRate           = Math.Max(0D, (currPrice - prevPrice) * 100 / prevPrice);         // 반등 상승율
            var downUpRate       = upRate == 0 ? 0D : (-downRate / upRate);                         // 반등율
            var targetRate       = ((triggerRate / (candleCount - 1)) + (feeRate * 2)) / 100;       // 목표 수익율
            var targetSellPrice  = avgPrice + (avgPrice * targetRate);                              // 매도 목표가

            // 현재가가 평단가 보다 (수익율/2 + 수료율2배) 이상일때 전체 매도


            WriteLog("currPrice {0:N0}, prevPrice {1:N0}, highPrice {2:N0}", currPrice, prevPrice, highPrice);
            WriteLog("currPrice {0:N0}, downRate {1:F6}, upRate {2:F6}, downUpRate {3:F6}", currPrice, downRate, upRate, downUpRate);

            //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 args = new object[] { coinName, currPrice, prevPrice, highPrice, changeRate, candlesRate, avgPrice, targetProfit };
            var buyTs  = DateTime.Now - LastBuyDate;
            var sellTs = DateTime.Now - LastSellDate;
            var result = null as JObject;

            //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 &&                                       // 매도 이후 분봉의 절반이상이 지나고
                         currPrice <= triggerDownPrice && currPrice >= triggerUpPrice &&                            // 현재가가 촉발 금액 사이에서 반등하고
                         downUpRate <= candleCount * 2)                                                             // 반등율이 캔들갯수의 2배수가 넘지 않아야 함
                {
                    // BUY
                    var total       = ToOrderPrice(krwBalance);
                    var avgBuyPrice = currPrice;
                    result      = React.executeDeal(true, false, coinName, 0, 0, total);
                    LastBuyDate = DateTime.Now;
                    WriteLog("#### {0} BUY : 매수 평단가 {1:N0}: 매수금 {2:N0}: 수량 {3:F6}", coinName, avgBuyPrice, total, total / avgBuyPrice);
                }
                else if (coinBalance > minTradeKRW &&                                                               // 코인 보유금이 최소거래 금액 보다 크고
                         (buyTs.TotalSeconds >= CandleType.Minute * 60 * candleCount / 3 * 2 ||                     // 매도 이후 분봉의 3분2 이상이 지나고
                          currPrice >= targetSellPrice))                                                            // 현재가가 평단가 보다 (수익율/캔들수-1) + 수료율2배 이상일때 전체 매도
                {
                    // 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);
            //}
        }
Пример #29
0
        private void PointHalfStrategy()
        {
            // 3분봉 2개를 기준으로 이전 시가 에서 현재 금액 등낙률을 가져온다.
            // 등낙률 0.5% 이상이 되면 오르면 팔고/ 내리면 산다.
            // 거래시 보유 현금, 보유 코인의 절반을 거래하되 거래 금액이 만원 미만인 경우 전체 금액으로 거래한다.

            var KRWAccount = ApiData.getAsset().Where(x => "KRW".Equals(x.Value <string>("currency"))).First();
            var krwBalance = KRWAccount.Value <double>("balance");                                           // 보유 현금

            txtKRW.Text = krwBalance.ToString("N0");
            var candles    = ApiData.getCandle <List <Candle> >(CoinName, CandleType, CandleCount);
            var prevCandle = candles[2];
            var currCandle = candles[0];
            var currPrice  = currCandle.Close;
            var prevPrice  = prevCandle.Close;

            var orderChance = ApiData.getOrdersChance(CoinName);
            var ask         = orderChance["ask_account"];
            var coinVol     = ask.Value <double>("balance");                                                  // 보유 코인 수량
            var avgPrice    = (coinVol * currPrice < 5000) ? currPrice : ask.Value <double>("avg_buy_price"); // 매수 평단가

            var coinPrice = avgPrice * coinVol;                                                               // 보유 코인 금액
            var upRatio   = (currPrice - avgPrice) / currPrice * 100;                                         // 평단 대비 상승폭 (%)
            var downRatio = (currPrice - prevPrice) / currPrice * 100;                                        // 현재가 대비 하락폭 (%)
            var result    = null as JObject;                                                                  // 거래 결과

            Debug.WriteLine("upRatio : {0}, downRatio {1}", upRatio, downRatio);
            WriteLog("upRatio : {0}, downRatio {1}", upRatio, downRatio);

            try
            {
                if (upRatio >= TriggerRatio && coinPrice > 5000)
                {
                    // 올랐을때 코인 금액 절반 팔기
                    var vol = (coinPrice / 2) > 5000 ? coinVol / 2 : coinVol;
                    vol = Math.Truncate(vol * 100000) / 100000;
                    Debug.WriteLine("#### {2} SELL : 금액 {0}, 수량 {1}", vol * currPrice, vol, CoinName);
                    WriteLog("#### {2} SELL : 금액 {0}, 수량 {1}", vol * currPrice, vol, CoinName);
                    result = React.executeDeal(false, false, CoinName, vol, 0, 0);
                }
                else if (downRatio <= -(TriggerRatio) && krwBalance > 5000)
                {
                    // 내렸을때 보유 현금 절반으로 코인 사기
                    var total = (krwBalance / 2) > 5000 ? krwBalance / 2 : krwBalance;
                    total = Math.Truncate(total * 1000) / 1000;
                    Debug.WriteLine("#### {2} BUY : 금액 {0}, 수량 {1}", total, total / currPrice, CoinName);
                    WriteLog("#### {2} BUY : 금액 {0}, 수량 {1}", total, total / currPrice, CoinName);
                    result = React.executeDeal(true, false, CoinName, 0, 0, total);
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex);
                WriteLog(ex.StackTrace);
            }

            if (result != null)
            {
                Debug.WriteLine("#### RESULT : {0}", result.ToString());
                WriteLog("#### RESULT : {0}", result.ToString());
            }
        }
Пример #30
0
        //public ActionResult MakeUserInactive(int id)
        //{
        //}
        public ActionResult ReactToMessage(int MessageId, React react)
        {
            Message message = db.Messages.Find(MessageId);
            if (message == null)
            {
                return HttpNotFound();
            }

            var curUserId = db.Users.Single(s => s.UserName == User.Identity.Name).UserId;

            bool hasMessageHasSameReact = (from mr in db.MessageReactions
                                           where mr.MessageId == MessageId
                                           where mr.React == react
                                           where mr.UserId == curUserId
                                           select mr).Count() == 1;

            if (hasMessageHasSameReact) return RedirectToAction("Index");

            MessageReaction messageReaction = new MessageReaction()
            {
                MessageId = MessageId,
                UserId = curUserId,
                React = react,
            };

            try
            {
                db.MessageReactions.Add(messageReaction);
                db.SaveChanges();
            }
            catch
            {
                return View();
            }
            return View();
        }
        private void PointHalfStrategy()
        {
            // 1분봉 3개를 기준으로 이전 시가 에서 현재 금액 등낙률을 가져온다.
            // 등낙률 0.5% 이상이 되면 오르면 팔고/ 내리면 산다.
            // 거래시 보유 현금, 보유 코인의 절반을 거래하되 거래 금액이 만원 미만인 경우 전체 금액으로 거래한다.
            var algIdx      = cmbAlgorithm.SelectedIndex;
            var idx         = (algIdx > 0) ? algIdx : Convert.ToInt32(txtMaxRatio.Text);
            var candleType  = BotSetting.CandleTypes[idx];
            var candles     = ApiData.getCandle <List <Candle> >(CoinName, candleType, 3);
            var prevCandle  = candles[2];       // 시가 봉
            var currCandle  = candles[0];       // 현재가 봉
            var currPrice   = currCandle.Close;
            var prevPrice   = prevCandle.Close;
            var orderChance = GetOrderChance(ApiData, CoinName, currPrice);
            //var ask = orderChance["ask_account"];
            //var bid = orderChance["bid_account"];
            var krwBalance = orderChance.KRWBalance;                            // 보유 현금
            var coinVol    = orderChance.CoinVol;                               // 보유 코인 수량
            var avgPrice   = orderChance.AvgBuyPrice;                           // 매수 평단가
            var coinPrice  = orderChance.CoinBalance;                           // 보유 코인 금액

            //var upRatio = (currPrice - avgPrice) / currPrice * 100;     // 평단 대비 상승폭 (%)
            //var downRatio = (currPrice - prevPrice) / currPrice * 100;  // 현재가 대비 하락폭 (%)
            var ratio     = (currPrice - prevPrice) / currPrice * 100;  // 등락폭 (%)
            var tradeRate = Convert.ToInt32(txtTradeRate.Text) / 100;   // 거래 비중 (%)
            var result    = null as JObject;                            // 거래 결과

            //txtKRW.Text = krwBalance.ToString("N0");
            //txtCoinBalance.Text = coinPrice.ToString("N0");

            Debug.WriteLine("이전가: {0:N0}, 현재가 {1:N0}, ratio : {2:F4}%", prevPrice, currPrice, ratio);
            WriteLog("이전가: {0:N0}, 현재가 {1:N0}, ratio : {2:F4}%", prevPrice, currPrice, ratio);

            try
            {
                if (avgPrice + (avgPrice * TriggerRatio / 100) <= currPrice && coinPrice >= 5000)
                {
                    // 현재가가 평단가보다 등락폭 이상 올랐을때 전량 매도
                    var vol = coinVol;
                    vol = Math.Truncate(vol * 100000) / 100000;
                    Debug.WriteLine("#### {2} ALL SELL : 금액 {0:N0}, 수량 {1:F6}", vol * currPrice, vol, CoinName);
                    WriteLog("#### {2} ALL SELL : 금액 {0:N0}, 수량 {1:F6}", vol * currPrice, vol, CoinName);
                    result       = React.executeDeal(false, false, CoinName, vol, 0, 0);
                    LastSellDate = DateTime.Now;
                }
                else if (ratio >= TriggerRatio && coinPrice >= 5000 && (DateTime.Now - LastSellDate).TotalMinutes >= idx)
                {
                    // 올랐을때 코인 금액 절반 팔기
                    var vol = (coinPrice * tradeRate) > 5000 ? coinVol * tradeRate : coinVol;
                    vol = Math.Truncate(vol * 100000) / 100000;
                    Debug.WriteLine("#### {2} SELL : 금액 {0:N0}, 수량 {1:F6}", vol * currPrice, vol, CoinName);
                    WriteLog("#### {2} SELL : 금액 {0:N0}, 수량 {1:F6}", vol * currPrice, vol, CoinName);
                    result       = React.executeDeal(false, false, CoinName, vol, 0, 0);
                    LastSellDate = DateTime.Now;
                }
                else if (ratio <= -(TriggerRatio + 0.1) && krwBalance > 5000 && (DateTime.Now - LastBuyDate).TotalMinutes >= idx)
                {
                    // 내렸을때 보유 현금 절반으로 코인 사기
                    var total = (krwBalance * tradeRate) > 5000 ? krwBalance * tradeRate : krwBalance;
                    total = Math.Truncate(total * 1000) / 1000;
                    Debug.WriteLine("#### {2} BUY : 금액 {0:N0}, 수량 {1:F6}", total, total / currPrice, CoinName);
                    WriteLog("#### {2} BUY : 금액 {0:N0}, 수량 {1:F6}", total, total / currPrice, CoinName);
                    result      = React.executeDeal(true, false, CoinName, 0, 0, total);
                    LastBuyDate = DateTime.Now;
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex);
                WriteLog(ex.StackTrace);
            }

            orderChance = GetOrderChance(ApiData, CoinName, currPrice);

            if (result != null)
            {
                Debug.WriteLine("#### RESULT : {0}", result.ToString());
                WriteLog("#### RESULT : {0}", result.ToString());
            }
        }
        private void MinuteCandleByTicks()
        {
            // 설정값
            var coinName    = Coin.Ticker;
            var candleType  = CandleType.Name;
            var ticks       = CandleCount;
            var triggerRate = Rate;
            var fee         = FeeRate;
            var tradeRate   = TradeRate;
            var profit      = ProfitRate;

            // 해당 코인 보유금액이 있으면 매도 없으면 매수
            var candles     = ApiData.getCandle <List <Candle> >(coinName, candleType, CandleCount); // 캔들 조회
            var currCandle  = candles.First();                                                       // 현재 캔들
            var currPrice   = currCandle.Close;                                                      // 현재가
            var orderChance = GetOrderChance(ApiData, coinName, currPrice);                          // 주문 가능 정보
            var coinPrice   = orderChance.CoinBalance * currPrice;                                   // 코인 보유금
            var krwBalance  = orderChance.KRWBalance;                                                // 보유 현금
            var coinVol     = orderChance.CoinVol;                                                   // 보유 코인 수량
            var avgPrice    = orderChance.AvgBuyPrice;                                               // 매수 평단가
            var minTradeKRW = Settings.Default.minTradeKRW;                                          // 최소 거래 금액

            if (coinPrice <= minTradeKRW && krwBalance <= minTradeKRW)
            {
                // 보유현금과 보유 코인이 최소 거래금액 보다 적으면 거래 없음
                WriteLog("#### 거래 불가 : 보유현금 {0}, 코인보유금 {1}, 최소 거래 금액 {2},", krwBalance, coinPrice, minTradeKRW);
                return;
            }

            // 분봉 N개를 기준으로 이전 시가 에서 현재 금액 등낙률을 가져온다.
            // 촉발 등낙률 초과하여 떨어지다 수수료율 2배 이상 상승 했을때 거래비율 만큼 산다.
            // 매수 이후 (1% - 수수료율) 이상 떨어지면 전체 손절
            // 매수 이후 (1% + 수수료율) 이상 오르면 전체 익절
            var prevCandle  = candles[1];                                                   // 직전 캔들
            var lastCandle  = candles.Last();                                               // 마지막 캔들
            var prevPrice   = prevCandle.Close;                                             // 직전종가
            var startPrice  = lastCandle.Open;                                              // 마지막 캔들 시작가
            var change      = (currPrice - prevPrice);                                      // 변동가
            var currentRate = (change / currPrice) * 100;                                   // 등락율
            var downChange  = (startPrice - currPrice);                                     // 상승전 변동가
            var downRate    = (downChange / startPrice) * 100;                              // 상승전 하락율
            var tradeProfit = (currPrice - avgPrice / startPrice) * 100;                    // 수익
            var result      = null as JObject;

            if (krwBalance > minTradeKRW &&
                downRate >= profit + (fee * 2) &&
                currentRate >= (fee * 2))
            {
                // BUY
                // 보유현금이 최소 거래금액 보다 많음
                // 수익율 초과하여 떨어지다 수수료율 2배 이상 상승 했을때 거래비율 만큼 산다.
                var total = Math.Truncate(krwBalance * 1000) / 1000;
                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 (krwBalance > minTradeKRW &&
                     currPrice - <= avgPrice + (avgPrice * (fee * 2)) &&
                     currPrice >= (fee * 2))
            {
                // SELL
                // 코인평가금 최소 거래금액 보다 많음
                // 현재가가 평단가 보다 (수익율 - 수료율 * 2) 이하일때 전체 매도
                // 현재가가 평단가 보다 (수익율 + 수료율 * 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);
            }



            // 분봉 N개를 기준으로 이전 시가 에서 현재 금액 등낙률을 가져온다.
            // 촉발 등낙률 초과하여 떨어지다 수수료율 2배 이상 상승 했을때 거래비율 만큼 산다.
            // 매수 이후 (1% - 수수료율) 이상 떨어지면 전체 손절
            // 매수 이후 (1% + 수수료율) 이상 오르면 전체 익절
            var prevCandle  = candles[1];                                                   // 직전 캔들
            var lastCandle  = candles.Last();                                               // 마지막 캔들
            var prevPrice   = prevCandle.Close;                                             // 직전종가
            var startPrice  = lastCandle.Open;                                              // 마지막 캔들 시작가
            var change      = (currPrice - prevPrice);                                      // 변동가
            var currentRate = (change / currPrice) * 100;                                   // 등락율
            var downChange  = (startPrice - currPrice);                                     // 상승전 변동가
            var downRate    = (downChange / startPrice) * 100;                              // 상승전 하락율


            //var algIdx = cmbAlgorithm.SelectedIndex;
            //var idx = (algIdx > 0) ? algIdx : Convert.ToInt32(txtMinute.Text);
            //var candleType = BotSetting.CandleTypes[idx];
            var orderChance = GetOrderChance(ApiData, CoinName, currPrice);
            //var ask = orderChance["ask_account"];
            //var bid = orderChance["bid_account"];
            var krwBalance = orderChance.KRWBalance;                            // 보유 현금
            var coinVol    = orderChance.CoinVol;                               // 보유 코인 수량
            var avgPrice   = orderChance.AvgBuyPrice;                           // 매수 평단가
            var coinPrice  = orderChance.CoinBalance;                           // 보유 코인 금액

            //var upRatio = (currPrice - avgPrice) / currPrice * 100;     // 평단 대비 상승폭 (%)
            //var downRatio = (currPrice - prevPrice) / currPrice * 100;  // 현재가 대비 하락폭 (%)
            var ratio     = (currPrice - prevPrice) / currPrice * 100;      // 등락폭 (%)
            var tradeRate = Convert.ToDouble(txtTradeRate.Text) / 100D;     // 거래 비중 (%)
            var result    = null as JObject;                                // 거래 결과

            //txtKRW.Text = krwBalance.ToString("N0");
            //txtCoinBalance.Text = coinPrice.ToString("N0");

            Debug.WriteLine("이전가: {0:N0}, 현재가 {1:N0}, ratio : {2:F4}%", prevPrice, currPrice, ratio);
            WriteLog("이전가: {0:N0}, 현재가 {1:N0}, ratio : {2:F4}%", prevPrice, currPrice, ratio);

            try
            {
                if (avgPrice + (2 * (avgPrice * Rate / 100)) <= currPrice && coinPrice >= 5000)
                {
                    // 현재가가 평단가보다 등락폭 2배 이상 올랐을때 전량 매도
                    var vol = coinVol;
                    vol = Math.Truncate(vol * 100000) / 100000;
                    Debug.WriteLine("#### {2} ALL SELL : 금액 {0:N0}, 수량 {1:F6}", vol * currPrice, vol, CoinName);
                    WriteLog("#### {2} ALL SELL : 금액 {0:N0}, 수량 {1:F6}", vol * currPrice, vol, CoinName);
                    result       = React.executeDeal(false, false, CoinName, vol, 0, 0);
                    LastSellDate = DateTime.Now;
                }
                else if (ratio >= Rate && coinPrice >= 5000 && ((DateTime.Now - LastSellDate).TotalMinutes >= idx || ratio >= Rate * 1.5))
                {
                    // 올랐을때 코인 금액 절반 팔기
                    var vol = (coinPrice * tradeRate) > 5000 ? coinVol * tradeRate : coinVol;
                    vol = Math.Truncate(vol * 100000) / 100000;
                    Debug.WriteLine("#### {2} SELL : 금액 {0:N0}, 수량 {1:F6}", vol * currPrice, vol, CoinName);
                    WriteLog("#### {2} SELL : 금액 {0:N0}, 수량 {1:F6}", vol * currPrice, vol, CoinName);
                    result       = React.executeDeal(false, false, CoinName, vol, 0, 0);
                    LastSellDate = DateTime.Now;
                }
                else if (ratio <= -(Rate * 1.2) && krwBalance > 5000 && (DateTime.Now - LastBuyDate).TotalMinutes >= idx)
                {
                    // 1.2배 내렸을때 보유 현금 절반으로 코인 사기
                    var total = (krwBalance * tradeRate) > 5000 ? krwBalance * tradeRate : krwBalance;
                    total = Math.Truncate(total * 1000) / 1000;
                    Debug.WriteLine("#### {2} BUY : 금액 {0:N0}, 수량 {1:F6}", total, total / currPrice, CoinName);
                    WriteLog("#### {2} BUY : 금액 {0:N0}, 수량 {1:F6}", total, total / currPrice, CoinName);
                    result      = React.executeDeal(true, false, CoinName, 0, 0, total);
                    LastBuyDate = DateTime.Now;
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex);
                WriteLog(ex.StackTrace);
            }

            orderChance = GetOrderChance(ApiData, CoinName, currPrice);

            if (result != null)
            {
                Debug.WriteLine("#### RESULT : {0}", result.ToString());
                WriteLog("#### RESULT : {0}", result.ToString());
            }
        }
Пример #33
0
        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);
            }
        }
        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 * 2); // 캔들 조회 (2배로 여유롭게)
            var currPrice        = candles.First().Close;                                                     // 현재가
            var prevPrice        = candles[1].Close;                                                          // 직전종가
            var highPrice        = candles.GetRange(1, candleCount - 1).Max(x => x.High);                     // 최고가
            var downPrice        = highPrice * (triggerRate + (feeRate * 2)) / 100;                           // 하락가
            var triggerDownPrice = highPrice - downPrice;                                                     // 매수 하락 촉발가
            var downRate         = Math.Min(0D, (currPrice - highPrice) * 100 / highPrice);                   // 하락율
            var upPrice          = prevPrice * ((triggerRate / candleCount) + (feeRate * 2)) / 100;           // 반등가
            var triggerUpPrice   = prevPrice + upPrice;                                                       // 매수 반등 촉발가
            var upRate           = Math.Max(0D, (currPrice - prevPrice) * 100 / prevPrice);                   // 반등 상승율
            var downUpRate       = upRate == 0 ? 0D : (-downRate / upRate);                                   // 반등율

            // 보유현금 및 주문 정보
            var orderChance    = ApiData.getOrdersChance(coinName);                                 // 주문 가능 정보
            var bid            = orderChance["bid_account"];
            var ask            = orderChance["ask_account"];
            var krwBalance     = bid.Value <double>("balance");                                     // 보유 현금
            var coinVol        = ask.Value <double>("balance");                                     // 보유 코인 수량
            var avgPrice       = ask.Value <double>("avg_buy_price");                               // 매수 평단가
            var bidLock        = bid.Value <double>("locked");                                      // 매수 대기 금액
            var coinBuyBalance = avgPrice * coinVol;                                                // 코인 매수금
            var coinBalance    = currPrice * coinVol;                                               // 코인 평가금
            var totalBalance   = krwBalance + coinBalance;                                          // 현재 자산
            var minTradeKRW    = Settings.Default.minTradeKRW;                                      // 최소 거래 금액

            avgPrice = avgPrice < minTradeKRW ? currPrice : avgPrice;

            // 거래 쿨다운 타임
            var buyTs           = (DateTime.Now - LastSellDate).TotalSeconds;                       // 매도 경과 시간 (초)
            var buyCoolDownSec  = CandleType.Minute * 60;                                           // 매수 쿨다운 시간 (초)
            var buyCountDownSec = buyCoolDownSec - buyTs;                                           // 매수 쿨다운 시간 (초)

            var sellTs           = (DateTime.Now - LastBuyDate).TotalSeconds;                       // 매수 경과 시간 (초)
            var sellCoolDownSec  = (CandleType.Minute * 60 * candleCount / 3 * 2);                  // 매도 쿨다운 시간 (초)
            var sellCountDownSec = sellCoolDownSec - sellTs;                                        // 매도 까지 남은 시간 (초)

            var targetRate      = ((triggerRate / (candleCount - 1)) + (feeRate * 2)) / 100;        // 목표 수익율
            var targetSellPrice = avgPrice + (avgPrice * targetRate);                               // 매도 목표가

            var result = null as JObject;
            var args   = new object[] {
                DateTime.Now,
                coinName,
                currPrice,
                prevPrice,
                highPrice,
                downRate,
                upRate,
                avgPrice,
                StartKRW,
                totalBalance,
                triggerDownPrice,
                triggerUpPrice,
                targetSellPrice,
                sellCountDownSec,
                buyCoolDownSec,
            };

            log.Debug(JsonConvert.SerializeObject(candles));
            log.Debug(JsonConvert.SerializeObject(orderChance));

            string format = "[{0:T}] {1} : 현재가 {2:N0}, 직전가 {3:N0}, 최고가 {4:N0}, 하락율 {5:F6}, 반등율 {6:F6}, 평단가 {7:N0}";

            format += (sellCountDownSec > 0) ? ", 매수 까지 남은 시간(초) {13:N0}" : "";
            format += (buyCoolDownSec > 0) ? ", 매도 까지 남은 시간(초) {14:N0}" : "";
            format += "\r\n[{0:T}] {1} : 시작자산 {8:N0}, 현재자산 {9:N0} 매수 하락 촉발가 {10:N0}, 매수 반등 촉발가 {11:N0}, 매도 목표가 {12:N0}";
            WriteCurrent(format, args);

            if (StartKRW < minTradeKRW && krwBalance > minTradeKRW && coinBalance < minTradeKRW)
            {
                // 거래 시작 금액
                StartKRW = krwBalance;
            }

            txtKRWBalance.Text  = krwBalance.ToString("N0");
            txtCoinBalance.Text = coinBalance.ToString("N0");
            txtBalance.Text     = totalBalance.ToString("N0");
            txtStartKRW.Text    = StartKRW.ToString("N0");

            var buySates  = null as string;
            var sellSates = null as string;

            try
            {
                if (coinBalance <= minTradeKRW && krwBalance <= minTradeKRW)
                {
                    // 보유현금과 보유 코인이 최소 거래금액 보다 적으면 거래 없음
                    WriteLog("#### 거래 불가 : 보유현금 {0}, 코인보유금 {1}, 최소 거래 금액 {2},", krwBalance, coinBalance, minTradeKRW);
                    return;
                }

                if (coinBalance <= minTradeKRW && krwBalance <= minTradeKRW)
                {
                    // 보유현금과 보유 코인이 최소 거래금액 보다 적으면 거래 없음
                    WriteLog("#### 거래 불가 : 보유현금 {0}, 코인보유금 {1}, 최소 거래 금액 {2},", krwBalance, coinBalance, minTradeKRW);
                    return;
                }

                if (krwBalance > minTradeKRW &&                                                                   // 보유 현금이 최소거래 금액 보다 크고
                    buySec <= 0D && /* */                                                                         // 매도 이후 분봉의 절반이상이 지나고
                    currPrice <= Math.Truncate(triggerDownPrice) && currPrice >= Math.Truncate(triggerUpPrice) && // 현재가가 촉발 금액 사이에서 반등하고
                    downUpRate <= candleCount * 2)                                                                // 반등율이 캔들갯수의 2배수가 넘지 않아야 함
                {
                    // BUY
                    var total       = ToOrderPrice(krwBalance);
                    var avgBuyPrice = currPrice;
                    result   = React.executeDeal(true, false, coinName, 0, 0, total);
                    buySates = result.Value <string>("state");

                    if ("cancel".Equals(buySates))
                    {
                        System.Threading.Thread.Sleep(1000);
                        result   = React.executeDeal(true, false, coinName, 0, 0, total);
                        buySates = result.Value <string>("state");
                    }
                }
                else if (coinBalance > minTradeKRW &&                                                               // 코인 보유금이 최소거래 금액 보다 크고
                         (sellCountDownSec <= 0D ||                                                                 // 매도 이후 분봉의 3분2 이상이 지나거나
                          currPrice >= Math.Truncate(targetSellPrice)))                                             // 현재가가 평단가 보다 (수익율/캔들수-1) + 수료율2배 이상일때 전체 매도
                {
                    // SELL
                    // 현재가가 평단가 보다 (수익율/캔들수 + 수료율2배) 이상일때 전체 매도
                    var vol = coinVol;
                    vol       = Math.Truncate(vol * 100000) / 100000;
                    result    = React.executeDeal(false, false, coinName, vol, 0, 0);
                    sellSates = result.Value <string>("state");
                }

                if (result != null)
                {
                    WriteLog("{0} RESULT : {1}", coinName, JsonConvert.SerializeObject(result));

                    var uuid = result.Value <string>("uuid");
                    var side = result.Value <string>("side");

                    if (result != null && !"cancel".Equals(buySates))
                    {
                        WriteLog("#### START GetOrderResultAsync : {0}", uuid);
                        //result = GetOrderResultAsync(uuid);
                        result = GetOrderResult(uuid);
                        WriteLog("#### FINISH GetOrderResultAsync : {0}", uuid);

                        if (result == null)
                        {
                            WriteLog("#### 거래 결과를 가져올수 없습니다.");
                            return;
                        }

                        var state       = result.Value <string>("state");
                        var price       = result.Value <double?>("price") ?? 0D;
                        var volume      = result.Value <double?>("volume") ?? 0D;
                        var tradeCount  = result.Value <double>("trade_count");
                        var trades      = result["trades"] as JArray;
                        var tradePrice  = trades[0].Value <double>("price");
                        var tradeVolume = trades[0].Value <double>("volume");
                        var tradeFunds  = trades[0].Value <double>("funds");

                        args = new object[] { uuid, side, state, price, volume, tradeCount, tradePrice, tradeVolume, tradeFunds };
                        WriteLog("#### uuid {0}, side {1}, state {2}, price {3:N0}, volume {4:F6}, tradeCount {5:N0}, tradePrice {6:N0}, tradeVolume {7:N0}, tradeFunds {8:N0}", args);

                        if ("bid".Equals(side))
                        {
                            // BUY
                            LastBuyDate = DateTime.Now;
                            WriteLog("#### {0} BUY : 매수금 {1:N0} : 매수 평단가 {1:N0} : 수량 {3:F6}", coinName, price * volume, price, volume);
                        }
                        else if ("ask".Equals(side))
                        {
                            // SELL
                            LastSellDate = DateTime.Now;
                            WriteLog("#### {0} SELL : 매도금 {1:N0} : 매도 평단가 {1:N0} : 수량 {3:F6}", coinName, price * volume, price, volume);
                        }

                        // 수익
                        var balance = GetBalance(coinName);
                        krwBalance   = balance.KRWBalance;
                        coinBalance  = currPrice * balance.CoinVol;
                        totalBalance = krwBalance + coinBalance;
                        var profit     = totalBalance - StartKRW;
                        var profitRate = (StartKRW == 0) ? 0D : profit / StartKRW * 100;

                        txtKRWBalance.Text  = krwBalance.ToString("N0");
                        txtCoinBalance.Text = coinBalance.ToString("N0");
                        txtBalance.Text     = totalBalance.ToString("N0");
                        txtProfitPrice.Text = profit.ToString("N0");
                        txtProfitRate.Text  = profitRate.ToString("F4");

                        args = new object[] { coinName, StartKRW, totalBalance, profit, profitRate, krwBalance, coinBalance };
                        WriteLog("#### {0} 수익 : 거래시작금액 {1:N0}, 현재평가 금액 {2:N0}, 수익금액 {3:N0}, 수익율 {4:F6}, 보유현금 {5:N0}, 코인 평가 {6:N0}", args);
                    }
                }
            }
            catch (Exception ex)
            {
                WriteLog(ex.StackTrace);
            }
        }
        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 * 2); // 캔들 조회 (2배로 여유롭게)
            var currPrice = candles.First().Close;                                                     // 현재가

            // 보유현금 및 주문 정보
            var orderChance    = ApiData.getOrdersChance(coinName);                                 // 주문 가능 정보
            var bid            = orderChance["bid_account"];
            var ask            = orderChance["ask_account"];
            var krwBalance     = bid.Value <double>("balance");                                     // 보유 현금
            var coinVol        = ask.Value <double>("balance");                                     // 보유 코인 수량
            var avgPrice       = ask.Value <double>("avg_buy_price");                               // 매수 평단가
            var bidLock        = bid.Value <double>("locked");                                      // 매수 대기 금액
            var coinBuyBalance = avgPrice * coinVol;                                                // 코인 매수금
            var coinBalance    = currPrice * coinVol;                                               // 코인 평가금
            var minTradeKRW    = Settings.Default.minTradeKRW;                                      // 최소 거래 금액

            // 분봉 N개를 기준으로 직전 시가 에서 현재 금액 등낙률을 가져온다.
            //var prevCandle = candles[1];                                                          // 직전 캔들
            //var lastCandle = candles.Last();                                                      // 마지막 캔들
            var prevPrice        = candles[1].Close;                                                // 직전종가
            var highPrice        = candles.GetRange(1, candleCount - 1).Max(x => x.High);           // 최고가
            var downPrice        = highPrice * (triggerRate + (feeRate * 2)) / 100;                 // 하락가
            var triggerDownPrice = highPrice - downPrice;                                           // 매수 하락 촉발가
            var downRate         = Math.Min(0D, (currPrice - highPrice) * 100 / highPrice);         // 하락율
            var upPrice          = prevPrice * ((triggerRate / candleCount) + (feeRate * 2)) / 100; // 반등가
            var triggerUpPrice   = prevPrice + upPrice;                                             // 매수 반등 촉발가
            var upRate           = Math.Max(0D, (currPrice - prevPrice) * 100 / prevPrice);         // 반등 상승율
            var downUpRate       = upRate == 0 ? 0D : (-downRate / upRate);                         // 반등율
            var targetRate       = ((triggerRate / (candleCount - 1)) + (feeRate * 2)) / 100;       // 목표 수익율
            var targetSellPrice  = avgPrice + (avgPrice * targetRate);                              // 매도 목표가

            var buyTs  = DateTime.Now - LastBuyDate;
            var sellTs = DateTime.Now - LastSellDate;
            var result = null as JObject;
            var args   = new object[] {
                DateTime.Now,
                coinName,
                currPrice,
                prevPrice,
                highPrice,
                downRate,
                upRate,
                avgPrice,
                targetSellPrice,
                triggerDownPrice,
                triggerUpPrice,
                targetSellPrice,
            };

            string format = "[{0:T}] {1} : 현재가 {2:N0}, 직전가 {3:N0}, 최고가 {4:N0}, 하락율 {5:F6}, 반등율 {6:F6}, 평단가 {7:N0}";

            format += "\r\n[{0:T}] {1} : 매수 하락 촉발가 {8:N0}, 매수 반등 촉발가 {9:N0}, 매도 목표가 {10:N0}";
            WriteCurrent(format, 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 &&                                       // 매도 이후 분봉의 절반이상이 지나고
                         currPrice <= triggerDownPrice && currPrice >= triggerUpPrice &&                            // 현재가가 촉발 금액 사이에서 반등하고
                         downUpRate <= candleCount * 2)                                                             // 반등율이 캔들갯수의 2배수가 넘지 않아야 함
                {
                    // BUY
                    var total       = ToOrderPrice(krwBalance);
                    var avgBuyPrice = currPrice;
                    result = React.executeDeal(true, false, coinName, 0, 0, total);
                }
                else if (coinBalance > minTradeKRW &&                                                               // 코인 보유금이 최소거래 금액 보다 크고
                         (buyTs.TotalSeconds >= CandleType.Minute * 60 * candleCount / 3 * 2 ||                     // 매도 이후 분봉의 3분2 이상이 지나고
                          currPrice >= targetSellPrice))                                                            // 현재가가 평단가 보다 (수익율/캔들수-1) + 수료율2배 이상일때 전체 매도
                {
                    // SELL
                    // 현재가가 평단가 보다 (수익율/캔들수 + 수료율2배) 이상일때 전체 매도
                    var vol = coinVol;
                    vol    = Math.Truncate(vol * 100000) / 100000;
                    result = React.executeDeal(false, false, coinName, vol, 0, 0);
                }
            }
            catch (Exception ex)
            {
                WriteLog(ex.StackTrace);
            }

            if (result != null)
            {
                var uuid = result.Value <string>("uuid");
                var side = result.Value <string>("side");

                WriteLog("#### START GetOrderResultAsync : {0}", uuid);
                result = GetOrderResultAsync(uuid, coinName).GetAwaiter().GetResult();
                WriteLog("#### FINISH GetOrderResultAsync : {0}", uuid);

                var state       = result.Value <double>("state");
                var price       = result.Value <double>("price");
                var volume      = result.Value <double>("volume");
                var tradeCount  = result.Value <double>("trade_count");
                var trades      = result["trades"] as JArray;
                var tradePrice  = trades[0].Value <double>("price");
                var tradeVolume = trades[0].Value <double>("volume");
                var tradeFunds  = trades[0].Value <double>("funds");

                args = new object[] { uuid, side, state, price, volume, tradeCount, tradePrice, tradeVolume, tradeFunds };
                WriteLog("#### uuid {0}, side {1}, state {2}, price {3:N0}, volume {4:F6}, tradeCount {5:N0}, tradePrice {6:N0}, tradeVolume {7:N0}, tradeFunds {8:N0}", args);

                if ("bid".Equals(side))
                {
                    // BUY
                    LastBuyDate = DateTime.Now;
                    WriteLog("#### {0} BUY : 매수금 {1:N0} : 매수 평단가 {1:N0} : 수량 {3:F6}", coinName, price * volume, price, volume);
                }
                else if ("ask".Equals(side))
                {
                    // SELL
                    LastSellDate = DateTime.Now;
                    WriteLog("#### {0} SELL : 매도금 {1:N0} : 매도 평단가 {1:N0} : 수량 {3:F6}", coinName, price * volume, price, volume);
                }

                // 수익
                var balance = GetBalance(coinName);
                krwBalance  = balance.KRWBalance;
                coinBalance = currPrice * balance.CoinVol;
                var totalBalance = krwBalance + coinBalance;
                var profit       = totalBalance - StartKRW;
                var profitRate   = (StartKRW == 0) ? 0D : profit / StartKRW * 100;

                txtKRWBalance.Text  = krwBalance.ToString("N0");
                txtCoinBalance.Text = coinBalance.ToString("N0");
                txtBalance.Text     = totalBalance.ToString("N0");

                args = new object[] { coinName, StartKRW, totalBalance, profit, profitRate, krwBalance, coinBalance };
                WriteLog("#### {0} 수익 : 거래시작금액 {1:N0}, 현재평가 금액 {2:N0}, 수익금액 {3:N0}, 수익율 {4:F6}, 보유현금 {5:N0}, 코인 평가 {6:N0}", args);
            }
        }
Пример #36
0
        protected override Control CreateControl()
        {
            var changed  = Changed.Adapt <int, AnySignalEditor> (this);
            var changedf = Changed.Adapt <float, AnySignalEditor> (this);

            return(FoldableContainer.WithLabel(Name, true, HAlign.Left,
                                               Container.LabelAndControl("Seed: ",
                                                                         new NumericEdit(Seed, true, 1f, React.By((float s) => Seed = (int)s)
                                                                                         .And(changedf)), true),
                                               Container.LabelAndControl("Scale X: ",
                                                                         new NumericEdit(Scale.X, false, 1f, React.By((float s) => Scale = new Vec2(s, Scale.Y))
                                                                                         .And(changedf)), true),
                                               Container.LabelAndControl("Scale Y: ",
                                                                         new NumericEdit(Scale.Y, false, 1f, React.By((float s) => Scale = new Vec2(Scale.X, s))
                                                                                         .And(changedf)), true),
                                               Container.LabelAndControl("Periodic: ",
                                                                         new Picker(Periodic ? 1 : 0,
                                                                                    React.By((int i) => Periodic = i != 0).And(changed),
                                                                                    "No", "Yes"), true)));
        }