Moderator: admin
strategy.parameters:addBoolean("is_sell", "Is Sell", "", true);
strategy.parameters:addBoolean("is_buy", "Is Buy", "", true);
strategy.parameters:addBoolean("is_sell", "Is Sell", "", true);
strategy.parameters:addBoolean("is_buy", "Is Buy", "", true);
-- More information about this indicator can be found at:
-- http://fxcodebase.com/code/viewtopic.php?f=31&t=65680
--+------------------------------------------------------------------+
--| Copyright © 2018, Gehtsoft USA LLC |
--| http://fxcodebase.com |
--+------------------------------------------------------------------+
--| Developed by : Mario Jemic |
--| mario.jemic@gmail.com |
--+------------------------------------------------------------------+
--| Support our efforts by donating |
--| Paypal: https://goo.gl/9Rj74e |
--| BitCoin : 15VCJTLaz12Amr7adHSBtL9v8XomURo9RF |
--| BitCoin Cash: 1BEtS465S3Su438Kc58h2sqvVvHK9Mijtg |
--| Ethereum : 0x8C110cD61538fb6d7A2B47858F0c0AaBd663068D |
--| LiteCoin : LLU8PSY2vsq7B9kRELLZQcKf5nJQrdeqwD |
--+------------------------------------------------------------------+
local Modules = {};
function Init()
strategy:name("Conjure Strategy");
strategy:description("");
strategy.parameters:addBoolean("is_buy", "Is Buy", "", true);
strategy.parameters:addDouble("step", "Step", "", 50);
strategy.parameters:addDouble("step2", "Step2", "", 50);
strategy.parameters:addBoolean("AllowTrade", "Allow strategy to trade", "", true);
strategy.parameters:setFlag("AllowTrade", core.FLAG_ALLOW_TRADE);
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:addDouble("ProfitLevel", "Profit level for close orders in the account currency", "", 0);
strategy.parameters:addString("ProfitType", "Profit Type of level for close orders", "", "Fixed");
strategy.parameters:addStringAlternative("ProfitType", "Fixed", "", "Fixed");
strategy.parameters:addStringAlternative("ProfitType", "Percentage of balance", "", "Balance");
strategy.parameters:addString("LevelType", "Type of profit level", "", "ABOVE");
strategy.parameters:addStringAlternative("LevelType", "ABOVE", "", "ABOVE");
strategy.parameters:addStringAlternative("LevelType", "BELOW", "", "BELOW");
end
local is_buy;
local step;
local step2;
local AllowTrade;
local Account;
local Amount;
local Offer;
function Prepare(name_only)
for _, module in pairs(Modules) do module:Prepare(nameOnly); end
instance:name(profile:id() .. "(" .. instance.bid:name() .. ")");
if name_only then return ; end
local profitlevel = instance.parameters.ProfitLevel
assert(instance.parameters.ProfitType ~= "Balance" or (profitlevel >= 0 and profitlevel <= 100 ), "Incorrect value of the Profit Level. 0 <= Profit Level <= 100");
is_buy = instance.parameters.is_buy;
step = instance.parameters.step * instance.bid:pipSize();
step2 = instance.parameters.step2 * instance.ask:pipSize();
AllowTrade = instance.parameters.AllowTrade;
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;
ExtSubscribe(1, nil, "t1", not is_buy, "tick");
end
local initial_price;
local initial_price2;
function ExtUpdate(id, source, period)
if initial_price == nil then
initial_price = source:tick(NOW);
end
if is_buy then
if source:tick(NOW) - initial_price >= step then
initial_price = initial_price + step;
MarketOrder("B");
end
if initial_price2 == nil then
initial_price2 = source:tick(NOW);
end
if initial_price2 - source:tick(NOW) >= step2 then
initial_price2 = initial_price2 - step2;
MarketOrder("S");
end
end
local account = core.host:findTable("accounts"):find("AccountID", Account);
local mmr = core.host:execute("getTradingProperty", "MMR", instance.bid:instrument(), Account);
local emr = core.host:execute("getTradingProperty", "EMR", instance.bid:instrument(), Account);
local margin_needed = math.max(emr, mmr) * Amount;
if account.UsedMargin >= account.Balance or account.UsableMargin < margin_needed then
local offer_id = core.host:findTable("offers"):find("Instrument", instance.bid:instrument()).OfferID;
CloseAll(offer_id, Account, "B");
CloseAll(offer_id, Account, "S");
end
ControlProfit(id, source, period);
end
-- -----------------------------------------------------------------------
-- Return count of opened trades for spicific direction
-- (both directions if BuySell parameters is 'nil')
-- -----------------------------------------------------------------------
function haveTrades(BuySell)
local enum, row;
local found = false;
enum = core.host:findTable("trades"):enumerator();
row = enum:next();
while (not found) and (row ~= nil) do
if row.AccountID == Account and
row.Instrument == instance.bid:instrument() and
(row.BS == BuySell or BuySell == nil) then
found = true;
end
row = enum:next();
end
return found
end
-- -----------------------------------------------------------------------
-- Exit from the specified direction
-- -----------------------------------------------------------------------
function exit(BuySell, row)
if not(AllowTrade) then
return ;
end
local valuemap, success, msg;
if haveTrades(BuySell) then
valuemap = core.valuemap();
-- switch the direction since the order must be in oppsite direction
if BuySell == "B" then
BuySell = "S";
else
BuySell = "B";
end
valuemap.OrderType = "CM";
valuemap.OfferID=row.OfferID;
valuemap.AcctID = Account;
valuemap.NetQtyFlag = "N";
valuemap.TradeID=row.TradeID;
valuemap.Quantity=row.Lot;
valuemap.BuySell = BuySell;
success, msg = terminal:execute(101, valuemap);
if not(success) then
terminal:alertMessage(instance.bid:instrument(), instance.bid[instance.bid:size() - 1], "Open order failed" .. msg, instance.bid:date(instance.bid:size() - 1));
end
end
end
function ControlProfit(id, source, period)
if haveTrades() then
local trades = core.host:findTable("trades");
local enum = trades:enumerator();
local PL=0;
while true do
local row = enum:next();
if row == nil then break end
if row.AccountID == Account and row.Instrument==instance.bid:instrument() then
if row.BS == 'B' then
PL=PL+row.GrossPL;
elseif row.BS == 'S' then
PL=PL+row.GrossPL;
end
end
end
local profitLevel = instance.parameters.ProfitLevel;
local currentBalance = core.host:findTable("accounts"):find("AccountID", Account).Balance;
if (instance.parameters.ProfitType == "Balance") then
profitLevel = currentBalance * instance.parameters.ProfitLevel / 100;
end
if (PL >= profitLevel and instance.parameters.LevelType=="ABOVE") or (PL<=profitLevel and instance.parameters.LevelType=="BELOW") then
local enum = trades:enumerator();
while true do
local row = enum:next();
if row == nil then break end
if row.AccountID == Account and row.Instrument==instance.bid:instrument() then
if row.BS == 'B' then
if AllowTrade then
exit('B',row);
exit('S',row);
end
elseif row.BS == 'S' then
if AllowTrade then
exit('B',row);
exit('S',row);
end
end
end
end
end
end
end
function CloseAll(offer_id, account_id, bs)
local valuemap;
valuemap = core.valuemap();
valuemap.Command = "CreateOrder";
valuemap.OrderType = "CM";
valuemap.OfferID = offer_id;
valuemap.BuySell = bs;
valuemap.AcctID = account_id;
valuemap.NetQtyFlag = "y";
local success, msg;
success, msg = terminal:execute(100, valuemap);
assert(success, msg);
end
function MarketOrder(BuySell)
local valuemap = core.valuemap();
valuemap.Command = "CreateOrder";
valuemap.OrderType = "OM";
valuemap.OfferID = Offer;
valuemap.AcctID = Account;
valuemap.Quantity = Amount * BaseSize;
valuemap.BuySell = BuySell;
local success, msg = terminal:execute(200, valuemap);
if not(success) then
terminal:alertMessage(instance.bid:instrument(), instance.bid[NOW], "Open order failed" .. msg, instance.bid:date(NOW));
return false;
end
return true;
end
dofile(core.app_path() .. "\\strategies\\standard\\include\\helper.lua");
Users browsing this forum: No registered users and 86 guests