public PosInfo(IPosition pos) { m_isLong = pos.IsLong; m_isShort = pos.IsShort; m_isVirtual = pos.IsVirtual; m_entryBarNum = pos.EntryBarNum; m_shares = pos.Shares; m_entryPrice = pos.AverageEntryPrice; m_entrySignalName = pos.EntrySignalName; m_entryNotes = pos.EntryNotes; m_entryCommission = pos.EntryCommission; m_exitBarNum = pos.ExitBarNum; m_exitPrice = pos.ExitPrice; m_exitCommission = pos.ExitCommission; m_secInfo = new SecInfo(pos.Security.SecurityDescription); try { m_avgPx = pos.GetBalancePrice(pos.Security.Bars.Count - 1); } catch (Exception) { // подавляю все возможные исключения здесь m_avgPx = Double.NaN; } }
private static double PrepareValue(KeyValuePair <DateTime, IPosition> node, int curBar, PositionGridDisplayMode mode) { double res; IPosition pos = node.Value; switch (mode) { //case PositionGridDisplayMode.Iv: // res = "Not implemented"; // break; case PositionGridDisplayMode.Px: res = pos.GetBalancePrice(curBar); break; case PositionGridDisplayMode.Qty: int sign = pos.IsLong ? 1 : -1; res = sign * Math.Abs(pos.Shares); break; //case PositionGridDisplayMode.Symbol: // res = pos.Security.Symbol; // break; default: res = Constants.NaN; break; } return(res); }
public virtual double Execute(IPosition pos, int barNum) { if (pos == null) { return(0); } var curProfit = pos.OpenMFE(barNum); var entryPrice = pos.GetBalancePrice(barNum); curProfit *= 100 / entryPrice * pos.Security.Margin; double stop; if (curProfit > TrailEnable) { var shift = (curProfit - TrailLoss) / 100; stop = entryPrice * (1 + (pos.IsLong ? shift : -shift)); var last = pos.GetStop(barNum - 1); if (last > 0) { stop = pos.IsLong ? Math.Max(stop, last) : Math.Min(stop, last); } } else { var shift = (0 - StopLoss) / 100; stop = entryPrice * (1 + (pos.IsLong ? shift : -shift)); } return(stop); }
public double Execute(IPosition pos, int barNum) { if (pos == null || pos.EntryBarNum > barNum) { return(0); } return(pos.GetBalancePrice(barNum)); }
public static void GetBasePnl(IList <IPosition> positions, int barNum, double f, double futNominal, out CashPnlUsd cashPnlUsd, out CashPnlBtc cashPnlBtc) { double pnlBtc = 0; double pnlUsd = 0; double cashBtc = 0; double cashUsd = 0; int len = positions.Count; for (int j = 0; j < len; j++) { IPosition pos = positions[j]; // Пока что State лучше не трогать //if (pos.PositionState == PositionState.HaveError) { int sign = pos.IsLong ? 1 : -1; double qty = Math.Abs(pos.Shares); double begPx = pos.GetBalancePrice(barNum); // PROD-6085 - PnL(в битках) = (Позиция в лотах) * (номинал 10 долларов) * (1/BegPx - 1/EndPx) // На обычном рынке знак "минус" стоит в честь того, что при покупке инструмента наличные средства уменьшаются, // а прибыль вычисляется пропорционально величине (EndPx - BegPx). // Но с биткойном все наоборот: из НАЧАЛЬНОЙ цены вычисляют конечную (1/BegPx - 1/EndPx) // {Это нужно, чтобы на росте фьючерса получать прибыль} // Поэтому требуется еще одно инвертирование знака. cashBtc += sign * qty * futNominal / begPx; pnlBtc -= sign * qty * futNominal / f; //// TODO: Учет комиссии //cashBtc -= pos.EntryCommission; if (!pos.IsActiveForBar(barNum)) { // Знак "ПЛЮС" стоит в честь того, что при ЗАКРЫТИИ ЛОНГА наличные средства УВЕЛИЧИВАЮТСЯ // Но еще помним про инвертирование на Дерибите cashBtc -= sign * qty * futNominal / pos.ExitPrice; pnlBtc += sign * qty * futNominal / f; //// TODO: Учет комиссии //cashBtc -= pos.ExitCommission; } } } // End for (int j = 0; j < len; j++) // Также насколько понял описание на сайте Дерибит, упрощается конвертация в доллары // https://www.deribit.com/main#/pages/docs/futures (section 4: Example) // При этом для перевода в баксы используется КОНЕЧНЫЙ КУРС EndPx! cashUsd = cashBtc * f; pnlUsd = pnlBtc * f; cashPnlUsd = new CashPnlUsd(cashUsd, pnlUsd); cashPnlBtc = new CashPnlBtc(cashBtc, pnlBtc); }
private static string PrepareTooltip(KeyValuePair <DateTime, IPosition> node, int curBar, PositionGridDisplayMode mode) { string res; IPosition pos = node.Value; switch (mode) { case PositionGridDisplayMode.Iv: res = "-"; // Как у Алексея сделано if (pos.Security.SecurityDescription.IsOption) { res = "na"; } break; case PositionGridDisplayMode.Px: res = pos.GetBalancePrice(curBar).ToString(CultureInfo.InvariantCulture); break; case PositionGridDisplayMode.Dir: res = pos.IsLong ? "Long" : "Short"; break; case PositionGridDisplayMode.Qty: res = pos.Shares.ToString(CultureInfo.InvariantCulture); break; case PositionGridDisplayMode.Symbol: res = pos.Security.Symbol; break; case PositionGridDisplayMode.IsVirtual: res = pos.IsVirtual.ToString(CultureInfo.InvariantCulture); break; default: res = "Mode '" + mode + "' is not implemented."; break; } return(res); }