factor-out pickers into jotai atoms

master
Avraham Sakal 2 years ago
parent 0994a118a9
commit b02c71d206

162
dist/index.js vendored

@ -1088,7 +1088,7 @@ var require_react_development = __commonJS({
} }
return dispatcher.useContext(Context); return dispatcher.useContext(Context);
} }
function useState2(initialState) { function useState(initialState) {
var dispatcher = resolveDispatcher(); var dispatcher = resolveDispatcher();
return dispatcher.useState(initialState); return dispatcher.useState(initialState);
} }
@ -1890,7 +1890,7 @@ var require_react_development = __commonJS({
exports.useMemo = useMemo; exports.useMemo = useMemo;
exports.useReducer = useReducer2; exports.useReducer = useReducer2;
exports.useRef = useRef3; exports.useRef = useRef3;
exports.useState = useState2; exports.useState = useState;
exports.useSyncExternalStore = useSyncExternalStore; exports.useSyncExternalStore = useSyncExternalStore;
exports.useTransition = useTransition; exports.useTransition = useTransition;
exports.version = ReactVersion; exports.version = ReactVersion;
@ -24379,11 +24379,11 @@ var require_react_jsx_runtime_development = __commonJS({
return jsxWithValidation(type, props, key, false); return jsxWithValidation(type, props, key, false);
} }
} }
var jsx5 = jsxWithValidationDynamic; var jsx6 = jsxWithValidationDynamic;
var jsxs3 = jsxWithValidationStatic; var jsxs4 = jsxWithValidationStatic;
exports.Fragment = REACT_FRAGMENT_TYPE; exports.Fragment = REACT_FRAGMENT_TYPE;
exports.jsx = jsx5; exports.jsx = jsx6;
exports.jsxs = jsxs3; exports.jsxs = jsxs4;
})(); })();
} }
} }
@ -24404,6 +24404,18 @@ var require_jsx_runtime = __commonJS({
// src/index.tsx // src/index.tsx
var import_client = __toESM(require_client(), 1); var import_client = __toESM(require_client(), 1);
// src/Header.tsx
var import_jsx_runtime = __toESM(require_jsx_runtime(), 1);
function Header() {
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "header", children: [
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h1", { children: "Choose Probabilities" }),
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h5", { children: "X-Axis = Ticks, Y-Axis = Underlying Price" }),
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h5", { children: "Begin with 2 Ticks, T_0 and T_1. Can add more in-between or at ends. Do not have to be equidistant." }),
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h5", { children: 'Begin with 2 Nodes to the "right" of each Node representing what can happen in the next tick. Can add more. No not need to be equidistant.' })
] });
}
var Header_default = Header;
// node_modules/@kurkle/color/dist/color.esm.js // node_modules/@kurkle/color/dist/color.esm.js
function round(v) { function round(v) {
return v + 0.5 | 0; return v + 0.5 | 0;
@ -35977,19 +35989,36 @@ function createTypedChart(type, registerables) {
} }
var Line = /* @__PURE__ */ createTypedChart("line", LineController); var Line = /* @__PURE__ */ createTypedChart("line", LineController);
// src/Header.tsx // src/HistoricalImpliedVolatilityChart.tsx
var import_jsx_runtime = __toESM(require_jsx_runtime(), 1); var import_jsx_runtime2 = __toESM(require_jsx_runtime(), 1);
function Header() { Chart.register(LineElement, plugin_tooltip, plugin_legend, CategoryScale, LinearScale, PointElement);
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "header", children: [ function HistoricalImpliedVolatilityChart() {
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h1", { children: "Choose Probabilities" }), return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h5", { children: "X-Axis = Ticks, Y-Axis = Underlying Price" }), Line,
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h5", { children: "Begin with 2 Ticks, T_0 and T_1. Can add more in-between or at ends. Do not have to be equidistant." }), {
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h5", { children: 'Begin with 2 Nodes to the "right" of each Node representing what can happen in the next tick. Can add more. No not need to be equidistant.' }) datasetIdKey: "id",
] }); data: {
labels: ["Jun", "Jul", "Aug"],
datasets: [
{
//@ts-ignore
id: 1,
label: "",
data: [5, 6, 7]
},
{
//@ts-ignore
id: 2,
label: "",
data: [3, 2, 1]
}
]
}
}
) });
} }
var Header_default = Header;
// src/QuoteDatePicker.tsx // src/Picker.tsx
var import_react3 = __toESM(require_react(), 1); var import_react3 = __toESM(require_react(), 1);
// node_modules/jotai/esm/vanilla.mjs // node_modules/jotai/esm/vanilla.mjs
@ -36637,63 +36666,78 @@ function useAtom(atom2, options) {
]; ];
} }
// src/QuoteDatePicker.tsx // src/Picker.tsx
var import_jsx_runtime2 = __toESM(require_jsx_runtime(), 1); var import_jsx_runtime3 = __toESM(require_jsx_runtime(), 1);
var $dates = atom([]); function create$Picker({ $options = atom([]), $isLoading = atom(false), $selectedOption = atom(""), $url = atom(""), $isEnabled = atom(true) }) {
var $isLoading = atom(false); return atom({
function QuoteDatePicker() { $options,
const [dates, setDates] = useAtom($dates); $isLoading,
$selectedOption,
$url,
Picker: () => {
const [url, setUrl] = useAtom($url);
const [options, setOptions2] = useAtom($options);
const [isLoading, setIsLoading] = useAtom($isLoading); const [isLoading, setIsLoading] = useAtom($isLoading);
const [selectedOption, setSelectedOption] = useAtom($selectedOption);
const [isEnabled, setIsEnabled] = useAtom($isEnabled);
(0, import_react3.useEffect)(() => { (0, import_react3.useEffect)(() => {
fetch("http://127.0.0.1:8234/option_quotes/AAPL/quote_dates").then((x) => x.json()).catch((err) => ["2021-01-02", "2021-01-03", "2021-01-04"]).then((dates_) => { if (isEnabled) {
setDates(dates_); fetch(url).then((x) => x.json()).catch((err) => ["AAPL", "MSFT", "GOOG"]).then((underlyings_) => {
setOptions2(underlyings_);
setIsLoading(false); setIsLoading(false);
}); });
}, []); }
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { children: isLoading ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: "Loading..." }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("select", { children: dates.map( }, [isEnabled, url]);
(date) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("option", { value: date, children: date }, date) return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { children: isLoading ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: "Loading..." }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("select", { value: selectedOption, onChange: (e) => {
) }) }); setSelectedOption(e.target.value);
}, children: [
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("option", { value: "" }, ""),
options.map(
(date) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("option", { value: date, children: date }, date)
)
] }) });
}
});
} }
// src/App.tsx // src/App.tsx
var import_jsx_runtime3 = __toESM(require_jsx_runtime(), 1); var import_jsx_runtime4 = __toESM(require_jsx_runtime(), 1);
Chart.register(LineElement, plugin_tooltip, plugin_legend, CategoryScale, LinearScale, PointElement); var baseUrl = "http://127.0.0.1:8234";
var $underlyingsUrl = atom(`${baseUrl}/option_quotes/underlyings`);
var $underlyingPicker = create$Picker({ $url: $underlyingsUrl });
var $quoteDatePicker = create$Picker({
$url: atom((get) => `${baseUrl}/option_quotes/${get(get($underlyingPicker).$selectedOption)}/quote_dates`),
$isEnabled: atom((get) => get(get($underlyingPicker).$selectedOption) !== "")
});
var $frontMonthPicker = create$Picker({
$url: atom((get) => `${baseUrl}/option_quotes/${get(get($underlyingPicker).$selectedOption)}/${get(get($quoteDatePicker).$selectedOption)}/expirations`),
$isEnabled: atom((get) => get(get($quoteDatePicker).$selectedOption) !== "" && get(get($underlyingPicker).$selectedOption) !== "")
});
var $backMonthPicker = create$Picker({
$url: atom((get) => `${baseUrl}/option_quotes/${get(get($underlyingPicker).$selectedOption)}/${get(get($quoteDatePicker).$selectedOption)}/expirations`),
$isEnabled: atom((get) => get(get($quoteDatePicker).$selectedOption) !== "" && get(get($underlyingPicker).$selectedOption) !== "")
});
function App() { function App() {
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { children: [ const { Picker: UnderlyingPicker, $selectedOption } = useAtomValue($underlyingPicker);
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Header_default, {}), const { Picker: QuoteDatePicker } = useAtomValue($quoteDatePicker);
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(QuoteDatePicker, {}), const { Picker: FrontMonthPicker } = useAtomValue($frontMonthPicker);
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)( const { Picker: BackMonthPicker } = useAtomValue($backMonthPicker);
Line, return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { children: [
{ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Header_default, {}),
datasetIdKey: "id", /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(UnderlyingPicker, {}),
data: { /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(QuoteDatePicker, {}),
labels: ["Jun", "Jul", "Aug"], /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(FrontMonthPicker, {}),
datasets: [ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(BackMonthPicker, {}),
{ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(HistoricalImpliedVolatilityChart, {})
//@ts-ignore
id: 1,
label: "",
data: [5, 6, 7]
},
{
//@ts-ignore
id: 2,
label: "",
data: [3, 2, 1]
}
]
}
}
)
] }); ] });
} }
var App_default = App; var App_default = App;
// src/index.tsx // src/index.tsx
var import_jsx_runtime4 = __toESM(require_jsx_runtime(), 1); var import_jsx_runtime5 = __toESM(require_jsx_runtime(), 1);
var rootEl = document.getElementById("app"); var rootEl = document.getElementById("app");
var Root = (0, import_client.createRoot)(rootEl); var Root = (0, import_client.createRoot)(rootEl);
Root.render(/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(App_default, {})); Root.render(/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(App_default, {}));
/*! Bundled license information: /*! Bundled license information:
react/cjs/react.development.js: react/cjs/react.development.js:

@ -1,34 +1,38 @@
//import Chart from 'chart.js/auto';
import { Chart as ChartJS, Tooltip, Legend, LineElement, CategoryScale, LinearScale, PointElement } from "chart.js";
import { Line } from 'react-chartjs-2';
import Header from './Header'; import Header from './Header';
import { QuoteDatePicker } from "./QuoteDatePicker"; import { HistoricalImpliedVolatilityChart } from "./HistoricalImpliedVolatilityChart";
import { create$Picker } from './Picker';
import { atom as $, useAtomValue } from 'jotai';
ChartJS.register(LineElement, Tooltip, Legend, CategoryScale, LinearScale, PointElement); const baseUrl = 'http://127.0.0.1:8234';
const $underlyingsUrl = $(`${baseUrl}/option_quotes/underlyings`);
const $underlyingPicker = create$Picker({$url:$underlyingsUrl});
const $quoteDatePicker = create$Picker({
$url: $((get) => `${baseUrl}/option_quotes/${get(get($underlyingPicker).$selectedOption)}/quote_dates`),
$isEnabled: $((get) => get(get($underlyingPicker).$selectedOption)!=='')
});
const $frontMonthPicker = create$Picker({
$url: $((get) => `${baseUrl}/option_quotes/${get(get($underlyingPicker).$selectedOption)}/${get(get($quoteDatePicker).$selectedOption)}/expirations`),
$isEnabled: $((get) => get(get($quoteDatePicker).$selectedOption)!=='' && get(get($underlyingPicker).$selectedOption)!=='')
});
const $backMonthPicker = create$Picker({
$url: $((get) => `${baseUrl}/option_quotes/${get(get($underlyingPicker).$selectedOption)}/${get(get($quoteDatePicker).$selectedOption)}/expirations`),
$isEnabled: $((get) => get(get($quoteDatePicker).$selectedOption)!=='' && get(get($underlyingPicker).$selectedOption)!=='')
});
function App() { function App() {
const {Picker:UnderlyingPicker, $selectedOption} = useAtomValue($underlyingPicker);
const {Picker:QuoteDatePicker} = useAtomValue($quoteDatePicker);
const {Picker:FrontMonthPicker} = useAtomValue($frontMonthPicker);
const {Picker:BackMonthPicker} = useAtomValue($backMonthPicker);
return ( return (
<div> <div>
<Header /> <Header />
<UnderlyingPicker />
<QuoteDatePicker /> <QuoteDatePicker />
<Line <FrontMonthPicker />
datasetIdKey='id' <BackMonthPicker />
data={{ <HistoricalImpliedVolatilityChart />
labels: ['Jun', 'Jul', 'Aug'],
datasets: [
{//@ts-ignore
id: 1,
label: '',
data: [5, 6, 7],
},
{//@ts-ignore
id: 2,
label: '',
data: [3, 2, 1],
},
],
}}
/>
</div> </div>
); );
} }

@ -0,0 +1,27 @@
import { Chart as ChartJS, Tooltip, Legend, LineElement, CategoryScale, LinearScale, PointElement } from "chart.js";
import { Line } from 'react-chartjs-2';
ChartJS.register(LineElement, Tooltip, Legend, CategoryScale, LinearScale, PointElement);
export function HistoricalImpliedVolatilityChart(){
return (<div>
<Line
datasetIdKey='id'
data={{
labels: ['Jun', 'Jul', 'Aug'],
datasets: [
{//@ts-ignore
id: 1,
label: '',
data: [5, 6, 7],
},
{//@ts-ignore
id: 2,
label: '',
data: [3, 2, 1],
},
],
}}
/>
</div>);
}

@ -0,0 +1,44 @@
import { useEffect } from "react";
import { atom as $, useAtom, Atom, PrimitiveAtom } from 'jotai';
type PickerInput = { $options?:PrimitiveAtom<Array<string>>, $isLoading?:PrimitiveAtom<boolean>, $selectedOption?:PrimitiveAtom<string>, $url:Atom<string>, $isEnabled?:Atom<boolean> };
export function create$Picker({ $options=$([]), $isLoading=$(false), $selectedOption=$(''), $url=$(''), $isEnabled=$(true) }: PickerInput){
return $({
$options,
$isLoading,
$selectedOption,
$url,
Picker: ()=>{
const [url, setUrl] = useAtom($url);
const [options, setOptions] = useAtom($options);
const [isLoading, setIsLoading] = useAtom($isLoading);
const [selectedOption, setSelectedOption] = useAtom($selectedOption);
const [isEnabled, setIsEnabled] = useAtom($isEnabled);
useEffect(()=>{
if(isEnabled){
fetch(url)
.then(x=>x.json())
.catch((err)=>['AAPL', 'MSFT', 'GOOG'])
.then((underlyings_)=>{ setOptions(underlyings_); setIsLoading(false); })
}
},[isEnabled, url])
return (
<div>
{isLoading
?
<span>Loading...</span>
:
<select value={selectedOption} onChange={(e)=>{ setSelectedOption(e.target.value); }}>
<option key="" value=""></option>
{options.map((date)=>
<option key={date} value={date}>{date}</option>
)}
</select>
}
</div>
);
}
});
}

@ -1,32 +0,0 @@
import { useEffect, useState } from "react";
import { atom as $, useAtom } from 'jotai';
const $dates = $<Array<string>>([]);
const $isLoading = $<boolean>(false);
export function QuoteDatePicker(){
const [dates, setDates] = useAtom($dates);
const [isLoading, setIsLoading] = useAtom($isLoading);
useEffect(()=>{
fetch('http://127.0.0.1:8234/option_quotes/AAPL/quote_dates')
.then(x=>x.json())
.catch((err)=>['2021-01-02', '2021-01-03', '2021-01-04'])
.then((dates_)=>{ setDates(dates_); setIsLoading(false); })
},[])
return (
<div>
{isLoading
?
<span>Loading...</span>
:
<select>
{dates.map((date)=>
<option key={date} value={date}>{date}</option>
)}
</select>
}
</div>
);
}
Loading…
Cancel
Save