by Apprentice » Thu Apr 18, 2013 4:45 am
Closes ALL Open Positions, PLUS any pending Entry and Exit Orders
- Code: Select all
-- Strategy profile initialization routine
-- Defines Strategy profile properties and Strategy parameters
-- TODO: Add minimal and maximal value of numeric parameters and default color of the streams
function Init()
strategy:name("Close all at total Equity");
strategy:description("Closes ALL Open Positions, PLUS any pending Entry and Exit Orders, when the Account EQUITY reaches a certain target dollar");
strategy.parameters:addGroup("Price Parameters");
strategy.parameters:addString("TF", "TF", "Time frame ('t1', 'm1', 'm5', etc.)", "t1");
strategy.parameters:setFlag("TF", core.FLAG_PERIODS);
strategy.parameters:addGroup("Parameters");
strategy.parameters:addDouble("EL", "Equity Level", "Total Equity Level", 200000);
strategy.parameters:addGroup("Trading Parameters");
strategy.parameters:addBoolean("AllowTrade", "Allow strategy to trade", "", false);
strategy.parameters:addString("Account", "Account to trade on", "", "");
strategy.parameters:setFlag("Account", core.FLAG_ACCOUNT);
strategy.parameters:addInteger("Amount", "Trade Amount in Lots", "", 1, 1, 100);
strategy.parameters:addBoolean("SetLimit", "Set Limit Orders", "", false);
strategy.parameters:addInteger("Limit", "Limit Order in pips", "", 30, 1, 10000);
strategy.parameters:addBoolean("SetStop", "Set Stop Orders", "", false);
strategy.parameters:addInteger("Stop", "Stop Order in pips", "", 30, 1, 10000);
strategy.parameters:addBoolean("TrailingStop", "Trailing stop order", "", false);
strategy.parameters:addGroup("Notification");
strategy.parameters:addBoolean("ShowAlert", "Show Alert", "", true);
strategy.parameters:addBoolean("PlaySound", "Play Sound", "", true);
strategy.parameters:addBoolean("RecurSound", "Recurrent Sound", "", false);
strategy.parameters:addFile("SoundFile", "Sound File", "", "");
strategy.parameters:setFlag("SoundFile", core.FLAG_SOUND);
strategy.parameters:addBoolean("SendEmail", "Send Email", "", true);
strategy.parameters:addString("Email", "Email", "", "");
strategy.parameters:setFlag("Email", core.FLAG_EMAIL);
end
-- strategy instance initialization routine
-- Processes strategy parameters and creates output streams
-- TODO: Calculate all constants, create instances all necessary indicators and load all required libraries
-- Parameters block
local EL;
local gSource = nil; -- the source stream
local AllowTicks = true;
local PlaySound;
local RecurrentSound;
local SoundFile;
local Email;
local SendEmail;
local AllowTrade;
local Account;
local Amount;
local BaseSize;
local SetLimit;
local Limit;
local SetStop;
local Stop;
local TrailingStop;
local Offer;
local CanClose;
--TODO: Add variable(s) for your indicator(s) if needed
local nexecuting = 0;
-- Routine
function Prepare(nameOnly)
EL = instance.parameters.EL;
local name = profile:id() .. "(" .. instance.bid:instrument() .. ", " .. tostring(EL) .. ")";
instance:name(name);
if nameOnly then
return ;
end
if (not(AllowTicks)) then
assert(instance.parameters.TF ~= "t1", "The strategy cannot be applied on ticks.");
end
ShowAlert = instance.parameters.ShowAlert;
PlaySound = instance.parameters.PlaySound;
if PlaySound then
RecurrentSound = instance.parameters.RecurSound;
SoundFile = instance.parameters.SoundFile;
else
SoundFile = nil;
end
assert(not(PlaySound) or (PlaySound and SoundFile ~= ""), "Sound file must be specified");
SendEmail = instance.parameters.SendEmail;
if SendEmail then
Email = instance.parameters.Email;
else
Email = nil;
end
assert(not(SendEmail) or (SendEmail and Email ~= ""), "E-mail address must be specified");
AllowTrade = instance.parameters.AllowTrade;
if AllowTrade then
Account = instance.parameters.Account;
Amount = instance.parameters.Amount;
BaseSize = core.host:execute("getTradingProperty", "baseUnitSize", instance.bid:instrument(), Account);
Offer = core.host:findTable("offers"):find("Instrument", instance.bid:instrument()).OfferID;
CanClose = core.host:execute("getTradingProperty", "canCreateMarketClose", instance.bid:instrument(), Account);
SetLimit = instance.parameters.SetLimit;
Limit = instance.parameters.Limit * instance.bid:pipSize();
SetStop = instance.parameters.SetStop;
Stop = instance.parameters.Stop * instance.bid:pipSize();
TrailingStop = instance.parameters.TrailingStop;
end
gSource = ExtSubscribe(1, nil, instance.parameters.TF, instance.parameters.Type == "Bid", "bar");
--TODO: Find indicator's profile, intialize parameters, and create indicator's instance (if needed)
end
-- strategy calculation routine
-- TODO: Add your code for decision making
-- TODO: Update the instance of your indicator(s) if needed
function ExtUpdate(id, source, period)
if AllowTrade then
local Equity = core.host:findTable("accounts"):find("AccountID", Account).Equity;
if Equity >= EL then
-- Level Reached Close all Now
if nexecuting > 0 then
return ;
end
closeAllTrades();
removeAllOrders();
end
end
end
function closeAllTrades()
local offerListLong = {};
local offerListShort = {};
local iLong = 0;
local iShort = 0;
local enum, row;
enum = core.host:findTable("trades"):enumerator();
row = enum:next();
while (row ~= nil) do
if row.AccountID == Account then
if CanClose then
-- close trades immediatelly if we can close
local valuemap = core.valuemap();
valuemap.Command = "CreateOrder";
valuemap.OrderType = "CM";
valuemap.OfferID = offer;
valuemap.AcctID = Account;
valuemap.Quantity = row.Lot;
valuemap.TradeID = row.TradeID;
if row.BS == "B" then
valuemap.BuySell = "S";
else
valuemap.BuySell = "B";
end
local success, msg = terminal:execute(100, valuemap);
if not (success) then
terminal:alertMessage(instance.bid:instrument(), instance.bid[NOW], "create order failed:" .. msg, instance.bid:date(NOW));
end
else
if row.BS == "B" then
iLong = iLong +1;
offerListLong[iLong] = row.OfferID;
else
iShort = iShort +1;
offerListShort[iShort] = row.OfferID;
end
end
end
row = enum:next();
end
local i ;
if iLong > 0 then
for i = 1, iLong, 1 do
local valuemap = core.valuemap();
valuemap.Command = "CreateOrder";
valuemap.OrderType = "CM";
valuemap.OfferID = offerListLong[i];
valuemap.AcctID = Account;
valuemap.NetQtyFlag = "Y";
valuemap.BuySell = "S";
local success, msg = terminal:execute(100, valuemap);
if not (success) then
terminal:alertMessage(instance.bid:instrument(), instance.bid[NOW], "net order create order failed:", instance.bid:date(NOW));
end
end
end
if iShort > 0 then
for i = 1, iShort, 1 do
local valuemap = core.valuemap();
valuemap.Command = "CreateOrder";
valuemap.OrderType = "CM";
valuemap.OfferID = offerListShort[i];
valuemap.AcctID = Account;
valuemap.NetQtyFlag = "Y";
valuemap.BuySell = "B";
local success, msg = terminal:execute(100, valuemap);
if not (success) then
terminal:alertMessage(instance.bid:instrument(), instance.bid[NOW], "net order create order failed:" .. msg, instance.bid:date(NOW));
end
end
end
end
function removeAllOrders()
local enum, row;
enum = core.host:findTable("orders"):enumerator();
row = enum:next();
while (row ~= nil) do
if row.FixStatus == "W" then
local valuemap = core.valuemap();
valuemap.Command = "DeleteOrder";
valuemap.OrderID = row.OrderID;
success, msg = terminal:execute(200, valuemap);
if not(success) then
terminal:alertMessage(instance.bid:instrument(), instance.bid[NOW], "Failed delete order " .. msg, instance.bid:date(NOW));
else
nexecuting = nexecuting + 1;
end
end
row = enum:next();
end
end
function ExtAsyncOperationFinished(cookie, success, message, message1, message2)
if cookie == 200 then --Trade Close Or Open Event
nexecuting = nexecuting - 1;
if not(success) then
terminal:alertMessage(instance.bid:instrument(), instance.bid[NOW], "Failed delete order:" .. msg, instance.bid:date(NOW));
end
end
end
dofile(core.app_path() .. "\\strategies\\standard\\include\\helper.lua");