How can I use Profit/Loss table to compare value.

Section for discussions related to indicators, use of indicators, and building of trading stategies using indicators.

Moderator: admin

How can I use Profit/Loss table to compare value.

Postby Saito_N » Wed Nov 15, 2017 3:42 pm

first I try to index with this codes (I never made a table before) ** edit note I think I miss a little thing that because at start the PL not have a value (nil).
Code: Select all
..
local PL={};

function Prepare(onlyName)
..
PL.list = core.host:findTable("trades"):find("AccountID", Account).PL;
..
end

function ExtUpdate(id, source, period)
..
PL.list:update(core.UpdateLast);
..
end


but it's report error "attempt to index a nil value". What can I do to index Profit/loss to the table for compare value like

Code: Select all
if (condition opened "B") and (PL[period] < PL[period-2]) then
   Exit("B")
elseif (condition opened "S") and PL[period] < PL[period-2] then
   Exit("S")
end

Help me please.

Best regard.
User avatar
Saito_N
 
Posts: 9
Joined: Tue Mar 21, 2017 3:13 pm

Re: How can I use Profit/Loss table to compare value.

Postby Apprentice » Sun Nov 19, 2017 4:27 pm

Can you share a complete code?
User avatar
Apprentice
FXCodeBase: Confirmed User
 
Posts: 17510
Joined: Thu Dec 31, 2009 11:59 am
Location: Zagreb, Croatia

Re: How can I use Profit/Loss table to compare value.

Postby Saito_N » Wed Nov 22, 2017 2:19 pm

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
Image

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

Attachments
DUMMY.lua
Dummy Codes
(8.21 KiB) Downloaded 10 times
User avatar
Saito_N
 
Posts: 9
Joined: Tue Mar 21, 2017 3:13 pm


Return to Discussions

Who is online

Users browsing this forum: No registered users and 3 guests