отрывок из моего кода.
Sig - сигнал: -1/0/+1 - продавать/закрывать/покупать
Aggression - коэффициент <=1.0 - доля от макс. разрешенной позиции, которой можно оперировать за раз.
cp - текущая позиция, шт.: <0/0/>0 - шорт/пусто/лонг
P - текущая цена (при работе робота по закрытию бара - цена закрытия бара)
Код: Выделить всё
if(Sig!=0)
{
var FI=GetFinInfo();
if(Sig>0) // индикатор пошел в рост
{
double AvailMoney=CurrentMoney; // наличные
int n=(int)(AvailMoney/P); // сколько штук можно купить
n/=FI.Lot; // сколько можно купить лотов
n*=FI.Lot; // сколько штук можно купить с учетом лотов
int ns=(cp<0 ? cp+n : n); // сколько из них пойдет в лонг
int maxAllowed=(int)MaxLongAllowed();
if(ns>maxAllowed) ns=maxAllowed;
if(ns>0)
{ // будет лонг
double rate=(cp>0 ? cp/(cp+ns) : 0.0); // текущий уровень затаривания
rate+=Aggression; if(rate>=0.95) rate=1.0;
ns=(int)(ns*rate/FI.Lot); // лотов с учетом к-та агрессии
if(ns==0) ns=1; // взять как минимум один лот
ns*=FI.Lot;
if(ns>maxAllowed) ns=maxAllowed; // на всякий случай
}
if(ns>0) EnterLong(ns); else // закроет шорт, если был, и купит ns; без шорта добавит ns
if(ns<0) CloseShort(n); else // сокращение шорта сколько можно (денег на полное закрытие не хватает)
if(cp<0) CloseShort(); // ns=0: закрытие шорта, если был (денег хватает)
} else
if(Sig<0) // индикатор начал падать
{
double AvailMoney=CurrentMoney; // наличные
if(cp>0) AvailMoney+=2.0*cp*P; // + актив в лонге, доступный для покрытия шорта
else AvailMoney+=2.0*cp*AverPrice(); // - пассив для покрытия шорта
int n=(int)(AvailMoney/P); // сколько всего можно продать
n/=FI.Lot; // сколько можно продать лотов
n*=FI.Lot; // сколько штук можно продать с учетом лотов
int ns=(cp>0 ? cp-n : -n); // сколько из них пойдет в шорт
int maxAllowed=(int)MaxShortAllowed();
if(ns<-maxAllowed) ns=-maxAllowed;
if(ns<0)
{ // будет шорт
double rate=(cp<0 ? cp/(cp+ns) : 0.0); // текущий уровень затаривания
rate+=Aggression; if(rate>=0.95) rate=1.0;
ns=(int)(ns*rate/FI.Lot); // лотов с учетом к-та агрессии
if(ns==0) ns=-1; // продать как минимум один лот
ns*=FI.Lot;
if(ns<-maxAllowed) ns=-maxAllowed; // на всякий случай
}
if(ns<0) EnterShort(-ns); else // закроет лонг, если был, и продаст ns; без лонга продаст еще ns
if(cp>0) CloseLong(); // закрытие лонга (это всегда доступно)
} // Sig<0
} // Sig!=0
/*
else
{ // Sig==0
if(cp!=0) ClosePosition();
} // Sig==0
*/
Как-то так.