Moderator: admin
-- Version Oct 14, 2010
function Init()
strategy:name("FBSR Strategy");
strategy:description("FBSR Strategy");
strategy.parameters:addGroup("RSI Parameters");
strategy.parameters:addInteger("Frame", "RSI Period", "", 8, 2, 1000);
strategy.parameters:addInteger("OVRB", "Overbought level", "", 60, 2, 100);
strategy.parameters:addInteger("OVRS", "Oversold level", "", 40, 2, 100);
strategy.parameters:addInteger("PIN" , "RSI Price Type", "", 4);
strategy.parameters:addIntegerAlternative("PIN" , "Open", "", 1);
strategy.parameters:addIntegerAlternative("PIN", "High", "", 2);
strategy.parameters:addIntegerAlternative("PIN" , "Low", "", 3);
strategy.parameters:addIntegerAlternative("PIN" , "Close", "", 4);
strategy.parameters:addIntegerAlternative("PIN", "Median", "", 5);
strategy.parameters:addIntegerAlternative("PIN" , "Typical", "", 6);
strategy.parameters:addIntegerAlternative("PIN" , "Weighted ", "", 7);
strategy.parameters:addGroup("Strategy Time Frame");
strategy.parameters:addString("TF", "Time Frame", "", "m15");
strategy.parameters:setFlag("TF", core.FLAG_PERIODS);
strategy.parameters:addGroup("Trading Parameters");
strategy.parameters:addBoolean("Test", "Use RSI Confirmation", "", true);
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("Alert Parameters");
strategy.parameters:addBoolean("ShowAlert", "Show Alert", "", true);
strategy.parameters:addBoolean("PlaySound", "Play Sound", "", false);
strategy.parameters:addFile("SoundFile", "Sound File", "", "");
strategy.parameters:setFlag("SoundFile", core.FLAG_SOUND);
strategy.parameters:addBoolean("RecurrentSound", "Recurrent Sound", "", false);
strategy.parameters:addGroup("Email Parameters");
strategy.parameters:addBoolean("SendEmail", "Send email", "", false);
strategy.parameters:addString("Email", "Email address", "", "");
strategy.parameters:setFlag("Email", core.FLAG_EMAIL);
end
local Email;
local ShowAlert;
local SoundFile;
local RecurrentSound;
local AllowTrade;
local Offer;
local CanClose;
local Account;
local Amount;
local SetLimit;
local Limit;
local SetStop;
local Stop;
local barsource = nil;
local name;
local Allow;
local PRICE;
local PIN;
local Frame;
local RSI;
local OVRB;
local OVRS;
local FBSR;
--local EXIT;
local Test;
function Prepare(onlyName)
assert(core.indicators:findIndicator("FBSR") ~= nil, "Please download and install FBSR Indicator!");
Test = instance.parameters.Test;
OVRB = instance.parameters.OVRB;
OVRS = instance.parameters.OVRS;
Frame = instance.parameters.Frame;
PIN = instance.parameters.PIN;
Allow = instance.parameters.Allow;
--EXIT = instance.parameters.EXIT;
local SendEmail = instance.parameters.SendEmail;
if SendEmail then
Email = instance.parameters.Email;
else
Email = nil;
end
assert(not(SendEmail) or (SendEmail and Email ~= ""), "Email address must be specified");
assert(instance.parameters.TF ~= "t1", "The time frame must not be tick");
assert(not(instance.parameters.PlaySound) or (instance.parameters.PlaySound and instance.parameters.SoundFile ~= ""), "Sound file must be chosen");
name = profile:id() .. "(" .. "FBSR(" .. instance.bid:name() .. "." .. instance.parameters.TF .. ", "..instance.parameters.Frame .. ")";
ShowAlert = instance.parameters.ShowAlert;
if instance.parameters.PlaySound then
SoundFile = instance.parameters.SoundFile;
RecurrentSound = instance.parameters.RecurrentSound;
else
SoundFile = nil;
RecurrentSound = false;
end
AllowTrade = instance.parameters.AllowTrade;
if AllowTrade then
Account = instance.parameters.Account;
Amount = instance.parameters.Amount * 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;
name = name .. ", trade) ";
else
name = name .. ", signal) ";
end
instance:name(name);
if onlyName then
return ;
end
barsource = ExtSubscribe(1, nil, instance.parameters.TF, true, "bar");
if PIN == 1 then
PRICE = barsource.open;
elseif PIN==2 then
PRICE = barsource.high;
elseif PIN==3 then
PRICE = barsource.low;
elseif PIN==4 then
PRICE = barsource.close;
elseif PIN==5 then
PRICE = barsource.median;
elseif PIN==6 then
PRICE = barsource.typical;
elseif PIN==7 then
PRICE = barsource.weighted;
end
RSI=core.indicators:create("RSI", PRICE, Frame);
FBSR=core.indicators:create("FBSR", barsource);
end
function ExtUpdate(id, source, period)
if id == 1 and period > 1 then
RSI:update(core.UpdateLast);
if not RSI.DATA:hasData(period) or not RSI.DATA:hasData(period-1) then
return;
end
FBSR:update(core.UpdateLast);
if not FBSR.R:hasData(period) and not FBSR.S:hasData(period) then
return;
end
if not FBSR.R:hasData(period-1) and not FBSR.S:hasData(period-1) then
return;
end
if FBSR.R[period] ~= FBSR.R[period-1] then
return;
end
if FBSR.S[period] ~= FBSR.S[period-1] then
return;
end
if Test then
if core.crossesOver(barsource.close, FBSR.R, period) and RSI.DATA[period] > OVRB then
TRADE ("Long");
elseif core.crossesUnder(barsource.close, FBSR.S, period) and RSI.DATA[period] < OVRS then
TRADE ("Short");
end
if EXIT then
end
else
if core.crossesOver(barsource.close, FBSR.R, period) then
TRADE ("Long");
elseif core.crossesUnder(barsource.close, FBSR.S, period) then
TRADE ("Short");
end
end
end
end
local NOTE;
function TRADE (SIDE)
if SIDE == "Long" then
NOTE ="Enter " .. SIDE .. " Position";
elseif SIDE == "Short" then
NOTE ="Enter " .. SIDE .. " Position";
elseif SIDE == "Close" then
NOTE ="Close All Position";
end
if ShowAlert then
terminal:alertMessage(instance.bid:instrument(), instance.bid[NOW], NOTE, instance.bid:date(NOW));
end
if SoundFile ~= nil then
terminal:alertSound(SoundFile, RecurrentSound);
end
if Email ~= nil then
terminal:alertEmail(Email, NOTE , name .." " .. NOTE)
end
if SIDE == "Long" then
exit("S");
enter("B") ;
elseif SIDE == "Short" then
exit("B");
enter("S");
elseif SIDE == "Close" and EXIT then
exit("B");
exit("S");
end
end
-- enter into the specified direction
function enter(BuySell)
if not(AllowTrade) then
return ;
end
local enum, row, valuemap, success, msg;
-- check whether we have at least one trade on the specified account
-- in the specified direction for the specified instrument
local count = 0;
enum = core.host:findTable("trades"):enumerator();
row = enum:next();
while count == 0 and row ~= nil do
if row.AccountID == Account and
row.OfferID == Offer and
row.BS == BuySell then
count = count + 1;
end
row = enum:next();
end
-- do not enter if position in the
-- specified direction already exists
if count > 0 then
return ;
end
local valuemap, success, msg;
valuemap = core.valuemap();
valuemap.OrderType = "OM";
valuemap.OfferID = Offer;
valuemap.AcctID = Account;
valuemap.Quantity = Amount;
valuemap.BuySell = BuySell;
valuemap.PegTypeStop = "M";
if SetLimit then
-- set limit order
if BuySell == "B" then
valuemap.RateLimit = instance.ask[NOW] + Limit;
else
valuemap.RateLimit = instance.bid[NOW] - Limit;
end
end
if SetStop then
-- set limit order
if BuySell == "B" then
valuemap.RateStop = instance.ask[NOW] - Stop;
else
valuemap.RateStop = instance.bid[NOW] + Stop;
end
if TrailingStop then
valuemap.TrailStepStop = 1;
end
end
success, msg = terminal:execute(100, 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
-- exit from the specified direction
function exit(BuySell)
if not(AllowTrade) then
return ;
end
local enum, row, valuemap, success, msg;
-- check whether we have at least one trade on the specified account
-- in the specified direction for the specified instrument
local count = 0;
enum = core.host:findTable("trades"):enumerator();
row = enum:next();
while count == 0 and row ~= nil do
if row.AccountID == Account and
row.OfferID == Offer and
row.BS == BuySell then
count = count + 1;
end
row = enum:next();
end
if count > 0 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 = Offer;
valuemap.AcctID = Account;
valuemap.NetQtyFlag = "Y";
valuemap.BuySell = BuySell;
success, msg = terminal:execute(101, valuemap);
if not(success) then
terminal:alertMessage(instance.bid:instrument(), instance.bid[instance.bid:size() - 1], "Close order failed" .. msg, instance.bid:date(instance.bid:size() - 1));
end
end
end
dofile(core.app_path() .. "\\strategies\\standard\\include\\helper.lua");
Users browsing this forum: No registered users and 22 guests