Originally Posted By: Nektodron
Алгоритм работать не будет. Я уже вам писал, что нельзя смешивать ручное управление заявками и позиции. Либо то, либо другое.
sec.Positions.LastPositionActive - это использовать нельзя.
Nektodron, вернёмся к нашим баранам. Дело не в sec.Positions.LastPositionActive, встроил предложенный Вами метод определения значения/цены открытой позиции и кол-ва контрактов (пробовал подставлять значения lotsBalance и curQty(вариант ниже)), но всё-равно после открытия позиции, на каждом баре вместо ордера на переворот (или частичное закрытие) в ТСлаб проходит сообщение: 11:15:30.00:Скрипт: RT2. Не могу создать заявку с нулевым количеством!

Прошу попробовать, как это работает:
Code:
using System;
using System.Collections.Generic;
using System.Linq;
using TSLab.Script;
using TSLab.Script.Handlers;
using TSLab.Script.Optimization;
using TSLab.Script.Helpers;
using TSLab.Script.Realtime;

namespace TSLab.Samples
{
	public class Final : IExternalScript
	{
		public OptimProperty Contracts = new OptimProperty(2, 1, 1, 1);
		public OptimProperty OtskokL = new OptimProperty(5, 1, 1, 1);
		public OptimProperty buL = new OptimProperty(2, 1, 1, 1);
		public OptimProperty OtskokS = new OptimProperty(5, 1, 1, 1);
		public OptimProperty buS = new OptimProperty(2, 1, 1, 1);
		
		private double CalcCurrentPrice(ISecurityRt rtSec, out double curQty, out double curPrice)
		{
			curQty = 0;
			curPrice = 0;
			if (rtSec != null)
			{
				var orders = rtSec.Orders.OrderBy(ord => ord.Date);
				foreach (var order in orders)
				{
					if (order.IsExecuted)
					{
						int bs = (order.IsBuy ? 1 : -1);
						double qty = order.Quantity * bs;
						double price = order.Price;
						double newQty = curQty + qty;
						bool isGrowPos = Math.Abs(newQty) > Math.Abs(curQty);
						if (isGrowPos)
						{
							curPrice = newQty == 0 ? 0 : (curQty*curPrice + qty*price)/newQty;
						}
						curQty = newQty;
					}
				}
			}
			curPrice = curQty == 0 ? 0 : curPrice;
			return curPrice;
		}
		
		public virtual void Execute(IContext ctx, ISecurity sec)
		{
			
			// Торговля.
			if (!sec.Positions.IsRealtime) return;
			{
				int i = sec.Bars.Count - 1;
				if (i < 0) return;
				IList<IQueueData> buyQueue=sec.GetBuyQueue(i);//получаем биржевой стакан
				IList<IQueueData> sellQueue = sec.GetSellQueue(i);//получаем биржевой стакан
				ISecurityRt secRt = sec as ISecurityRt;
				if (secRt == null) return;
				
				double curQty; // объявляем переменные
				double curPrice;
				CalcCurrentPrice(secRt, out curQty, out curPrice); // и вызываем метод				
				
				//текущая позиция. если больше нуля-в лонге. меньше нуля-в шорте
				double lotsBalance = 0;
				//пробегаемся по всем исполненным ордерам. необходимо текущее число лотов
				foreach (IOrder order in secRt.Orders)
				//Проверка что мы на этом баре не ставили заявки!!!
				if (order.Date >= sec.Bars[i].Date) return;
				else
				if (order.OrderType == TSLab.DataSource.OrderType.Limit)
				{					
					lotsBalance += order.IsBuy ? (order.Quantity-order.RestQuantity) :
					(-order.Quantity+order.RestQuantity);
					//для примера-если ордер не исполнился-убиваем
					if (!order.IsExecuted) secRt.CancelOrder(order);
				}
					//условие-у нас нулевой баланс лотов
				if (lotsBalance == 0)
				{
					//ставим стоп-лимит на бай
					secRt.NewOrder(TSLab.DataSource.OrderType.Growth, true, buyQueue[0].Price, Contracts, "LE");
					//ставим стоп-лимит на селл
					secRt.NewOrder(TSLab.DataSource.OrderType.Fall, false, sellQueue[0].Price, Contracts, "SE");
				}
				else
				if (lotsBalance < 0)
				{
					//закрываем отрицательный баланс покупкой
					secRt.NewOrder(TSLab.DataSource.OrderType.Growth, true, buyQueue[0].Price+10, -curQty + Contracts, "SXLE");
					{
					
						//если есть промежуточный профит закрываем один контракт
						if (sec.LowPrices[i] <= curPrice - OtskokS)
						secRt.NewOrder(TSLab.DataSource.OrderType.Growth, true, curPrice - buS, 1, "SXTP");
					}
				}
				else
				{
					//закрываем положительный баланс лотов продажей
					secRt.NewOrder(TSLab.DataSource.OrderType.Fall, false, sellQueue[0].Price-10, curQty - Contracts, "LXSE");
					{
						//если есть промежуточный профит закрываем один контракт
						if (sec.HighPrices[i] >= curPrice + OtskokL)
						secRt.NewOrder(TSLab.DataSource.OrderType.Fall, false, curPrice + buL, 1, "LXTP");
					}
				}
			}
		}
	}
}

Какие ещё есть идеи?

P. S. Ещё момент, сначала выставляются новые ордера, потом отменяются старые.