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");
}
}
}
}
}
}