private void ClosePosition() { Print("Start closing!"); if (LState.PosDirection == 0) { return; } if (LState.PosDirection == 1) { var tresult = CStrategyTrade.ExecuteByMarket(false, (double)LState.PurchasedAmount).Result; if (tresult != null) { LState.PurchasedAmount -= tresult.BaseQty; } } else { var tresult = CStrategyTrade.ExecuteByMarket(true, GetBuyAmount((double)LState.PurchasedAmount).Result).Result; if (tresult != null) { LState.PurchasedAmount += tresult.BaseQty; } } }
private void ClosePosition() { Print("Start closing!"); if (LState.ClosePositionSum <= 0) { return; } if (LParam.IsDirectionLong) { var tresult = CStrategyTrade.ExecuteByMarket(false, LState.ClosePositionSum).Result; if (tresult != null) { LState.PurchasedAmount -= tresult.BaseQty; Print(String.Format("Позиция Long закрылась на шаге {0}. Сума: {1} {2}, цена: {3}.", LState.CurrentStep, tresult.BaseQty, LParam.Market.BaseCurrency, tresult.AveragePrice)); LState.CurrentStep = 0; ClearState(); Stop(); } } else { var tresult = CStrategyTrade.ExecuteByMarket(true, GetBuyAmount(LState.ClosePositionSum).Result).Result; if (tresult != null) { LState.PurchasedAmount += tresult.BaseQty; Print(String.Format("Позиция Short закрылась на шаге {0}. Сума: {1} {2}, цена {3}.", LState.CurrentStep, tresult.BaseQty, LParam.Market.BaseCurrency, tresult.AveragePrice)); LState.CurrentStep = 0; ClearState(); Stop(); } } }
//нужная сума для перехода с шага FromStep на FromStep+1 (FromStep >= 1) private double GetEnterPositionSum(TradeResult tresult, int FromStep) { var CurRest = LParam.IsDirectionLong ? LParam.BalanceRestBuy : LParam.BalanceRestSell; int count = CurRest.Values.Count; double result = 0; if (FromStep > count - 1) //не хватает значений { if (LParam.IsDirectionLong) //for buy { result = Math.Round((double)tresult.MarketQty * LParam.GridFactor, 8); //в MarketCurrency } else { result = Math.Round((double)tresult.BaseQty * LParam.GridFactor, 8); //в BaseCurrency } } else { if (CurRest.IsPercentSize) { result = CStrategyTrade.CalcSumFromPercent(CurRest.Values[FromStep], LParam.IsDirectionLong).Result; } else { result = CurRest.Values[FromStep]; } } return(result); }
private void OnUpdateTicker(Ticker ticker) { lock (LockLTicker) { LastTicker = ticker; } if (LState.PosDirection == 0 && LParam.IsLong && (double)ticker.Ask < LState.EnterLongPrice) //enter Long { var tresult = CStrategyTrade.ExecuteByMarket(true, -1).Result; if (tresult != null) { LState.PosDirection = 1; LState.ClosePositionSum = (double)tresult.BaseQty; double avgPrice = (double)tresult.AveragePrice; LState.ClosePositionPrice = ExTool.IncreasePrice(avgPrice, LParam.CloseDistance); LState.StopPositionPrice = ExTool.DecreasePrice(avgPrice, LParam.StopDistance); Print(String.Format("Выполнено вход в позицию Long на суму: {0} {1} по цене: {2}. ({3} {4})", tresult.BaseQty, LParam.Market.BaseCurrency, avgPrice, tresult.MarketQty, LParam.Market.MarketCurrency)); } } if (LState.PosDirection == 0 && LParam.IsShort && (double)ticker.Bid > LState.EnterLongPrice) //enter Short { var tresult = CStrategyTrade.ExecuteByMarket(false, -1).Result; if (tresult != null) { LState.PosDirection = -1; LState.ClosePositionSum = (double)tresult.BaseQty; double avgPrice = (double)tresult.AveragePrice; LState.ClosePositionPrice = ExTool.DecreasePrice(avgPrice, LParam.CloseDistance); LState.StopPositionPrice = ExTool.IncreasePrice(avgPrice, LParam.StopDistance); Print(String.Format("Выполнено вход в позицию Short на суму: {0} {1} по цене: {2}. ({3} {4})", tresult.BaseQty, LParam.Market.BaseCurrency, avgPrice, tresult.MarketQty, LParam.Market.MarketCurrency)); } } if (LState.PosDirection == 1 && (double)ticker.Bid > LState.ClosePositionPrice) //close Long { var tresult = CStrategyTrade.ExecuteByMarket(false, LState.ClosePositionSum).Result; if (tresult != null) { double avgPrice = (double)tresult.AveragePrice; FirstInit(avgPrice); Print(String.Format("Позиция Long закрылась на суму: {0} {1} по цене: {2}. ({3} {4})", tresult.BaseQty, LParam.Market.BaseCurrency, avgPrice, tresult.MarketQty, LParam.Market.MarketCurrency)); } } if (LState.PosDirection == 1 && (double)ticker.Ask < LState.ClosePositionPrice) //close Short { var tresult = CStrategyTrade.ExecuteByMarket(true, LState.ClosePositionSum).Result; if (tresult != null) { double avgPrice = (double)tresult.AveragePrice; FirstInit(avgPrice); Print(String.Format("Позиция Short закрылась на суму: {0} {1} по цене: {2}. ({3} {4})", tresult.BaseQty, LParam.Market.BaseCurrency, avgPrice, tresult.MarketQty, LParam.Market.MarketCurrency)); } } if (LState.PosDirection != 0 && LState.StopPositionPrice != 0) //check Stop { if (LState.PosDirection == 1) { if ((double)ticker.Ask < LState.ClosePositionPrice) //close Long by stop { var tresult = CStrategyTrade.ExecuteByMarket(false, LState.ClosePositionSum).Result; if (tresult != null) { double avgPrice = (double)tresult.AveragePrice; FirstInit(avgPrice); Print(String.Format("Позиция Long закрылась по стопу на суму: {0} {1} по цене: {2}. ({3} {4})", tresult.BaseQty, LParam.Market.BaseCurrency, avgPrice, tresult.MarketQty, LParam.Market.MarketCurrency)); } } } if (LState.PosDirection == -1) { if ((double)ticker.Bid > LState.ClosePositionPrice) //close Short by stop { var tresult = CStrategyTrade.ExecuteByMarket(true, LState.ClosePositionSum).Result; if (tresult != null) { double avgPrice = (double)tresult.AveragePrice; FirstInit(avgPrice); Print(String.Format("Позиция Short закрылась по стопу на суму: {0} {1} по цене: {2}. ({3} {4})", tresult.BaseQty, LParam.Market.BaseCurrency, avgPrice, tresult.MarketQty, LParam.Market.MarketCurrency)); } } } } }
private void Decide() { double pdiff = 0; int CurCross = 0; try { pdiff = 1 - Math.Min(LState.LastMALong, LState.LastMAShort) / Math.Max(LState.LastMALong, LState.LastMAShort); CurCross = IsCrosses(); } catch (Exception ex) { System.Media.SystemSounds.Beep.Play(); Print(String.Format("Ошибка Decide: {0}", ex.Message), true); return; } if (pdiff >= LParam.DiffPerc) //разница достаточна { if (LParam.OneByCandle == true) { if (CurrentCandleExecute == true) //уже была сделка в текущей свече { if (CurCross != 0 || LState.PrevCross != 0) { Print("Уже была сделка на текущую свечу."); if (CurCross != 0) { LState.PrevCross = CurCross; } } return; } } //Print("Текущая разница: " + Math.Round(pdiff, 3) + " достаточна"); if (CurCross != 0) //пересеч. сейчас { Print("Есть пересечение и разница достаточна - смена позиции.", true); CStrategyTrade.ChangeStrategyState(this, LState, CurCross, true, false, true);//ExposeOrder(CurCross); LState.ExecuteCandleTime = CStrategyPrices.LastCandleTime; SetStopOrders(); } else { if (LState.PrevCross != 0) //было пересеч. раньше { Print("Разница достаточна, смена позиции по прошлому пересечению.", true); CStrategyTrade.ChangeStrategyState(this, LState, LState.PrevCross, true, false, true);//ExposeOrder(PrevCross); LState.ExecuteCandleTime = CStrategyPrices.LastCandleTime; SetStopOrders(); } } LState.PrevCross = 0; //аннулировать пересеч. раньше } else { //Print("Текущая разница: " + Math.Round(pdiff, 3) + " не достаточна"); if (CurCross != 0) { Print("Разница не достаточна, запомнить текущее пересечение", true); LState.PrevCross = CurCross; //запомнить пересечение } } }
private void OnUpdateTicker(Ticker ticker) { if (LParam.MaxStepsNumber <= 0) { return; } lock (LockLTicker) { LastTicker = ticker; } if (ErrorsCount > 10) { Stop(); return; } foreach (var item in LState.LLStrategies) { item.OnUpdateTicker(ticker); } if (LState.CurrentStep == 0) { var tresult = CStrategyTrade.ExecuteByMarket(LParam.IsDirectionLong, -1).Result; if (tresult != null) { LState.CurrentStep = 1; double avgPrice = (double)tresult.AveragePrice; double NRsum = SetUpLLStrategies(avgPrice); if (LParam.IsDirectionLong) { ZeroPointChange(avgPrice, (double)tresult.BaseQty); LState.PurchasedAmount += tresult.BaseQty; LState.EnterPositionPrice = DecreasePrice(avgPrice, LParam.StepRepresentEnter, LState.CurrentStep); LState.EnterPositionSum = GetEnterPositionSum(tresult, LState.CurrentStep); //for buy LState.ClosePositionPrice = IncreasePrice(avgPrice, LParam.StepRepresentClose, LState.CurrentStep); LState.ClosePositionSum = NRsum + (double)tresult.BaseQty;//for sell } else { ZeroPointChange(avgPrice, (double)tresult.BaseQty); LState.PurchasedAmount -= tresult.BaseQty; LState.EnterPositionPrice = IncreasePrice(avgPrice, LParam.StepRepresentEnter, LState.CurrentStep); LState.EnterPositionSum = GetEnterPositionSum(tresult, LState.CurrentStep); //for sell LState.ClosePositionPrice = DecreasePrice(avgPrice, LParam.StepRepresentClose, LState.CurrentStep); //for buy LState.ClosePositionSum = NRsum + (double)tresult.MarketQty; //Math.Round((double)tresult.MarketQty / LState.ClosePositionPrice, 8); } ActiveOrdersInfo(); Print(String.Format("Выполнено вход в позицию {0} на суму: {1} {2} по цене: {3}. ({4} {5})", LParam.IsDirectionLong ? "Long" : "Short", tresult.BaseQty, LParam.Market.BaseCurrency, avgPrice, tresult.MarketQty, LParam.Market.MarketCurrency)); SaveData(false); ErrorsCount = 0; } else { ErrorsCount++; } return; } if (LParam.IsDirectionLong) { if ((double)ticker.Bid > LState.ClosePositionPrice) { var tresult = CStrategyTrade.ExecuteByMarket(false, LState.ClosePositionSum).Result; if (tresult != null) { LState.PurchasedAmount -= tresult.BaseQty; Print(String.Format("Позиция Long закрылась на шаге {0}. Продано: {1} {2}, цена: {3}. ({4} {5})", LState.CurrentStep, tresult.BaseQty, LParam.Market.BaseCurrency, tresult.AveragePrice, tresult.MarketQty, LParam.Market.MarketCurrency)); LState.CurrentStep = 0; ClearState(); ActiveOrdersInfo(); SaveData(false); ErrorsCount = 0; } else { ErrorsCount++; } return; } if (LState.CurrentStep < LParam.MaxStepsNumber && (double)ticker.Ask < LState.EnterPositionPrice) { var tresult = CStrategyTrade.ExecuteByMarket(true, GetBuyAmount(LState.EnterPositionSum, ticker).Result).Result; if (tresult != null) { LState.CurrentStep += 1; double avgPrice = (double)tresult.AveragePrice; double NRsum = SetUpLLStrategies(avgPrice); LState.PurchasedAmount += (decimal)NRsum + tresult.BaseQty; ZeroPointChange(avgPrice, (double)tresult.BaseQty); LState.EnterPositionPrice = DecreasePrice(avgPrice, LParam.StepRepresentEnter, LState.CurrentStep); LState.EnterPositionSum = GetEnterPositionSum(tresult, LState.CurrentStep); //for buy double ZeroPoint = GetZeroPoint(); LState.ClosePositionPrice = IncreasePrice(ZeroPoint, LParam.StepRepresentClose, LState.CurrentStep); LState.ClosePositionSum += NRsum + (double)tresult.BaseQty; //for sell Print(String.Format("Выполнен переход на следующий шаг {0}. Куплено на: {1} {2}, цена: {3}. ({4} {5})", LState.CurrentStep, tresult.MarketQty, LParam.Market.MarketCurrency, avgPrice, tresult.BaseQty, LParam.Market.BaseCurrency)); ActiveOrdersInfo(); SaveData(false); ErrorsCount = 0; } else { ErrorsCount++; } return; } } else { if ((double)ticker.Ask < LState.ClosePositionPrice) { var tresult = CStrategyTrade.ExecuteByMarket(true, GetBuyAmount(LState.ClosePositionSum, ticker).Result).Result; if (tresult != null) { LState.PurchasedAmount += tresult.BaseQty; Print(String.Format("Позиция Short закрылась на шаге {0}. Куплено на: {1} {2}, цена {3}. ({4} {5})", LState.CurrentStep, tresult.MarketQty, LParam.Market.MarketCurrency, tresult.AveragePrice, tresult.BaseQty, LParam.Market.BaseCurrency)); LState.CurrentStep = 0; ClearState(); ActiveOrdersInfo(); SaveData(false); ErrorsCount = 0; } else { ErrorsCount++; } return; } if (LState.CurrentStep < LParam.MaxStepsNumber && (double)ticker.Bid > LState.EnterPositionPrice) { var tresult = CStrategyTrade.ExecuteByMarket(false, LState.EnterPositionSum).Result; if (tresult != null) { LState.CurrentStep += 1; double avgPrice = (double)tresult.AveragePrice; double NRsum = SetUpLLStrategies(avgPrice); LState.PurchasedAmount -= tresult.BaseQty; ZeroPointChange(avgPrice, (double)tresult.BaseQty); LState.EnterPositionPrice = IncreasePrice(avgPrice, LParam.StepRepresentEnter, LState.CurrentStep); LState.EnterPositionSum = GetEnterPositionSum(tresult, LState.CurrentStep);//for sell double ZeroPoint = GetZeroPoint(); LState.ClosePositionPrice = DecreasePrice(ZeroPoint, LParam.StepRepresentClose, LState.CurrentStep); //for buy LState.ClosePositionSum += NRsum + (double)tresult.MarketQty; //Math.Round((double)tresult.MarketQty / LState.ClosePositionPrice, 8); Print(String.Format("Выполнен переход на следующий шаг {0}. Продано: {1} {2}, цена: {3}. ({4} {5})", LState.CurrentStep, tresult.BaseQty, LParam.Market.BaseCurrency, avgPrice, tresult.MarketQty, LParam.Market.MarketCurrency)); ActiveOrdersInfo(); SaveData(false); ErrorsCount = 0; } else { ErrorsCount++; } return; } } }