exiting strategy "long" when "short entry" triggered, hit "stop loss" and "hit target" - pine-script-v4

Sorry for my bad English(English is not my first language)
I want to execute , exit the "long" and enter the "short" at the same time when "short entry" is trigged. I tried below code.It only exit when hit Target and Stoploss.It doesn't exit the "long" at "short entry" and doesn't exit the "short" at "long entry".
Much appreciate any help!
strategy.entry (id="Long", long=strategy.long, when = ValidLong, comment ="Long" )
strategy.entry (id="Short", long=strategy.short, when=ValidShort, comment="Short" )
strategy.exit(id = "Long Exit", from_entry = "Long", limit =Target , loss = Stoploss , when = strategy.position_size > 0)
strategy.exit(id = "Short Exit", from_entry = "Short", limit = Target, loss = Stoploss, when = strategy.position_size < 0 )

Related

VBA Parse Nested JSON

VBA Noob here. Please excuse any gaps in terminology etc.
I am trying to parse a JSON file into a spreadsheet using VBA-JSON v2.2.3 (c) Tim Hall - https://github.com/VBA-tools/VBA-JSON.
The JSON file looks like this:
{
"site": "{5BEC7C29-FF95-4ECC-9314-064B52618EEE}",
"from": "2017-01-16",
"to": "2017-01-22",
"timeSheet": [
{
"date": "2017-01-16",
"person": "{E2A5FDE1-33F8-43CA-A01D-5DD4A3A5E23A}",
"personName": "James Smith",
"company": "{B03CF7B3-0BE9-44B4-8E55-47782FDD87C0}",
"companyName": "Acme Company Ltd",
"minutes": "510",
"activities": [
{
"name": "Training",
"code": "TR",
"minutes": "240"
},
{
"name": "Administration",
"code": "AD",
"minutes": "150"
},
{
"name": "Payroll",
"code": "PR",
"minutes": "60"
},
{
"name": "Meal break",
"code": "",
"minutes": "60"
}
]
}
]
}
There may be any number of 'timeSheet' records, as well as any number of 'Activities' within each timeSheet including zero.
I want a row in the spreadsheet for each activity, with the name and other data outputted next to that days activities. Essentially showing a log of all the activities done, for how long and by who. To complicate issues, I still need the name etc outputting even if no activities are recorded. I will then fill with 'unallocated time' or something similar.
Below is as far as I have got (abridged), with an updated count of the activities occurring every loop. This feels a little hacky and doesn't give me what I am looking for, often adding additional rows and sometimes missing activities entirely.
i = 2
j = 1
activCount = CStr(JSON("timeSheet")(1)("activities").Count)
If activCount = 0 Then activCount = 1
ws.Cells(i, 1) = JSON("site")
ws.Cells(i, 2) = JSON("from")
ws.Cells(i, 3) = JSON("to")
For Each item In JSON("timeSheet")
For j = 1 To activCount
On Error Resume Next
ws.Cells(i, 4) = item("date")
ws.Cells(i, 5) = item("personName")
ws.Cells(i, 6) = item("companyName")
ws.Cells(i, 7) = item("minutes")
ws.Cells(i, 9) = item("activities")(j)("name")
ws.Cells(i, 10) = item("activities")(j)("code")
ws.Cells(i, 11) = item("activities")(j)("minutes")
activCount = CStr(JSON("timeSheet")(i)("activities").Count)
If activCount = 0 Then activCount = 1
i = i + 1
Next
Next
Can someone help? I have run out of ideas and have been working it for some time! Thank you. :)
This worked fine for me:
Sub TestJson2()
Dim ts, act
Dim Json As Object, c As Range
'reading json from a worksheet cell...
Set Json = JsonConverter.ParseJson(Range("A3").Value)
Set c = ActiveSheet.Range("C5")
'loop over timesheets
For Each ts In Json("timeSheet")
'loop over timesheet activities
For Each act In ts("activities")
c.Resize(1, 11).Value = Array(Json("site"), Json("from"), Json("to"), _
ts("date"), ts("personName"), ts("companyName"), _
ts("minutes"), act("name"), act("code"), _
act("minutes"))
Set c = c.Offset(1, 0)
Next act
Next ts
End Sub

