public override void OnReceiveEvent(string[] param) { if (int.TryParse(param[6], out int volume)) { slim.Wait(); SendConsecutive?.Invoke(this, new SendConsecutive(new Charts { Date = param[0], Price = param[1].StartsWith("-") ? param[1].Substring(1) : param[1], Volume = volume })); if (slim.Release() > 0) { Console.WriteLine(string.Concat(GetType().FullName, '_', Code)); } } if (param.Length == 0x20 && double.TryParse(param[1].StartsWith("-") ? param[1].Substring(1) : param[1], out double price)) { Current = price; Revenue = (long)((price - Purchase) * Quantity * TransactionMultiplier); Rate = (price / Purchase - 1) * (Quantity > 0 ? 1 : -1); } else if (int.TryParse(param[1].StartsWith("-") ? param[1].Substring(1) : param[1], out int current)) { Current = current; Revenue = (current - Purchase) * Quantity; Rate = current / (double)Purchase - 1; } SendStocks?.Invoke(this, new SendHoldingStocks(Code, Quantity, Purchase, Current, Revenue, Rate, Base, Secondary, AdjustTheColorAccordingToTheCurrentSituation(WaitOrder, OrderNumber.Count))); }
public override void OnReceiveEvent(string[] param) { if (int.TryParse(string.Concat(param[8], param[9]), out int volume)) { SendConsecutive?.Invoke(this, new SendConsecutive(new Charts { Date = param[0], Price = param[4], Volume = volume })); } if (double.TryParse(param[4], out double current)) { Current = current; Revenue = (long)((current - (Purchase ?? 0D)) * Quantity * transactionMultiplier); Rate = (Quantity > 0 ? current / (double)Purchase : Purchase / (double)current) - 1; if (OrderNumber.Count > 0 && strategics is TrendFollowingBasicFutures && OrderNumber.ContainsValue(Bid) == false && OrderNumber.ContainsValue(Offer) == false) { foreach (var kv in OrderNumber) { if (kv.Value < Bid || kv.Value > Offer) { SendBalance?.Invoke(this, new SendSecuritiesAPI(new Catalog.XingAPI.Order { FnoIsuNo = Code, OrgOrdNo = kv.Key, OrdQty = "1" })); } } } } if (param[0].CompareTo(end) > 0 && uint.TryParse(param[0], out uint remain) && (RollOver == false || Temporary.RemainingDay.Contains(remain))) { var quantity = Math.Abs(Quantity); RollOver = Temporary.RemainingDay.Remove(remain); if (RollOver == false) { RollOver = true; } while (quantity > 0) { SendBalance?.Invoke(this, new SendSecuritiesAPI(new Catalog.XingAPI.Order { FnoIsuNo = Code, BnsTpCode = Quantity > 0 ? "1" : "2", FnoOrdprcPtnCode = ((int)Catalog.XingAPI.FnoOrdprcPtnCode.시장가).ToString("D2"), OrdPrc = Purchase.ToString("F2"), OrdQty = "1" })); quantity--; } } SendStocks?.Invoke(this, new SendHoldingStocks(Code, Quantity, Purchase, Current, Revenue, Rate, Base, Secondary, AdjustTheColorAccordingToTheCurrentSituation(WaitOrder, OrderNumber.Count))); }
internal void OnReceiveTrendsInPrices(SendConsecutive e, double gap, double peek) { switch (strategics) { case TrendsInValuation tv: var interval = e.Date.Length == 6 ? new DateTime(NextOrderTime.Year, NextOrderTime.Month, NextOrderTime.Day, int.TryParse(e.Date.Substring(0, 2), out int hour) ? hour : DateTime.Now.Hour, int.TryParse(e.Date.Substring(2, 2), out int minute) ? minute : DateTime.Now.Minute, int.TryParse(e.Date.Substring(4), out int second) ? second : DateTime.Now.Second) : DateTime.Now; if (tv.TradingAddtionalQuantity > 0 && Bid < peek * (1 - tv.AdditionalPosition) && gap > 0 && OrderNumber.ContainsValue(Bid) == false && WaitOrder && (tv.AddtionalInterval == 0 || tv.AddtionalInterval > 0 && interval.CompareTo(NextOrderTime) > 0)) { SendBalance?.Invoke(this, new SendSecuritiesAPI(new Tuple <int, string, int, int, string>((int)OpenOrderType.신규매수, tv.Code, tv.TradingAddtionalQuantity, Bid, string.Empty))); WaitOrder = false; if (tv.AddtionalInterval > 0) { NextOrderTime = MeasureTheDelayTime(tv.AddtionalInterval, interval); } } else if (tv.TradingSubtractionalQuantity > 0 && Offer > peek * (1 + tv.SubtractionalPosition) && Offer > Purchase && gap < 0 && OrderNumber.ContainsValue(Offer) == false && WaitOrder && (tv.SubtractionalInterval == 0 || tv.SubtractionalInterval > 0 && interval.CompareTo(NextOrderTime) > 0)) { SendBalance?.Invoke(this, new SendSecuritiesAPI(new Tuple <int, string, int, int, string>((int)OpenOrderType.신규매도, tv.Code, tv.TradingSubtractionalQuantity, Offer, string.Empty))); WaitOrder = false; if (tv.SubtractionalInterval > 0) { NextOrderTime = MeasureTheDelayTime(tv.SubtractionalInterval, interval); } } break; case TrendsInStockPrices ts: if (ts.Setting.Equals(Interface.Setting.Short) == false && Bid < peek * (1 - ts.AdditionalPurchase) && gap > 0 && OrderNumber.ContainsValue(Bid) == false && WaitOrder) { SendBalance?.Invoke(this, new SendSecuritiesAPI(new Tuple <int, string, int, int, string>((int)OpenOrderType.신규매수, ts.Code, ts.Quantity, Bid, string.Empty))); WaitOrder = false; } else if (ts.Setting.Equals(Interface.Setting.Long) == false && Offer > peek * (1 + ts.RealizeProfit) && Offer > Purchase && gap < 0 && OrderNumber.ContainsValue(Offer) == false && WaitOrder) { SendBalance?.Invoke(this, new SendSecuritiesAPI(new Tuple <int, string, int, int, string>((int)OpenOrderType.신규매도, ts.Code, ts.Quantity, Offer, string.Empty))); WaitOrder = false; } break; case TrendToCashflow tc: if (tc.TradingQuantity > 0 && Bid < peek * (1 - tc.PositionAddition) && gap > 0 && OrderNumber.ContainsValue(Bid) == false && WaitOrder) { SendBalance?.Invoke(this, new SendSecuritiesAPI(new Tuple <int, string, int, int, string>((int)OpenOrderType.신규매수, tc.Code, tc.TradingQuantity, Bid, string.Empty))); WaitOrder = false; } else if (tc.TradingQuantity > 0 && Offer > peek * (1 + tc.PositionRevenue) && Offer > Purchase && gap < 0 && OrderNumber.ContainsValue(Offer) == false && WaitOrder) { SendBalance?.Invoke(this, new SendSecuritiesAPI(new Tuple <int, string, int, int, string>((int)OpenOrderType.신규매도, tc.Code, tc.TradingQuantity, Offer, string.Empty))); WaitOrder = false; } break; } Base = peek; Secondary = gap; }
public override void OnReceiveEvent(string time, string price, string volume) { if (int.TryParse(volume, out int vol)) { var consecutive = new SendConsecutive(time, price, vol); Consecutive?.Invoke(this, consecutive); if (Current != consecutive.Price) { Revenue = (long)((consecutive.Price - Purchase) * Quantity); Rate = consecutive.Price / (double)Purchase - 1; Current = consecutive.Price; } } }
internal void OnReceiveTrendsInPrices(SendConsecutive e, double gap, int minute) { switch (strategics) { case TrendFollowingBasicFutures tf: if (minute == 0x5A0) { if (WaitOrder && (e.Date.CompareTo(cme) > 0 || e.Date.CompareTo(eurex) < 0 || e.Date.CompareTo(start) > 0 && e.Date.CompareTo(end) < 0) && (gap > 0 ? tf.QuantityLong - Quantity > 0 : tf.QuantityShort + Quantity > 0) && (gap > 0 ? e.Volume > tf.ReactionLong : e.Volume < -tf.ReactionShort) && (gap > 0 ? e.Volume + Secondary > e.Volume : e.Volume + Secondary < e.Volume) && OrderNumber.Count == 0) { SendBalance?.Invoke(this, new SendSecuritiesAPI(new Catalog.XingAPI.Order { FnoIsuNo = Code, BnsTpCode = gap > 0 ? "2" : "1", FnoOrdprcPtnCode = e.Date.CompareTo(start) > 0 && e.Date.CompareTo(end) < 0 ? ((int)Catalog.XingAPI.FnoOrdprcPtnCode.지정가).ToString("D2") : ((int)Catalog.XingAPI.ErxPrcCndiTpCode.지정가).ToString("D1"), OrdPrc = (gap > 0 ? Offer : Bid).ToString("F2"), OrdQty = "1" })); WaitOrder = false; } Base = gap; } else { if (WaitOrder && (e.Date.CompareTo(cme) > 0 || e.Date.CompareTo(eurex) < 0 || e.Date.CompareTo(start) > 0 && e.Date.CompareTo(end) < 0) && (tf.QuantityShort + Quantity < 0 && Base < 0 || Base > 0 && Quantity - tf.QuantityLong > 0) && Revenue / Math.Abs(Quantity) > 0x927C) { SendBalance?.Invoke(this, new SendSecuritiesAPI(new Catalog.XingAPI.Order { FnoIsuNo = Code, BnsTpCode = Quantity > 0 ? "1" : "2", FnoOrdprcPtnCode = e.Date.CompareTo(start) > 0 && e.Date.CompareTo(end) < 0 ? ((int)Catalog.XingAPI.FnoOrdprcPtnCode.시장가).ToString("D2") : ((int)Catalog.XingAPI.ErxPrcCndiTpCode.시장가).ToString("D1"), OrdPrc = (Quantity > 0 ? Bid : Offer).ToString("F2"), OrdQty = "1" })); WaitOrder = false; } Secondary = gap; } break; } }
public override void OnReceiveEvent(string[] param) { if (int.TryParse(string.Concat(param[8], param[9]), out int volume)) { SendConsecutive?.Invoke(this, new SendConsecutive(new Charts { Date = param[0], Price = param[4], Volume = volume })); } if (double.TryParse(param[4], out double current)) { Current = current; Revenue = (long)((current - Purchase) * Quantity * transactionMutiplier); Rate = (Quantity > 0 ? current / (double)Purchase : Purchase / (double)current) - 1; } SendStocks?.Invoke(this, new SendHoldingStocks(Code, Quantity, Purchase, Current, Revenue, Rate, Base, Secondary, AdjustTheColorAccordingToTheCurrentSituation(WaitOrder, OrderNumber.Count))); }
public override void OnReceiveEvent(string[] param) { if (int.TryParse(param[6], out int volume)) { SendConsecutive?.Invoke(this, new SendConsecutive(new Charts { Date = param[0], Price = param[1].StartsWith("-") ? param[1].Substring(1) : param[1], Volume = volume })); } if (int.TryParse(param[1].StartsWith("-") ? param[1].Substring(1) : param[1], out int current)) { Current = current; Revenue = (current - Purchase) * Quantity; Rate = current / (double)Purchase - 1; } SendStocks?.Invoke(this, new SendHoldingStocks(Code, Quantity, Purchase, Current, Revenue, Rate, Base, Secondary, AdjustTheColorAccordingToTheCurrentSituation(WaitOrder, OrderNumber.Count))); }
public override void OnReceiveDrawChart(object sender, SendConsecutive e) { if (GetCheckOnDate(e.Date)) { Short.Pop(); Long.Pop(); Trend.Pop(); } Trend.Push(Trend.Count > 0 ? EMA.Make(Line.Item3, Trend.Count, e.Price, Trend.Peek()) : EMA.Make(e.Price)); Short.Push(Short.Count > 0 ? EMA.Make(Line.Item1, Short.Count, e.Price, Short.Peek()) : EMA.Make(e.Price)); Long.Push(Long.Count > 0 ? EMA.Make(Line.Item2, Long.Count, e.Price, Long.Peek()) : EMA.Make(e.Price)); if (e.Volume != 0 && e.Date.Length > 8 && Short.Count > 1 && Long.Count > 1) { double popShort = Short.Pop(), popLong = Long.Pop(), gap = popShort - popLong - (Short.Peek() - Long.Peek()); Short.Push(popShort); Long.Push(popLong); var date = e.Date.Substring(6, 4); if (date.CompareTo(Base.Start) > 0 && date.CompareTo(Base.Transmit) < 0 && Strategics is Catalog.TrendsToCashflow tc && DateTime.TryParseExact(e.Date.Substring(0, 12), Base.FullDateFormat, CultureInfo.CurrentCulture, DateTimeStyles.None, out DateTime cInterval)) { if (Balance.Quantity > tc.ReservationQuantity - 1 && (Offer ?? int.MaxValue) < e.Price && OrderNumber.Any(o => o.Key[0] == '8' && o.Value == e.Price - GetQuoteUnit(e.Price, Market))) { CumulativeFee += (uint)(e.Price * tc.ReservationQuantity * (Commission + Base.Tax)); Balance.Revenue += (long)((e.Price - (Balance.Purchase ?? 0D)) * tc.ReservationQuantity); Balance.Quantity -= tc.ReservationQuantity; var profit = OrderNumber.First(o => o.Key.StartsWith("8") && o.Value == e.Price - GetQuoteUnit(e.Price, Market)); if (OrderNumber.Remove(profit.Key)) { Capital -= profit.Value * tc.ReservationQuantity; Offer = profit.Value; } } else if ((Bid ?? int.MinValue) > e.Price && OrderNumber.Any(o => o.Key[0] == '7' && o.Value == e.Price + GetQuoteUnit(e.Price, Market))) { CumulativeFee += (uint)(e.Price * Commission * tc.ReservationQuantity); Balance.Purchase = (double)((e.Price * tc.ReservationQuantity + (Balance.Purchase ?? 0D) * Balance.Quantity) / (Balance.Quantity + tc.ReservationQuantity)); Balance.Quantity += tc.ReservationQuantity; var profit = OrderNumber.First(o => o.Key.StartsWith("7") && o.Value == e.Price + GetQuoteUnit(e.Price, Market)); if (OrderNumber.Remove(profit.Key)) { Capital += profit.Value * tc.ReservationQuantity; Bid = profit.Value; } } else if (Balance.Quantity > tc.TradingQuantity - 1 && OrderNumber.Any(o => o.Key[0] == '2' && o.Value == e.Price - GetQuoteUnit(e.Price, Market))) { CumulativeFee += (uint)(e.Price * tc.TradingQuantity * (Commission + Base.Tax)); Balance.Revenue += (long)((e.Price - (Balance.Purchase ?? 0D)) * tc.TradingQuantity); Balance.Quantity -= tc.TradingQuantity; var profit = OrderNumber.First(o => o.Key.StartsWith("2") && o.Value == e.Price - GetQuoteUnit(e.Price, Market)); if (OrderNumber.Remove(profit.Key)) { Capital -= profit.Value * tc.TradingQuantity; } } else if (OrderNumber.Any(o => o.Key.StartsWith("1") && o.Value == e.Price + GetQuoteUnit(e.Price, Market))) { CumulativeFee += (uint)(e.Price * Commission * tc.TradingQuantity); Balance.Purchase = (double)((e.Price * tc.TradingQuantity + (Balance.Purchase ?? 0D) * Balance.Quantity) / (Balance.Quantity + tc.TradingQuantity)); Balance.Quantity += tc.TradingQuantity; var profit = OrderNumber.First(o => o.Key.StartsWith("1") && o.Value == e.Price + GetQuoteUnit(e.Price, Market)); if (OrderNumber.Remove(profit.Key)) { Capital += profit.Value * tc.TradingQuantity; } } else if (Balance.Quantity > tc.TradingQuantity - 1 && OrderNumber.ContainsValue(e.Price) == false && e.Price > Trend.Peek() * (1 + tc.PositionRevenue) && e.Price > (Balance.Purchase ?? 0D) && gap < 0 && (tc.Interval == 0 || tc.Interval > 0 && cInterval.CompareTo(NextOrderTime) > 0)) { var unit = GetQuoteUnit(e.Price, Market); if (OrderNumber.ContainsValue(e.Price + unit) == false) { OrderNumber[Base.GetOrderNumber((int)OrderType.신규매도)] = e.Price + unit; } if (tc.Interval > 0) { NextOrderTime = Base.MeasureTheDelayTime(tc.Interval, cInterval); } } else if (tc.TradingQuantity > 0 && OrderNumber.ContainsValue(e.Price) == false && e.Price < Trend.Peek() * (1 - tc.PositionAddition) && gap > 0 && (tc.Interval == 0 || tc.Interval > 0 && cInterval.CompareTo(NextOrderTime) > 0)) { var unit = GetQuoteUnit(e.Price, Market); if (OrderNumber.ContainsValue(e.Price - unit) == false) { OrderNumber[Base.GetOrderNumber((int)OrderType.신규매수)] = e.Price - unit; } if (tc.Interval > 0) { NextOrderTime = Base.MeasureTheDelayTime(tc.Interval, cInterval); } } } else if (date.CompareTo(Base.Transmit) > 0 && Strategics is Catalog.TrendsToCashflow cf) { OrderNumber.Clear(); long revenue = Balance.Revenue - CumulativeFee, unrealize = (long)((e.Price - (Balance.Purchase ?? 0D)) * Balance.Quantity); var avg = EMA.Make(++Accumulative, revenue - TodayRevenue + unrealize - TodayUnrealize, Before); if (cf.ReservationQuantity > 0 && Balance.Quantity > cf.ReservationQuantity - 1) { var stock = Market; int quantity = Balance.Quantity / cf.ReservationQuantity, price = e.Price, sell = (int)((Balance.Purchase ?? 0D) * (1 + cf.ReservationRevenue)), buy = (int)((Balance.Purchase ?? 0D) * (1 - cf.Addition)), upper = (int)(price * 1.3), lower = (int)(price * 0.7), bPrice = Base.GetStartingPrice(lower, stock), sPrice = Base.GetStartingPrice(sell, stock); sPrice = sPrice < lower ? lower + GetQuoteUnit(sPrice, stock) : sPrice; while (sPrice < upper && quantity-- > 0) { OrderNumber[Base.GetOrderNumber((int)OrderType.예약매도)] = sPrice; for (int i = 0; i < cf.Unit; i++) { sPrice += GetQuoteUnit(sPrice, stock); } } while (bPrice < upper && bPrice < buy) { OrderNumber[Base.GetOrderNumber((int)OrderType.예약매수)] = bPrice; for (int i = 0; i < cf.Unit; i++) { bPrice += GetQuoteUnit(bPrice, stock); } } Bid = OrderNumber.Count > 0 && OrderNumber.Any(o => o.Key.StartsWith("7")) ? OrderNumber.Where(o => o.Key.StartsWith("7")).Max(o => o.Value) : 0; Offer = OrderNumber.Count > 0 && OrderNumber.Any(o => o.Key.StartsWith("8")) ? OrderNumber.Where(o => o.Key.StartsWith("8")).Min(o => o.Value) : 0; } SendMessage = new Catalog.Strategics.Statistics { Key = string.Concat("TC.", cf.AnalysisType), Date = e.Date.Substring(0, 6), Cumulative = revenue + unrealize, Base = SendMessage.Base > Capital ? SendMessage.Base : Capital, Statistic = (int)avg, Price = (int)Trend.Peek() }; Before = avg; TodayRevenue = revenue; TodayUnrealize = unrealize; } }
void OnReceiveDrawChart(object sender, SendConsecutive e) { int tShort, tLong, tMinute, trend; switch (strategics) { case TrendsInValuation _: tShort = tv.Short; tLong = tv.Long; trend = tv.Trend; if (GetCheckOnDate(e.Date, 0x5A0)) { Short.Pop(); Long.Pop(); Trend.Pop(); } Trend.Push(Trend.Count > 0 ? EMA.Make(trend, Trend.Count, e.Price, Trend.Peek()) : EMA.Make(e.Price)); tMinute = tv.AddtionalInterval; break; case TrendToCashflow _: tShort = tc.Short; tLong = tc.Long; trend = tc.Trend; if (GetCheckOnDate(e.Date, 0x5A0)) { Short.Pop(); Long.Pop(); Trend.Pop(); } Trend.Push(Trend.Count > 0 ? EMA.Make(trend, Trend.Count, e.Price, Trend.Peek()) : EMA.Make(e.Price)); tMinute = tc.Interval; break; case TrendsInStockPrices _: tShort = ts.Short; tLong = ts.Long; trend = ts.Trend; switch (ts) { case TrendsInStockPrices sp when sp.LongShort.Equals(LongShort.Minute) && sp.TrendType.Equals(Interface.Trend.Minute) || sp.LongShort.Equals(LongShort.Day) && sp.TrendType.Equals(Interface.Trend.Day): if (GetCheckOnDate(e.Date, sp.LongShort.Equals(LongShort.Minute) && sp.TrendType.Equals(Interface.Trend.Minute) ? 1 : 0x5A0)) { Short.Pop(); Long.Pop(); Trend.Pop(); } break; case TrendsInStockPrices sp when sp.LongShort.Equals(LongShort.Day) && sp.TrendType.Equals(Interface.Trend.Minute): if (GetCheckOnDate(e.Date, 1)) Trend.Pop(); if (GetCheckOnDate(e.Date, 0x5A0)) { Short.Pop(); Long.Pop(); } break; case TrendsInStockPrices sp when sp.LongShort.Equals(LongShort.Minute) && sp.TrendType.Equals(Interface.Trend.Day): if (GetCheckOnDate(e.Date, 0x5A0)) Trend.Pop(); if (GetCheckOnDate(e.Date, 1)) { Short.Pop(); Long.Pop(); } break; } Trend.Push(Trend.Count > 0 ? EMA.Make(trend, Trend.Count, e.Price, Trend.Peek()) : EMA.Make(e.Price)); tMinute = (int)ts.TrendType; break; case TrendFollowingBasicFutures _: if (GetCheckOnDate(e.Date, tf.Minute)) { Short.Pop(); Long.Pop(); } tShort = tf.Short; tLong = tf.Long; tMinute = tf.Minute; break; case ScenarioAccordingToTrend _: tShort = st.Short; tLong = st.Long; trend = st.Trend; if (e.Date.Length > 6 && double.IsNaN(Compare) && Trend.Count > 0 && string.IsNullOrEmpty(st.Calendar) == false && (e.Date.Length == 8 ? e.Date.Substring(2) : e.Date.Substring(0, 6)).CompareTo(st.Calendar) >= 0) { Compare = Trend.Pop(); if (int.TryParse(e.Date.Length == 8 ? e.Date.Substring(2, 4) : e.Date.Substring(0, 4), out int closest)) { var baseDate = int.MaxValue; var temp = string.Empty; var list = new List <ConvertConsensus>(ho.Consensus.Item1); list.AddRange(ho.Consensus.Item2); foreach (var parse in list.OrderByDescending(o => o.Date)) { if (int.TryParse(parse.Date.Substring(0, 5).Replace(".", string.Empty), out int date) && Math.Abs(date - closest) < baseDate) { baseDate = Math.Abs(date - closest); temp = parse.Date; } } var estimate = new Security(temp, list, st).EstimateThePrice(e.Date, Compare); if (estimate.Count > 3) { ho.EstimatedPrice = estimate; } else { return; } } Trend.Clear(); } if (GetCheckOnDate(e.Date, 0x5A0)) { Short.Pop(); Long.Pop(); if (double.IsNaN(Compare) && Trend.Count > 0) { Trend.Pop(); } } if (double.IsNaN(Compare)) { Trend.Push(Trend.Count > 0 ? EMA.Make(trend, Trend.Count, e.Price, Trend.Peek()) : EMA.Make(e.Price)); } tMinute = st.IntervalInSeconds; break; default: return; } Short.Push(Short.Count > 0 ? EMA.Make(tShort, Short.Count, e.Price, Short.Peek()) : EMA.Make(e.Price)); Long.Push(Long.Count > 0 ? EMA.Make(tLong, Long.Count, e.Price, Long.Peek()) : EMA.Make(e.Price)); if (e.Volume != 0 && e.Date.Length != 8 && Short.Count > 1 && Long.Count > 1) { double popShort = Short.Pop(), popLong = Long.Pop(), gap = popShort - popLong - (Short.Peek() - Long.Peek()); Short.Push(popShort); Long.Push(popLong); switch (sender) { case OpenAPI.HoldingStocks os: os.OnReceiveTrendsInPrices(e, gap, Trend.Peek()); break; case XingAPI.HoldingStocks xs: xs.OnReceiveTrendsInPrices(e, gap, tMinute); break; case HoldingStocks hs: hs.OnReceiveTrendsInPrices(e, gap, popShort, popLong, hs.Code.Length == 6 ? (Trend.Count > 0 ? Trend.Peek() : CalculateTheEstimatedPrice(e.Date)) : tMinute); break; } } }
internal void OnReceiveTrendsInPrices(SendConsecutive e, double gap, double peek) { DateTime interval; switch (strategics) { case SatisfyConditionsAccordingToTrends sc: interval = e.Date.Length == 6 ? new DateTime(NextOrderTime.Year, NextOrderTime.Month, NextOrderTime.Day, int.TryParse(e.Date.Substring(0, 2), out int cHour) ? cHour : DateTime.Now.Hour, int.TryParse(e.Date.Substring(2, 2), out int cMinute) ? cMinute : DateTime.Now.Minute, int.TryParse(e.Date.Substring(4), out int cSecond) ? cSecond : DateTime.Now.Second) : DateTime.Now; if (sc.TradingBuyQuantity > 0 && Bid < peek * (1 - sc.TradingBuyRate) && gap > 0 && OrderNumber.ContainsValue(Bid) == false && WaitOrder && (sc.TradingBuyInterval == 0 || sc.TradingBuyInterval > 0 && interval.CompareTo(NextOrderTime) > 0)) { SendBalance?.Invoke(this, new SendSecuritiesAPI(new Tuple <int, string, int, int, string>((int)OpenOrderType.신규매수, sc.Code, sc.TradingBuyQuantity, Bid, string.Empty))); WaitOrder = false; if (sc.TradingBuyInterval > 0) { NextOrderTime = MeasureTheDelayTime(sc.TradingBuyInterval * (Purchase > 0 && Bid > 0 ? Purchase / (double)Bid : 1), interval); } } else if (Quantity > 0) { if (sc.TradingSellQuantity > 0 && Offer > peek * (1 + sc.TradingSellRate) && Offer > Purchase + tax * Offer && gap < 0 && OrderNumber.ContainsValue(Offer) == false && WaitOrder && (sc.TradingSellInterval == 0 || sc.TradingSellInterval > 0 && interval.CompareTo(NextOrderTime) > 0)) { SendBalance?.Invoke(this, new SendSecuritiesAPI(new Tuple <int, string, int, int, string>((int)OpenOrderType.신규매도, sc.Code, sc.TradingSellQuantity, Offer, string.Empty))); WaitOrder = false; if (sc.TradingSellInterval > 0) { NextOrderTime = MeasureTheDelayTime(sc.TradingSellInterval * (Purchase > 0 && Offer > 0 ? Offer / (double)Purchase : 1), interval); } } else if (SellPrice > 0 && sc.ReservationSellQuantity > 0 && Offer > SellPrice && OrderNumber.ContainsValue(Offer) == false && WaitOrder) { for (int i = 0; i < sc.ReservationSellUnit; i++) { SellPrice += GetQuoteUnit(SellPrice, Market); } SendBalance?.Invoke(this, new SendSecuritiesAPI(new Tuple <int, string, int, int, string>((int)OpenOrderType.신규매도, sc.Code, sc.ReservationSellQuantity, Offer, string.Empty))); WaitOrder = false; } else if (BuyPrice > 0 && sc.ReservationBuyQuantity > 0 && Bid < BuyPrice && OrderNumber.ContainsValue(Bid) == false && WaitOrder) { for (int i = 0; i < sc.ReservationBuyUnit; i++) { BuyPrice -= GetQuoteUnit(BuyPrice, Market); } SendBalance?.Invoke(this, new SendSecuritiesAPI(new Tuple <int, string, int, int, string>((int)OpenOrderType.신규매수, sc.Code, sc.ReservationBuyQuantity, Bid, string.Empty))); WaitOrder = false; } else if (SellPrice == 0 && Purchase > 0) { SellPrice = GetStartingPrice((int)((1 + sc.ReservationSellRate) * Purchase), Market); } else if (BuyPrice == 0 && Purchase > 0) { BuyPrice = GetStartingPrice((int)(Purchase * (1 - sc.ReservationBuyRate)), Market); } } break; case TrendsInValuation tv: interval = e.Date.Length == 6 ? new DateTime(NextOrderTime.Year, NextOrderTime.Month, NextOrderTime.Day, int.TryParse(e.Date.Substring(0, 2), out int hour) ? hour : DateTime.Now.Hour, int.TryParse(e.Date.Substring(2, 2), out int minute) ? minute : DateTime.Now.Minute, int.TryParse(e.Date.Substring(4), out int second) ? second : DateTime.Now.Second) : DateTime.Now; if (tv.TradingAddtionalQuantity > 0 && Bid < peek * (1 - tv.AdditionalPosition) && gap > 0 && OrderNumber.ContainsValue(Bid) == false && WaitOrder && (tv.AddtionalInterval == 0 || tv.AddtionalInterval > 0 && interval.CompareTo(NextOrderTime) > 0)) { SendBalance?.Invoke(this, new SendSecuritiesAPI(new Tuple <int, string, int, int, string>((int)OpenOrderType.신규매수, tv.Code, tv.TradingAddtionalQuantity, Bid, string.Empty))); WaitOrder = false; if (tv.AddtionalInterval > 0) { NextOrderTime = MeasureTheDelayTime(tv.AddtionalInterval, interval); } } else if (tv.TradingSubtractionalQuantity > 0 && Offer > peek * (1 + tv.SubtractionalPosition) && Offer > Purchase && gap < 0 && OrderNumber.ContainsValue(Offer) == false && WaitOrder && (tv.SubtractionalInterval == 0 || tv.SubtractionalInterval > 0 && interval.CompareTo(NextOrderTime) > 0)) { SendBalance?.Invoke(this, new SendSecuritiesAPI(new Tuple <int, string, int, int, string>((int)OpenOrderType.신규매도, tv.Code, tv.TradingSubtractionalQuantity, Offer, string.Empty))); WaitOrder = false; if (tv.SubtractionalInterval > 0) { NextOrderTime = MeasureTheDelayTime(tv.SubtractionalInterval, interval); } } break; case TrendsInStockPrices ts: if (ts.Setting.Equals(Interface.Setting.Short) == false && Bid < peek * (1 - ts.AdditionalPurchase) && gap > 0 && OrderNumber.ContainsValue(Bid) == false && WaitOrder) { SendBalance?.Invoke(this, new SendSecuritiesAPI(new Tuple <int, string, int, int, string>((int)OpenOrderType.신규매수, ts.Code, ts.Quantity, Bid, string.Empty))); WaitOrder = false; } else if (ts.Setting.Equals(Interface.Setting.Long) == false && Offer > peek * (1 + ts.RealizeProfit) && Offer > Purchase && gap < 0 && OrderNumber.ContainsValue(Offer) == false && WaitOrder) { SendBalance?.Invoke(this, new SendSecuritiesAPI(new Tuple <int, string, int, int, string>((int)OpenOrderType.신규매도, ts.Code, ts.Quantity, Offer, string.Empty))); WaitOrder = false; } break; case TrendToCashflow tc: if (tc.TradingQuantity > 0 && Bid < peek * (1 - tc.PositionAddition) && gap > 0 && OrderNumber.ContainsValue(Bid) == false && WaitOrder) { SendBalance?.Invoke(this, new SendSecuritiesAPI(new Tuple <int, string, int, int, string>((int)OpenOrderType.신규매수, tc.Code, tc.TradingQuantity, Bid, string.Empty))); WaitOrder = false; } else if (tc.TradingQuantity > 0 && Offer > peek * (1 + tc.PositionRevenue) && Offer > Purchase && gap < 0 && OrderNumber.ContainsValue(Offer) == false && WaitOrder) { SendBalance?.Invoke(this, new SendSecuritiesAPI(new Tuple <int, string, int, int, string>((int)OpenOrderType.신규매도, tc.Code, tc.TradingQuantity, Offer, string.Empty))); WaitOrder = false; } break; case TrendFollowingBasicFutures tf: if (0x5A0 == (int)peek) { if (WaitOrder && e.Date.CompareTo(start) > 0 && e.Date.CompareTo(end) < 0 && (gap > 0 ? tf.QuantityLong - Quantity > 0 : tf.QuantityShort + Quantity > 0) && (gap > 0 ? e.Volume > tf.ReactionLong : e.Volume < -tf.ReactionShort) && (gap > 0 ? e.Volume + Secondary > e.Volume : e.Volume + Secondary < e.Volume) && OrderNumber.Count == 0) { SendBalance?.Invoke(this, new SendSecuritiesAPI(new Tuple <string, int, string, string, int, string, string>(Code, 1, gap > 0 ? "2" : "1", ((int)Catalog.OpenAPI.OrderType.지정가).ToString(), 1, (gap > 0 ? Offer : Bid).ToString("F2"), string.Empty))); WaitOrder = false; } Base = gap; } else { if (WaitOrder && e.Date.CompareTo(start) > 0 && e.Date.CompareTo(end) < 0 && (tf.QuantityShort + Quantity < 0 && Base < 0 || Base > 0 && Quantity - tf.QuantityLong > 0) && Revenue / Math.Abs(Quantity) > 0x927C) { SendBalance?.Invoke(this, new SendSecuritiesAPI(new Tuple <string, int, string, string, int, string, string>(Code, 1, Quantity > 0 ? "1" : "2", ((int)Catalog.OpenAPI.OrderType.시장가).ToString(), 1, string.Empty, string.Empty))); WaitOrder = false; } Secondary = gap; } return; } Base = peek; Secondary = gap; }
protected internal long StartProgress(string code) { if (string.IsNullOrEmpty(code) == false) { var revise = new Temporary(code.Length).CallUpTheRevisedStockPrice(code).Result; var modify = revise != null && revise.Count > 0 ? new Catalog.Request.ConfirmRevisedStockPrice[revise.Count] : null; var index = 0; foreach (var queue in FindTheOldestDueDate(code)) { if (queue != null && queue.Count > 0) { var enumerable = queue.OrderBy(o => o.Date); var before = enumerable.First().Date.Substring(0, 6); while (revise != null && revise.Count > 0) { var param = revise.Dequeue(); if (param.Date.CompareTo(Days.Count > 0 ? Days.Max(o => o.Date).Substring(2) : before) > 0) { if (revise.Count == 0) { modify[index] = param; break; } var peek = revise.Peek(); if (param.Rate != peek.Rate) { modify[index++] = param; } } } if (Days.Count > 0) { foreach (var day in Days.OrderBy(o => o.Date)) { if (string.Compare(day.Date.Substring(2), before) < 0) { SendConsecutive convey; if (modify != null && int.TryParse(day.Price, out int price)) { var rate = 1D; foreach (var param in Array.FindAll(modify, o => string.IsNullOrEmpty(o.Date) == false && o.Date.CompareTo(day.Date.Substring(2)) > 0)) { rate *= param.Rate; } convey = new SendConsecutive(day.Date, GetStartingPrice((int)((1 + rate * 1e-2) * price), Market), day.Volume); } else { convey = new SendConsecutive(day); } Send?.Invoke(this, convey); } } Days.Clear(); } foreach (var consecutive in enumerable) { SendConsecutive convey; if (modify != null && int.TryParse(consecutive.Price, out int price)) { var rate = 1D; foreach (var param in Array.FindAll(modify, o => string.IsNullOrEmpty(o.Date) == false && o.Date.CompareTo(consecutive.Date.Substring(0, 6)) > 0)) { rate *= param.Rate; } convey = new SendConsecutive(consecutive.Date, GetStartingPrice((int)((1 + rate * 1e-2) * price), Market), consecutive.Volume); } else { convey = new SendConsecutive(consecutive); } Send?.Invoke(this, convey); } } } } return(GC.GetTotalMemory(true)); }
public override void OnReceiveDrawChart(object sender, SendConsecutive e) { Send?.Invoke(this, new SendSecuritiesAPI(e.Date)); }
internal void OnReceiveCurrentLocation(object sender, SendConsecutive e) { Stack.Push(e.Price); Date = e.Date[2..];
public abstract void OnReceiveDrawChart(object sender, SendConsecutive e);
public override void OnReceiveDrawChart(object sender, SendConsecutive e) { }
internal void OnReceiveTrendsInPrices(SendConsecutive e, double gap, double sShort, double sLong, double trend) { var date = e.Date.Substring(6, 4); switch (strategics) { case ScenarioAccordingToTrend st: if (e.Date.Length > 8 && date.CompareTo(start) > 0 && date.CompareTo(transmit) < 0 && DateTime.TryParseExact(e.Date.Substring(0, 12), format, CultureInfo.CurrentCulture, DateTimeStyles.None, out DateTime interval)) { if (NextOrderTime == null) { NextOrderTime = interval; } else if (Quantity > st.Quantity - 1 && OrderNumber.Any(o => o.Key.StartsWith("2") && o.Value == e.Price - GetQuoteUnit(e.Price, Market))) { CumulativeFee += (uint)(e.Price * st.Quantity * (Commission + tax)); Revenue += (long)((e.Price - (Purchase ?? 0D)) * st.Quantity); Quantity -= st.Quantity; var profit = OrderNumber.First(o => o.Key.StartsWith("2") && o.Value == e.Price - GetQuoteUnit(e.Price, Market)); if (OrderNumber.Remove(profit.Key) && Verify) { OnReceiveBalance(new string[] { string.Concat(interval.ToShortDateString(), " ", interval.ToLongTimeString()), profit.Key, profit.Value.ToString("N0") }); } Base -= profit.Value * st.Quantity; } else if (OrderNumber.Any(o => o.Key.StartsWith("1") && o.Value == e.Price + GetQuoteUnit(e.Price, Market))) { CumulativeFee += (uint)(e.Price * Commission * st.Quantity); Purchase = (double)((e.Price * st.Quantity + (Purchase ?? 0D) * Quantity) / (Quantity + st.Quantity)); Quantity += st.Quantity; var profit = OrderNumber.First(o => o.Key.StartsWith("1") && o.Value == e.Price + GetQuoteUnit(e.Price, Market)); if (OrderNumber.Remove(profit.Key) && Verify) { OnReceiveBalance(new string[] { string.Concat(interval.ToShortDateString(), " ", interval.ToLongTimeString()), profit.Key, profit.Value.ToString("N0") }); } Base += profit.Value * st.Quantity; } else if (Quantity > st.Quantity - 1 && OrderNumber.ContainsValue(e.Price) == false && e.Price > trend * (1 + st.ErrorRange) && e.Price > (Purchase ?? 0D) && gap < 0 && (st.IntervalInSeconds == 0 || st.IntervalInSeconds > 0 && interval.CompareTo(NextOrderTime) > 0)) { var unit = GetQuoteUnit(e.Price, Market); if (Verify && VerifyAmount > Quantity && DateTime.TryParseExact(e.Date.Substring(0, 12), format, CultureInfo.CurrentCulture, DateTimeStyles.None, out DateTime dt)) { OnReceiveConclusion(new string[] { string.Concat(OpenOrderType.신규매도, " ", dt.ToShortDateString(), " ", dt.ToLongTimeString(), " ", NextOrderTime), Quantity.ToString("N0"), (Purchase ?? 0D).ToString("N2"), (e.Price + unit).ToString("N0"), (Revenue - CumulativeFee).ToString("C0"), OrderNumber.Max(o => o.Key) }); VerifyAmount = Quantity; } if (OrderNumber.ContainsValue(e.Price + unit) == false) { OrderNumber[GetOrderNumber((int)OpenOrderType.신규매도)] = e.Price + unit; } if (st.IntervalInSeconds > 0) { NextOrderTime = MeasureTheDelayTime(st.IntervalInSeconds, interval); } } else if (OrderNumber.ContainsValue(e.Price) == false && e.Price < trend * (1 - st.ErrorRange) && gap > 0 && (st.IntervalInSeconds == 0 || st.IntervalInSeconds > 0 && interval.CompareTo(NextOrderTime) > 0)) { var unit = GetQuoteUnit(e.Price, Market); if (Verify && VerifyAmount < Quantity && DateTime.TryParseExact(e.Date.Substring(0, 12), format, CultureInfo.CurrentCulture, DateTimeStyles.None, out DateTime dt)) { OnReceiveConclusion(new string[] { string.Concat(OpenOrderType.신규매수, " ", dt.ToShortDateString(), " ", dt.ToLongTimeString(), " ", NextOrderTime), Quantity.ToString("N0"), (Purchase ?? 0D).ToString("N2"), (e.Price - unit).ToString("N0"), (Revenue - CumulativeFee).ToString("C0"), OrderNumber.Where(o => o.Key.StartsWith("1")).Max(o => o.Key) }); VerifyAmount = Quantity; } if (OrderNumber.ContainsValue(e.Price - unit) == false) { OrderNumber[GetOrderNumber((int)OpenOrderType.신규매수)] = e.Price - unit; } if (st.IntervalInSeconds > 0) { NextOrderTime = MeasureTheDelayTime(st.IntervalInSeconds, interval); } } } else if (date.CompareTo(transmit) > 0) { OrderNumber.Clear(); Count = 0; long revenue = Revenue - CumulativeFee, unrealize = (long)((e.Price - (Purchase ?? 0D)) * Quantity); var avg = EMA.Make(++Accumulative, revenue - TodayRevenue + unrealize - TodayUnrealize, Before); SendMessage = new Statistics { Date = e.Date.Substring(0, 6), Cumulative = (revenue + unrealize) / st.Quantity, Base = SendMessage.Base > Base / st.Quantity ? SendMessage.Base : Base / st.Quantity, Statistic = (int)(avg / st.Quantity), Price = e.Price }; SendStocks?.Invoke(this, new SendHoldingStocks(e.Date, e.Price, sShort, sLong, trend, revenue + unrealize, (long)(Base > 0 ? Base : 0))); Before = avg; TodayRevenue = revenue; TodayUnrealize = unrealize; } break; case TrendsInStockPrices ts: if (e.Date.Length > 8 && date.CompareTo(start) > 0 && date.CompareTo(transmit) < 0) { if (Quantity > ts.Quantity - 1 && OrderNumber.Any(o => o.Key.StartsWith("2") && o.Value == e.Price - GetQuoteUnit(e.Price, Market))) { CumulativeFee += (uint)(e.Price * ts.Quantity * (Commission + tax)); Revenue += (long)((e.Price - (Purchase ?? 0D)) * ts.Quantity); Quantity -= ts.Quantity; var profit = OrderNumber.First(o => o.Key.StartsWith("2") && o.Value == e.Price - GetQuoteUnit(e.Price, Market)); if (OrderNumber.Remove(profit.Key) && Verify && DateTime.TryParseExact(e.Date.Substring(0, 12), format, CultureInfo.CurrentCulture, DateTimeStyles.None, out DateTime dt)) { OnReceiveBalance(new string[] { string.Concat(dt.ToShortDateString(), " ", dt.ToLongTimeString()), profit.Key, profit.Value.ToString("N0") }); } Base -= profit.Value * ts.Quantity; } else if (OrderNumber.Any(o => o.Key.StartsWith("1") && o.Value == e.Price + GetQuoteUnit(e.Price, Market))) { CumulativeFee += (uint)(e.Price * Commission * ts.Quantity); Purchase = (double)((e.Price * ts.Quantity + (Purchase ?? 0D) * Quantity) / (Quantity + ts.Quantity)); Quantity += ts.Quantity; var profit = OrderNumber.First(o => o.Key.StartsWith("1") && o.Value == e.Price + GetQuoteUnit(e.Price, Market)); if (OrderNumber.Remove(profit.Key) && Verify && DateTime.TryParseExact(e.Date.Substring(0, 12), format, CultureInfo.CurrentCulture, DateTimeStyles.None, out DateTime dt)) { OnReceiveBalance(new string[] { string.Concat(dt.ToShortDateString(), " ", dt.ToLongTimeString()), profit.Key, profit.Value.ToString("N0") }); } Base += profit.Value * ts.Quantity; } else if (Quantity > ts.Quantity - 1 && OrderNumber.ContainsValue(e.Price) == false && e.Price > trend * (1 + ts.RealizeProfit) && e.Price > (Purchase ?? 0D) && gap < 0) { var quote = 0; for (int i = 0; i < ts.QuoteUnit; i++) { quote += GetQuoteUnit(e.Price, Market); } if (Verify && VerifyAmount > Quantity && DateTime.TryParseExact(e.Date.Substring(0, 12), format, CultureInfo.CurrentCulture, DateTimeStyles.None, out DateTime dt)) { OnReceiveConclusion(new string[] { string.Concat(OpenOrderType.신규매도, " ", dt.ToShortDateString(), " ", dt.ToLongTimeString()), Quantity.ToString("N0"), (Purchase ?? 0D).ToString("N2"), (e.Price + quote).ToString("N0"), (Revenue - CumulativeFee).ToString("C0"), OrderNumber.Max(o => o.Key) }); VerifyAmount = Quantity; } if (OrderNumber.ContainsValue(e.Price + quote) == false) { OrderNumber[GetOrderNumber((int)OpenOrderType.신규매도)] = e.Price + quote; } } else if (OrderNumber.ContainsValue(e.Price) == false && e.Price < trend * (1 - ts.AdditionalPurchase) && gap > 0) { var quote = 0; for (int i = 0; i < ts.QuoteUnit; i++) { quote += GetQuoteUnit(e.Price, Market); } if (Verify && VerifyAmount < Quantity && DateTime.TryParseExact(e.Date.Substring(0, 12), format, CultureInfo.CurrentCulture, DateTimeStyles.None, out DateTime dt)) { OnReceiveConclusion(new string[] { string.Concat(OpenOrderType.신규매수, " ", dt.ToShortDateString(), " ", dt.ToLongTimeString()), Quantity.ToString("N0"), (Purchase ?? 0D).ToString("N2"), (e.Price - quote).ToString("N0"), (Revenue - CumulativeFee).ToString("C0"), OrderNumber.Where(o => o.Key.StartsWith("1")).Max(o => o.Key) }); VerifyAmount = Quantity; } if (OrderNumber.ContainsValue(e.Price - quote) == false) { OrderNumber[GetOrderNumber((int)OpenOrderType.신규매수)] = e.Price - quote; } } } else if (date.CompareTo(transmit) > 0) { OrderNumber.Clear(); Count = 0; long revenue = Revenue - CumulativeFee, unrealize = (long)((e.Price - (Purchase ?? 0D)) * Quantity); var avg = EMA.Make(++Accumulative, revenue - TodayRevenue + unrealize - TodayUnrealize, Before); if (ts.Setting.Equals(Setting.Reservation) && Quantity > ts.Quantity - 1) { var stock = Market; int quantity = Quantity / ts.Quantity, price = e.Price, sell = (int)((Purchase ?? 0D) * (1 + ts.RealizeProfit)), buy = (int)((Purchase ?? 0D) * (1 - ts.AdditionalPurchase)), upper = (int)(price * 1.3), lower = (int)(price * 0.7), bPrice = GetStartingPrice(lower, stock), sPrice = GetStartingPrice(sell, stock); sPrice = sPrice < lower ? lower + GetQuoteUnit(sPrice, stock) : sPrice; while (sPrice < upper && quantity-- > 0) { OrderNumber[GetOrderNumber((int)OpenOrderType.신규매도)] = sPrice; for (int i = 0; i < ts.QuoteUnit; i++) { sPrice += GetQuoteUnit(sPrice, stock); } } while (bPrice < upper && bPrice < buy) { OrderNumber[GetOrderNumber((int)OpenOrderType.신규매수)] = bPrice; for (int i = 0; i < ts.QuoteUnit; i++) { bPrice += GetQuoteUnit(bPrice, stock); } } if (Verify && DateTime.TryParseExact(e.Date.Substring(0, 12), format, CultureInfo.CurrentCulture, DateTimeStyles.None, out DateTime dt)) { OnReceiveEvent(new string[] { string.Concat(dt.ToShortDateString(), " ", dt.ToLongTimeString()), OrderNumber.Where(o => o.Key.StartsWith("1")).Max(o => o.Key), OrderNumber.Where(o => o.Key.StartsWith("2")).Max(o => o.Key) }); } } SendMessage = new Statistics { Date = e.Date.Substring(0, 6), Cumulative = (revenue + unrealize) / ts.Quantity, Base = SendMessage.Base > Base / ts.Quantity ? SendMessage.Base : Base / ts.Quantity, Statistic = (int)(avg / ts.Quantity) }; SendStocks?.Invoke(this, new SendHoldingStocks(e.Date, e.Price, sShort, sLong, trend, revenue + unrealize, (long)(Base > 0 ? Base : 0))); Before = avg; TodayRevenue = revenue; TodayUnrealize = unrealize; } break; case TrendFollowingBasicFutures tf: break; } }