I am a beginner trying to write a simple piece of code for backtesting between 2 dates, using variables, to check bullish condition on a daily candle (Day0) for every day, if its met I want to check bullish condition on next daily candle (Day1) (storing the closing values for stoploss later on) and if true then use the high of the 3rd daily candle (Day2) as my entry strategy. Exit will be on 30th day from entry or at stoploss. Request help in fixing the code below:
strategy("Bullish scanner", overlay=true)
start = timestamp (2022,1,1,0,0)
end = timestamp (2022,9,30,0,0)
Day0 = dayofweek(start)
If Day0 >= start and Day0 <= end
Bull = (close(day0) > 1.1 * open(Day0))
var Day0Close = security(syminfo.tickerid, 'D', close(day0))
var Day1 = Day0 + 1
Trigger = (close(Day1) > open(Day1)) and (close(Day1) > close(Day0))
plotshape(Bull, style=shape.arrowup, location=location.abovebar, color=color.green, text='Bullish')
plotshape(Trigger, style=shape.arrowup, location=location.abovebar, color=color.yellow, text=’Trigger’)
var Day1Close = security(syminfo.tickerid, 'D', close(Day1))
var Day2 = Day1 + 1
var Day2High = security(syminfo.tickerid, 'D', high(Day2))
strategy.entry("Long", strategy.long, 1, Day2High, when = Trigger)
var stoploss = 0.9 * Day0Close
var NextDay = Day2 + 1
var NextDayClose = security(syminfo.tickerid, 'D', close(NextDay))
var count = 0
for count = 0 to 30
if NextDayClose > stoploss
NextDay = NextDay + 1
var NextDayClose = security(syminfo.tickerid, 'D', close(NextDay))
var count = count + 1
else NextDayClose = stoploss
strategy.close("Long", NextDayClose)
Code doesnot compile
I need to edit some URL data, but i am facing some issue, the url is coming as:
<cfset myurl = "http:/example.com/0.asp?rpttype=298&companyQ=148&companyQ=150&companyQ=176&companyQ=186&companyQ=195&companyQ=105&companyQ=136&companyQ=126&productQ=1072&productQ=1042&productQ=1043stateQ=&sortBy=1&sortOrder=1">
<cfset reURL = queryStringDeleteVar("companyQ",myurl)>
<cfset reURL = queryStringDeleteVar("productQ",reURL)>
<cfset reURL = reURL & "&companyQ=">
<cfset listData = ''>
<cfloop list="#getCompanyID#" index="k">
<cfset listData = ListChangeDelims(ListPrepend(listData,"%27+or+q2.comp+%3D%27=" & k),'',',')>
</cfloop>
<cfdump var="#reURL##listData#" label="URL Rewritten">
rewriting as:
http://example.com/0.asp?rpttype=298&stateQ=&sortBy=1&sortOrder=1&companyQ=%27+or+q2.comp+%3D%27=186%27+or+q2.comp+%3D%27=176%27+or+q2.comp+%3D%27=150%27+or+q2.comp+%3D%27=148
but it needs to be like this
http://example.com/0.asp?rpttype=298&stateQ=&sortBy=1&sortOrder=1&companyQ=186%27+or+q2.comp+%3D%27=176%27+or+q2.comp+%3D%27=150%27+or+q2.comp+%3D%27=148
i am missing something,
please guide
this
companyQ=%27+or+q2.comp+%3D%27=186
needs to like this for the first one only
companyQ=186
only the first one, remaining will stay as it is:
the value 186 is dynamic
I think this should just help you.
<cfset myurl = "http:/example.com/0.asp?rpttype=298&companyQ=148&companyQ=150&companyQ=176&companyQ=186&companyQ=195&companyQ=105&companyQ=136&companyQ=126&productQ=1072&productQ=1042&productQ=1043stateQ=&sortBy=1&sortOrder=1">
<cfset reURL = queryStringDeleteVar("companyQ",myurl)>
<cfset reURL = queryStringDeleteVar("productQ",reURL)>
<cfset reURL = reURL & "&companyQ=#listFirst(getCompanyID)#">
<cfset getCompanyID = listDeleteAt(getCompanyID,1)>
<cfset listData = ''>
<cfloop list="#getCompanyID#" index="k">
<cfset listData =ListPrepend(listData,"%27+or+q2.comp+%3D%27=" & k)>
</cfloop>
<cfset listData = listChangeDelims(listData,"") />
<cfdump var="#reURL##listData#" label="URL Rewritten">
I am currently working on modifying an existing function, by Ray, that checks the time elapsed and remaining:
Here is the function:
function ago(date){
var interval = "";
var offset = 0;
var result = 0;
if (isDate(arguments.date)){
var formattedDate = dateFormat(arguments.date, "dddd dd mmmm yyyy");
var k = datediff('d',arguments.date,now());
//writedump(k);
//abort;
if(k contains '-') {
if (dateDiff("s", now(), arguments.date) < 60){
// less than 1 minute show interval in seconds
offset = dateDiff("s", now(),arguments.date);
interval= offset == 1 ? "second":"seconds";
result = "#offset# #interval# left";
}else if (dateDiff("n",now(),arguments.date) < 60){
// less than 1 hour show interval in minutes
offset = dateDiff("n", now(),arguments.date);
interval= offset == 1 ? "minute":"minutes";
result = "#offset# #interval# left";
}else if (dateDiff("h",now(),arguments.date) < 24){
// less than 24 hours display interval in hours
offset = dateDiff("h", now(), arguments.date);
interval = offset == 1 ? "hour":"hours";
result = "#offset# #interval# left";
}else if (dateDiff("d",now(),arguments.date) < 2){
// less than 2 days display yesterday
result = "Tommarrow";
}else if (dateDiff("d", now(), arguments.date) < 7){
// less than 7 days display day
result = dayOfWeekAsString( dayOfWeek( arguments.date ));
}else if (dateDiff("w", now(), arguments.date)){
offset = dateDiff("w",now(), arguments.date);
interval = offset == 1 ? "week":"weeks";
result = "#offset# #interval# left";
}else if (dateDiff("m", now(), arguments.date)){
offset = dateDiff("m",now(), arguments.date);
interval = offset == 1 ? "month":"months";
result = "#offset# #interval# left";
}else if (dateDiff("yyyy", now(), arguments.date)){
offset = dateDiff("yyyy", now(), arguments.date);
interval = offset == 1 ? "year":"years";
result = "#offset# #interval# left";
}
else{
// otherwise display date
result = formattedDate;
}
}
else {
if (dateDiff("s", arguments.date, now()) < 60){
// less than 1 minute show interval in seconds
offset = dateDiff("s", arguments.date, now());
interval= offset == 1 ? "second":"seconds";
result = "#offset# #interval# ago";
}else if (dateDiff("n", arguments.date, now()) < 60){
// less than 1 hour show interval in minutes
offset = dateDiff("n", arguments.date, now());
interval= offset == 1 ? "minute":"minutes";
result = "#offset# #interval# ago";
}else if (dateDiff("h", arguments.date, now()) < 24){
// less than 24 hours display interval in hours
offset = dateDiff("h", arguments.date, now());
interval = offset == 1 ? "hour":"hours";
result = "#offset# #interval# ago";
}else if (dateDiff("d", arguments.date, now()) < 2){
// less than 2 days display yesterday
result = "yesterday";
}else if (dateDiff("d", arguments.date, now()) < 7){
// less than 7 days display day
result = dayOfWeekAsString( dayOfWeek( arguments.date ));
}else if (dateDiff("w", arguments.date, now())){
offset = dateDiff("w", arguments.date, now());
interval = offset == 1 ? "week":"weeks";
result = "#offset# #interval# ago";
}else if (dateDiff("m", arguments.date, now())){
offset = dateDiff("m", arguments.date, now());
interval = offset == 1 ? "month":"months";
result = "#offset# #interval# ago";
}else if (dateDiff("yyyy", arguments.date, now())){
offset = dateDiff("yyyy", arguments.date, now());
interval = offset == 1 ? "year":"years";
result = "#offset# #interval# ago";
}
else{
// otherwise display date
result = formattedDate;
}
}
interval = "<abbr title='" & formattedDate & "'>" & result & "</abbr>";
}
return interval;
}
The result is "1 week left" or "2 weeks ago". But rather than "2 weeks", it should show me "1 week 4 days", or whatever the days remaining are, unless it is exactly "2 weeks".
Wow that is a lot of if statements, probably better to look for a calculated approach like the following:
<cfset date1 = CreateDate(2014,07,07)>
<cfset date2 = CreateDate(2014,07,19)>
<cfset dateDifference = dateDiff("d",date1,date2)>
<cfset weeks = int(dateDifference/7)>
<cfset days = dateDifference MOD 7>
<cfoutput>
#weeks# weeks and #days# days ago
</cfoutput>
Then if you need to do it the other way around, e.g. weeks and days until, you can to that as well, just change the output text. All you need to do is make sure that date1 is always before (in time) than date2.
UPDATE
After looking at this again and based on what your where looking for I found this blog post from Steve Withington:
http://www.stephenwithington.com/blog/index.cfm/2008/8/15/Using-ColdFusion-to-Create-an-Ebayesque-Auction-Countdown-Timer-Custom-Tag
I then took his code and turned it into a function that I think should do what you want, or pretty close to it:
<cfscript>
function timeUntil(dateStart, dateEnd) {
var compareGivenDates = DateCompare(arguments.dateStart, arguments.dateEnd, "s");
var rightNow = DateFormat(now(), "mm/dd/yyyy") & " " & TimeFormat(now(), "hh:mm:ss tt");
var compareNow = DateCompare(rightNow, arguments.dateStart, "s");
switch (compareNow) {
case -1:
throw(message="End date must be after start date", detail="The end date must be after the start date otherwise the calculations will not be possible.");
case 1:
var arguments.dateStart = rightNow;
}
var returnTimeRemaining="";
var dateStart = DateFormat(arguments.dateStart, "mm/dd/yyyy") & " " & TimeFormat(arguments.dateStart, "hh:mm:ss tt");
var dateEnd = DateFormat(arguments.dateEnd, "mm/dd/yyyy") & " " & TimeFormat(arguments.dateEnd, "hh:mm:ss tt");
var hdif = Abs(DateDiff("h", dateEnd, dateStart));
var ndif = Abs(DateDiff("n", dateEnd, dateStart));
var sdif = Abs(DateDiff("s", dateEnd, dateStart));
var years2go = Abs(DateDiff("yyyy", dateEnd, dateStart));
var months2go = Abs(DateDiff("m", dateEnd, dateStart));
var weeks2go = Abs(DateDiff("ww", dateEnd, dateStart));
var days2go = Abs(DateDiff("d", dateEnd, dateStart));
if (DatePart('h', now()) LT 12 OR days2go EQ 1) {
var h = 'h';
} else {
var h = 'H';
}
var hours2go = TimeFormat(dateEnd-dateStart, h);
var min2go = TimeFormat("#dateEnd-dateStart#", "m");
var sec2go = TimeFormat("#dateEnd-dateStart#", "s");
var newmonths = months2go-(years2go*12);
var tempDate = dateadd("m", months2go, arguments.dateStart);
var newweeks = Abs(DateDiff("ww", arguments.dateEnd, tempDate));
var tempdays = Abs(DateDiff("d", arguments.dateEnd, tempDate));
var newdays = tempdays-(newweeks*7);
var comparison = DateCompare(dateStart, dateEnd, "s");
switch (comparison) {
case -1:
if (years2go GTE 1) {
returnTimeRemaining = returnTimeRemaining & "#years2go#y ";
}
if (newmonths GTE 1) {
returnTimeRemaining = returnTimeRemaining & "#newmonths#m ";
}
if (newweeks GTE 1) {
returnTimeRemaining = returnTimeRemaining & "#newweeks#w ";
}
if (newdays GTE 1) {
returnTimeRemaining = returnTimeRemaining & "#newdays#d ";
}
if (ndif GTE 60) {
returnTimeRemaining = returnTimeRemaining & "#hours2go#h ";
}
if (sdif GTE 60) {
returnTimeRemaining = returnTimeRemaining & "#min2go#m ";
}
if (sdif GTE 1) {
returnTimeRemaining = returnTimeRemaining & "#sec2go#s";
} else {
returnTimeRemaining = "0s";
}
break;
case 0:
returnTimeRemaining = false;
break;
case 1:
returnTimeRemaining = false;
break;
}
return returnTimeRemaining
}
</cfscript>
<cfoutput>
#timeUntil(CreateDateTime(2013, 7, 19, 0, 0, 0), now())#
</cfoutput>
Apart from converting it to script and making it a function, there are a few changes in here from Steve's original to get it to not return the months, weeks, days, etc... when they are 0. I've run a load of test dates through it and it appears to work ok for all the cases I have tried. Still feel there is far more code there then should be necessary but I don't have the time to spend refactoring it down.
UPDATE 2
Used this code in a programming hack session today and refactored it and improved it to the following:
<cfscript>
public string function timeDifferenceFormattedString(
required date dateStart,
date dateEnd = Now()
) {
// Is datestart actually after dateend?
switch (DateCompare(arguments.dateStart,arguments.dateEnd)) {
case 1:
var suffix = 'since';
var currentLowerDate = arguments.dateEnd;
var currentUpperDate = arguments.dateStart;
break;
case 0:
return 'The dates are the same';
break;
case -1:
var suffix = 'until';
var currentLowerDate = arguments.dateStart;
var currentUpperDate = arguments.dateEnd;
break;
}
var arrDateParts = [ 'yyyy' , 'm' , 'ww' , 'd', 'h', 'n', 's' ];
var arrDatePartsHuman = [ 'year' , 'month' , 'week' , 'day', 'hour', 'minute', 'second' ];
var arrDateDiffs = [];
for ( var i = 1; i<=ArrayLen(arrDateParts);i++ ) {
var thisDiff = Int(DateDiff( arrDateParts[i] , currentLowerDate, currentUpperDate ));
if (
thisDiff > 0
) {
arrDateDiffs.add( thisDiff & ' ' & arrDatePartsHuman[i] & ( thisDiff > 1 ? 's' : '' ) );
currentLowerDate = DateAdd( arrDateParts[i] , thisDiff, currentLowerDate );
}
}
arrDateDiffs.add(suffix);
return ArrayToList(arrDateDiffs,' ');
}
</cfscript>
<cfoutput>
<p>#timeDifferenceFormattedString(CreateDateTime(2013, 7, 10, 0, 0, 0), now())#</p>
<p>#timeDifferenceFormattedString(CreateDateTime(2013, 7, 10, 0, 0, 0), CreateDateTime(2013, 7, 10, 0, 0, 0))#</p>
<p>#timeDifferenceFormattedString(now(),CreateDateTime(2013, 7, 10, 0, 0, 0))#</p>
</cfoutput>
To take this further again you could pass in the "human" output values and suffixes as well to make the string formatting even more flexible.
I'm trying to detect whether I've multiplied the numerator and denominator of a complex fraction enough times (by 10/10) to get integers on both top and bottom. Often my algorithm works. Sometimes, though, the Int() function doesn't work as expected and I get huge numbers out of it. Here is a simplified version of what I'm running:
<cfoutput>
<cfset RealNumber = RandRange(1000, 10000) / 1000 />
RealNumber = "#RealNumber#" Int(RealNumber) = "#Int(RealNumber)#"<br />
<cfloop condition="RealNumber NEQ Int(RealNumber)">
<cfset RealNumber = RealNumber * 10 />
RealNumber = "#RealNumber#" Int(RealNumber) = "#Int(RealNumber)#"<br />
</cfloop>
</cfoutput>
Most of the time this gets what I want, but sometimes it looks like this:
RealNumber = "9.184" Int(RealNumber) = "9"
RealNumber = "91.84" Int(RealNumber) = "91"
RealNumber = "918.4" Int(RealNumber) = "918"
RealNumber = "9184" Int(RealNumber) = "9183"
RealNumber = "91840" Int(RealNumber) = "91839"
RealNumber = "918400" Int(RealNumber) = "918399"
RealNumber = "9184000" Int(RealNumber) = "9183999"
RealNumber = "91840000" Int(RealNumber) = "91839999"
RealNumber = "918400000" Int(RealNumber) = "918399999"
RealNumber = "9184000000" Int(RealNumber) = "9183999999"
RealNumber = "91840000000" Int(RealNumber) = "91839999999"
RealNumber = "918400000000" Int(RealNumber) = "918399999999"
RealNumber = "9.184E+012" Int(RealNumber) = "9.184E+012"
RealNumber = "9.184E+013" Int(RealNumber) = "9.184E+013"
RealNumber = "9.184E+014" Int(RealNumber) = "9.184E+014"
RealNumber = "9.184E+015" Int(RealNumber) = "9.184E+015"
Or even like this:
RealNumber = "2.152" Int(RealNumber) = "2"
RealNumber = "21.52" Int(RealNumber) = "21"
RealNumber = "215.2" Int(RealNumber) = "215"
RealNumber = "2152" Int(RealNumber) = "2152"
RealNumber = "21520" Int(RealNumber) = "21520"
RealNumber = "215200" Int(RealNumber) = "215200"
RealNumber = "2152000" Int(RealNumber) = "2152000"
RealNumber = "21520000" Int(RealNumber) = "21520000"
RealNumber = "215200000" Int(RealNumber) = "215200000"
RealNumber = "2152000000" Int(RealNumber) = "2152000000"
RealNumber = "21520000000" Int(RealNumber) = "21520000000"
RealNumber = "215200000000" Int(RealNumber) = "215200000000"
RealNumber = "2.152E+012" Int(RealNumber) = "2.152E+012"
RealNumber = "2.152E+013" Int(RealNumber) = "2.152E+013"
RealNumber = "2.152E+014" Int(RealNumber) = "2.152E+014"
RealNumber = "2.152E+015" Int(RealNumber) = "2.152E+015"
RealNumber = "2.152E+016" Int(RealNumber) = "2.152E+016"
What am I doing wrong and how do I compensate for this?
RealNumber = "9.184E+015"
The output is deceptive. If you use #RealNumber.toString()# the real value is probably something like 9.183999999999998E15. CF uses the approximate type Double for most mathematical operations. So what you are seeing is normal behavior for floating point numbers. If you need greater accuracy, use PrecisionEvaluate. It makes use of BigDecimals for arithmetic operations (because they are more precise than java.lang.Double).
Try using javacast.. ColdFusion is trying to dynamically determine your variable type and is not doing a great job.. Javacast covers a multitude of sins.
<cfoutput>
<cfset RealNumber = RandRange(1000, 10000) / 1000 />
RealNumber = "#RealNumber#" Int(RealNumber) = "#Int(RealNumber)#"<br />
<cfloop condition="RealNumber NEQ Int(RealNumber)">
<cfset RealNumber = RealNumber * 10 />
RealNumber = "#RealNumber#" Int(RealNumber) = "#javaCast("int", RealNumber)#"<br />
</cfloop>
Val() seems to correct it too:
<cfoutput>
<cfset RealNumber = RandRange(1000, 10000) / 1000 />
"#val(RealNumber)#" = INT: "#val(Int(RealNumber))#"<br />
<cfloop condition="val(RealNumber) NEQ Val(Int(RealNumber))">
<cfset RealNumber = RealNumber * 10 />
"#val(RealNumber)#" INT: "#val(Int(RealNumber))#"<br />
</cfloop>
</cfoutput>
I am working on migrating a bunch of data from an old database into a new one. In the process of migrating a created a UDF for my script that would give me a bunch of data that I need. When I run a loop that calls the UDF multiple times I find that the first iteration runs fine, but then the UDF disappears from the following iterations.
My code is:
<cffunction name="getCats" access="public">
<cfargument name="assignments" type="any" />
<cfquery name="getCats" datasource="pgdold">
SELECT c1.id AS id1, c1.category AS name1, c2.id AS id2, c2.category AS name2, c3.id AS id3, c3.category AS name3, c4.id AS id4, c4.category AS name4, c5.id AS id5, c5.category AS name5
FROM category c1
LEFT JOIN category AS c2 ON c2.parentid = c1.id
LEFT JOIN category AS c3 ON c3.parentid = c2.id
LEFT JOIN category AS c4 ON c4.parentid = c3.id
LEFT JOIN category AS c5 ON c5.parentid = c4.id
</cfquery>
<cfquery name="get" dbtype="query">
SELECT (name1 + '/' + name2 + '/' + name3 + '/' + name4 + '/' + name5) AS category
FROM getCats
WHERE
<cfloop query="Arguments.assignments">
(id1 = #Arguments.assignments.categoryid# OR id2 = #Arguments.assignments.categoryid# OR id3 = #Arguments.assignments.categoryid# OR id4 = #Arguments.assignments.categoryid# OR id5 = #Arguments.assignments.categoryid#)
<cfif Arguments.assignments.currentrow IS NOT Arguments.assignments.recordCount> OR </cfif>
</cfloop>
</cfquery>
<cfreturn get />
</cffunction>
<cfscript>
olddb = {datasource='pgdold'};
a = new Query(argumentCollection=olddb);
a.setSQL('SELECT * FROM products LIMIT 10');
p = a.execute();
pr = p.getResult();
</cfscript>
<cfscript>
products = arrayNew();
for(i=1;i<=pr.recordCount;i++){
product = {};
if(!reFind('([0-9]+\-)(G|g)(I|i)(F|f)(T|t)',pr['sku'][i])){
b = new Query(argumentCollection=olddb);
b.setSql('SELECT * FROM productpics WHERE sku = :sku ORDER BY picorder');
b.addParam(name='sku',value=pr['sku'][i]);
pics = b.execute().getResult();
picList = '';
for(j=1;j<=pics.recordCount;j++){
picList = picList & ';' & pics['imagename'][j];
}
d = new Query(argumentCollection=olddb);
d.setSql('SELECT * FROM skucategories WHERE sku = :sku');
d.addParam(name='sku', value=pr['sku'][i]);
assignments = d.execute().getResult();
categories = getCats(assignments);
writeDump(categories);
product = {
store = 'admin',
websites = 'base',
attribute_set = 'Default',
categories = '',
type = 'simple',
sku = pr['sku'][i],
name = reReplace(reReplace(pr['title'][i],'\"','&##34;','all'),'\,','&##44;','all'),
price = pr['price'][i],
description = reReplace(reReplace(pr['detail'][i],'\"','&##34;','all'),'\,','&##44;','all'),
short_description = '',
image = pics['imagename'][1],
small_image = pics['imagename'][1],
thumbnail = pics['imagename'][1],
weight = pr['weight'][i],
has_options = 1,
is_in_stock = 1,
qty = 1000,
disabled = 'No',
status = 'Enabled',
options_container = 'Black after info Column',
tax_class_id = 'Taxable Goods',
visibility = 'Catalog,Search',
gallery = right(picList,len(picList)-1) // Seperate images by semicolon (;)
};
arrayAppend(products,product);
}
}
</cfscript>
It is the getCats function that disappears.
* yes the code is ugly and inefficient. It wasn't meant to do anything more than this one job and after it finishes the job it is going to be thrown away, so don't tell me about the ugliness or inefficiencies.
Without reading every line of your code posted, I have a Strong feeling that it has to do with Var scooping... since you are calling that UDF in a Loop.
Please var scope you query variables.
Pre CF9:
<!--- insert after <cfargument> --->
<cfset var getCats = "">
<cfset var get = "">
At, or Post CF9 with Local scope:
<cfquery name="local.getCats" datasource="pgdold">
<cfquery name="local.get" dbtype="query">
You named a variable in the UDF with the same name as the UDF. Either var scope it or rename that query to something else. I recommend naming it something else.