I'm taking a time to doing research. I just finish the function codes and here you can see.
- Code: Select all
local PL1={};
local countPL=0;
function getPL()
local enum2, row2={};
enum2 = core.host:findTable("trades"):enumerator();
row2 = enum2:next();
if row2 == nil then
PL1[countPL] = 0;
end
while row2 ~= nil do
countPL = countPL+1;
PL1[countPL] = row2.PL;
row2 = enum2:next();
end
return PL1;
end
and how to use as a strategy
Like I said I want to exit when P/L lastest < P/L before. Looking not good but it does what I want.
here Dummy codes strategy operate by moving average.
- Code: Select all
function Init()
strategy:name("DUMMY Strategy");
strategy:description("Show how to exit with PL difference.");
strategy:type(core.Both);
strategy.parameters:addGroup("Trading Parameters");
strategy.parameters:addString("TF", "Time frame", "", "m30");
strategy.parameters:setFlag("TF", core.FLAG_PERIODS);
strategy.parameters:addString("Type", "Price Type", "", "Bid");
strategy.parameters:addStringAlternative("Type", "Bid", "", "Bid");
strategy.parameters:addStringAlternative("Type", "Ask", "", "Ask");
strategy.parameters:addGroup("Moving Average parameters");
strategy.parameters:addString("Method", "MA method", "MVA", "MVA");
strategy.parameters:addStringAlternative("Method", "MVA", "MVA", "MVA");
strategy.parameters:addStringAlternative("Method", "EMA", "EMA", "EMA");
strategy.parameters:addGroup("Fast Parameters");
strategy.parameters:addInteger("Fast", "Fast Averege Period", "", 15);
strategy.parameters:addGroup("Slow Parameters");
strategy.parameters:addInteger("Slow", "Slow Averege Period", "", 46);
strategy.parameters:addGroup("Notification Signal");
strategy.parameters:addBoolean("ShowAlert", "Show Alert", "", true);
CreateTradingParameters();
end
function CreateTradingParameters()
strategy.parameters:addGroup("Trading");
strategy.parameters:addBoolean("AllowTrade", "Allow trade", "If trading is not allowed, the strategy works just as a signal", true);
strategy.parameters:addString("Account", "Account", "", "");
strategy.parameters:setFlag("Account", core.FLAG_ACCOUNT);
strategy.parameters:addString("CustomID", "Custom Identifier", "The identifier that can be used to distinguish strategy instances", "TEST");
strategy.parameters:addInteger("Amount", "Amount to Trade", "Specify the amount to trade in lots", 10, 1, 1000);
strategy.parameters:addBoolean("SetStopAllow", "Set Stop Allow", "Want to set stop?", true);
strategy.parameters:addInteger("Stop", "Stop", "Stop in pip", 25);
end
--Prepare variable for function
--parameters from Function_init.
local Slow, Fast;
local Method;
local TF;
local Type;
--parameters from Function_prepare.
local first;
--Variables for indicators.
local fma, sma;
local src;
--Variables for Trade utility.
local allow;
local Account;
local amount;
local Offer;
local valuemap;
local SetStopAllow, Stop;
local baseSize;
local PL1={};
local countPL=0;
function Prepare(onlyName)
local name;
name = profile:id() .. "(" .. instance.bid:instrument() .. "," .. instance.parameters.Fast .. "," .. instance.parameters.Slow .. ")";
instance:name(name);
-- prepare for trade.
allow = instance.parameters.AllowTrade;
if allow then
Account = instance.parameters.Account;
Offer = core.host:findTable("offers"):find("Instrument", instance.bid:instrument()).OfferID;
baseSize = core.host:execute("getTradingProperty", "baseUnitSize", instance.bid:instrument(), Account);
amount = instance.parameters.Amount;
SetStopAllow=instance.parameters.SetStopAllow;
Stop=instance.parameters.Stop;
end
TF = instance.parameters.TF;
if TF ~= "t1" then
loaded = false;
data = ExtSubscribe(2, nil, TF, instance.parameters.Type == "Bid", "bar");
src = data;
else
loaded = true;
data = ExtSubscribe(1, nil, "t1", instance.parameters.Type == "Bid", "close");
src = data;
end
fma = core.indicators:create(instance.parameters.Method, src, instance.parameters.Fast);
sma = core.indicators:create(instance.parameters.Method, src, instance.parameters.Slow);
first = math.max(fma.DATA:first()+1, sma.DATA:first()+1);
bar = data:isBar();
end
--
function ExtUpdate(id, source, period)
fma:update(core.UpdateLast);
sma:update(core.UpdateLast);
-- PL Exit method.
getPL()
if opened("B") and PL1 ~= nil then
if (PL1[countPL] < PL1[countPL-1]) and PL1[countPL] > 0 then
Alert("exit by PL:" .. PL1[countPL]);
Exit("B");
countPL=0;
end
elseif opened("S") and PL1 ~= nil then
if (PL1[countPL] < PL1[countPL-1]) and PL1[countPL] > 0 then
Alert("exit by PL:" .. PL1[countPL]);
Exit("S");
countPL=0;
end
end
--ENTER
if not(opened("B") or opened("S")) then
if core.crossesOver(fma.DATA, sma.DATA, period) then
Alert("Over... ");
if allow then
Enter("B");
end
elseif core.crossesUnder(fma.DATA, sma.DATA, period) then
Alert("Under... ");
if allow then
Enter("S");
end
end
end
end
--
function Alert(direction)
if instance.parameters.ShowAlert then
local message;
local msgOpened;
if opened() == false then
msgOpened = "false";
elseif opened() == true then
msgOpened = "true";
end
message = direction
terminal:alertMessage(instance.bid:instrument(), instance.bid[NOW], message, instance.bid:date(NOW));
end
if instance.parameters.PlaySound then
terminal:alertSound(instance.parameters.SoundFile, instance.parameters.RecurrentSound);
end
end
function ExtAsyncOperationFinished(cookie, success, message)
if cookie == 1 then
loaded = true;
elseif cookie == 100 then
if not success then
terminal:alertMessage(instance.bid:instrument(), instance.bid[NOW], "open trade failed: " .. msg, instance.bid:date(NOW));
end
elseif cookie == 101 then
if not success then
terminal:alertMessage(instance.bid:instrument(), instance.bid[NOW], "close trade failed: " .. msg, instance.bid:date(NOW));
end
end
end
--============================================================================--
-- TRADING UTILITY FUNCTIONS --
--============================================================================--
local requestId;
function Enter(side)
if allow then
valuemap = core.valuemap();
valuemap.OrderType = "OM";
valuemap.OfferID = Offer;
valuemap.AcctID = Account;
valuemap.Quantity = baseSize * amount;
valuemap.BuySell = side;
valuemap.CustomID = CustomID;
--Set Stop
valuemap.PegTypeStop ="O";
if SetStopAllow then
if side == "B" then
valuemap.PegPriceOffsetPipsStop = -Stop;
else
valuemap.PegPriceOffsetPipsStop = Stop;
end
end
success, msg = terminal:execute(100, valuemap);
if not success then
terminal:alertMessage(instance.bid:instrument(), instance.bid[NOW], "open trade failed: " .. msg, instance.bid:date(NOW));
else
requestId = msg;
end
end
end
function Exit(side)
local row;
if requestId ~= nil then
row = core.host:findTable("trades"):find("OpenOrderReqID", requestId);
if row ~= nil then
valuemap = core.valuemap();
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
success, msg = terminal:execute(101, valuemap);
if not success then
terminal:alertMessage(instance.bid:instrument(), instance.bid[NOW], "close trade failed: " .. msg, instance.bid:date(NOW));
end
end
end
end
function opened(BuySell)
local enum, row;
local found = false;
enum = core.host:findTable("trades"):enumerator();
row = enum:next();
while row ~= nil do
if row.AccountID == Account and row.OfferID == Offer and (row.BS == BuySell or BuySell == nil) then
found = true;
break;
end
row = enum:next();
end
return found;
end
function getPL()
local enum2, row2={};
enum2 = core.host:findTable("trades"):enumerator();
row2 = enum2:next();
if row2 == nil then
PL1[countPL] = 0;
end
while row2 ~= nil do
countPL = countPL+1;
PL1[countPL] = row2.PL;
row2 = enum2:next();
end
return PL1;
end
dofile(core.app_path() .. "\\strategies\\standard\\include\\helper.lua");