error when selecting multiple tables

SELECT pc_info_tbl.`serial_id` "Serial Number",
pc_info_tbl.`replacement_warranty_date` "Replacement Warranty",
pc_info_tbl.`service_warranty_date` "Service Warranty",
personel_tbl.`fname` "First Name",
personel_tbl.`mname` "Middle Name",
personel_tbl.`lname` "Last Name",
repair_records_tbl.`repair_date` "Repair Date",
repair_records_tbl.`service_slip_no` "Service Slip Number",
repair_records_tbl.`itmd_personel_id` "ITMD Personnel",
repair_records_tbl.`notes` "Notes"
FROM repair_records_tbl,
itmd_personel_tbl,
pc_info_tbl,
personel_tbl
WHERE repair_records_tbl.`personel_id` = personel_tbl.`personel_id`,
repair_records_tbl.`serial_id` = pc_info_tbl.`serial_id`,
repair_records_tbl.`itmd_personel_id` = itmd_personel_tbl.`itmd_personel_id`;
I want to select multiple tables, but I get error some where on repair_records_tbl.`serial_id` = pc_info_tbl.`serial_id`, repair_records_tbl.`i
Error Code: 1064
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ' repair_records_tbl.serial_id = pc_info_tbl.serial_id, repair_records_tbl.`i' at line 5
anyone can teach me the right syntax?
Your where clause has a syntax error. May be you want to use AND
Change:
WHERE repair_records_tbl.`personel_id` = personel_tbl.`personel_id`,
repair_records_tbl.`serial_id` = pc_info_tbl.`serial_id`,
repair_records_tbl.`itmd_personel_id` = itmd_personel_tbl.`itmd_personel_id`;
to:
WHERE
repair_records_tbl.`personel_id` = personel_tbl.`personel_id`
and repair_records_tbl.`serial_id` = pc_info_tbl.`serial_id`
and repair_records_tbl.`itmd_personel_id` = itmd_personel_tbl.`itmd_personel_id`;
You separate column names while doing the select by comma but use AND/OR between the two where clauses and not separate them by comma:
SELECT pc_info_tbl.`serial_id` "Serial Number", pc_info_tbl.`replacement_warranty_date` "Replacement Warranty", pc_info_tbl.`service_warranty_date` "Service Warranty", personel_tbl.`fname` "First Name", personel_tbl.`mname` "Middle Name", personel_tbl.`lname` "Last Name", repair_records_tbl.`repair_date` "Repair Date", repair_records_tbl.`service_slip_no` "Service Slip Number", repair_records_tbl.`itmd_personel_id` "ITMD Personnel", repair_records_tbl.`notes` "Notes"
FROM repair_records_tbl, itmd_personel_tbl, pc_info_tbl, personel_tbl
WHERE repair_records_tbl.`personel_id` = personel_tbl.`personel_id`
AND repair_records_tbl.`serial_id` = pc_info_tbl.`serial_id`
AND repair_records_tbl.`itmd_personel_id` = itmd_personel_tbl.`itmd_personel_id`;

Parsing JSON from Google Distance Matrix API with Corona SDK

So I'm trying to pull data from a JSON string (as seen below). When I decode the JSON using the code below, and then attempt to index the duration text, I get a nil return. I have tried everything and nothing seems to work.
Here is the Google Distance Matrix API JSON:
{
"destination_addresses" : [ "San Francisco, CA, USA" ],
"origin_addresses" : [ "Seattle, WA, USA" ],
"rows" : [
{
"elements" : [
{
"distance" : {
"text" : "1,299 km",
"value" : 1299026
},
"duration" : {
"text" : "12 hours 18 mins",
"value" : 44303
},
"status" : "OK"
}]
}],
"status" : "OK"
}
And here is my code:
local json = require ("json")
local http = require("socket.http")
local myNewData1 = {}
local SaveData1 = function (event)
distanceReturn = ""
distance = ""
local URL1 = "http://maps.googleapis.com/maps/api/distancematrix/json?origins=Seattle&destinations=San+Francisco&mode=driving&&sensor=false"
local response1 = http.request(URL1)
local data2 = json.decode(response1)
if response1 == nil then
native.showAlert( "Data is nill", { "OK"})
print("Error1")
distanceReturn = "Error1"
elseif data2 == nill then
distanceReturn = "Error2"
native.showAlert( "Data is nill", { "OK"})
print("Error2")
else
for i = 1, #data2 do
print("Working")
print(data2[i].rows)
for j = 1, #data2[i].rows, 1 do
print("\t" .. data2[i].rows[j])
for k = 1, #data2[i].rows[k].elements, 1 do
print("\t" .. data2[i].rows[j].elements[k])
for g = 1, #data2[i].rows[k].elements[k].duration, 1 do
print("\t" .. data2[i].rows[k].elements[k].duration[g])
for f = 1, #data2[i].rows[k].elements[k].duration[g].text, 1 do
print("\t" .. data2[i].rows[k].elements[k].duration[g].text)
distance = data2[i].rows[k].elements[k].duration[g].text
distanceReturn = data2[i].rows[k].elements[k].duration[g].text
end
end
end
end
end
end
timer.performWithDelay (100, SaveData1, 999999)
Your loops are not correct. Try this shorter solution.
Replace all your "for i = 1, #data2 do" loop for this one below:
print("Working")
for i,row in ipairs(data2.rows) do
for j,element in ipairs(row.elements) do
print(element.duration.text)
end
end
This question was solved on Corona Forums by Rob Miracle (http://forums.coronalabs.com/topic/47319-parsing-json-from-google-distance-matrix-api/?hl=print_r#entry244400). The solution is simple:
"JSON and Lua tables are almost identical data structures. In this case your table data2 has top level entries:
data2.destination_addresses
data2.origin_addresses
data2.rows
data2.status
Now data2.rows is another table that is indexed by numbers (the [] brackets) but here is only one of them, but its still an array entry:
data.rows[1]
Then inside of it is another numerically indexed table called elements.
So far to get to the element they are (again there is only one of them
data2.rows[1].elements[1]
then it's just accessing the remaining elements:
data2.rows[1].elements[1].distance.text
data2.rows[1].elements[1].distance.value
data2.rows[1].elements[1].duration.text
data2.rows[1].elements[1].duration.value
There is a great table printing function called print_r which can be found in the community code which is great for dumping tables like this to see their structure."

Lua - Error repeating a function?

I'm working on an 'impossible' game, where you are basically asked a bunch of trick questions.
The first time I run the script, everything works perfectly. If the user decides to play again by typing in 'y', it will re-run the mainScript function. However, the script automatically re-runs the mainScript after finishing it a second time, without taking user input. I might be making a simple mistake, I'm not sure. Here is the script: (Sorry, I know it is kind of long)
math.randomseed(os.time())
local lives = 3
local points = 0
Questions = {
{"What is the magic word?", "A) Please", "B) Abra-Cadabra", "C) Lotion", "D) Cheese", "c"},
{"Does anyone love you?", "A) Yes", "B) No", "C) Everyone loves me!", "D) My mother does", "b"},
{"How many fingers do you have?", "A) None", "B) Eight", "C) Seventeen", "D) Ten", "d"},
{"What is 1 + 1?", "A) Window", "B) Door", "C) Two", "D) That's a stupid question", "a"}
}
savedQuestions = {} --Load the Questions table into savedQuestions
for i, v in pairs(Questions) do
table.insert(savedQuestions, v)
end
function loadTable() --Load the savedQuestions into Questions
for i = 1, #savedQuestions do
table.insert(Questions, savedQuestions[i])
end
end
function waitForStart()
local chk = io.read() tostring(chk)
if (chk:sub(1, 5)):lower() == "start" then
return true
end
waitForStart()
end
function lookForAnswer(ans)
table.remove(Questions, number)
local input = io.read() tostring(input)
if input:lower() == ans then
points = points + 1
return true
end
lives = lives - 1
return false
end
function mainScript()
lives = 3
points = 0
print("Welcome to the Impossible quiz!")
print("Type 'start' when you are ready to begin\n")
waitForStart() io.write("\n")
for i = 1, #Questions do
number = math.random(1, #Questions)
local prob = Questions[number]
local q = prob[1]
local a = prob[6]
print(q)
print(prob[2] .. "\n" .. prob[3] .. "\n" .. prob[4] .. "\n" .. prob[5] .. "\n")
if lookForAnswer(a) then
print("Correct! Points: " .. points .. " Lives: " .. lives .. "\n\n")
else
print("WRONG! Points: " .. points .. " Lives: " .. lives .. "\n\n")
if lives <= 0 then
return false
end
end
end
return true
end
function checkForReplay()
print("Would you like to play again? (Y / N)")
local chk = io.read() tostring(chk)
if (chk:sub(1, 1)):lower() == "y" then
return true
end
return false
end
function checkWin()
if mainScript() then
print("You won!")
print("Points: " .. points .. "\n")
if checkForReplay() then
Questions = {}
loadTable()
mainScript()
else
exit()
end
else
print("You lose!")
print("Points: " .. points .. "\n")
if checkForReplay() then
Questions = {}
loadTable()
mainScript()
else
exit()
end
end
end
while true do
checkWin()
end
You should factor out the "startover" logic into the loop, you would see better. Then you notice how there is common code in both if chunks of your checkWin, factor that out too:
function checkWin()
if mainScript() then
print("You won!")
else
print("You lose!")
end
print("Points: " .. points .. "\n")
if not checkForReplay() then
exit()
end
end
while true do
checkWin()
-- if you get here you have not exited so start over:
Questions = {}
loadTable()
mainScript() -- oops! what's that doing here?
end
Note also that it is better to let the script return than call os.exit() (assuming that is what exit() is in your code -- see for example How to terminate Lua script?):
function checkWin()
if mainScript() then
print("You won!")
else
print("You lose!")
end
print("Points: " .. points .. "\n")
return checkForReplay()
end
local playAgain = checkWin()
while playAgain do
Questions = {}
loadTable()
playAgain = checkWin()
end

Variables Resetting When Using Parallel Function in Lua with ComputerCraft

I am a beginner designing a Lua program in ComputerCraft (Minecraft) that asks the player for their name the first time they use it, and records it. For now, I want a program that detects if the variable firstnameis equal to nil and asks for the name if it is so. If the variable is not equal to nil, it says that you do not need to register. I currently have register()called only after pressing 5from the main menu.
The problem is that each time I assign a string to firstnameupon being prompted, firstnamereturns to nil when the main menu comes up. I even put print(firstname)at the end of the menu to test this.
I have assumed this is due to the parallel function that this all runs in. I run MainMenu() and Controls()in parallel so that I can listen for keyboard input and redstone input at the same time.
How can I keep both functions listening and the menu working, while preserving variables?
Here is the full code:
rednet.open("back") --Opens rednet on the back side of computer
local innerdooropen = false --Stuff to do with the airlock
local outerdooropen = false
function reset() --A handy function for screen reset
term.clear()
term.setCursorPos(1,1)
end
local function register() --This is the registration menu system
if firstname == nil then
print "Welcome to Obsidian Station!"
print "You must register before entering"
print "Please type your first name"
local firstname = read()
if firstname ~= "" then
print("Enter your last name")
local lastname = read()
print("You are now registered "..firstname.." "..lastname)
sleep(3)
rednet.broadcast(firstname.." "..lastname)
elseif firstname == "" then
print "You must register to enter"
shell.run("startup")
end
end
if firstname ~= nil then
print("Registration Not Needed")
sleep(2)
end
end
--Beginning of Section You Don't Have to Read
local function MainMenu()
while true do
term.clear()
term.setCursorPos(1, 1)
if innerdooropen == true then
rs.setOutput("left", false)
end
if outerdooropen == true then
rs.setOutput("right", false)
end
if innerdooropen == false then
rs.setOutput("left", true)
end
if outerdooropen == false then
rs.setOutput("right", true)
end
print "Safety Airlock Control"
print "~~~~~~~~~~~~~~~~~~~~~~"
print "[1] Open Outer Door"
print "[2] Open Inner Door"
print "[3] Close Both Doors"
print ""
print "[4] Open Both Doors - WARNING! DANGEROUS!"
print ""
print "[5] Register"
print(firstname)
input = read()
if input == "2" then
print "Inner Door Open"
outerdooropen = false
sleep "1"
innerdooropen = true
end
if input == "1" then
print "Outer Door Open"
innerdooropen = false
sleep "1"
outerdooropen = true
end
if input == "3" then
print "Both Doors Closed"
innerdooropen = false
outerdooropen = false
end
if input == "5" then
reset()
register()
end
if input == "6" then
print("firstname: "..firstname)
sleep(3)
end
if input == "4" then
term.clear()
term.setCursorPos(1, 1)
print "CONFIRM BOTH DOORS OPEN? [y] [n]"
input = read()
if input == "y" then
print "OPENING AIRLOCK DOORS IN"
sleep "1"
print "10"
sleep "1"
print "9"
sleep "1"
print "8"
sleep "1"
print "7"
sleep "1"
print "6"
sleep "1"
print "5"
sleep "1"
print "4"
sleep "1"
print "3"
sleep "1"
print "2"
sleep "1"
print "1"
sleep "1"
innerdooropen = true
outerdooropen = true
print "DOORS OPEN"
sleep "1"
end
elseif input == "n" then
term.clear()
term.setCursorPos(1, 1)
shell.run("startup")
end
end
end
--end of section you don't have to read
local function Controls()
while true do
local e = os.pullEvent()
if e == "redstone" and rs.getInput("bottom") then
redstone.setOutput ("left", true)
sleep "1"
redstone.setOutput ("right", false)
innerdooropen = true
outerdooropen = false
end
end
end
while true do
parallel.waitForAll(MainMenu,Controls)
end
Initialize firstname outside of the parallel. Put local firstname up at the top of your code, and change local firstname = read() to just firstname = read(), and do the same for last name.
You are creating the variable after you check whether or not it is nil, which is why it always returns nil. Similarly, when the function ends, firstname no longer exists, since it is called and created inside of the function. So it will always return nil.
The top of your code should look like so
rednet.open("back") --Opens rednet on the back side of computer
local innerdooropen = false --Stuff to do with the airlock
local outerdooropen = false
local firstname = ""
local lastname = ""
And the other section should be as follows:
if firstname == nil then
print "Welcome to Obsidian Station!"
print "You must register before entering"
print "Please type your first name"
firstname = read()
if firstname ~= "" then
print("Enter your last name")
lastname = read()
print("You are now registered "..firstname.." "..lastname)
sleep(3)
You should initialize firstname before you check if it is equal to nil.
local firstname = nil; --Move this up here so that you can access it elsewhere.
local lastname = nil; --This is also needed out here.
local function register() --This is the registration menu system
if firstname == nil then
print "Welcome to Obsidian Station!"
print "You must register before entering"
print "Please type your first name"
firstname = read() --Change this to just setting firstname to the read name.
if firstname ~= "" then
print("Enter your last name")
lastname = read()
print("You are now registered "..firstname.." "..lastname)
sleep(3)
rednet.broadcast(firstname.." "..lastname)
elseif firstname == "" then
print "You must register to enter"
shell.run("startup")
end
end
if firstname ~= nil then --Now this will not error as well.
print("Registration Not Needed")
sleep(2)
end
end
This allows for firstname to be accessed elsewhere and not just within that first if statement. You were checking if an uninitialized variable was equal to nil or not.
EDIT: Saw purxiz's answer and realized that you also probably want lastname to be outside of the loop. I fixed it in my code above now.